I’ve added a 4 line LED display to an ESP32 Sprinkler Controller. I’m attempting to rotate two data points on one line of the display. I found an example of how to do so on GITHUB at 9-Valve-Sprinkler-Controller. My ultimate goal is to reduce the number of items displayed on this line to two, rather than three. The line of code I don’t fully understand is;
display_phase = (id(display_passthrough_counter) & 6) >> 1;
From my research, I believe the line of code is performing a bit shift. If this is the case, please help me understand how that works. How do the “& 6” and “>> 1” figure into the code?
For clarity, here’s the section of code this line comes from;
lambda: |-
id(display_passthrough_counter)++;
// Current run state
static const char *run_state_string;
// Establish state - rain, or auto off string
if(((id(automatic_watering_enable) == false) || (id(is_raining) == true )) && (id(sprinklers_status).state == false)){
if(id(is_raining) == true){
run_state_string = "${rain_string}";
} else {
run_state_string = "${auto_off_string}";
}
} else {
// Convert Enum to string
int state = id($devicename).controller_state();
switch(state){
case 0:
run_state_string = "${idle_state_string}";
break;
case 1:
run_state_string = "${starting_state_string}";
break;
case 2:
run_state_string = "${active_state_string}";
break;
case 3:
run_state_string = "${stopping_state_string}";
break;
case 4:
run_state_string = "${bypass_state_string}";
break;
default:
run_state_string = "UNKNOWN";
break;
}
}
// Line 0
// Print the current time
if(id(ds1307_time).is_failed() == false){
it.strftime(0, 0, "%a %b %d/%y %I:%M", id(ds1307_time).now());
if (id(ds1307_time).now().hour <12){
// Use shadow address ("\x08") of custom character for "A". Using "\x00" fails to display character.
it.print(19,0, "\x08");
} else {
it.print(19,0, "\x01");
}
} else {
it.print(0, 0, "Date Unknown!");
it.print(14, 0, "--:--");
}
// Line 1
it.print(0, 1, run_state_string );
if (id(display_ip_address) == true){
std::string val = id(our_ip_address).state;
// Line 3
it.print(0, 3, val.c_str()); // Display IP address instead of valve state
} else {
int display_phase = 0;
std::string val;
char dbm_str[17];
// Alternate between valve state and WiFi disconnected message if WiFi is disconnected.
if((id(wifi_connection_state) == true) || (((id(display_passthrough_counter) & 2) == 0))){
// This handles the state of the fault LED for all fault types
if(id(has_fault) == false){
// Turn off fault LED
digitalWrite(13, false);
} else {
// Turn on fault LED
digitalWrite(13, true);
}
// If no WiFi fault, cycle through valve state, ip address, ssid, and rssi
if(id(wifi_connection_state) == true){
display_phase = (id(display_passthrough_counter) & 6) >> 1;
switch(display_phase){
case 1:
// Display IP address
val = id(our_ip_address).state;
it.printf(0, 3, "IP: %s", val.c_str());
break;
case 2:
// Display SSID
val = id(network_ssid).state;
it.printf(0, 3, "SSID: %s", val.c_str());
break;
case 3: // RSSI
// Display RSSI
val = id(wifi_signal_dbm).state;
snprintf(dbm_str, 16, "RSSI: %d dBm",(int8_t) val.c_str()[0]);
it.print(0, 3, dbm_str);
break;
default:
// Valve status
// Update current open valve
if (id(sprinklers_status).state == true){
// Controller running, so a valve should be open
// Display Zone Name and Time Remaning
// Line 3
it.print(0, 3, id(valves_status_string));
it.printf(12, 3, "T:%s", id(current_zone_time_remaining).c_str());
} else {
// No valves open
// Line 3
it.print(0, 3, id(to_string("${valves_idle_string}")));
}
break;
}
} else {
// Display "No WiFi Conn!"
// If no fault, then set turn on fault led
// This will flash the fault led if there isn't any WiFi connection.
if(id(has_fault) == false){
digitalWrite(13, true);
}
// Line 3
it.print(0, 3, id(to_string("${no_wifi_string}")));
}
}
}