From 87ec0cce21c08a3ef94de5bb0b2afa6d5dc03d7e Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sun, 28 Jul 2024 18:47:13 +0200 Subject: [PATCH] Revert "Analog GPIO extensions" This reverts commit 7c1cf6a81fe9538324044864c7a79a7fe4380d0e. --- CHANGELOG.md | 5 +- RELEASENOTES.md | 4 - .../tasmota_xsns_sensor/xsns_02_analog.ino | 170 ++++++++---------- 3 files changed, 76 insertions(+), 103 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8be994b64..9df16d77c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,15 +10,12 @@ All notable changes to this project will be documented in this file. - Matter support for split lights (`SetOption68 1` and `SetOption37 128`) (#21834) - Berry `webserver_async` (#21836) - NeoPool command `NPSetOption` to enabled/disable data validation/connection statistics (#21850) -- Analog GPIO ``ADC Input`` with ``AdcParam 1,,,1`` provide direct light control -- Analog GPIO ``ADC Voltage`` with ``AdcParam 11,,,,`` provide energy monitoring with dc voltage -- Analog GPIO ``ADC Current`` with ``AdcParam 12,,,,`` provide energy monitoring with dc voltage ### Breaking Changed ### Changed - Berry consolidated constants for solidified classes reduces Flash size (#2185) -- Berry updated precompiled Windows binary (#21858) +- Berry updated precompiled Windows binary ### Fixed - Berry `light.get` for separate RGB/CT (#21818) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index dda3ffe0e..102884e1d 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -126,9 +126,6 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm - Support for Sonoff iFan04-H using template [#16402](https://github.com/arendst/Tasmota/issues/16402) - Support for Sonoff POWCT Ring [#21131](https://github.com/arendst/Tasmota/issues/21131) - Support for Wooliis Hall Effect Coulometer or Battery capacity monitor [#21732](https://github.com/arendst/Tasmota/issues/21732) -- Analog GPIO ``ADC Input`` with ``AdcParam 1,,,1`` provide direct light control -- Analog GPIO ``ADC Voltage`` with ``AdcParam 11,,,,`` provide energy monitoring with dc voltage -- Analog GPIO ``ADC Current`` with ``AdcParam 12,,,,`` provide energy monitoring with dc voltage - Skip MQTT response if command is prefixed with underscore [#21740](https://github.com/arendst/Tasmota/issues/21740) - Skip MQTT response if commands are executed prefixed with ``Backlog2`` (no delay) or ``Backlog3`` [#21740](https://github.com/arendst/Tasmota/issues/21740) - Extend command ``SetOption147 1`` to disable publish of IRReceived MQTT messages [#21574](https://github.com/arendst/Tasmota/issues/21574) @@ -173,7 +170,6 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm - ESP32 MI32 refactoring, bugfixes, generic device scanning [#21603](https://github.com/arendst/Tasmota/issues/21603) - ESP32 MI32 improve parser [#21648](https://github.com/arendst/Tasmota/issues/21648) - ESP32 TM1621 number overflow from "9999" to "12E3" [#21131](https://github.com/arendst/Tasmota/issues/21131) -- Berry updated precompiled Windows binary [#21858](https://github.com/arendst/Tasmota/issues/21858) - Berry simplified `module persist` [#21812](https://github.com/arendst/Tasmota/issues/21812) - Berry consolidated constants for solidified classes reduces Flash size [#2185](https://github.com/arendst/Tasmota/issues/2185) - Matter refactoring of bridged devices [#21575](https://github.com/arendst/Tasmota/issues/21575) diff --git a/tasmota/tasmota_xsns_sensor/xsns_02_analog.ino b/tasmota/tasmota_xsns_sensor/xsns_02_analog.ino index 6a0a8af3e..85b0d116e 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_02_analog.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_02_analog.ino @@ -34,6 +34,7 @@ #ifdef ESP8266 #define ANALOG_RESOLUTION 10 // 12 = 4095, 11 = 2047, 10 = 1023 #define ANALOG_RANGE 1023 // 4095 = 12, 2047 = 11, 1023 = 10 +#define ANALOG_PERCENT 10 // backward compatible div10 range #endif // ESP8266 #ifdef ESP32 @@ -41,6 +42,8 @@ #define ANALOG_RESOLUTION 12 // 12 = 4095, 11 = 2047, 10 = 1023 #undef ANALOG_RANGE #define ANALOG_RANGE 4095 // 4095 = 12, 2047 = 11, 1023 = 10 +#undef ANALOG_PERCENT +#define ANALOG_PERCENT ((ANALOG_RANGE + 50) / 100) // approximation to 1% ADC range #endif // ESP32 #define TO_CELSIUS(x) ((x) - 273.15f) @@ -209,53 +212,52 @@ void AdcGetSettings(uint32_t idx) { void AdcInitParams(uint8_t idx) { if ((Adcs.type != Adc[idx].type) || (Adc[idx].param1 > 1000000)) { - switch (Adc[idx].type) { - case ADC_INPUT: - Adc[idx].param1 = 0; - Adc[idx].param2 = ANALOG_RANGE; - Adc[idx].param3 = 0; // Default mode (0) or Direct mode (1) using Dimmer or Channel command - case ADC_TEMP: - // Default Shelly 2.5 and 1PM parameters - Adc[idx].param1 = ANALOG_NTC_BRIDGE_RESISTANCE; - Adc[idx].param2 = ANALOG_NTC_RESISTANCE; - Adc[idx].param3 = ANALOG_NTC_B_COEFFICIENT * 10000; - Adc[idx].param4 = 0; // Default to Shelly mode with NTC towards GND - break; - case ADC_LIGHT: - Adc[idx].param1 = ANALOG_LDR_BRIDGE_RESISTANCE; - Adc[idx].param2 = ANALOG_LDR_LUX_CALC_SCALAR; - Adc[idx].param3 = ANALOG_LDR_LUX_CALC_EXPONENT * 10000; - break; - case ADC_RANGE: - Adc[idx].param1 = 0; - Adc[idx].param2 = ANALOG_RANGE; - Adc[idx].param3 = 0; - Adc[idx].param4 = 100; - break; - case ADC_CT_POWER: - Adc[idx].param1 = ANALOG_CT_FLAGS; // (uint32_t) 0 - Adc[idx].param2 = ANALOG_CT_MULTIPLIER; // (uint32_t) 100000 - Adc[idx].param3 = ANALOG_CT_VOLTAGE; // (int) 10 - break; - case ADC_PH: - Adc[idx].param1 = ANALOG_PH_CALSOLUTION_LOW_PH * ANALOG_PH_DECIMAL_MULTIPLIER; // PH of the calibration solution 1, which is the one with the lower PH - Adc[idx].param2 = ANALOG_PH_CALSOLUTION_LOW_ANALOG_VALUE; // Reading of AnalogInput while probe is in solution 1 - Adc[idx].param3 = ANALOG_PH_CALSOLUTION_HIGH_PH * ANALOG_PH_DECIMAL_MULTIPLIER; // PH of the calibration solution 2, which is the one with the higher PH - Adc[idx].param4 = ANALOG_PH_CALSOLUTION_HIGH_ANALOG_VALUE; // Reading of AnalogInput while probe is in solution 2 - break; - case ADC_MQ: - Adc[idx].param1 = ANALOG_MQ_TYPE; // Could be MQ-002, MQ-004, MQ-131 .... - Adc[idx].param2 = (int)(ANALOG_MQ_A * ANALOG_MQ_DECIMAL_MULTIPLIER); // Exponential regression - Adc[idx].param3 = (int)(ANALOG_MQ_B * ANALOG_MQ_DECIMAL_MULTIPLIER); // Exponential regression - Adc[idx].param4 = (int)(ANALOG_MQ_RatioMQCleanAir * ANALOG_MQ_DECIMAL_MULTIPLIER); // Exponential regression - break; - case ADC_VOLTAGE: - case ADC_CURRENT: - Adc[idx].param1 = 0; - Adc[idx].param2 = ANALOG_RANGE; - Adc[idx].param3 = 0; - Adc[idx].param4 = ANALOG_V33 * 10000; - break; + if (ADC_TEMP == Adc[idx].type) { + // Default Shelly 2.5 and 1PM parameters + Adc[idx].param1 = ANALOG_NTC_BRIDGE_RESISTANCE; + Adc[idx].param2 = ANALOG_NTC_RESISTANCE; + Adc[idx].param3 = ANALOG_NTC_B_COEFFICIENT * 10000; + Adc[idx].param4 = 0; // Default to Shelly mode with NTC towards GND + } + else if (ADC_LIGHT == Adc[idx].type) { + Adc[idx].param1 = ANALOG_LDR_BRIDGE_RESISTANCE; + Adc[idx].param2 = ANALOG_LDR_LUX_CALC_SCALAR; + Adc[idx].param3 = ANALOG_LDR_LUX_CALC_EXPONENT * 10000; + } + else if (ADC_RANGE == Adc[idx].type) { + Adc[idx].param1 = 0; + Adc[idx].param2 = ANALOG_RANGE; + Adc[idx].param3 = 0; + Adc[idx].param4 = 100; + } + else if (ADC_CT_POWER == Adc[idx].type) { + Adc[idx].param1 = ANALOG_CT_FLAGS; // (uint32_t) 0 + Adc[idx].param2 = ANALOG_CT_MULTIPLIER; // (uint32_t) 100000 + Adc[idx].param3 = ANALOG_CT_VOLTAGE; // (int) 10 + } + else if (ADC_PH == Adc[idx].type) { + Adc[idx].param1 = ANALOG_PH_CALSOLUTION_LOW_PH * ANALOG_PH_DECIMAL_MULTIPLIER; // PH of the calibration solution 1, which is the one with the lower PH + Adc[idx].param2 = ANALOG_PH_CALSOLUTION_LOW_ANALOG_VALUE; // Reading of AnalogInput while probe is in solution 1 + Adc[idx].param3 = ANALOG_PH_CALSOLUTION_HIGH_PH * ANALOG_PH_DECIMAL_MULTIPLIER; // PH of the calibration solution 2, which is the one with the higher PH + Adc[idx].param4 = ANALOG_PH_CALSOLUTION_HIGH_ANALOG_VALUE; // Reading of AnalogInput while probe is in solution 2 + } + else if (ADC_MQ == Adc[idx].type) { + Adc[idx].param1 = ANALOG_MQ_TYPE; // Could be MQ-002, MQ-004, MQ-131 .... + Adc[idx].param2 = (int)(ANALOG_MQ_A * ANALOG_MQ_DECIMAL_MULTIPLIER); // Exponential regression + Adc[idx].param3 = (int)(ANALOG_MQ_B * ANALOG_MQ_DECIMAL_MULTIPLIER); // Exponential regression + Adc[idx].param4 = (int)(ANALOG_MQ_RatioMQCleanAir * ANALOG_MQ_DECIMAL_MULTIPLIER); // Exponential regression + } + else if (ADC_VOLTAGE == Adc[idx].type) { + Adc[idx].param1 = 0; + Adc[idx].param2 = ANALOG_RANGE; + Adc[idx].param3 = 0; + Adc[idx].param4 = ANALOG_V33 * 10000; + } + else if (ADC_CURRENT == Adc[idx].type) { + Adc[idx].param1 = 0; + Adc[idx].param2 = ANALOG_RANGE; + Adc[idx].param3 = 0; + Adc[idx].param4 = ANALOG_V33 * 10000; } } if ((Adcs.type != Adc[idx].type) || (0 == Adc[idx].param1) || (Adc[idx].param1 > ANALOG_RANGE)) { @@ -383,6 +385,7 @@ uint16_t AdcRead(uint32_t pin, uint32_t factor) { return analog; } +#ifdef USE_RULES void AdcEvery250ms(void) { char adc_idx[3] = { 0 }; uint32_t offset = 0; @@ -392,35 +395,12 @@ void AdcEvery250ms(void) { offset = 1; #endif if (ADC_INPUT == Adc[idx].type) { - int adc = AdcRead(Adc[idx].pin, 4); // 4 = 16 mS - int new_value = changeUIntScale(adc, Adc[idx].param1, Adc[idx].param2, 0, 100); - if ((new_value < Adc[idx].last_value -2) || - (new_value > Adc[idx].last_value +2) || - ((0 == new_value) && (Adc[idx].last_value != 0)) || // Lowest end - ((100 == new_value) && (Adc[idx].last_value != 100))) { // Highest end + uint16_t new_value = AdcRead(Adc[idx].pin, 5); + if ((new_value < Adc[idx].last_value -ANALOG_PERCENT) || (new_value > Adc[idx].last_value +ANALOG_PERCENT)) { Adc[idx].last_value = new_value; - if (-1 == Adc[idx].indexOfPointer) { - Adc[idx].indexOfPointer = 0; - continue; // Skip action on restart - } -#ifdef USE_LIGHT - if (0 == Adc[idx].param3) { // Default (0) or Direct mode (1) -#endif // USE_LIGHT - Response_P(PSTR("{\"ANALOG\":{\"A%ddiv10\":%d}}"), idx + offset, new_value); - XdrvRulesProcess(0); -#ifdef USE_LIGHT - } else { - char command[33]; - if (Settings->flag3.pwm_multi_channels) { // SetOption68 - Enable multi-channels PWM instead of Color PWM -// snprintf_P(command, sizeof(command), PSTR("_" D_CMND_CHANNEL "%d %d"), idx +1, new_value); - snprintf_P(command, sizeof(command), PSTR(D_CMND_CHANNEL "%d %d"), idx +1, new_value); - } else { -// snprintf_P(command, sizeof(command), PSTR("_" D_CMND_DIMMER "3 %d"), new_value); - snprintf_P(command, sizeof(command), PSTR(D_CMND_DIMMER "3 %d"), new_value); // Change both RGB and W(W) Dimmers with no fading - } - ExecuteCommand(command, SRC_SWITCH); - } -#endif // USE_LIGHT + uint16_t value = Adc[idx].last_value / ANALOG_PERCENT; + Response_P(PSTR("{\"ANALOG\":{\"A%ddiv10\":%d}}"), idx + offset, (value > 99) ? 100 : value); + XdrvRulesProcess(0); } } else if (ADC_JOY == Adc[idx].type) { @@ -436,6 +416,7 @@ void AdcEvery250ms(void) { } } } +#endif // USE_RULES uint8_t AdcGetButton(uint32_t pin) { for (uint32_t idx = 0; idx < Adcs.present; idx++) { @@ -660,21 +641,16 @@ void AdcShow(bool json) { switch (Adc[idx].type) { case ADC_INPUT: { -#ifdef USE_LIGHT - if (0 == Adc[idx].param3) { // Default (0) or Direct mode (1) -#endif // USE_LIGHT - uint16_t analog = AdcRead(Adc[idx].pin, 5); - if (json) { - AdcShowContinuation(&jsonflg); - ResponseAppend_P(PSTR("\"A%d\":%d"), idx + offset, analog); + uint16_t analog = AdcRead(Adc[idx].pin, 5); + + if (json) { + AdcShowContinuation(&jsonflg); + ResponseAppend_P(PSTR("\"A%d\":%d"), idx + offset, analog); #ifdef USE_WEBSERVER - } else { - WSContentSend_PD(HTTP_SNS_ANALOG, "", idx + offset, analog); + } else { + WSContentSend_PD(HTTP_SNS_ANALOG, "", idx + offset, analog); #endif // USE_WEBSERVER - } -#ifdef USE_LIGHT } -#endif // USE_LIGHT break; } case ADC_TEMP: { @@ -839,11 +815,10 @@ void CmndAdcParam(void) { if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= MAX_ADCS)) { uint8_t idx = XdrvMailbox.index -1; if (XdrvMailbox.data_len) { - if (XdrvMailbox.payload > 0) { + if (XdrvMailbox.payload > ADC_INPUT) { AdcGetSettings(idx); if (ArgC() > 3) { // Process parameter entry char argument[XdrvMailbox.data_len]; - // AdcParam 1, 0, ANALOG_RANGE, 0 ADC_INPUT rule | dimmer // AdcParam 2, 32000, 10000, 3350 ADC_TEMP Shelly mode // AdcParam 2, 32000, 10000, 3350, 1 ADC_TEMP Alternate mode // AdcParam 3, 10000, 12518931, -1.405 @@ -859,8 +834,7 @@ void CmndAdcParam(void) { Adc[idx].type = XdrvMailbox.payload; Adc[idx].param1 = strtol(ArgV(argument, 2), nullptr, 10); // param1 = int Adc[idx].param2 = strtol(ArgV(argument, 3), nullptr, 10); // param2 = int - if ((ADC_INPUT == XdrvMailbox.payload) || - (ADC_RANGE == XdrvMailbox.payload)) { + if (ADC_RANGE == XdrvMailbox.payload) { Adc[idx].param3 = abs(strtol(ArgV(argument, 4), nullptr, 10)); // param3 = abs(int) Adc[idx].param4 = abs(strtol(ArgV(argument, 5), nullptr, 10)); // param4 = abs(int) } else { @@ -923,7 +897,13 @@ void CmndAdcParam(void) { // AddLog(LOG_LEVEL_INFO, PSTR("ADC: MQ reset mq%d, a = %2_f, b = %2_f, ratioMQCleanAir = %2_f"), Adc[idx].param1, &a, &b, &ratioMQCleanAir); } } else { // Set default values based on current adc type - // AdcParam 1 + // AdcParam 2 + // AdcParam 3 + // AdcParam 4 + // AdcParam 5 + // AdcParam 6 + // AdcParam 7 + // AdcParam 8 Adcs.type = 0; AdcInitParams(idx); } @@ -934,9 +914,7 @@ void CmndAdcParam(void) { // AdcParam AdcGetSettings(idx); Response_P(PSTR("{\"" D_CMND_ADCPARAM "%d\":[%d,%d,%d"), idx +1, Adcs.type, Adc[idx].param1, Adc[idx].param2); - if ((ADC_INPUT == Adc[idx].type) || - (ADC_RANGE == Adc[idx].type) || - (ADC_MQ == Adc[idx].type)) { + if ((ADC_RANGE == Adc[idx].type) || (ADC_MQ == Adc[idx].type)) { ResponseAppend_P(PSTR(",%d,%d"), Adc[idx].param3, Adc[idx].param4); // param3 = int, param4 = int } else { @@ -1002,9 +980,11 @@ bool Xsns02(uint32_t function) { default: if (Adcs.present) { switch (function) { +#ifdef USE_RULES case FUNC_EVERY_250_MSECOND: AdcEvery250ms(); break; +#endif // USE_RULES case FUNC_EVERY_SECOND: AdcEverySecond(); break;