mirror of https://github.com/arendst/Tasmota.git
Add support for analog buttons
Add support for analog buttons indexed within standard button range
This commit is contained in:
parent
6b65f616d7
commit
d5b8d6ae24
|
@ -83,3 +83,4 @@ The attached binaries can also be downloaded from http://ota.tasmota.com/tasmota
|
||||||
- Add support for inverted NeoPixelBus data line by enabling ``#define USE_WS2812_INVERTED`` (#8988)
|
- Add support for inverted NeoPixelBus data line by enabling ``#define USE_WS2812_INVERTED`` (#8988)
|
||||||
- Add PWM dimmer color/trigger on tap, SO88 led, DGR WITH_LOCAL flag by Paul Diem (#9474)
|
- Add PWM dimmer color/trigger on tap, SO88 led, DGR WITH_LOCAL flag by Paul Diem (#9474)
|
||||||
- Add support for stateful ACs using ``StateMode`` in tasmota-ir.bin by Arik Yavilevich (#9472)
|
- Add support for stateful ACs using ``StateMode`` in tasmota-ir.bin by Arik Yavilevich (#9472)
|
||||||
|
- Add support for analog buttons indexed within standard button range
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
- Add PWM dimmer color/trigger on tap, SO88 led, DGR WITH_LOCAL flag by Paul Diem (#9474)
|
- Add PWM dimmer color/trigger on tap, SO88 led, DGR WITH_LOCAL flag by Paul Diem (#9474)
|
||||||
- Add support for stateful ACs using ``StateMode`` in tasmota-ir.bin by Arik Yavilevich (#9472)
|
- Add support for stateful ACs using ``StateMode`` in tasmota-ir.bin by Arik Yavilevich (#9472)
|
||||||
- Add Zigbee ``ZbData`` command for better support of device specific data
|
- Add Zigbee ``ZbData`` command for better support of device specific data
|
||||||
|
- Add support for analog buttons indexed within standard button range
|
||||||
|
|
||||||
## Released
|
## Released
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,6 @@ struct BUTTON {
|
||||||
uint8_t touch_hits[MAX_KEYS] = { 0 }; // Hits in a row to filter out noise
|
uint8_t touch_hits[MAX_KEYS] = { 0 }; // Hits in a row to filter out noise
|
||||||
#endif // ESP32
|
#endif // ESP32
|
||||||
uint8_t present = 0; // Number of buttons found flag
|
uint8_t present = 0; // Number of buttons found flag
|
||||||
uint8_t adc = 99; // ADC0 button number
|
|
||||||
} Button;
|
} Button;
|
||||||
|
|
||||||
#ifdef ESP32
|
#ifdef ESP32
|
||||||
|
@ -90,14 +89,11 @@ void ButtonInit(void)
|
||||||
Button.present++;
|
Button.present++;
|
||||||
pinMode(Pin(GPIO_KEY1, i), bitRead(Button.no_pullup_mask, i) ? INPUT : ((16 == Pin(GPIO_KEY1, i)) ? INPUT_PULLDOWN_16 : INPUT_PULLUP));
|
pinMode(Pin(GPIO_KEY1, i), bitRead(Button.no_pullup_mask, i) ? INPUT : ((16 == Pin(GPIO_KEY1, i)) ? INPUT_PULLDOWN_16 : INPUT_PULLUP));
|
||||||
}
|
}
|
||||||
#ifdef ESP8266
|
#ifdef USE_ADC
|
||||||
#ifndef USE_ADC_VCC
|
else if (PinUsed(GPIO_ADC_BUTTON, i) || PinUsed(GPIO_ADC_BUTTON_INV, i)) {
|
||||||
else if ((99 == Button.adc) && AdcButtonPresent(0)) {
|
|
||||||
Button.present++;
|
Button.present++;
|
||||||
Button.adc = i;
|
|
||||||
}
|
}
|
||||||
#endif // USE_ADC_VCC
|
#endif // USE_ADC
|
||||||
#endif // ESP8266
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,22 +153,11 @@ void ButtonHandler(void)
|
||||||
}
|
}
|
||||||
Button.dual_code = 0;
|
Button.dual_code = 0;
|
||||||
}
|
}
|
||||||
}
|
} else
|
||||||
else {
|
#endif // ESP8266
|
||||||
if (PinUsed(GPIO_KEY1, button_index)) {
|
|
||||||
button_present = 1;
|
|
||||||
button = (digitalRead(Pin(GPIO_KEY1, button_index)) != bitRead(Button.inverted_mask, button_index));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#ifndef USE_ADC_VCC
|
|
||||||
if (Button.adc == button_index) {
|
|
||||||
button_present = 1;
|
|
||||||
button = AdcGetButton(0);
|
|
||||||
}
|
|
||||||
#endif // USE_ADC_VCC
|
|
||||||
#else // ESP32
|
|
||||||
if (PinUsed(GPIO_KEY1, button_index)) {
|
if (PinUsed(GPIO_KEY1, button_index)) {
|
||||||
button_present = 1;
|
button_present = 1;
|
||||||
|
#ifdef ESP32
|
||||||
if (bitRead(Button.touch_mask, button_index)) { // Touch
|
if (bitRead(Button.touch_mask, button_index)) { // Touch
|
||||||
uint32_t _value = touchRead(Pin(GPIO_KEY1, button_index));
|
uint32_t _value = touchRead(Pin(GPIO_KEY1, button_index));
|
||||||
button = NOT_PRESSED;
|
button = NOT_PRESSED;
|
||||||
|
@ -192,11 +177,22 @@ void ButtonHandler(void)
|
||||||
if (bitRead(TOUCH_BUTTON.calibration, button_index+1)) {
|
if (bitRead(TOUCH_BUTTON.calibration, button_index+1)) {
|
||||||
AddLog_P2(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
|
AddLog_P2(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
|
||||||
}
|
}
|
||||||
} else { // Normal button
|
} else
|
||||||
|
#endif // ESP32
|
||||||
|
{ // Normal button
|
||||||
button = (digitalRead(Pin(GPIO_KEY1, button_index)) != bitRead(Button.inverted_mask, button_index));
|
button = (digitalRead(Pin(GPIO_KEY1, button_index)) != bitRead(Button.inverted_mask, button_index));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // ESP8266 or ESP32
|
#ifdef USE_ADC
|
||||||
|
else if (PinUsed(GPIO_ADC_BUTTON, button_index)) {
|
||||||
|
button_present = 1;
|
||||||
|
button = AdcGetButton(Pin(GPIO_ADC_BUTTON, button_index));
|
||||||
|
}
|
||||||
|
else if (PinUsed(GPIO_ADC_BUTTON_INV, button_index)) {
|
||||||
|
button_present = 1;
|
||||||
|
button = AdcGetButton(Pin(GPIO_ADC_BUTTON_INV, button_index));
|
||||||
|
}
|
||||||
|
#endif // USE_ADC
|
||||||
if (button_present) {
|
if (button_present) {
|
||||||
XdrvMailbox.index = button_index;
|
XdrvMailbox.index = button_index;
|
||||||
XdrvMailbox.payload = button;
|
XdrvMailbox.payload = button;
|
||||||
|
|
|
@ -650,8 +650,8 @@ const uint16_t kGpioNiceList[] PROGMEM = {
|
||||||
AGPIO(GPIO_ADC_INPUT) + MAX_ADCS, // Analog inputs
|
AGPIO(GPIO_ADC_INPUT) + MAX_ADCS, // Analog inputs
|
||||||
AGPIO(GPIO_ADC_TEMP) + MAX_ADCS, // Thermistor
|
AGPIO(GPIO_ADC_TEMP) + MAX_ADCS, // Thermistor
|
||||||
AGPIO(GPIO_ADC_LIGHT) + MAX_ADCS, // Light sensor
|
AGPIO(GPIO_ADC_LIGHT) + MAX_ADCS, // Light sensor
|
||||||
AGPIO(GPIO_ADC_BUTTON) + MAX_ADCS, // Button
|
AGPIO(GPIO_ADC_BUTTON) + MAX_KEYS, // Button
|
||||||
AGPIO(GPIO_ADC_BUTTON_INV) + MAX_ADCS,
|
AGPIO(GPIO_ADC_BUTTON_INV) + MAX_KEYS,
|
||||||
AGPIO(GPIO_ADC_RANGE) + MAX_ADCS, // Range
|
AGPIO(GPIO_ADC_RANGE) + MAX_ADCS, // Range
|
||||||
AGPIO(GPIO_ADC_CT_POWER) + MAX_ADCS, // Current
|
AGPIO(GPIO_ADC_CT_POWER) + MAX_ADCS, // Current
|
||||||
AGPIO(GPIO_ADC_JOY) + MAX_ADCS, // Joystick
|
AGPIO(GPIO_ADC_JOY) + MAX_ADCS, // Joystick
|
||||||
|
@ -668,8 +668,8 @@ const uint16_t kAdcNiceList[] PROGMEM = {
|
||||||
AGPIO(GPIO_ADC_INPUT), // Analog inputs
|
AGPIO(GPIO_ADC_INPUT), // Analog inputs
|
||||||
AGPIO(GPIO_ADC_TEMP), // Thermistor
|
AGPIO(GPIO_ADC_TEMP), // Thermistor
|
||||||
AGPIO(GPIO_ADC_LIGHT), // Light sensor
|
AGPIO(GPIO_ADC_LIGHT), // Light sensor
|
||||||
AGPIO(GPIO_ADC_BUTTON), // Button
|
AGPIO(GPIO_ADC_BUTTON) + MAX_KEYS, // Button
|
||||||
AGPIO(GPIO_ADC_BUTTON_INV),
|
AGPIO(GPIO_ADC_BUTTON_INV) + MAX_KEYS,
|
||||||
AGPIO(GPIO_ADC_RANGE), // Range
|
AGPIO(GPIO_ADC_RANGE), // Range
|
||||||
AGPIO(GPIO_ADC_CT_POWER), // Current
|
AGPIO(GPIO_ADC_CT_POWER), // Current
|
||||||
AGPIO(GPIO_ADC_JOY), // Joystick
|
AGPIO(GPIO_ADC_JOY), // Joystick
|
||||||
|
|
|
@ -477,6 +477,7 @@ const char HTTP_SCRIPT_TEMPLATE2[] PROGMEM =
|
||||||
const char HTTP_SCRIPT_TEMPLATE3[] PROGMEM =
|
const char HTTP_SCRIPT_TEMPLATE3[] PROGMEM =
|
||||||
"\";"
|
"\";"
|
||||||
"sk(g[13]," STR(ADC0_PIN) ");"; // Set ADC0
|
"sk(g[13]," STR(ADC0_PIN) ");"; // Set ADC0
|
||||||
|
|
||||||
const char HTTP_SCRIPT_TEMPLATE4[] PROGMEM =
|
const char HTTP_SCRIPT_TEMPLATE4[] PROGMEM =
|
||||||
"g=o.shift();" // FLAG
|
"g=o.shift();" // FLAG
|
||||||
"for(i=0;i<" STR(GPIO_FLAG_USED) ";i++){"
|
"for(i=0;i<" STR(GPIO_FLAG_USED) ";i++){"
|
||||||
|
@ -1800,13 +1801,23 @@ void HandleTemplateConfiguration(void)
|
||||||
first_done = true;
|
first_done = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#ifdef ESP8266
|
||||||
|
for (uint32_t i = 0; i < ARRAY_SIZE(kAdcNiceList); i++) { // hs=[36,68,100,132,168,200,232,264,292,324,356,388,421,453];
|
||||||
|
uint32_t midx = pgm_read_word(kAdcNiceList + i);
|
||||||
|
if (midx & 0x001F) {
|
||||||
|
if (first_done) { WSContentSend_P(PSTR(",")); }
|
||||||
|
WSContentSend_P(PSTR("%d"), midx);
|
||||||
|
first_done = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
WSContentSend_P(PSTR("];"));
|
WSContentSend_P(PSTR("];"));
|
||||||
|
|
||||||
WSContentSend_P(HTTP_SCRIPT_TEMPLATE2);
|
WSContentSend_P(HTTP_SCRIPT_TEMPLATE2);
|
||||||
|
|
||||||
#ifdef ESP8266
|
#ifdef ESP8266
|
||||||
WSContentSend_P(PSTR("os=\""));
|
WSContentSend_P(PSTR("os=\""));
|
||||||
for (uint32_t i = 0; i < ARRAY_SIZE(kAdcNiceList); i++) { // FLAG: }2'0'>None}3}2'17'>Analog}3...
|
for (uint32_t i = 0; i < ARRAY_SIZE(kAdcNiceList); i++) { // GPIO: }2'0'>None}3}2'17'>Analog}3...
|
||||||
if (1 == i) {
|
if (1 == i) {
|
||||||
WSContentSend_P(HTTP_MODULE_TEMPLATE_REPLACE_NO_INDEX, AGPIO(GPIO_USER), D_SENSOR_USER); // }2'15'>User}3
|
WSContentSend_P(HTTP_MODULE_TEMPLATE_REPLACE_NO_INDEX, AGPIO(GPIO_USER), D_SENSOR_USER); // }2'15'>User}3
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,8 +24,15 @@
|
||||||
|
|
||||||
#define XSNS_02 2
|
#define XSNS_02 2
|
||||||
|
|
||||||
|
#ifdef ESP8266
|
||||||
|
#define ANALOG_RESOLUTION 10 // 12 = 4095, 11 = 2047, 10 = 1023
|
||||||
|
#define ANALOG_RANGE 1023 // 4095 = 12, 2047 = 11, 1023 = 10
|
||||||
|
#else // ESP32
|
||||||
|
#undef ANALOG_RESOLUTION
|
||||||
#define ANALOG_RESOLUTION 12 // 12 = 4095, 11 = 2047, 10 = 1023
|
#define ANALOG_RESOLUTION 12 // 12 = 4095, 11 = 2047, 10 = 1023
|
||||||
|
#undef ANALOG_RANGE
|
||||||
#define ANALOG_RANGE 4095 // 4095 = 12, 2047 = 11, 1023 = 10
|
#define ANALOG_RANGE 4095 // 4095 = 12, 2047 = 11, 1023 = 10
|
||||||
|
#endif // ESP8266 or ESP32
|
||||||
|
|
||||||
#define TO_CELSIUS(x) ((x) - 273.15)
|
#define TO_CELSIUS(x) ((x) - 273.15)
|
||||||
#define TO_KELVIN(x) ((x) + 273.15)
|
#define TO_KELVIN(x) ((x) + 273.15)
|
||||||
|
@ -64,6 +71,17 @@
|
||||||
|
|
||||||
#define CT_FLAG_ENERGY_RESET (1 << 0) // Reset energy total
|
#define CT_FLAG_ENERGY_RESET (1 << 0) // Reset energy total
|
||||||
|
|
||||||
|
// Buttons
|
||||||
|
// ---- Inverted
|
||||||
|
// 3V3 ---| |----|
|
||||||
|
// |
|
||||||
|
// 3V3 --- R1 ----|--- R1 --- Gnd
|
||||||
|
// |
|
||||||
|
// |---| |--- Gnd
|
||||||
|
// | ----
|
||||||
|
// ADC
|
||||||
|
#define ANALOG_BUTTON 128 // Add resistor tolerance
|
||||||
|
|
||||||
// Odroid joysticks
|
// Odroid joysticks
|
||||||
// ---- Up
|
// ---- Up
|
||||||
// 3V3 ---| |------------
|
// 3V3 ---| |------------
|
||||||
|
@ -154,6 +172,7 @@ void AdcInitParams(uint8_t idx) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdcAttach(uint8_t pin, uint8_t type) {
|
void AdcAttach(uint8_t pin, uint8_t type) {
|
||||||
|
if (Adcs.present == MAX_ADCS) { return; }
|
||||||
Adc[Adcs.present].pin = pin;
|
Adc[Adcs.present].pin = pin;
|
||||||
if (adcAttachPin(Adc[Adcs.present].pin)) {
|
if (adcAttachPin(Adc[Adcs.present].pin)) {
|
||||||
Adc[Adcs.present].type = type;
|
Adc[Adcs.present].type = type;
|
||||||
|
@ -174,12 +193,6 @@ void AdcInit(void) {
|
||||||
if (PinUsed(GPIO_ADC_LIGHT, i)) {
|
if (PinUsed(GPIO_ADC_LIGHT, i)) {
|
||||||
AdcAttach(Pin(GPIO_ADC_LIGHT, i), ADC_LIGHT);
|
AdcAttach(Pin(GPIO_ADC_LIGHT, i), ADC_LIGHT);
|
||||||
}
|
}
|
||||||
if (PinUsed(GPIO_ADC_BUTTON, i)) {
|
|
||||||
AdcAttach(Pin(GPIO_ADC_BUTTON, i), ADC_BUTTON);
|
|
||||||
}
|
|
||||||
if (PinUsed(GPIO_ADC_BUTTON_INV, i)) {
|
|
||||||
AdcAttach(Pin(GPIO_ADC_BUTTON_INV, i), ADC_BUTTON_INV);
|
|
||||||
}
|
|
||||||
if (PinUsed(GPIO_ADC_RANGE, i)) {
|
if (PinUsed(GPIO_ADC_RANGE, i)) {
|
||||||
AdcAttach(Pin(GPIO_ADC_RANGE, i), ADC_RANGE);
|
AdcAttach(Pin(GPIO_ADC_RANGE, i), ADC_RANGE);
|
||||||
}
|
}
|
||||||
|
@ -190,6 +203,15 @@ void AdcInit(void) {
|
||||||
AdcAttach(Pin(GPIO_ADC_JOY, i), ADC_JOY);
|
AdcAttach(Pin(GPIO_ADC_JOY, i), ADC_JOY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (uint32_t i = 0; i < MAX_KEYS; i++) {
|
||||||
|
if (PinUsed(GPIO_ADC_BUTTON, i)) {
|
||||||
|
AdcAttach(Pin(GPIO_ADC_BUTTON, i), ADC_BUTTON);
|
||||||
|
}
|
||||||
|
else if (PinUsed(GPIO_ADC_BUTTON_INV, i)) {
|
||||||
|
AdcAttach(Pin(GPIO_ADC_BUTTON_INV, i), ADC_BUTTON_INV);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (Adcs.present) {
|
if (Adcs.present) {
|
||||||
#ifdef ESP32
|
#ifdef ESP32
|
||||||
analogSetClockDiv(1); // Default 1
|
analogSetClockDiv(1); // Default 1
|
||||||
|
@ -253,18 +275,19 @@ void AdcEvery250ms(void) {
|
||||||
}
|
}
|
||||||
#endif // USE_RULES
|
#endif // USE_RULES
|
||||||
|
|
||||||
bool AdcButtonPresent(uint32_t idx) {
|
uint8_t AdcGetButton(uint32_t pin) {
|
||||||
return ((ADC_BUTTON == Adc[idx].type) || (ADC_BUTTON_INV == Adc[idx].type));
|
for (uint32_t idx = 0; idx < Adcs.present; idx++) {
|
||||||
}
|
if (Adc[idx].pin == pin) {
|
||||||
|
|
||||||
uint8_t AdcGetButton(uint32_t idx) {
|
|
||||||
if (ADC_BUTTON_INV == Adc[idx].type) {
|
if (ADC_BUTTON_INV == Adc[idx].type) {
|
||||||
return (AdcRead(Adc[idx].pin, 1) < 128);
|
return (AdcRead(Adc[idx].pin, 1) < ANALOG_BUTTON);
|
||||||
}
|
}
|
||||||
else if (ADC_BUTTON == Adc[idx].type) {
|
else if (ADC_BUTTON == Adc[idx].type) {
|
||||||
return (AdcRead(Adc[idx].pin, 1) > 128);
|
return (AdcRead(Adc[idx].pin, 1) > ANALOG_BUTTON);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
uint16_t AdcGetLux(uint32_t idx) {
|
uint16_t AdcGetLux(uint32_t idx) {
|
||||||
int adc = AdcRead(Adc[idx].pin, 2);
|
int adc = AdcRead(Adc[idx].pin, 2);
|
||||||
|
|
Loading…
Reference in New Issue