AlexBelfegor / esphome-mq135

Yaml code for MQ135 sensor
MIT License
48 stars 14 forks source link

Sudden PPM C02 value changes #6

Open Rahulsharma0810 opened 1 year ago

Rahulsharma0810 commented 1 year ago

Esphome shows sudden changes in PPM.

Corrected PPM CO2: 508.0 ppm to 2316001.0 ppm and returned after a few seconds. PPM CO2 546.8 pm to 52620.1 ppm and returned after a few seconds.

image image
globals:

#The load resistance on the board. Value in KiloOhms
  - id: RLOAD
    type: float
    restore_value: no
    initial_value: '1.025'

#Calibration resistance at atmospheric CO2 level. Outdoor calibration data
  - id: RZERO
    type: float
    restore_value: no
    initial_value: '35.429'

#Atmospheric CO2 level for calibration purposes. Outdoor CO2 level during calibration. Usually 450, but it's better to clarify.
  - id: ATMOCO2
    type: float
    restore_value: no
    initial_value: '450'

#Parameters for calculating ppm of CO2 from sensor resistance
#  Exponential regression:
#  GAS      | a      | b
#  CO       | 605.18 | -3.937  
#  Alcohol  | 77.255 | -3.18 
#  CO2      | 110.47 | -2.862
#  Tolueno  | 44.947 | -3.445
#  NH4      | 102.2  | -2.473
#  Acetona  | 34.668 | -3.369
  - id: PARA
    type: float
    restore_value: no
    initial_value: '110.47'
  - id: PARB
    type: float
    restore_value: no
    initial_value: '-2.862'

#Parameters to model temperature and humidity dependence
  - id: CORA
    type: float
    restore_value: no
    initial_value: '0.00035'
  - id: CORB
    type: float
    restore_value: no
    initial_value: '0.02718'
  - id: CORC
    type: float
    restore_value: no
    initial_value: '1.39538'
  - id: CORD
    type: float
    restore_value: no
    initial_value: '0.0018'
  - id: CORE
    type: float
    restore_value: no
    initial_value: '-0.003333333'
  - id: CORF
    type: float
    restore_value: no
    initial_value: '-0.001923077'
  - id: CORG
    type: float
    restore_value: no
    initial_value: '1.130128205'

# Here you need to indicate the supply voltage of the MQ135 sensor. It can be measured with a voltmeter. Please note that the rated power will not always be accurate.
  - id: volt_resolution
    type: float
    restore_value: no
    initial_value: '5.14'

# 1 for Exponential, 2 for Linear
  - id: regression_method
    type: int
    restore_value: no
    initial_value: '1'

i2c:
  sda: 21
  scl: 22
  scan: False
  id: bus_a

sensor:
  - platform: dht
    pin: 13
    temperature:
      name: "Temperature dht"
      id: dht_temperature
    humidity:
      name: "Humidity"
      id: dht_humidity
      filters:
      - lambda: if ((id(dht_temperature).state)>=0) {return (id(dht_humidity).raw_state + (25.0 - id(dht_temperature).state) * (-0.15));} else {return id(dht_humidity).raw_state;}
    update_interval: 30s

  - platform: adc
    pin: 35
    name: "Gas ADC"
    update_interval: 1s
    filters:
      - multiply: 3.3 # for NodeMcu ESP8266 v3 Lua
    accuracy_decimals: 4
    unit_of_measurement: V
    id: sensor_volt

  - platform: template
    #Linearization of the temperature dependency curve under and above 20 degree C
    #below 20degC: fact = a * t * t - b * t - (h - 33) * d
    #above 20degC: fact = a * t + b * h + c
    #this assumes a linear dependency on humidity
    #getCorrectionFactor
    name: "Correction Factor"
    lambda: |-
      if (id(dht_temperature).state<20) {
        return (id(CORA) * id(dht_temperature).state * id(dht_temperature).state - id(CORB) *
          id(dht_temperature).state + id(CORC) - (id(dht_humidity).state - 33.) * id(CORD));
      } else {
        return (id(CORE) * id(dht_temperature).state + id(CORF) * id(dht_humidity).state + id(CORG));
      }
    update_interval: 10s
    accuracy_decimals: 6
    id: correction_factor

  - platform: template
    #Get the resistance of the sensor, ie. the measurement value @return The sensor resistance in kOhm
    # RS = [(VC x RL) / VRL] - RL
    # RS_air = ((5.14*1.0)/sensor_volt)-1.0 Calculate RS in fresh air 
    #getResistance
    name: "Resistance"
    lambda: |-
      return ((id(volt_resolution)*id(RLOAD)/id(sensor_volt).state) - id(RLOAD));
    update_interval: 5s
    accuracy_decimals: 3
    unit_of_measurement: kOm
    id: resistance

  - platform: template
    # Get the resistance of the sensor, ie. the measurement value correctedfor temp/hum @return The corrected sensor resistance kOhm
    #getCorrectedResistance
    name: "Corrected Resistance"
    lambda: |-
      return (id(resistance).state / id(correction_factor).state);
    update_interval: 5s
    accuracy_decimals: 3
    unit_of_measurement: kOm
    id: corrected_resistance

  - platform: template
    # Get the ppm of CO2 sensed (assuming only CO2 in the air). The ppm of CO2 in the air
    #getPPM
    name: "PPM CO2"
    lambda: |-
      if (id(regression_method)==1) {
        return (id(PARA) * pow((id(resistance).state / id(RZERO)), id(PARB)));
      } else {
        return (pow(10, (log10(id(resistance).state / id(RZERO)) - id(PARB)) / id(PARA)));
      }
    update_interval: 5s
    unit_of_measurement: ppm
    id: ppm_co2

  - platform: template
    # Get the ppm of CO2 sensed (assuming only CO2 in the air), corrected  for temp. The ppm of CO2 in the air
    #getCorrectedPPM
    name: "Corrected PPM CO2"
    lambda: |-
      if (id(regression_method)==1) {
        return (id(PARA) * pow((id(corrected_resistance).state / id(RZERO)), id(PARB)));
      } else {
        return (pow(10, (log10(id(corrected_resistance).state / id(RZERO)) - id(PARB)) / id(PARA)));
      }
    update_interval: 5s
    unit_of_measurement: ppm
    id: corrected_ppm_co2

  - platform: template
    # Get the resistance RZero of the sensor for calibration purposes. The sensor resistance RZero in kOhm
    #getRZero
    name: "RZero"
    lambda: |-
      return (id(resistance).state / pow((id(ATMOCO2) / id(PARA)), (1./id(PARB))));
    filters:
      - sliding_window_moving_average:
          window_size: 15
          send_every: 1
    update_interval: 5s
    accuracy_decimals: 3
    unit_of_measurement: kOm
    id: r_zero

  - platform: template
    # Get the corrected resistance RZero of the sensor for calibration purposes. The corrected sensor resistance RZERO in kOhm for ATMOCO2 level
    #getCorrectedRZero
    name: "CorrectedRZero"
    lambda: |-
      return (id(corrected_resistance).state / pow((id(ATMOCO2) / id(PARA)), (1./id(PARB))));
    filters:
      - sliding_window_moving_average:
          window_size: 15
          send_every: 1
    update_interval: 5s
    accuracy_decimals: 3
    unit_of_measurement: kOm
    id: corrected_r_zero
madebywitteveen commented 1 year ago

Hi, did you got it working ?

Rahulsharma0810 commented 1 year ago

Not yet. I will try to replace it waveshare MQ135. The current sensor I have is generic I doubt its workability.

madebywitteveen commented 1 year ago

Which one sensor are you using now ?

madebywitteveen commented 1 year ago

I don't know whether it is in the code or the sensor but every few minutes all the readings are reset to zero and the code starts over so it seems, do you know why that is perhaps ? and all the corrected values staying at 'NA' is that with you also? is it needed for the code to work to have the temperature sensor connected ?

thanks, bye