WLED/wled00/button.cpp

163 lines
4.3 KiB
C++
Raw Normal View History

#include "wled.h"
2020-03-25 10:14:23 +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-19 18:39:16 +02:00
void shortPressAction(uint8_t b)
{
2021-05-19 18:39:16 +02:00
if (!macroButton[b])
{
toggleOnOff();
2020-02-22 16:17:32 +01:00
colorUpdated(NOTIFIER_CALL_MODE_BUTTON);
} else {
2021-05-19 18:39:16 +02:00
applyPreset(macroButton[b]);
}
}
2021-05-19 18:39:16 +02:00
bool isButtonPressed(uint8_t i)
{
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;
DEBUG_PRINT(F("Touch value: "));
DEBUG_PRINTLN(touchRead(btnPin[i]));
#endif
break;
}
return false;
}
2021-05-19 18:39:16 +02:00
void handleSwitch(uint8_t b)
2021-04-12 00:45:33 +02:00
{
2021-05-19 18:39:16 +02:00
if (buttonPressedBefore[b] != isButtonPressed(b)) {
buttonPressedTime[b] = millis();
buttonPressedBefore[b] = !buttonPressedBefore[b];
2021-04-12 00:45:33 +02:00
}
2021-05-19 18:39:16 +02:00
if (buttonLongPressed[b] == buttonPressedBefore[b]) return;
2021-04-12 00:45:33 +02:00
2021-05-19 18:39:16 +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-19 18:39:16 +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-19 18:39:16 +02:00
buttonLongPressed[b] = buttonPressedBefore[b]; //save the last "long term" switch state
2021-04-12 00:45:33 +02:00
}
}
void handleButton()
{
2021-05-19 18:39:16 +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-19 18:39:16 +02:00
if (buttonType[b] == BTN_TYPE_SWITCH) { //button is not momentary, but switch. This is only suitable on pins whose on-boot state does not matter (NOT gpio0)
handleSwitch(b); continue;
}
2019-10-18 12:19:52 +02:00
2021-05-19 18:39:16 +02:00
//momentary button logic
if (isButtonPressed(b)) //pressed
2019-10-18 12:19:52 +02:00
{
2021-05-19 18:39:16 +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-19 18:39:16 +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-19 18:39:16 +02:00
buttonLongPressed[b] = true;
}
2019-10-18 12:19:52 +02:00
}
}
2021-05-19 18:39:16 +02:00
else if (!isButtonPressed(b) && buttonPressedBefore[b]) //released
{
2021-05-19 18:39:16 +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
{
2021-05-19 18:39:16 +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;
}
2021-05-19 18:39:16 +02:00
if (buttonWaitTime[b] && millis() - buttonWaitTime[b] > 450 && !buttonPressedBefore[b])
{
buttonWaitTime[b] = 0;
shortPressAction(b);
}
}
}
void handleIO()
{
handleButton();
//set relay when LEDs turn on
if (strip.getBrightness())
{
lastOnTime = millis();
if (offMode)
{
2021-01-17 00:20:31 +01:00
if (rlyPin>=0) {
pinMode(rlyPin, OUTPUT);
digitalWrite(rlyPin, rlyMde);
}
offMode = false;
}
} else if (millis() - lastOnTime > 600)
{
2021-01-17 00:20:31 +01:00
if (!offMode) {
#ifdef ESP8266
2021-02-24 20:23:32 +01:00
// turn off built-in LED if strip is turned off
// this will break digital bus so will need to be reinitialised on On
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, HIGH);
#endif
2021-01-17 00:20:31 +01:00
if (rlyPin>=0) {
pinMode(rlyPin, OUTPUT);
digitalWrite(rlyPin, !rlyMde);
}
}
offMode = true;
}
}