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 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 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 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 support for analog buttons indexed within standard button range
|
||||
|
||||
## Released
|
||||
|
||||
|
|
|
@ -49,7 +49,6 @@ struct BUTTON {
|
|||
uint8_t touch_hits[MAX_KEYS] = { 0 }; // Hits in a row to filter out noise
|
||||
#endif // ESP32
|
||||
uint8_t present = 0; // Number of buttons found flag
|
||||
uint8_t adc = 99; // ADC0 button number
|
||||
} Button;
|
||||
|
||||
#ifdef ESP32
|
||||
|
@ -90,14 +89,11 @@ void ButtonInit(void)
|
|||
Button.present++;
|
||||
pinMode(Pin(GPIO_KEY1, i), bitRead(Button.no_pullup_mask, i) ? INPUT : ((16 == Pin(GPIO_KEY1, i)) ? INPUT_PULLDOWN_16 : INPUT_PULLUP));
|
||||
}
|
||||
#ifdef ESP8266
|
||||
#ifndef USE_ADC_VCC
|
||||
else if ((99 == Button.adc) && AdcButtonPresent(0)) {
|
||||
#ifdef USE_ADC
|
||||
else if (PinUsed(GPIO_ADC_BUTTON, i) || PinUsed(GPIO_ADC_BUTTON_INV, i)) {
|
||||
Button.present++;
|
||||
Button.adc = i;
|
||||
}
|
||||
#endif // USE_ADC_VCC
|
||||
#endif // ESP8266
|
||||
#endif // USE_ADC
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -157,22 +153,11 @@ void ButtonHandler(void)
|
|||
}
|
||||
Button.dual_code = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
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
|
||||
} else
|
||||
#endif // ESP8266
|
||||
if (PinUsed(GPIO_KEY1, button_index)) {
|
||||
button_present = 1;
|
||||
#ifdef ESP32
|
||||
if (bitRead(Button.touch_mask, button_index)) { // Touch
|
||||
uint32_t _value = touchRead(Pin(GPIO_KEY1, button_index));
|
||||
button = NOT_PRESSED;
|
||||
|
@ -192,11 +177,22 @@ void ButtonHandler(void)
|
|||
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
|
||||
}
|
||||
} else { // Normal button
|
||||
} else
|
||||
#endif // ESP32
|
||||
{ // Normal button
|
||||
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) {
|
||||
XdrvMailbox.index = button_index;
|
||||
XdrvMailbox.payload = button;
|
||||
|
|
|
@ -650,8 +650,8 @@ const uint16_t kGpioNiceList[] PROGMEM = {
|
|||
AGPIO(GPIO_ADC_INPUT) + MAX_ADCS, // Analog inputs
|
||||
AGPIO(GPIO_ADC_TEMP) + MAX_ADCS, // Thermistor
|
||||
AGPIO(GPIO_ADC_LIGHT) + MAX_ADCS, // Light sensor
|
||||
AGPIO(GPIO_ADC_BUTTON) + MAX_ADCS, // Button
|
||||
AGPIO(GPIO_ADC_BUTTON_INV) + MAX_ADCS,
|
||||
AGPIO(GPIO_ADC_BUTTON) + MAX_KEYS, // Button
|
||||
AGPIO(GPIO_ADC_BUTTON_INV) + MAX_KEYS,
|
||||
AGPIO(GPIO_ADC_RANGE) + MAX_ADCS, // Range
|
||||
AGPIO(GPIO_ADC_CT_POWER) + MAX_ADCS, // Current
|
||||
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_TEMP), // Thermistor
|
||||
AGPIO(GPIO_ADC_LIGHT), // Light sensor
|
||||
AGPIO(GPIO_ADC_BUTTON), // Button
|
||||
AGPIO(GPIO_ADC_BUTTON_INV),
|
||||
AGPIO(GPIO_ADC_BUTTON) + MAX_KEYS, // Button
|
||||
AGPIO(GPIO_ADC_BUTTON_INV) + MAX_KEYS,
|
||||
AGPIO(GPIO_ADC_RANGE), // Range
|
||||
AGPIO(GPIO_ADC_CT_POWER), // Current
|
||||
AGPIO(GPIO_ADC_JOY), // Joystick
|
||||
|
|
|
@ -477,6 +477,7 @@ const char HTTP_SCRIPT_TEMPLATE2[] PROGMEM =
|
|||
const char HTTP_SCRIPT_TEMPLATE3[] PROGMEM =
|
||||
"\";"
|
||||
"sk(g[13]," STR(ADC0_PIN) ");"; // Set ADC0
|
||||
|
||||
const char HTTP_SCRIPT_TEMPLATE4[] PROGMEM =
|
||||
"g=o.shift();" // FLAG
|
||||
"for(i=0;i<" STR(GPIO_FLAG_USED) ";i++){"
|
||||
|
@ -1800,13 +1801,23 @@ void HandleTemplateConfiguration(void)
|
|||
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(HTTP_SCRIPT_TEMPLATE2);
|
||||
|
||||
#ifdef ESP8266
|
||||
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) {
|
||||
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
|
||||
|
||||
#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
|
||||
#undef ANALOG_RANGE
|
||||
#define ANALOG_RANGE 4095 // 4095 = 12, 2047 = 11, 1023 = 10
|
||||
#endif // ESP8266 or ESP32
|
||||
|
||||
#define TO_CELSIUS(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
|
||||
|
||||
// Buttons
|
||||
// ---- Inverted
|
||||
// 3V3 ---| |----|
|
||||
// |
|
||||
// 3V3 --- R1 ----|--- R1 --- Gnd
|
||||
// |
|
||||
// |---| |--- Gnd
|
||||
// | ----
|
||||
// ADC
|
||||
#define ANALOG_BUTTON 128 // Add resistor tolerance
|
||||
|
||||
// Odroid joysticks
|
||||
// ---- Up
|
||||
// 3V3 ---| |------------
|
||||
|
@ -154,6 +172,7 @@ void AdcInitParams(uint8_t idx) {
|
|||
}
|
||||
|
||||
void AdcAttach(uint8_t pin, uint8_t type) {
|
||||
if (Adcs.present == MAX_ADCS) { return; }
|
||||
Adc[Adcs.present].pin = pin;
|
||||
if (adcAttachPin(Adc[Adcs.present].pin)) {
|
||||
Adc[Adcs.present].type = type;
|
||||
|
@ -174,12 +193,6 @@ void AdcInit(void) {
|
|||
if (PinUsed(GPIO_ADC_LIGHT, i)) {
|
||||
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)) {
|
||||
AdcAttach(Pin(GPIO_ADC_RANGE, i), ADC_RANGE);
|
||||
}
|
||||
|
@ -190,6 +203,15 @@ void AdcInit(void) {
|
|||
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) {
|
||||
#ifdef ESP32
|
||||
analogSetClockDiv(1); // Default 1
|
||||
|
@ -253,18 +275,19 @@ void AdcEvery250ms(void) {
|
|||
}
|
||||
#endif // USE_RULES
|
||||
|
||||
bool AdcButtonPresent(uint32_t idx) {
|
||||
return ((ADC_BUTTON == Adc[idx].type) || (ADC_BUTTON_INV == Adc[idx].type));
|
||||
}
|
||||
|
||||
uint8_t AdcGetButton(uint32_t idx) {
|
||||
uint8_t AdcGetButton(uint32_t pin) {
|
||||
for (uint32_t idx = 0; idx < Adcs.present; idx++) {
|
||||
if (Adc[idx].pin == pin) {
|
||||
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) {
|
||||
return (AdcRead(Adc[idx].pin, 1) > 128);
|
||||
return (AdcRead(Adc[idx].pin, 1) > ANALOG_BUTTON);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16_t AdcGetLux(uint32_t idx) {
|
||||
int adc = AdcRead(Adc[idx].pin, 2);
|
||||
|
|
Loading…
Reference in New Issue