2020-03-25 09:00:55 +01:00
# include "wled.h"
2020-03-25 10:14:23 +01:00
2016-12-31 00:38:51 +01:00
/*
* Physical IO
*/
2021-04-12 00:45:33 +02:00
# define WLED_DEBOUNCE_THRESHOLD 50 //only consider button input of at least 50ms as valid (debouncing)
2021-05-20 19:54:07 +02:00
void shortPressAction ( uint8_t b )
2019-03-13 11:13:03 +01:00
{
2021-05-20 19:54:07 +02:00
if ( ! macroButton [ b ] )
2019-03-13 11:13:03 +01:00
{
toggleOnOff ( ) ;
2020-02-22 16:17:32 +01:00
colorUpdated ( NOTIFIER_CALL_MODE_BUTTON ) ;
2019-03-13 11:13:03 +01:00
} else {
2021-05-20 19:54:07 +02:00
applyPreset ( macroButton [ b ] ) ;
2019-03-13 11:13:03 +01:00
}
}
2021-05-20 19:54:07 +02:00
bool isButtonPressed ( uint8_t i )
2020-09-20 16:12:46 +02:00
{
2021-05-20 19:54:07 +02:00
if ( btnPin [ i ] < 0 ) return false ;
switch ( buttonType [ i ] ) {
case BTN_TYPE_NONE :
case BTN_TYPE_RESERVED :
break ;
case BTN_TYPE_PUSH :
case BTN_TYPE_SWITCH :
if ( digitalRead ( btnPin [ i ] ) = = LOW ) return true ;
break ;
case BTN_TYPE_PUSH_ACT_HIGH :
case BTN_TYPE_SWITCH_ACT_HIGH :
if ( digitalRead ( btnPin [ i ] ) = = HIGH ) return true ;
break ;
case BTN_TYPE_TOUCH :
# ifdef ARDUINO_ARCH_ESP32
if ( touchRead ( btnPin [ i ] ) < = touchThreshold ) return true ;
# endif
break ;
}
2020-09-20 16:12:46 +02:00
return false ;
}
2019-03-13 11:13:03 +01:00
2021-05-20 19:54:07 +02:00
void handleSwitch ( uint8_t b )
2021-04-12 00:45:33 +02:00
{
2021-05-20 19:54:07 +02:00
if ( buttonPressedBefore [ b ] ! = isButtonPressed ( b ) ) {
buttonPressedTime [ b ] = millis ( ) ;
buttonPressedBefore [ b ] = ! buttonPressedBefore [ b ] ;
2021-04-12 00:45:33 +02:00
}
2021-05-20 19:54:07 +02:00
if ( buttonLongPressed [ b ] = = buttonPressedBefore [ b ] ) return ;
2021-04-12 00:45:33 +02:00
2021-05-20 19:54:07 +02:00
if ( millis ( ) - buttonPressedTime [ b ] > WLED_DEBOUNCE_THRESHOLD ) { //fire edge event only after 50ms without change (debounce)
if ( buttonPressedBefore [ b ] ) { //LOW, falling edge, switch closed
if ( macroButton [ b ] ) applyPreset ( macroButton [ b ] ) ;
2021-04-12 00:45:33 +02:00
else { //turn on
if ( ! bri ) { toggleOnOff ( ) ; colorUpdated ( NOTIFIER_CALL_MODE_BUTTON ) ; }
}
} else { //HIGH, rising edge, switch opened
2021-05-20 19:54:07 +02:00
if ( macroLongPress [ b ] ) applyPreset ( macroLongPress [ b ] ) ;
2021-04-12 00:45:33 +02:00
else { //turn off
if ( bri ) { toggleOnOff ( ) ; colorUpdated ( NOTIFIER_CALL_MODE_BUTTON ) ; }
}
}
2021-05-20 19:54:07 +02:00
buttonLongPressed [ b ] = buttonPressedBefore [ b ] ; //save the last "long term" switch state
2021-04-12 00:45:33 +02:00
}
}
2021-05-21 13:33:22 +02:00
void handleAnalog ( uint8_t b )
{
static uint8_t oldRead [ WLED_MAX_BUTTONS ] ;
# ifdef ESP8266
uint8_t aRead = analogRead ( A0 ) > > 2 ; // convert 10bit read to 8bit
# else
uint8_t aRead = analogRead ( btnPin [ b ] ) > > 4 ; // convert 12bit read to 8bit
# endif
if ( oldRead [ b ] = = aRead ) return ; // no change in reading
// if no macro for "short press" and "long press" is defined use brightness control
if ( ! macroButton [ b ] & & ! macroLongPress [ b ] ) {
// if "double press" macro is 250 or greater use global brightness
if ( macroDoublePress [ b ] > = 250 ) {
// if change in analog read was detected change global brightness
bri = aRead ;
} else {
// otherwise use "double press" for segment selection
//uint8_t mainSeg = strip.getMainSegmentId();
WS2812FX : : Segment & seg = strip . getSegment ( macroDoublePress [ b ] ) ;
if ( aRead = = 0 ) {
seg . setOption ( SEG_OPTION_ON , 0 , macroDoublePress [ b ] ) ; // off
} else {
seg . setOpacity ( aRead , macroDoublePress [ b ] ) ;
seg . setOption ( SEG_OPTION_ON , 1 , macroDoublePress [ b ] ) ;
}
}
} else {
//TODO:
// we can either trigger a preset depending on the level (between short and long entries)
// or use it for RGBW direct control
}
colorUpdated ( NOTIFIER_CALL_MODE_DIRECT_CHANGE ) ;
}
2016-11-19 19:39:17 +01:00
void handleButton ( )
{
2021-05-20 19:54:07 +02:00
for ( uint8_t b = 0 ; b < WLED_MAX_BUTTONS ; b + + ) {
if ( btnPin [ b ] < 0 | | ! ( buttonType [ b ] > BTN_TYPE_NONE ) ) continue ;
2021-04-12 00:45:33 +02:00
2021-05-21 13:33:22 +02:00
if ( buttonType [ b ] = = BTN_TYPE_ANALOG ) { // button is not a button but a potentiometer
handleAnalog ( b ) ; continue ;
}
2021-04-12 00:45:33 +02:00
2021-05-21 13:33:22 +02:00
if ( buttonType [ b ] = = BTN_TYPE_SWITCH | | buttonType [ b ] = = BTN_TYPE_SWITCH_ACT_HIGH ) { //button is not momentary, but switch. This is only suitable on pins whose on-boot state does not matter (NOT gpio0)
2021-05-20 19:54:07 +02:00
handleSwitch ( b ) ; continue ;
}
2019-10-18 12:19:52 +02:00
2021-05-20 19:54:07 +02:00
//momentary button logic
if ( isButtonPressed ( b ) ) //pressed
2019-10-18 12:19:52 +02:00
{
2021-05-20 19:54:07 +02:00
if ( ! buttonPressedBefore [ b ] ) buttonPressedTime [ b ] = millis ( ) ;
buttonPressedBefore [ b ] = true ;
if ( millis ( ) - buttonPressedTime [ b ] > 600 ) //long press
2019-10-18 12:19:52 +02:00
{
2021-05-20 19:54:07 +02:00
if ( ! buttonLongPressed [ b ] )
{
if ( macroLongPress [ b ] ) { applyPreset ( macroLongPress [ b ] ) ; }
else _setRandomColor ( false , true ) ;
2019-10-18 12:19:52 +02:00
2021-05-20 19:54:07 +02:00
buttonLongPressed [ b ] = true ;
}
2019-10-18 12:19:52 +02:00
}
}
2021-05-20 19:54:07 +02:00
else if ( ! isButtonPressed ( b ) & & buttonPressedBefore [ b ] ) //released
2016-11-19 19:39:17 +01:00
{
2021-05-20 19:54:07 +02:00
long dur = millis ( ) - buttonPressedTime [ b ] ;
if ( dur < WLED_DEBOUNCE_THRESHOLD ) { buttonPressedBefore [ b ] = false ; continue ; } //too short "press", debounce
bool doublePress = buttonWaitTime [ b ] ;
buttonWaitTime [ b ] = 0 ;
if ( dur > 6000 & & b = = 0 ) //long press on button 0
2019-03-13 11:13:03 +01:00
{
2021-05-20 19:54:07 +02:00
WLED : : instance ( ) . initAP ( true ) ;
}
else if ( ! buttonLongPressed [ b ] ) { //short press
if ( macroDoublePress [ b ] )
{
if ( doublePress ) applyPreset ( macroDoublePress [ b ] ) ;
else buttonWaitTime [ b ] = millis ( ) ;
} else shortPressAction ( b ) ;
}
buttonPressedBefore [ b ] = false ;
buttonLongPressed [ b ] = false ;
2016-11-19 19:39:17 +01:00
}
2019-03-13 11:13:03 +01:00
2021-05-20 19:54:07 +02:00
if ( buttonWaitTime [ b ] & & millis ( ) - buttonWaitTime [ b ] > 450 & & ! buttonPressedBefore [ b ] )
{
buttonWaitTime [ b ] = 0 ;
shortPressAction ( b ) ;
}
2019-03-13 11:13:03 +01:00
}
}
void handleIO ( )
{
handleButton ( ) ;
//set relay when LEDs turn on
if ( strip . getBrightness ( ) )
{
lastOnTime = millis ( ) ;
if ( offMode )
2020-10-12 20:13:13 +02:00
{
2021-01-17 00:20:31 +01:00
if ( rlyPin > = 0 ) {
pinMode ( rlyPin , OUTPUT ) ;
digitalWrite ( rlyPin , rlyMde ) ;
}
2019-03-13 11:13:03 +01:00
offMode = false ;
}
} else if ( millis ( ) - lastOnTime > 600 )
{
2021-01-17 00:20:31 +01:00
if ( ! offMode ) {
# ifdef ESP8266
2021-05-20 19:54:07 +02:00
// turn off built-in LED if strip is turned off
// this will break digital bus so will need to be reinitialised on On
2021-01-21 01:21:16 +01:00
pinMode ( LED_BUILTIN , OUTPUT ) ;
digitalWrite ( LED_BUILTIN , HIGH ) ;
2020-10-12 20:13:13 +02:00
# endif
2021-01-17 00:20:31 +01:00
if ( rlyPin > = 0 ) {
pinMode ( rlyPin , OUTPUT ) ;
digitalWrite ( rlyPin , ! rlyMde ) ;
}
}
2019-03-13 11:13:03 +01:00
offMode = true ;
2016-11-19 19:39:17 +01:00
}
}