2020-03-25 08:00:55 +00:00
# include "wled.h"
2020-03-25 09:14:23 +00:00
2016-12-30 23:38:51 +00:00
/*
* Physical IO
*/
2021-04-11 22:45:33 +00:00
# define WLED_DEBOUNCE_THRESHOLD 50 //only consider button input of at least 50ms as valid (debouncing)
2021-05-20 17:54:07 +00:00
void shortPressAction ( uint8_t b )
2019-03-13 10:13:03 +00:00
{
2021-05-20 17:54:07 +00:00
if ( ! macroButton [ b ] )
2019-03-13 10:13:03 +00:00
{
toggleOnOff ( ) ;
2020-02-22 15:17:32 +00:00
colorUpdated ( NOTIFIER_CALL_MODE_BUTTON ) ;
2019-03-13 10:13:03 +00:00
} else {
2021-05-20 17:54:07 +00:00
applyPreset ( macroButton [ b ] ) ;
2019-03-13 10:13:03 +00:00
}
}
2021-05-20 17:54:07 +00:00
bool isButtonPressed ( uint8_t i )
2020-09-20 14:12:46 +00:00
{
2021-05-20 17:54:07 +00: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 14:12:46 +00:00
return false ;
}
2019-03-13 10:13:03 +00:00
2021-05-20 17:54:07 +00:00
void handleSwitch ( uint8_t b )
2021-04-11 22:45:33 +00:00
{
2021-05-20 17:54:07 +00:00
if ( buttonPressedBefore [ b ] ! = isButtonPressed ( b ) ) {
buttonPressedTime [ b ] = millis ( ) ;
buttonPressedBefore [ b ] = ! buttonPressedBefore [ b ] ;
2021-04-11 22:45:33 +00:00
}
2021-05-20 17:54:07 +00:00
if ( buttonLongPressed [ b ] = = buttonPressedBefore [ b ] ) return ;
2021-04-11 22:45:33 +00:00
2021-05-20 17:54:07 +00: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-11 22:45:33 +00:00
else { //turn on
if ( ! bri ) { toggleOnOff ( ) ; colorUpdated ( NOTIFIER_CALL_MODE_BUTTON ) ; }
}
} else { //HIGH, rising edge, switch opened
2021-05-20 17:54:07 +00:00
if ( macroLongPress [ b ] ) applyPreset ( macroLongPress [ b ] ) ;
2021-04-11 22:45:33 +00:00
else { //turn off
if ( bri ) { toggleOnOff ( ) ; colorUpdated ( NOTIFIER_CALL_MODE_BUTTON ) ; }
}
}
2021-05-20 17:54:07 +00:00
buttonLongPressed [ b ] = buttonPressedBefore [ b ] ; //save the last "long term" switch state
2021-04-11 22:45:33 +00:00
}
}
2021-05-21 11:33:22 +00: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 18:39:17 +00:00
void handleButton ( )
{
2021-05-20 17:54:07 +00:00
for ( uint8_t b = 0 ; b < WLED_MAX_BUTTONS ; b + + ) {
if ( btnPin [ b ] < 0 | | ! ( buttonType [ b ] > BTN_TYPE_NONE ) ) continue ;
2021-04-11 22:45:33 +00:00
2021-05-21 11:33:22 +00:00
if ( buttonType [ b ] = = BTN_TYPE_ANALOG ) { // button is not a button but a potentiometer
handleAnalog ( b ) ; continue ;
}
2021-04-11 22:45:33 +00:00
2021-05-21 11:33:22 +00: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 17:54:07 +00:00
handleSwitch ( b ) ; continue ;
}
2019-10-18 10:19:52 +00:00
2021-05-20 17:54:07 +00:00
//momentary button logic
if ( isButtonPressed ( b ) ) //pressed
2019-10-18 10:19:52 +00:00
{
2021-05-20 17:54:07 +00:00
if ( ! buttonPressedBefore [ b ] ) buttonPressedTime [ b ] = millis ( ) ;
buttonPressedBefore [ b ] = true ;
if ( millis ( ) - buttonPressedTime [ b ] > 600 ) //long press
2019-10-18 10:19:52 +00:00
{
2021-05-20 17:54:07 +00:00
if ( ! buttonLongPressed [ b ] )
{
if ( macroLongPress [ b ] ) { applyPreset ( macroLongPress [ b ] ) ; }
else _setRandomColor ( false , true ) ;
2019-10-18 10:19:52 +00:00
2021-05-20 17:54:07 +00:00
buttonLongPressed [ b ] = true ;
}
2019-10-18 10:19:52 +00:00
}
}
2021-05-20 17:54:07 +00:00
else if ( ! isButtonPressed ( b ) & & buttonPressedBefore [ b ] ) //released
2016-11-19 18:39:17 +00:00
{
2021-05-20 17:54:07 +00: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 10:13:03 +00:00
{
2021-05-20 17:54:07 +00: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 18:39:17 +00:00
}
2019-03-13 10:13:03 +00:00
2021-05-20 17:54:07 +00:00
if ( buttonWaitTime [ b ] & & millis ( ) - buttonWaitTime [ b ] > 450 & & ! buttonPressedBefore [ b ] )
{
buttonWaitTime [ b ] = 0 ;
shortPressAction ( b ) ;
}
2019-03-13 10:13:03 +00:00
}
}
void handleIO ( )
{
handleButton ( ) ;
//set relay when LEDs turn on
if ( strip . getBrightness ( ) )
{
lastOnTime = millis ( ) ;
if ( offMode )
2020-10-12 18:13:13 +00:00
{
2021-01-16 23:20:31 +00:00
if ( rlyPin > = 0 ) {
pinMode ( rlyPin , OUTPUT ) ;
digitalWrite ( rlyPin , rlyMde ) ;
}
2019-03-13 10:13:03 +00:00
offMode = false ;
}
} else if ( millis ( ) - lastOnTime > 600 )
{
2021-01-16 23:20:31 +00:00
if ( ! offMode ) {
# ifdef ESP8266
2021-05-20 17:54:07 +00: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 00:21:16 +00:00
pinMode ( LED_BUILTIN , OUTPUT ) ;
digitalWrite ( LED_BUILTIN , HIGH ) ;
2020-10-12 18:13:13 +00:00
# endif
2021-01-16 23:20:31 +00:00
if ( rlyPin > = 0 ) {
pinMode ( rlyPin , OUTPUT ) ;
digitalWrite ( rlyPin , ! rlyMde ) ;
}
}
2019-03-13 10:13:03 +00:00
offMode = true ;
2016-11-19 18:39:17 +00:00
}
}