mirror of https://github.com/arendst/Tasmota.git
Fix ESP32 touch button multi-press and hold detection
Fix ESP32 touch button multi-press and hold detection (#16596)
This commit is contained in:
parent
2f61040891
commit
3a4a82ba0a
16
CHANGELOG.md
16
CHANGELOG.md
|
@ -3,7 +3,17 @@ All notable changes to this project will be documented in this file.
|
|||
|
||||
## [Unreleased] - Development
|
||||
|
||||
## [12.1.1.2]
|
||||
## [12.1.1.3]
|
||||
### Added
|
||||
|
||||
### Changed
|
||||
|
||||
### Fixed
|
||||
- ESP32 touch button multi-press and hold detection (#16596)
|
||||
|
||||
### Removed
|
||||
|
||||
## [12.1.1.2] 20220927
|
||||
### Added
|
||||
- Berry has persistent MQTT subscriptions: auto-subscribe at (re)connection
|
||||
- Berry automated solidification of code
|
||||
|
@ -22,10 +32,6 @@ All notable changes to this project will be documented in this file.
|
|||
- Zigbee report unprocessed attributes
|
||||
- Platformio one Platform for all Tasmota frameworks Core32 2.0.5 (#16644)
|
||||
|
||||
### Fixed
|
||||
|
||||
### Removed
|
||||
|
||||
## [12.1.1.1] 20220910
|
||||
### Added
|
||||
- Support for SGP40 gas and air quality sensor (#16341)
|
||||
|
|
|
@ -107,7 +107,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
|
|||
|
||||
[Complete list](BUILDS.md) of available feature and sensors.
|
||||
|
||||
## Changelog v12.1.1.2
|
||||
## Changelog v12.1.1.3
|
||||
### Added
|
||||
- Command ``SetOption46 0..255`` to add 0..255 * 10 milliseconds power on delay before initializing I/O [#15438](https://github.com/arendst/Tasmota/issues/15438)
|
||||
- Command ``SetOption146 1`` to enable display of ESP32 internal temperature
|
||||
|
@ -148,5 +148,6 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
|
|||
- Button response delay regression from v12.0.2.4 [#16319](https://github.com/arendst/Tasmota/issues/16319)
|
||||
- Lost module name in GUI regression from v12.0.2.4 - 20220803 [#16324](https://github.com/arendst/Tasmota/issues/16324)
|
||||
- Removed whitespace from JSON values with no decimals [#16365](https://github.com/arendst/Tasmota/issues/16365)
|
||||
- ESP32 touch button multi-press and hold detection [#16596](https://github.com/arendst/Tasmota/issues/16596)
|
||||
|
||||
### Removed
|
||||
|
|
|
@ -465,7 +465,9 @@ const uint16_t kGpioNiceList[] PROGMEM = {
|
|||
AGPIO(GPIO_KEY1_INV_NP) + MAX_KEYS,
|
||||
#ifdef ESP32
|
||||
AGPIO(GPIO_KEY1_INV_PD) + MAX_KEYS,
|
||||
#if defined(SOC_TOUCH_VERSION_1) || defined(SOC_TOUCH_VERSION_2)
|
||||
AGPIO(GPIO_KEY1_TC) + MAX_KEYS, // Touch button
|
||||
#endif // ESP32 SOC_TOUCH_VERSION_1 or SOC_TOUCH_VERSION_2
|
||||
#endif
|
||||
AGPIO(GPIO_SWT1) + MAX_SWITCHES, // User connected external switches
|
||||
AGPIO(GPIO_SWT1_NP) + MAX_SWITCHES,
|
||||
|
|
|
@ -20,6 +20,6 @@
|
|||
#ifndef _TASMOTA_VERSION_H_
|
||||
#define _TASMOTA_VERSION_H_
|
||||
|
||||
const uint32_t VERSION = 0x0C010102; // 12.1.1.2
|
||||
const uint32_t VERSION = 0x0C010103; // 12.1.1.3
|
||||
|
||||
#endif // _TASMOTA_VERSION_H_
|
||||
|
|
|
@ -46,9 +46,6 @@ struct BUTTON {
|
|||
uint32_t no_pullup_mask = 0; // key no pullup flag (1 = no pullup)
|
||||
uint32_t pulldown_mask = 0; // key pulldown flag (1 = pulldown)
|
||||
uint32_t inverted_mask = 0; // Key inverted flag (1 = inverted)
|
||||
#ifdef ESP32
|
||||
uint32_t touch_mask = 0; // Touch flag (1 = inverted)
|
||||
#endif // ESP32
|
||||
uint16_t hold_timer[MAX_KEYS] = { 0 }; // Timer for button hold
|
||||
uint16_t dual_code = 0; // Sonoff dual received code
|
||||
uint8_t state[MAX_KEYS] = { 0 };
|
||||
|
@ -57,20 +54,19 @@ struct BUTTON {
|
|||
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_receive_count = 0; // Sonoff dual input flag
|
||||
#ifdef ESP32
|
||||
uint8_t touch_hits[MAX_KEYS] = { 0 }; // Hits in a row to filter out noise
|
||||
#endif // ESP32
|
||||
uint8_t first_change = 0;
|
||||
uint8_t present = 0; // Number of buttons found flag
|
||||
uint8_t mutex;
|
||||
} Button;
|
||||
|
||||
#ifdef ESP32
|
||||
#if defined(SOC_TOUCH_VERSION_1) || defined(SOC_TOUCH_VERSION_2)
|
||||
struct TOUCH_BUTTON {
|
||||
uint32_t touch_mask = 0; // Touch flag (1 = enabled)
|
||||
uint32_t calibration = 0; // Bitfield
|
||||
uint32_t pin_threshold = TOUCH_PIN_THRESHOLD;
|
||||
uint8_t hit_threshold = TOUCH_HIT_THRESHOLD;
|
||||
uint8_t hits[MAX_KEYS] = { 0 }; // Hits in a row to filter out noise
|
||||
} TOUCH_BUTTON;
|
||||
#endif // ESP32
|
||||
#endif // ESP32 SOC_TOUCH_VERSION_1 or SOC_TOUCH_VERSION_2
|
||||
|
||||
/********************************************************************************************/
|
||||
|
||||
|
@ -86,16 +82,17 @@ void ButtonInvertFlag(uint32_t button_bit) {
|
|||
bitSet(Button.inverted_mask, button_bit);
|
||||
}
|
||||
|
||||
#ifdef ESP32
|
||||
#if defined(SOC_TOUCH_VERSION_1) || defined(SOC_TOUCH_VERSION_2)
|
||||
void ButtonTouchFlag(uint32_t button_bit) {
|
||||
bitSet(Button.touch_mask, button_bit);
|
||||
bitSet(TOUCH_BUTTON.touch_mask, button_bit);
|
||||
}
|
||||
#endif // ESP32
|
||||
#endif // ESP32 SOC_TOUCH_VERSION_1 or SOC_TOUCH_VERSION_2
|
||||
|
||||
/*********************************************************************************************/
|
||||
|
||||
void ButtonProbe(void) {
|
||||
if (TasmotaGlobal.uptime < 4) { return; } // Block GPIO for 4 seconds after poweron to workaround Wemos D1 / Obi RTS circuit
|
||||
if (Button.mutex || (TasmotaGlobal.uptime < 4)) { return; } // Block GPIO for 4 seconds after poweron to workaround Wemos D1 / Obi RTS circuit
|
||||
Button.mutex = 1;
|
||||
|
||||
uint32_t state_filter;
|
||||
uint32_t first_change = Button.first_change;
|
||||
|
@ -119,8 +116,17 @@ void ButtonProbe(void) {
|
|||
for (uint32_t i = 0; i < MAX_KEYS; i++) {
|
||||
if (!PinUsed(GPIO_KEY1, i)) { continue; }
|
||||
|
||||
// Olimex user_switch2.c code to fix 50Hz induced pulses
|
||||
if (digitalRead(Pin(GPIO_KEY1, i)) != bitRead(Button.inverted_mask, i)) {
|
||||
bool button_not_activated;
|
||||
#if defined(SOC_TOUCH_VERSION_1) || defined(SOC_TOUCH_VERSION_2)
|
||||
if (bitRead(TOUCH_BUTTON.touch_mask, i)) {
|
||||
if (ac_detect || bitRead(TOUCH_BUTTON.calibration, i +1)) { continue; } // Touch is slow. Takes 21mS to read
|
||||
uint32_t value = touchRead(Pin(GPIO_KEY1, i));
|
||||
button_not_activated = ((value == 0) || (value > TOUCH_BUTTON.pin_threshold));
|
||||
} else
|
||||
#endif // ESP32 SOC_TOUCH_VERSION_1 or SOC_TOUCH_VERSION_2
|
||||
button_not_activated = (digitalRead(Pin(GPIO_KEY1, i)) != bitRead(Button.inverted_mask, i));
|
||||
|
||||
if (button_not_activated) {
|
||||
|
||||
if (ac_detect) { // Enabled with ButtonDebounce x9
|
||||
Button.state[i] |= 0x80;
|
||||
|
@ -194,6 +200,7 @@ void ButtonProbe(void) {
|
|||
}
|
||||
}
|
||||
}
|
||||
Button.mutex = 0;
|
||||
}
|
||||
|
||||
void ButtonInit(void) {
|
||||
|
@ -295,36 +302,23 @@ void ButtonHandler(void) {
|
|||
} else
|
||||
#endif // ESP8266
|
||||
if (PinUsed(GPIO_KEY1, button_index)) {
|
||||
button_present = 1;
|
||||
#ifdef ESP32
|
||||
#ifndef CONFIG_IDF_TARGET_ESP32C3
|
||||
if (bitRead(Button.touch_mask, button_index)) { // Touch
|
||||
|
||||
#if defined(SOC_TOUCH_VERSION_1) || defined(SOC_TOUCH_VERSION_2)
|
||||
if (bitRead(TOUCH_BUTTON.touch_mask, button_index) && bitRead(TOUCH_BUTTON.calibration, button_index +1)) { // Touch
|
||||
uint32_t _value = touchRead(Pin(GPIO_KEY1, button_index));
|
||||
button = NOT_PRESSED;
|
||||
if (_value != 0) { // Probably read-error
|
||||
if (_value < TOUCH_BUTTON.pin_threshold) {
|
||||
if (++Button.touch_hits[button_index] > TOUCH_BUTTON.hit_threshold) {
|
||||
if (!bitRead(TOUCH_BUTTON.calibration, button_index+1)) {
|
||||
button = PRESSED;
|
||||
}
|
||||
}
|
||||
if ((_value > 0) && (_value < TOUCH_BUTTON.pin_threshold)) { // Probably read-error (0)
|
||||
TOUCH_BUTTON.hits[button_index]++;
|
||||
} else {
|
||||
Button.touch_hits[button_index] = 0;
|
||||
}
|
||||
} else {
|
||||
Button.touch_hits[button_index] = 0;
|
||||
}
|
||||
if (bitRead(TOUCH_BUTTON.calibration, button_index+1)) {
|
||||
AddLog(LOG_LEVEL_INFO, PSTR("PLOT: %u, %u, %u,"), button_index+1, _value, Button.touch_hits[button_index]); // Button number (1..4), value, continuous hits under threshold
|
||||
TOUCH_BUTTON.hits[button_index] = 0;
|
||||
}
|
||||
AddLog(LOG_LEVEL_INFO, PSTR("PLOT: %u, %u, %u,"), button_index +1, _value, TOUCH_BUTTON.hits[button_index]); // Button number (1..4), value, continuous hits under threshold
|
||||
continue;
|
||||
} else
|
||||
#endif // not ESP32C3
|
||||
#endif // ESP32
|
||||
{ // Normal button
|
||||
// button = (digitalRead(Pin(GPIO_KEY1, button_index)) != bitRead(Button.inverted_mask, button_index));
|
||||
#endif // ESP32 SOC_TOUCH_VERSION_1 or SOC_TOUCH_VERSION_2
|
||||
|
||||
button_present = 1;
|
||||
button = Button.virtual_state[button_index];
|
||||
}
|
||||
}
|
||||
#ifdef USE_ADC
|
||||
else if (PinUsed(GPIO_ADC_BUTTON, button_index)) {
|
||||
button_present = 1;
|
||||
|
|
|
@ -46,7 +46,11 @@ const char kTasmotaCommands[] PROGMEM = "|" // No prefix
|
|||
#endif // USE_DEVICE_GROUPS
|
||||
D_CMND_SETSENSOR "|" D_CMND_SENSOR "|" D_CMND_DRIVER "|" D_CMND_JSON
|
||||
#ifdef ESP32
|
||||
"|Info|" D_CMND_TOUCH_CAL "|" D_CMND_TOUCH_THRES "|" D_CMND_TOUCH_NUM "|" D_CMND_CPU_FREQUENCY
|
||||
"|Info|"
|
||||
#if defined(SOC_TOUCH_VERSION_1) || defined(SOC_TOUCH_VERSION_2)
|
||||
D_CMND_TOUCH_CAL "|" D_CMND_TOUCH_THRES "|"
|
||||
#endif // ESP32 SOC_TOUCH_VERSION_1 or SOC_TOUCH_VERSION_2
|
||||
D_CMND_CPU_FREQUENCY
|
||||
#endif // ESP32
|
||||
#endif //FIRMWARE_MINIMAL_ONLY
|
||||
;
|
||||
|
@ -81,7 +85,11 @@ void (* const TasmotaCommand[])(void) PROGMEM = {
|
|||
#endif // USE_DEVICE_GROUPS
|
||||
&CmndSetSensor, &CmndSensor, &CmndDriver, &CmndJson
|
||||
#ifdef ESP32
|
||||
, &CmndInfo, &CmndTouchCal, &CmndTouchThres, &CmndTouchNum, &CmndCpuFrequency
|
||||
, &CmndInfo,
|
||||
#if defined(SOC_TOUCH_VERSION_1) || defined(SOC_TOUCH_VERSION_2)
|
||||
&CmndTouchCal, &CmndTouchThres,
|
||||
#endif // ESP32 SOC_TOUCH_VERSION_1 or SOC_TOUCH_VERSION_2
|
||||
&CmndCpuFrequency
|
||||
#endif // ESP32
|
||||
#endif //FIRMWARE_MINIMAL_ONLY
|
||||
};
|
||||
|
@ -2608,6 +2616,7 @@ void CmndCpuFrequency(void) {
|
|||
ResponseCmndNumber(getCpuFrequencyMhz());
|
||||
}
|
||||
|
||||
#if defined(SOC_TOUCH_VERSION_1) || defined(SOC_TOUCH_VERSION_2)
|
||||
void CmndTouchCal(void) {
|
||||
if (XdrvMailbox.payload >= 0) {
|
||||
if (XdrvMailbox.payload == 0) {
|
||||
|
@ -2630,12 +2639,6 @@ void CmndTouchThres(void) {
|
|||
}
|
||||
ResponseCmndNumber(TOUCH_BUTTON.pin_threshold);
|
||||
}
|
||||
|
||||
void CmndTouchNum(void) {
|
||||
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 32)) {
|
||||
TOUCH_BUTTON.hit_threshold = XdrvMailbox.payload;
|
||||
}
|
||||
ResponseCmndNumber(TOUCH_BUTTON.hit_threshold);
|
||||
}
|
||||
#endif // ESP32 SOC_TOUCH_VERSION_1 or SOC_TOUCH_VERSION_2
|
||||
|
||||
#endif // ESP32
|
||||
|
|
|
@ -1993,10 +1993,12 @@ void GpioInit(void)
|
|||
ButtonInvertFlag(mpin - AGPIO(GPIO_KEY1_INV_PD)); // 0 .. 3
|
||||
mpin -= (AGPIO(GPIO_KEY1_INV_PD) - AGPIO(GPIO_KEY1));
|
||||
}
|
||||
#if defined(SOC_TOUCH_VERSION_1) || defined(SOC_TOUCH_VERSION_2)
|
||||
else if ((mpin >= AGPIO(GPIO_KEY1_TC)) && (mpin < (AGPIO(GPIO_KEY1_TC) + MAX_KEYS))) {
|
||||
ButtonTouchFlag(mpin - AGPIO(GPIO_KEY1_TC)); // 0 .. 3
|
||||
mpin -= (AGPIO(GPIO_KEY1_TC) - AGPIO(GPIO_KEY1));
|
||||
}
|
||||
#endif // ESP32 SOC_TOUCH_VERSION_1 or SOC_TOUCH_VERSION_2
|
||||
#endif //ESP32
|
||||
else if ((mpin >= AGPIO(GPIO_REL1_INV)) && (mpin < (AGPIO(GPIO_REL1_INV) + MAX_RELAYS))) {
|
||||
bitSet(TasmotaGlobal.rel_inverted, mpin - AGPIO(GPIO_REL1_INV));
|
||||
|
|
Loading…
Reference in New Issue