diff --git a/tasmota/berry/include/be_gpio_defines.h b/tasmota/berry/include/be_gpio_defines.h index e40219dc4..8906f90a0 100644 --- a/tasmota/berry/include/be_gpio_defines.h +++ b/tasmota/berry/include/be_gpio_defines.h @@ -14,6 +14,7 @@ const be_const_member_t lv_gpio_constants[] = { { "ADC_INPUT", (int32_t) GPIO_ADC_INPUT }, { "ADC_JOY", (int32_t) GPIO_ADC_JOY }, { "ADC_LIGHT", (int32_t) GPIO_ADC_LIGHT }, + { "ADC_MQ", (int32_t) GPIO_ADC_MQ }, { "ADC_PH", (int32_t) GPIO_ADC_PH }, { "ADC_RANGE", (int32_t) GPIO_ADC_RANGE }, { "ADC_TEMP", (int32_t) GPIO_ADC_TEMP }, diff --git a/tasmota/berry/internal/gpio.be b/tasmota/berry/internal/gpio.be index 3c589a046..a1816dfc7 100644 --- a/tasmota/berry/internal/gpio.be +++ b/tasmota/berry/internal/gpio.be @@ -254,3 +254,4 @@ gpio.TFMINIPLUS_RX = 235 gpio.ZEROCROSS = 236 gpio.HALLEFFECT = 237 gpio.SENSOR_END = 238 +gpio.ADC_MQ = 239 diff --git a/tasmota/language/it_IT.h b/tasmota/language/it_IT.h index 2c7f37b61..5d200f748 100644 --- a/tasmota/language/it_IT.h +++ b/tasmota/language/it_IT.h @@ -788,6 +788,7 @@ #define D_SENSOR_ADC_CT_POWER "ADC - CTR alimentazione" #define D_SENSOR_ADC_JOYSTICK "ADC - Joystick" #define D_SENSOR_ADC_PH "ADC pH" +#define D_SENSOR_ADC_MQ "ADC MQ" #define D_GPIO_WEBCAM_PWDN "Webcam - PWDN" #define D_GPIO_WEBCAM_RESET "Webcam - RESET" #define D_GPIO_WEBCAM_XCLK "Webcam - XCLK" diff --git a/tasmota/language/pt_BR.h b/tasmota/language/pt_BR.h index 45a32b6da..4ab70c0b6 100644 --- a/tasmota/language/pt_BR.h +++ b/tasmota/language/pt_BR.h @@ -789,6 +789,7 @@ #define D_SENSOR_ADC_CT_POWER "PotĂȘncia do TC ADC" #define D_SENSOR_ADC_JOYSTICK "Joystick ADC" #define D_SENSOR_ADC_PH "pH ADC" +#define D_SENSOR_ADC_MQ "ADC MQ" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" diff --git a/tasmota/language/pt_PT.h b/tasmota/language/pt_PT.h index 5ba030dee..c7d398fbb 100644 --- a/tasmota/language/pt_PT.h +++ b/tasmota/language/pt_PT.h @@ -789,6 +789,7 @@ #define D_SENSOR_ADC_CT_POWER "PotĂȘncia do TC ADC" #define D_SENSOR_ADC_JOYSTICK "Joystick ADC" #define D_SENSOR_ADC_PH "pH ADC" +#define D_SENSOR_ADC_MQ "MQ ADC" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" diff --git a/tasmota/tasmota_template.h b/tasmota/tasmota_template.h index 0047c8b30..86efb5c41 100644 --- a/tasmota/tasmota_template.h +++ b/tasmota/tasmota_template.h @@ -399,8 +399,8 @@ const char kSensorNames[] PROGMEM = D_GPIO_SHIFT595_SRCLK "|" D_GPIO_SHIFT595_RCLK "|" D_GPIO_SHIFT595_OE "|" D_GPIO_SHIFT595_SER "|" D_SENSOR_SOLAXX1_RTS "|" D_SENSOR_OPTION " E|" - D_SENSOR_SDM230_TX "|" D_SENSOR_SDM230_RX - D_SENSOR_ADC_MQ "|" + D_SENSOR_SDM230_TX "|" D_SENSOR_SDM230_RX "|" + D_SENSOR_ADC_MQ ; const char kSensorNamesFixed[] PROGMEM = diff --git a/tasmota/xsns_02_analog.ino b/tasmota/xsns_02_analog.ino index 444021efd..444a3d0b4 100644 --- a/tasmota/xsns_02_analog.ino +++ b/tasmota/xsns_02_analog.ino @@ -134,6 +134,8 @@ #define ANALOG_MQ_RatioMQCleanAir 15.0 // Multiplier used to store pH with 2 decimal places in a non decimal datatype #define ANALOG_MQ_DECIMAL_MULTIPLIER 100.0 +// lenght of filter +#define ANALOG_MQ_SAMPLES 60 struct { uint8_t present = 0; @@ -152,6 +154,8 @@ struct { uint16_t last_value = 0; uint8_t type = 0; uint8_t pin = 0; + float mq_samples[ANALOG_MQ_SAMPLES]; + int indexOfPointer = -1; } Adc[MAX_ADCS]; #ifdef ESP8266 @@ -230,7 +234,7 @@ void AdcInitParams(uint8_t idx) { } } -void AdcAttach(uint8_t pin, uint8_t type) { +void AdcAttach(uint32_t pin, uint8_t type) { if (Adcs.present == MAX_ADCS) { return; } Adc[Adcs.present].pin = pin; if (adcAttachPin(Adc[Adcs.present].pin)) { @@ -367,20 +371,31 @@ uint16_t AdcGetLux(uint32_t idx) { return (uint16_t)ldrLux; } +void AddSampleMq(uint32_t idx){ + AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_APPLICATION "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 ++) + Adc[idx].mq_samples[i] = _adc; + } + else + Adc[idx].mq_samples[Adc[idx].indexOfPointer] = _adc; + Adc[idx].indexOfPointer++; + 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")); float avg = 0.0; - int retries = 5; - int retries_delay = 20; float _RL = 10; //Value in KiloOhms float _R0 = 10; - int _adc = AdcRead(Adc[idx].pin, 2); - avg += _adc; - for (int i = 0; i < retries-1; i ++) { - delay(retries_delay); - _adc = AdcRead(Adc[idx].pin, 2); - avg += _adc; - } - float voltage = (avg/ retries) * ANALOG_V33 / ((FastPrecisePow(2, ANALOG_RESOLUTION)) - 1); + for (int i = 0; i < ANALOG_MQ_SAMPLES; i ++) + avg += Adc[idx].mq_samples[i]; + float voltage = (avg / ANALOG_MQ_SAMPLES) * ANALOG_V33 / ((FastPrecisePow(2, ANALOG_RESOLUTION)) - 1); 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. @@ -389,7 +404,7 @@ float AdcGetMq(uint32_t idx) { 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: %d, ppm: %d,"), voltage, ppm_chr); + AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_APPLICATION "Ppm read. ADC-RAW: %2_f, ppm: %s,"), &voltage, ppm_chr); return ppm; } @@ -485,6 +500,7 @@ void AdcEverySecond(void) { AdcGetCurrentPower(idx, 5); } else if (ADC_MQ == Adc[idx].type) { + AddSampleMq(idx); AdcGetMq(idx); } }