diff --git a/CHANGELOG.md b/CHANGELOG.md index 821f8dfde..089d76cf6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ All notable changes to this project will be documented in this file. - TasmotaSerial ``read(buffer, size)`` regression from v9.3.0 - RCSwitch exception 0/6 on some protocols (#17285) - ESP32 exception 28 when RtcNtpServer is enabled on restart (#17338) +- Analog MQ exception 28 on restart (#17271) ### Removed diff --git a/RELEASENOTES.md b/RELEASENOTES.md index f464887a9..8a0d47cee 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -164,6 +164,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo - ModbusBridge buffer overflow [#16979](https://github.com/arendst/Tasmota/issues/16979) - ModbusBridge baudrates over 76500 baud [#17106](https://github.com/arendst/Tasmota/issues/17106) - SenseAir S8 module detection [#17033](https://github.com/arendst/Tasmota/issues/17033) +- Analog MQ exception 28 on restart [#17271](https://github.com/arendst/Tasmota/issues/17271) - RCSwitch exception 0/6 on some protocols [#17285](https://github.com/arendst/Tasmota/issues/17285) - ESP32 exception 28 when RtcNtpServer is enabled on restart [#17338](https://github.com/arendst/Tasmota/issues/17338) diff --git a/tasmota/tasmota_xsns_sensor/xsns_02_analog.ino b/tasmota/tasmota_xsns_sensor/xsns_02_analog.ino index 8c6464aea..5abb6b56a 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_02_analog.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_02_analog.ino @@ -386,46 +386,55 @@ uint16_t AdcGetLux(uint32_t idx) { } void AddSampleMq(uint32_t idx){ - AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_APPLICATION "Adding sample for mq-sensor")); +// AddLog(LOG_LEVEL_DEBUG, PSTR("ADC: Adding sample for mq-sensor")); + int _adc = AdcRead(Adc[idx].pin, 2); // init af array at same value - if (Adc[idx].indexOfPointer==-1) - { - AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_APPLICATION "Init samples for mq-sensor")); - for (int i = 0; i < ANALOG_MQ_SAMPLES; i ++) + if (Adc[idx].indexOfPointer==-1) { + +// AddLog(LOG_LEVEL_DEBUG, PSTR("ADC: Init samples for mq-sensor")); + + for (int i = 0; i < ANALOG_MQ_SAMPLES; i ++) { Adc[idx].mq_samples[i] = _adc; - } - else + } + } else { Adc[idx].mq_samples[Adc[idx].indexOfPointer] = _adc; + } Adc[idx].indexOfPointer++; - if (Adc[idx].indexOfPointer==ANALOG_MQ_SAMPLES) + if (Adc[idx].indexOfPointer==ANALOG_MQ_SAMPLES) { Adc[idx].indexOfPointer=0; + } } float AdcGetMq(uint32_t idx) { - AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_APPLICATION "Getting value for mq-sensor")); +// AddLog(LOG_LEVEL_DEBUG, PSTR("ADC: Getting value for mq-sensor")); + float avg = 0.0; - float _RL = 10; //Value in KiloOhms - float _R0 = 10; - for (int i = 0; i < ANALOG_MQ_SAMPLES; i ++) + for (int i = 0; i < ANALOG_MQ_SAMPLES; i ++) { avg += Adc[idx].mq_samples[i]; + } float voltage = (avg / ANALOG_MQ_SAMPLES) * ANALOG_V33 / ANALOG_RANGE; - float _RS_Calc = ((ANALOG_V33 * _RL) / voltage) -_RL; //Get value of RS in a gas - if (_RS_Calc < 0) _RS_Calc = 0; //No negative values accepted. - float _ratio = _RS_Calc / _R0; // Get ratio RS_gas/RS_air - float ppm= Adc[idx].param2/ANALOG_MQ_DECIMAL_MULTIPLIER*FastPrecisePow(_ratio, Adc[idx].param3/ANALOG_MQ_DECIMAL_MULTIPLIER); // <- Source excel analisis https://github.com/miguel5612/MQSensorsLib_Docs/tree/master/Internal_design_documents - if(ppm < 0) ppm = 0; //No negative values accepted or upper datasheet recomendation. - char ppm_chr[6]; - dtostrfd(ppm, 2, ppm_chr); - AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_APPLICATION "Ppm read. ADC-RAW: %2_f, ppm: %s,"), &voltage, ppm_chr); + float _RL = 10; // Value in KiloOhms + float _RS_Calc = ((ANALOG_V33 * _RL) / voltage) -_RL; // Get value of RS in a gas + if (_RS_Calc < 0) { + _RS_Calc = 0; // No negative values accepted. + } + + float _R0 = 10; + float _ratio = _RS_Calc / _R0; // Get ratio RS_gas/RS_air + float ppm = Adc[idx].param2 / ANALOG_MQ_DECIMAL_MULTIPLIER * FastPrecisePow(_ratio, Adc[idx].param3 / ANALOG_MQ_DECIMAL_MULTIPLIER); // Source excel analisis https://github.com/miguel5612/MQSensorsLib_Docs/tree/master/Internal_design_documents + if (ppm < 0) { ppm = 0; } // No negative values accepted or upper datasheet recomendation. + if (ppm > 100000) { ppm = 100000; } + +// AddLog(LOG_LEVEL_DEBUG, PSTR("ADC: Ppm read. ADC-RAW: %2_f, ppm: %2_f"), &voltage, &ppm); + return ppm; } float AdcGetPh(uint32_t idx) { int adc = AdcRead(Adc[idx].pin, 2); - float y1 = (float)Adc[idx].param1 / ANALOG_PH_DECIMAL_MULTIPLIER; int32_t x1 = Adc[idx].param2; float y2 = (float)Adc[idx].param3 / ANALOG_PH_DECIMAL_MULTIPLIER; @@ -434,12 +443,7 @@ float AdcGetPh(uint32_t idx) { float m = (y2 - y1) / (float)(x2 - x1); float ph = m * (float)(adc - x1) + y1; - - char phLow_chr[6]; - char phHigh_chr[6]; - dtostrfd(y1, 2, phLow_chr); - dtostrfd(y2, 2, phHigh_chr); - AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_APPLICATION "Analog pH read. ADC-RAW: %d, cal-low(pH=ADC): %s=%d, cal-high(pH=ADC): %s=%d"), adc, phLow_chr, x1, phHigh_chr,x2); +// AddLog(LOG_LEVEL_DEBUG, PSTR("ADC: Analog pH read. ADC-RAW: %d, cal-low(pH=ADC): %2_f = %d, cal-high(pH=ADC): %2_f = %d"), adc, &y1, x1, &y2, x2); return ph; } @@ -666,10 +670,9 @@ void AdcShow(bool json) { } case ADC_PH: { float ph = AdcGetPh(idx); - char ph_chr[6]; + char ph_chr[FLOATSZ]; dtostrfd(ph, 2, ph_chr); - if (json) { AdcShowContinuation(&jsonflg); ResponseAppend_P(PSTR("\"pH%d\":%s"), idx + offset, ph_chr); @@ -682,11 +685,11 @@ void AdcShow(bool json) { } case ADC_MQ: { float mq = AdcGetMq(idx); - char mq_chr[6]; + char mq_chr[FLOATSZ]; dtostrfd(mq, 2, mq_chr); float mqnumber =Adc[idx].param1; - char mqnumber_chr[6]; + char mqnumber_chr[FLOATSZ]; dtostrfd(mqnumber, 0, mqnumber_chr); if (json) { @@ -754,8 +757,8 @@ void CmndAdcParam(void) { Adc[idx].param2 = strtol(ArgV(argument, 3), nullptr, 10); Adc[idx].param3 = phHigh * ANALOG_PH_DECIMAL_MULTIPLIER; Adc[idx].param4 = strtol(ArgV(argument, 5), nullptr, 10); - AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_APPLICATION "Analog pH probe calibrated. cal-low(pH=ADC) %2_f=%d, cal-high(pH=ADC) %2_f=%d"), - &phLow, Adc[idx].param2, &phHigh, Adc[idx].param4); + +// AddLog(LOG_LEVEL_INFO, PSTR("ADC: Analog pH probe calibrated. cal-low(pH=ADC) %2_f = %d, cal-high(pH=ADC) %2_f = %d"), &phLow, Adc[idx].param2, &phHigh, Adc[idx].param4); } if (ADC_CT_POWER == XdrvMailbox.payload) { if (((1 == Adc[idx].param1) & CT_FLAG_ENERGY_RESET) > 0) { @@ -796,11 +799,11 @@ void CmndAdcParam(void) { ratioMQCleanAir=15; } } - Adc[idx].param2 = (int)(a * ANALOG_MQ_DECIMAL_MULTIPLIER); // Exponential regression - Adc[idx].param3 = (int)(b * ANALOG_MQ_DECIMAL_MULTIPLIER); // Exponential regression - Adc[idx].param4 = (int)(ratioMQCleanAir * ANALOG_MQ_DECIMAL_MULTIPLIER); // Exponential regression - AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_APPLICATION "Analog MQ reset: mq%d, a=%2_f, b=%2_f, ratioMQCleanAir=%2_f"), - Adc[idx].param1, &a, &b, &ratioMQCleanAir); + Adc[idx].param2 = (int)(a * ANALOG_MQ_DECIMAL_MULTIPLIER); // Exponential regression + Adc[idx].param3 = (int)(b * ANALOG_MQ_DECIMAL_MULTIPLIER); // Exponential regression + Adc[idx].param4 = (int)(ratioMQCleanAir * ANALOG_MQ_DECIMAL_MULTIPLIER); // Exponential regression + +// 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 2 @@ -829,7 +832,7 @@ void CmndAdcParam(void) { if (value % 10) { break; } value /= 10; } - char param3[33]; + char param3[FLOATSZ]; dtostrfd(((double)Adc[idx].param3)/10000, precision, param3); ResponseAppend_P(PSTR(",%s,%d"), param3, Adc[idx].param4); }