diff --git a/sonoff/sonoff.h b/sonoff/sonoff.h index 5b483f5bf..1f7714efd 100644 --- a/sonoff/sonoff.h +++ b/sonoff/sonoff.h @@ -262,10 +262,4 @@ const char kCommandSource[] PROGMEM = "I|MQTT|Restart|Button|Switch|Backlog|Seri const uint8_t kDefaultRfCode[9] PROGMEM = { 0x21, 0x16, 0x01, 0x0E, 0x03, 0x48, 0x2E, 0x1A, 0x00 }; -/*********************************************************************************************\ - * Extern global variables -\*********************************************************************************************/ - -extern uint8_t rotary_changed; // Rotary switch changed - #endif // _SONOFF_H_ diff --git a/sonoff/support_button.ino b/sonoff/support_button.ino index e771a4b89..c32011b42 100644 --- a/sonoff/support_button.ino +++ b/sonoff/support_button.ino @@ -23,44 +23,46 @@ * Button support \*********************************************************************************************/ -unsigned long button_debounce = 0; // Button debounce timer -uint16_t holdbutton[MAX_KEYS] = { 0 }; // Timer for button hold -uint16_t dual_button_code = 0; // Sonoff dual received code +struct BUTTON { + unsigned long debounce = 0; // Button debounce timer + uint16_t hold_timer[MAX_KEYS] = { 0 }; // Timer for button hold + uint16_t dual_code = 0; // Sonoff dual received code -uint8_t lastbutton[MAX_KEYS] = { NOT_PRESSED, NOT_PRESSED, NOT_PRESSED, NOT_PRESSED }; // Last button states -uint8_t multiwindow[MAX_KEYS] = { 0 }; // Max time between button presses to record press count -uint8_t multipress[MAX_KEYS] = { 0 }; // Number of button presses within multiwindow + uint8_t last_state[MAX_KEYS] = { NOT_PRESSED, NOT_PRESSED, NOT_PRESSED, NOT_PRESSED }; // Last button states + uint8_t window_timer[MAX_KEYS] = { 0 }; // Max time between button presses to record press count + uint8_t press_counter[MAX_KEYS] = { 0 }; // Number of button presses within Button.window_timer -uint8_t dual_hex_code = 0; // Sonoff dual input flag -uint8_t key_no_pullup = 0; // key no pullup flag (1 = no pullup) -uint8_t key_inverted = 0; // Key inverted flag (1 = inverted) -uint8_t buttons_present = 0; // Number of buttons found flag -uint8_t button_adc = 99; // ADC0 button number + uint8_t dual_receive_count = 0; // Sonoff dual input flag + uint8_t no_pullup_mask = 0; // key no pullup flag (1 = no pullup) + uint8_t inverted_mask = 0; // Key inverted flag (1 = inverted) + uint8_t present = 0; // Number of buttons found flag + uint8_t adc = 99; // ADC0 button number +} Button; /********************************************************************************************/ void ButtonPullupFlag(uint8 button_bit) { - bitSet(key_no_pullup, button_bit); + bitSet(Button.no_pullup_mask, button_bit); } void ButtonInvertFlag(uint8 button_bit) { - bitSet(key_inverted, button_bit); + bitSet(Button.inverted_mask, button_bit); } void ButtonInit(void) { - buttons_present = 0; + Button.present = 0; for (uint32_t i = 0; i < MAX_KEYS; i++) { if (pin[GPIO_KEY1 +i] < 99) { - buttons_present++; - pinMode(pin[GPIO_KEY1 +i], bitRead(key_no_pullup, i) ? INPUT : ((16 == pin[GPIO_KEY1 +i]) ? INPUT_PULLDOWN_16 : INPUT_PULLUP)); + Button.present++; + pinMode(pin[GPIO_KEY1 +i], bitRead(Button.no_pullup_mask, i) ? INPUT : ((16 == pin[GPIO_KEY1 +i]) ? INPUT_PULLDOWN_16 : INPUT_PULLUP)); } #ifndef USE_ADC_VCC - else if ((99 == button_adc) && ((ADC0_BUTTON == my_adc0) || (ADC0_BUTTON_INV == my_adc0))) { - buttons_present++; - button_adc = i; + else if ((99 == Button.adc) && ((ADC0_BUTTON == my_adc0) || (ADC0_BUTTON_INV == my_adc0))) { + Button.present++; + Button.adc = i; } #endif // USE_ADC_VCC } @@ -68,21 +70,21 @@ void ButtonInit(void) uint8_t ButtonSerial(uint8_t serial_in_byte) { - if (dual_hex_code) { - dual_hex_code--; - if (dual_hex_code) { - dual_button_code = (dual_button_code << 8) | serial_in_byte; + if (Button.dual_receive_count) { + Button.dual_receive_count--; + if (Button.dual_receive_count) { + Button.dual_code = (Button.dual_code << 8) | serial_in_byte; serial_in_byte = 0; } else { if (serial_in_byte != 0xA1) { - dual_button_code = 0; // 0xA1 - End of Sonoff dual button code + Button.dual_code = 0; // 0xA1 - End of Sonoff dual button code } } } if (0xA0 == serial_in_byte) { // 0xA0 - Start of Sonoff dual button code serial_in_byte = 0; - dual_button_code = 0; - dual_hex_code = 3; + Button.dual_code = 0; + Button.dual_receive_count = 3; } return serial_in_byte; @@ -117,22 +119,22 @@ void ButtonHandler(void) if (!button_index && ((SONOFF_DUAL == my_module_type) || (CH4 == my_module_type))) { button_present = 1; - if (dual_button_code) { - AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_APPLICATION D_BUTTON " " D_CODE " %04X"), dual_button_code); + if (Button.dual_code) { + AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_APPLICATION D_BUTTON " " D_CODE " %04X"), Button.dual_code); button = PRESSED; - if (0xF500 == dual_button_code) { // Button hold - holdbutton[button_index] = (loops_per_second * Settings.param[P_HOLD_TIME] / 10) -1; // SetOption32 (40) + if (0xF500 == Button.dual_code) { // Button hold + Button.hold_timer[button_index] = (loops_per_second * Settings.param[P_HOLD_TIME] / 10) -1; // SetOption32 (40) hold_time_extent = 1; } - dual_button_code = 0; + Button.dual_code = 0; } } else if (pin[GPIO_KEY1 +button_index] < 99) { button_present = 1; - button = (digitalRead(pin[GPIO_KEY1 +button_index]) != bitRead(key_inverted, button_index)); + button = (digitalRead(pin[GPIO_KEY1 +button_index]) != bitRead(Button.inverted_mask, button_index)); } #ifndef USE_ADC_VCC - if (button_adc == button_index) { + if (Button.adc == button_index) { button_present = 1; if (ADC0_BUTTON_INV == my_adc0) { button = (AdcRead(1) < 128); @@ -150,17 +152,17 @@ void ButtonHandler(void) // Serviced } else if (SONOFF_4CHPRO == my_module_type) { - if (holdbutton[button_index]) { holdbutton[button_index]--; } + if (Button.hold_timer[button_index]) { Button.hold_timer[button_index]--; } bool button_pressed = false; - if ((PRESSED == button) && (NOT_PRESSED == lastbutton[button_index])) { + if ((PRESSED == button) && (NOT_PRESSED == Button.last_state[button_index])) { AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_APPLICATION D_BUTTON "%d " D_LEVEL_10), button_index +1); - holdbutton[button_index] = loops_per_second; + Button.hold_timer[button_index] = loops_per_second; button_pressed = true; } - if ((NOT_PRESSED == button) && (PRESSED == lastbutton[button_index])) { + if ((NOT_PRESSED == button) && (PRESSED == Button.last_state[button_index])) { AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_APPLICATION D_BUTTON "%d " D_LEVEL_01), button_index +1); - if (!holdbutton[button_index]) { button_pressed = true; } // Do not allow within 1 second + if (!Button.hold_timer[button_index]) { button_pressed = true; } // Do not allow within 1 second } if (button_pressed) { if (!SendKey(0, button_index +1, POWER_TOGGLE)) { // Execute Toggle command via MQTT if ButtonTopic is set @@ -169,26 +171,26 @@ void ButtonHandler(void) } } else { - if ((PRESSED == button) && (NOT_PRESSED == lastbutton[button_index])) { + if ((PRESSED == button) && (NOT_PRESSED == Button.last_state[button_index])) { if (Settings.flag.button_single) { // SetOption13 (0) - Allow only single button press for immediate action AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_APPLICATION D_BUTTON "%d " D_IMMEDIATE), button_index +1); if (!SendKey(0, button_index +1, POWER_TOGGLE)) { // Execute Toggle command via MQTT if ButtonTopic is set ExecuteCommandPower(button_index +1, POWER_TOGGLE, SRC_BUTTON); // Execute Toggle command internally } } else { - multipress[button_index] = (multiwindow[button_index]) ? multipress[button_index] +1 : 1; - AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_APPLICATION D_BUTTON "%d " D_MULTI_PRESS " %d"), button_index +1, multipress[button_index]); - multiwindow[button_index] = loops_per_second / 2; // 0.5 second multi press window + Button.press_counter[button_index] = (Button.window_timer[button_index]) ? Button.press_counter[button_index] +1 : 1; + AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_APPLICATION D_BUTTON "%d " D_MULTI_PRESS " %d"), button_index +1, Button.press_counter[button_index]); + Button.window_timer[button_index] = loops_per_second / 2; // 0.5 second multi press window } blinks = 201; } if (NOT_PRESSED == button) { - holdbutton[button_index] = 0; + Button.hold_timer[button_index] = 0; } else { - holdbutton[button_index]++; + Button.hold_timer[button_index]++; if (Settings.flag.button_single) { // SetOption13 (0) - Allow only single button press for immediate action - if (holdbutton[button_index] == loops_per_second * hold_time_extent * Settings.param[P_HOLD_TIME] / 10) { // SetOption32 (40) - Button held for factor times longer + if (Button.hold_timer[button_index] == loops_per_second * hold_time_extent * Settings.param[P_HOLD_TIME] / 10) { // SetOption32 (40) - Button held for factor times longer // Settings.flag.button_single = 0; snprintf_P(scmnd, sizeof(scmnd), PSTR(D_CMND_SETOPTION "13 0")); // Disable single press only ExecuteCommand(scmnd, SRC_BUTTON); @@ -196,19 +198,19 @@ void ButtonHandler(void) } else { if (Settings.flag.button_restrict) { // SetOption1 (0) - Button restriction if (Settings.param[P_HOLD_IGNORE] > 0) { // SetOption40 (0) - Do not ignore button hold - if (holdbutton[button_index] > loops_per_second * Settings.param[P_HOLD_IGNORE] / 10) { - holdbutton[button_index] = 0; // Reset button hold counter to stay below hold trigger - multipress[button_index] = 0; // Discard button press to disable functionality + if (Button.hold_timer[button_index] > loops_per_second * Settings.param[P_HOLD_IGNORE] / 10) { + Button.hold_timer[button_index] = 0; // Reset button hold counter to stay below hold trigger + Button.press_counter[button_index] = 0; // Discard button press to disable functionality DEBUG_CORE_LOG(PSTR("BTN: " D_BUTTON "%d cancel by " D_CMND_SETOPTION "40 %d"), button_index +1, Settings.param[P_HOLD_IGNORE]); } } - if (holdbutton[button_index] == loops_per_second * Settings.param[P_HOLD_TIME] / 10) { // SetOption32 (40) - Button hold - multipress[button_index] = 0; + if (Button.hold_timer[button_index] == loops_per_second * Settings.param[P_HOLD_TIME] / 10) { // SetOption32 (40) - Button hold + Button.press_counter[button_index] = 0; SendKey(0, button_index +1, 3); // Execute Hold command via MQTT if ButtonTopic is set } } else { - if (holdbutton[button_index] == loops_per_second * hold_time_extent * Settings.param[P_HOLD_TIME] / 10) { // SetOption32 (40) - Button held for factor times longer - multipress[button_index] = 0; + if (Button.hold_timer[button_index] == loops_per_second * hold_time_extent * Settings.param[P_HOLD_TIME] / 10) { // SetOption32 (40) - Button held for factor times longer + Button.press_counter[button_index] = 0; snprintf_P(scmnd, sizeof(scmnd), PSTR(D_CMND_RESET " 1")); ExecuteCommand(scmnd, SRC_BUTTON); } @@ -217,64 +219,62 @@ void ButtonHandler(void) } if (!Settings.flag.button_single) { // SetOption13 (0) - Allow multi-press - if (multiwindow[button_index]) { - multiwindow[button_index]--; + if (Button.window_timer[button_index]) { + Button.window_timer[button_index]--; } else { - if (!restart_flag && !holdbutton[button_index] && (multipress[button_index] > 0) && (multipress[button_index] < MAX_BUTTON_COMMANDS +3)) { + if (!restart_flag && !Button.hold_timer[button_index] && (Button.press_counter[button_index] > 0) && (Button.press_counter[button_index] < MAX_BUTTON_COMMANDS +3)) { bool single_press = false; - if (multipress[button_index] < 3) { // Single or Double press + if (Button.press_counter[button_index] < 3) { // Single or Double press if ((SONOFF_DUAL_R2 == my_module_type) || (SONOFF_DUAL == my_module_type) || (CH4 == my_module_type)) { single_press = true; } else { - single_press = (Settings.flag.button_swap +1 == multipress[button_index]); // SetOption11 (0) - if ((1 == buttons_present) && (2 == devices_present)) { // Single Button with two devices only + single_press = (Settings.flag.button_swap +1 == Button.press_counter[button_index]); // SetOption11 (0) + if ((1 == Button.present) && (2 == devices_present)) { // Single Button with two devices only if (Settings.flag.button_swap) { // SetOption11 (0) - multipress[button_index] = (single_press) ? 1 : 2; + Button.press_counter[button_index] = (single_press) ? 1 : 2; } } else { - multipress[button_index] = 1; + Button.press_counter[button_index] = 1; } } } -#ifdef USE_LIGHT - if ((MI_DESK_LAMP == my_module_type) && (button_index == 0) && (rotary_changed) && (LightPower())) { - rotary_changed = 0; // Color temp changed, no need to turn of the light - } else { +#if defined(USE_LIGHT) && defined(ROTARY_V1) + if (!((0 == button_index) && RotaryButtonPressed())) { #endif - if (single_press && SendKey(0, button_index + multipress[button_index], POWER_TOGGLE)) { // Execute Toggle command via MQTT if ButtonTopic is set + if (single_press && SendKey(0, button_index + Button.press_counter[button_index], POWER_TOGGLE)) { // Execute Toggle command via MQTT if ButtonTopic is set // Success } else { - if (multipress[button_index] < 3) { // Single or Double press + if (Button.press_counter[button_index] < 3) { // Single or Double press if (WifiState() > WIFI_RESTART) { // WPSconfig, Smartconfig or Wifimanager active restart_flag = 1; } else { - ExecuteCommandPower(button_index + multipress[button_index], POWER_TOGGLE, SRC_BUTTON); // Execute Toggle command internally + ExecuteCommandPower(button_index + Button.press_counter[button_index], POWER_TOGGLE, SRC_BUTTON); // Execute Toggle command internally } } else { // 3 - 7 press if (!Settings.flag.button_restrict) { // SetOption1 (0) - snprintf_P(scmnd, sizeof(scmnd), kCommands[multipress[button_index] -3]); + snprintf_P(scmnd, sizeof(scmnd), kCommands[Button.press_counter[button_index] -3]); ExecuteCommand(scmnd, SRC_BUTTON); } } } -#ifdef USE_LIGHT +#if defined(USE_LIGHT) && defined(ROTARY_V1) } #endif - multipress[button_index] = 0; + Button.press_counter[button_index] = 0; } } } } } - lastbutton[button_index] = button; + Button.last_state[button_index] = button; } } void ButtonLoop(void) { - if (buttons_present) { - if (TimeReached(button_debounce)) { - SetNextTimeInterval(button_debounce, Settings.button_debounce); // ButtonDebounce (50) + if (Button.present) { + if (TimeReached(Button.debounce)) { + SetNextTimeInterval(Button.debounce, Settings.button_debounce); // ButtonDebounce (50) ButtonHandler(); } } diff --git a/sonoff/support_rotary.ino b/sonoff/support_rotary.ino index d327bd116..cc1ca0eb2 100644 --- a/sonoff/support_rotary.ino +++ b/sonoff/support_rotary.ino @@ -18,20 +18,21 @@ */ #ifdef USE_LIGHT +//#define ROTARY_V1 +#ifdef ROTARY_V1 /*********************************************************************************************\ * Rotary support \*********************************************************************************************/ -unsigned long rotary_debounce = 0; // Rotary debounce timer -uint8_t rotaries_found = 0; -uint8_t rotary_state = 0; -uint8_t rotary_position = 128; -uint8_t rotary_last_position = 128; -uint8_t interrupts_in_use = 0; -uint8_t rotary_changed = 0; - -//#define ROTARY_V1 -#ifdef ROTARY_V1 +struct ROTARY { + unsigned long debounce = 0; // Rotary debounce timer + uint8_t present = 0; + uint8_t state = 0; + uint8_t position = 128; + uint8_t last_position = 128; + uint8_t interrupts_in_use_count = 0; + uint8_t changed = 0; +} Rotary; /********************************************************************************************/ @@ -43,22 +44,22 @@ void update_position(void) * https://github.com/PaulStoffregen/Encoder/blob/master/Encoder.h */ - s = rotary_state & 3; + s = Rotary.state & 3; if (digitalRead(pin[GPIO_ROT1A])) s |= 4; if (digitalRead(pin[GPIO_ROT1B])) s |= 8; switch (s) { case 0: case 5: case 10: case 15: break; case 1: case 7: case 8: case 14: - rotary_position++; break; + Rotary.position++; break; case 2: case 4: case 11: case 13: - rotary_position--; break; + Rotary.position--; break; case 3: case 12: - rotary_position = rotary_position + 2; break; + Rotary.position = Rotary.position + 2; break; default: - rotary_position = rotary_position - 2; break; + Rotary.position = Rotary.position - 2; break; } - rotary_state = (s >> 2); + Rotary.state = (s >> 2); } #ifndef ARDUINO_ESP8266_RELEASE_2_3_0 // Fix core 2.5.x ISR not in IRAM Exception @@ -74,11 +75,20 @@ void update_rotary(void) } } +bool RotaryButtonPressed(void) +{ + if ((MI_DESK_LAMP == my_module_type) && (Rotary.changed) && LightPower()) { + Rotary.changed = 0; // Color temp changed, no need to turn of the light + return true; + } + return false; +} + void RotaryInit(void) { - rotaries_found = 0; + Rotary.present = 0; if ((pin[GPIO_ROT1A] < 99) && (pin[GPIO_ROT1B] < 99)) { - rotaries_found++; + Rotary.present++; pinMode(pin[GPIO_ROT1A], INPUT_PULLUP); pinMode(pin[GPIO_ROT1B], INPUT_PULLUP); @@ -87,11 +97,11 @@ void RotaryInit(void) if ((pin[GPIO_ROT1A] < 6) || (pin[GPIO_ROT1A] > 11)) { attachInterrupt(digitalPinToInterrupt(pin[GPIO_ROT1A]), update_rotary, CHANGE); - interrupts_in_use++; + Rotary.interrupts_in_use_count++; } if ((pin[GPIO_ROT1B] < 6) || (pin[GPIO_ROT1B] > 11)) { attachInterrupt(digitalPinToInterrupt(pin[GPIO_ROT1B]), update_rotary, CHANGE); - interrupts_in_use++; + Rotary.interrupts_in_use_count++; } } } @@ -102,53 +112,53 @@ void RotaryInit(void) void RotaryHandler(void) { - if (interrupts_in_use < 2) { + if (Rotary.interrupts_in_use_count < 2) { noInterrupts(); update_rotary(); } else { noInterrupts(); } - if (rotary_last_position != rotary_position) { + if (Rotary.last_position != Rotary.position) { if (MI_DESK_LAMP == my_module_type) { // Mi Desk lamp - if (holdbutton[0]) { - rotary_changed = 1; + if (Button.hold_timer[0]) { + Rotary.changed = 1; // button1 is pressed: set color temperature int16_t t = LightGetColorTemp(); - t = t + (rotary_position - rotary_last_position); + t = t + (Rotary.position - Rotary.last_position); if (t < 153) { t = 153; } if (t > 500) { t = 500; } - DEBUG_CORE_LOG(PSTR("ROT: " D_CMND_COLORTEMPERATURE " %d"), rotary_position - rotary_last_position); + DEBUG_CORE_LOG(PSTR("ROT: " D_CMND_COLORTEMPERATURE " %d"), Rotary.position - Rotary.last_position); LightSetColorTemp((uint16_t)t); } else { int8_t d = Settings.light_dimmer; - d = d + (rotary_position - rotary_last_position); + d = d + (Rotary.position - Rotary.last_position); if (d < 1) { d = 1; } if (d > 100) { d = 100; } - DEBUG_CORE_LOG(PSTR("ROT: " D_CMND_DIMMER " %d"), rotary_position - rotary_last_position); + DEBUG_CORE_LOG(PSTR("ROT: " D_CMND_DIMMER " %d"), Rotary.position - Rotary.last_position); LightSetDimmer((uint8_t)d); Settings.light_dimmer = d; } } - rotary_last_position = 128; - rotary_position = 128; + Rotary.last_position = 128; + Rotary.position = 128; } interrupts(); } void RotaryLoop(void) { - if (rotaries_found) { - if (TimeReached(rotary_debounce)) { - SetNextTimeInterval(rotary_debounce, Settings.button_debounce); // Using button_debounce setting for this as well + if (Rotary.present) { + if (TimeReached(Rotary.debounce)) { + SetNextTimeInterval(Rotary.debounce, Settings.button_debounce); // Using button_debounce setting for this as well RotaryHandler(); } } diff --git a/sonoff/support_switch.ino b/sonoff/support_switch.ino index ca1d486fa..40bbcc2b9 100644 --- a/sonoff/support_switch.ino +++ b/sonoff/support_switch.ino @@ -31,34 +31,36 @@ const uint8_t SWITCH_PROBE_INTERVAL = 10; // Time in milliseconds between swit Ticker TickerSwitch; -unsigned long switch_debounce = 0; // Switch debounce timer -uint16_t switch_no_pullup = 0; // Switch pull-up bitmask flags -uint8_t switch_state_buf[MAX_SWITCHES] = { 0 }; -uint8_t lastwallswitch[MAX_SWITCHES]; // Last wall switch states -uint8_t holdwallswitch[MAX_SWITCHES] = { 0 }; // Timer for wallswitch push button hold -uint8_t switch_virtual[MAX_SWITCHES]; // Virtual switch states -uint8_t switches_found = 0; +struct SWITCH { + unsigned long debounce = 0; // Switch debounce timer + uint16_t no_pullup_mask = 0; // Switch pull-up bitmask flags + uint8_t state[MAX_SWITCHES] = { 0 }; + uint8_t last_state[MAX_SWITCHES]; // Last wall switch states + uint8_t hold_timer[MAX_SWITCHES] = { 0 }; // Timer for wallswitch push button hold + uint8_t virtual_state[MAX_SWITCHES]; // Virtual switch states + uint8_t present = 0; +} Switch; /********************************************************************************************/ void SwitchPullupFlag(uint16 switch_bit) { - bitSet(switch_no_pullup, switch_bit); + bitSet(Switch.no_pullup_mask, switch_bit); } uint8_t SwitchLastState(uint8_t index) { - return lastwallswitch[index]; + return Switch.last_state[index]; } void SwitchSetVirtual(uint8_t index, uint8_t state) { - switch_virtual[index] = state; + Switch.virtual_state[index] = state; } uint8_t SwitchGetVirtual(uint8_t index) { - return switch_virtual[index]; + return Switch.virtual_state[index]; } /*********************************************************************************************/ @@ -77,29 +79,29 @@ void SwitchProbe(void) if (1 == digitalRead(pin[GPIO_SWT1 +i])) { if (force_high) { // Enabled with SwitchDebounce x1 - if (1 == switch_virtual[i]) { - switch_state_buf[i] = state_filter; // With noisy input keep current state 1 unless constant 0 + if (1 == Switch.virtual_state[i]) { + Switch.state[i] = state_filter; // With noisy input keep current state 1 unless constant 0 } } - if (switch_state_buf[i] < state_filter) { - switch_state_buf[i]++; - if (state_filter == switch_state_buf[i]) { - switch_virtual[i] = 1; + if (Switch.state[i] < state_filter) { + Switch.state[i]++; + if (state_filter == Switch.state[i]) { + Switch.virtual_state[i] = 1; } } } else { if (force_low) { // Enabled with SwitchDebounce x2 - if (0 == switch_virtual[i]) { - switch_state_buf[i] = 0; // With noisy input keep current state 0 unless constant 1 + if (0 == Switch.virtual_state[i]) { + Switch.state[i] = 0; // With noisy input keep current state 0 unless constant 1 } } - if (switch_state_buf[i] > 0) { - switch_state_buf[i]--; - if (0 == switch_state_buf[i]) { - switch_virtual[i] = 0; + if (Switch.state[i] > 0) { + Switch.state[i]--; + if (0 == Switch.state[i]) { + Switch.virtual_state[i] = 0; } } } @@ -110,17 +112,17 @@ void SwitchProbe(void) void SwitchInit(void) { - switches_found = 0; + Switch.present = 0; for (uint32_t i = 0; i < MAX_SWITCHES; i++) { - lastwallswitch[i] = 1; // Init global to virtual switch state; + Switch.last_state[i] = 1; // Init global to virtual switch state; if (pin[GPIO_SWT1 +i] < 99) { - switches_found++; - pinMode(pin[GPIO_SWT1 +i], bitRead(switch_no_pullup, i) ? INPUT : ((16 == pin[GPIO_SWT1 +i]) ? INPUT_PULLDOWN_16 : INPUT_PULLUP)); - lastwallswitch[i] = digitalRead(pin[GPIO_SWT1 +i]); // Set global now so doesn't change the saved power state on first switch check + Switch.present++; + pinMode(pin[GPIO_SWT1 +i], bitRead(Switch.no_pullup_mask, i) ? INPUT : ((16 == pin[GPIO_SWT1 +i]) ? INPUT_PULLDOWN_16 : INPUT_PULLUP)); + Switch.last_state[i] = digitalRead(pin[GPIO_SWT1 +i]); // Set global now so doesn't change the saved power state on first switch check } - switch_virtual[i] = lastwallswitch[i]; + Switch.virtual_state[i] = Switch.last_state[i]; } - if (switches_found) { TickerSwitch.attach_ms(SWITCH_PROBE_INTERVAL, SwitchProbe); } + if (Switch.present) { TickerSwitch.attach_ms(SWITCH_PROBE_INTERVAL, SwitchProbe); } } /*********************************************************************************************\ @@ -138,18 +140,18 @@ void SwitchHandler(uint8_t mode) for (uint32_t i = 0; i < MAX_SWITCHES; i++) { if ((pin[GPIO_SWT1 +i] < 99) || (mode)) { - if (holdwallswitch[i]) { - holdwallswitch[i]--; - if (0 == holdwallswitch[i]) { + if (Switch.hold_timer[i]) { + Switch.hold_timer[i]--; + if (0 == Switch.hold_timer[i]) { SendKey(1, i +1, 3); // Execute command via MQTT } } - button = switch_virtual[i]; + button = Switch.virtual_state[i]; // enum SwitchModeOptions {TOGGLE, FOLLOW, FOLLOW_INV, PUSHBUTTON, PUSHBUTTON_INV, PUSHBUTTONHOLD, PUSHBUTTONHOLD_INV, PUSHBUTTON_TOGGLE, MAX_SWITCH_OPTION}; - if (button != lastwallswitch[i]) { + if (button != Switch.last_state[i]) { switchflag = 3; switch (Settings.switchmode[i]) { case TOGGLE: @@ -162,35 +164,35 @@ void SwitchHandler(uint8_t mode) switchflag = ~button &1; // Follow inverted wall switch state break; case PUSHBUTTON: - if ((PRESSED == button) && (NOT_PRESSED == lastwallswitch[i])) { + if ((PRESSED == button) && (NOT_PRESSED == Switch.last_state[i])) { switchflag = 2; // Toggle with pushbutton to Gnd } break; case PUSHBUTTON_INV: - if ((NOT_PRESSED == button) && (PRESSED == lastwallswitch[i])) { + if ((NOT_PRESSED == button) && (PRESSED == Switch.last_state[i])) { switchflag = 2; // Toggle with releasing pushbutton from Gnd } break; case PUSHBUTTON_TOGGLE: - if (button != lastwallswitch[i]) { + if (button != Switch.last_state[i]) { switchflag = 2; // Toggle with any pushbutton change } break; case PUSHBUTTONHOLD: - if ((PRESSED == button) && (NOT_PRESSED == lastwallswitch[i])) { - holdwallswitch[i] = loops_per_second * Settings.param[P_HOLD_TIME] / 10; + if ((PRESSED == button) && (NOT_PRESSED == Switch.last_state[i])) { + Switch.hold_timer[i] = loops_per_second * Settings.param[P_HOLD_TIME] / 10; } - if ((NOT_PRESSED == button) && (PRESSED == lastwallswitch[i]) && (holdwallswitch[i])) { - holdwallswitch[i] = 0; + if ((NOT_PRESSED == button) && (PRESSED == Switch.last_state[i]) && (Switch.hold_timer[i])) { + Switch.hold_timer[i] = 0; switchflag = 2; // Toggle with pushbutton to Gnd } break; case PUSHBUTTONHOLD_INV: - if ((NOT_PRESSED == button) && (PRESSED == lastwallswitch[i])) { - holdwallswitch[i] = loops_per_second * Settings.param[P_HOLD_TIME] / 10; + if ((NOT_PRESSED == button) && (PRESSED == Switch.last_state[i])) { + Switch.hold_timer[i] = loops_per_second * Settings.param[P_HOLD_TIME] / 10; } - if ((PRESSED == button) && (NOT_PRESSED == lastwallswitch[i]) && (holdwallswitch[i])) { - holdwallswitch[i] = 0; + if ((PRESSED == button) && (NOT_PRESSED == Switch.last_state[i]) && (Switch.hold_timer[i])) { + Switch.hold_timer[i] = 0; switchflag = 2; // Toggle with pushbutton to Gnd } break; @@ -202,7 +204,7 @@ void SwitchHandler(uint8_t mode) } } - lastwallswitch[i] = button; + Switch.last_state[i] = button; } } } @@ -210,9 +212,9 @@ void SwitchHandler(uint8_t mode) void SwitchLoop(void) { - if (switches_found) { - if (TimeReached(switch_debounce)) { - SetNextTimeInterval(switch_debounce, Settings.switch_debounce); + if (Switch.present) { + if (TimeReached(Switch.debounce)) { + SetNextTimeInterval(Switch.debounce, Settings.switch_debounce); SwitchHandler(0); } } diff --git a/sonoff/xdrv_16_tuyadimmer.ino b/sonoff/xdrv_16_tuyadimmer.ino index cb18f2891..b3b2ca0ea 100644 --- a/sonoff/xdrv_16_tuyadimmer.ino +++ b/sonoff/xdrv_16_tuyadimmer.ino @@ -372,7 +372,7 @@ void TuyaSerialInput(void) bool TuyaButtonPressed(void) { - if (!XdrvMailbox.index && ((PRESSED == XdrvMailbox.payload) && (NOT_PRESSED == lastbutton[XdrvMailbox.index]))) { + if (!XdrvMailbox.index && ((PRESSED == XdrvMailbox.payload) && (NOT_PRESSED == Button.last_state[XdrvMailbox.index]))) { AddLog_P(LOG_LEVEL_DEBUG, PSTR("TYA: Reset GPIO triggered")); TuyaResetWifi(); return true; // Reset GPIO served here