diff --git a/src/httpserver/new_http.c b/src/httpserver/new_http.c index 116f92d33..775611c80 100644 --- a/src/httpserver/new_http.c +++ b/src/httpserver/new_http.c @@ -233,6 +233,7 @@ const char *htmlPinRoleNames[] = { "Btn_Tgl_All_n", "DigitalInput", "DigitalInput_n", + "ToggleChannelOnToggle", "e", "e", }; diff --git a/src/new_pins.c b/src/new_pins.c index 557b54199..5b12a89fc 100644 --- a/src/new_pins.c +++ b/src/new_pins.c @@ -604,6 +604,9 @@ void PIN_Input_Handler(int pinIndex) } } +byte g_timesDown[PLATFORM_GPIO_MAX]; +byte g_timesUp[PLATFORM_GPIO_MAX]; +byte g_lastValidState[PLATFORM_GPIO_MAX]; // background ticks, timer repeat invoking interval 5ms. void PIN_ticks(void *param) @@ -621,6 +624,33 @@ void PIN_ticks(void *param) // read pin digital value (and already invert it if needed) value = PIN_ReadDigitalInputValue_WithInversionIncluded(i); CHANNEL_Set(g_cfg.pins.channels[i], value,0); + } else if(g_cfg.pins.roles[i] == IOR_ToggleChannelOnToggle) { + // we must detect a toggle, but with debouncing + value = PIN_ReadDigitalInputValue_WithInversionIncluded(i); + if(value) { + if(g_timesUp[i] > 50) { + if(g_lastValidState[i] != value) { + // became up + g_lastValidState[i] = value; + CHANNEL_Toggle(g_cfg.pins.channels[i]); + } + } else { + g_timesUp[i]++; + } + g_timesDown[i] = 0; + } else { + if(g_timesDown[i] > 50) { + if(g_lastValidState[i] != value) { + // became down + g_lastValidState[i] = value; + CHANNEL_Toggle(g_cfg.pins.channels[i]); + } + } else { + g_timesDown[i]++; + } + g_timesUp[i] = 0; + + } } } } diff --git a/src/new_pins.h b/src/new_pins.h index acae4cfef..5e678b32b 100644 --- a/src/new_pins.h +++ b/src/new_pins.h @@ -24,6 +24,7 @@ enum IORole { IOR_DigitalInput, // as above, but inverted IOR_DigitalInput_n, + IOR_ToggleChannelOnToggle, IOR_Total_Options, };