Page 1 of 1

MQ135 sensor Attribute Error

Posted: Sat Apr 02, 2022 2:51 am
by soggycashew
I'm trying to connect a mq135 gas/c02 sensor to my project and found the drivers link in Awsome MicroPython to GitHub HERE and I just cant get this thing to work. I'm using the DHT22 temp and hum sensor (I know it works) instead of the DHT11 so I had to change a few things for that. Anyways I'm getting the error:
Traceback (most recent call last):
File "<stdin>", line 12, in <module>
File "mq135.py", line 78, in get_rzero
AttributeError: 'ADC' object has no attribute 'get_resistance'
and I have no idea why? line 12 in the example is rzero = MQ135.get_rzero(adc3) and below I posted the example and driver. Sugestions?

Code: Select all

import machine, time
from dht22 import DHT22
from mq135 import MQ135

adc3 = machine.ADC(machine.Pin(29))
dht22 = DHT22(machine.Pin(2,machine.Pin.IN,machine.Pin.PULL_UP))

while True:

    T, H = dht22.read() # Gets Temp & Hum from dht22.py library

    rzero = MQ135.get_rzero(adc3)
    corrected_rzero = MQ135.get_corrected_rzero(adc3,T, H)
    resistance = MQ135.get_resistance(adc3)
    ppm = MQ135.get_ppm(adc3)
    corrected_ppm = MQ135.get_corrected_ppm(adc3,T, H)

    print("DHT22 Temperature: " + str(T) +"\t Humidity: "+ str(H))
    print("MQ135 RZero: " + str(rzero) +"\t Corrected RZero: "+ str(corrected_rzero)+
          "\t Resistance: "+ str(resistance) +"\t PPM: "+str(ppm)+
          "\t Corrected PPM: "+str(corrected_ppm)+"ppm")
    time.sleep(1)
DRIVER:

Code: Select all

"""Micropython library for dealing with MQ135 gas sensor
Based on Arduino Library developed by G.Krocker (Mad Frog Labs)
and the corrections from balk77 and ViliusKraujutis

More info:
    https://hackaday.io/project/3475-sniffing-trinket/log/12363-mq135-arduino-library
    https://github.com/ViliusKraujutis/MQ135
    https://github.com/balk77/MQ135
"""

import math
import time
from machine import ADC

class MQ135(object):
    """ Class for dealing with MQ13 Gas Sensors """
    # The load resistance on the board
    RLOAD = 10.0
    # Calibration resistance at atmospheric CO2 level
    RZERO = 76.63
    # Parameters for calculating ppm of CO2 from sensor resistance
    PARA = 116.6020682
    PARB = 2.769034857

    # Parameters to model temperature and humidity dependence
    CORA = 0.00035
    CORB = 0.02718
    CORC = 1.39538
    CORD = 0.0018
    CORE = -0.003333333
    CORF = -0.001923077
    CORG = 1.130128205

    # Atmospheric CO2 level for calibration purposes
    ATMOCO2 = 397.13


    def __init__(self, pin):
        self.pin = pin

    def get_correction_factor(self, temperature, humidity):
        """Calculates the correction factor for ambient air temperature and relative humidity

        Based on the linearization of the temperature dependency curve
        under and above 20 degrees Celsius, asuming a linear dependency on humidity,
        provided by Balk77 https://github.com/GeorgK/MQ135/pull/6/files
        """

        if temperature < 20:
            return self.CORA * temperature * temperature - self.CORB * temperature + self.CORC - (humidity - 33.) * self.CORD

        return self.CORE * temperature + self.CORF * humidity + self.CORG

    def get_resistance(self):
        """Returns the resistance of the sensor in kOhms // -1 if not value got in pin"""
        adc = ADC(self.pin)
        value = adc.read_u16()
        if value == 0:
            return -1

        return (1023./value - 1.) * self.RLOAD

    def get_corrected_resistance(self, temperature, humidity):
        """Gets the resistance of the sensor corrected for temperature/humidity"""
        return self.get_resistance()/ self.get_correction_factor(temperature, humidity)

    def get_ppm(self):
        """Returns the ppm of CO2 sensed (assuming only CO2 in the air)"""
        return self.PARA * math.pow((self.get_resistance()/ self.RZERO), -self.PARB)

    def get_corrected_ppm(self, temperature, humidity):
        """Returns the ppm of CO2 sensed (assuming only CO2 in the air)
        corrected for temperature/humidity"""
        return self.PARA * math.pow((self.get_corrected_resistance(temperature, humidity)/ self.RZERO), -self.PARB)

    def get_rzero(self):
        """Returns the resistance RZero of the sensor (in kOhms) for calibratioin purposes"""
        return self.get_resistance() * math.pow((self.ATMOCO2/self.PARA), (1./self.PARB))

    def get_corrected_rzero(self, temperature, humidity):
        """Returns the resistance RZero of the sensor (in kOhms) for calibration purposes
        corrected for temperature/humidity"""
        return self.get_corrected_resistance(temperature, humidity) * math.pow((self.ATMOCO2/self.PARA), (1./self.PARB))
    

Re: MQ135 sensor Attribute Error

Posted: Sat Apr 02, 2022 1:12 pm
by tepalia02
Hi, is this library properly installed in your computer? https://github.com/rubfi/MQ135

Re: MQ135 sensor Attribute Error

Posted: Sat Apr 02, 2022 5:24 pm
by soggycashew
Its not on my computer its on Raspbery Pi Pico? and yes its on there correctly. If I use the below code to see if the mq135 is reading values it does.

Re: MQ135 sensor Attribute Error

Posted: Sat Apr 02, 2022 7:29 pm
by soggycashew
I got it worked out..... I'm posting the code that works with a (DHT22 humidity and temp sensor) and the (MQ135 gas sensor).

Also you have to run/print rzero for a bit to get your RZERO and change in in the library like I did below...

# Calibration resistance at atmospheric CO2 level
RZERO = -15.01019 # OLD 76.63

mq135_dth22_example.py EXAMPLE CODE:

Code: Select all

import time
from machine import Pin
from dht22 import DHT22
from mq135 import MQ135


adc3 = MQ135(29)
dht22 = DHT22(machine.Pin(2,machine.Pin.IN,machine.Pin.PULL_UP))

while True:
    
    T, H = dht22.read() # Gets Temp & Hum from dht22.py library

    while True:
        rzero = adc3.get_rzero()
        corrected_rzero = adc3.get_corrected_rzero(T, H)
        resistance = adc3.get_resistance()
        ppm = adc3.get_ppm()
        corrected_ppm = adc3.get_corrected_ppm(T, H)

        print("MQ135 RZero: " + str(rzero) +"\t Corrected RZero: "+ str(corrected_rzero)+
              "\t Resistance: "+ str(resistance) +"\t PPM: "+str(ppm)+
              "\t Corrected PPM: "+str(corrected_ppm)+"ppm")
        time.sleep(0.3)
mq135.py LIBRARY: with changes

Code: Select all

"""Micropython library for dealing with MQ135 gas sensor
Based on Arduino Library developed by G.Krocker (Mad Frog Labs)
and the corrections from balk77 and ViliusKraujutis

More info:
    https://hackaday.io/project/3475-sniffing-trinket/log/12363-mq135-arduino-library
    https://github.com/ViliusKraujutis/MQ135
    https://github.com/balk77/MQ135
"""

import math
import time
from machine import ADC

class MQ135(object):
    """ Class for dealing with MQ13 Gas Sensors """
    # The load resistance on the board
    RLOAD = 10.0
    # Calibration resistance at atmospheric CO2 level
    RZERO = 76.63
    # Parameters for calculating ppm of CO2 from sensor resistance
    PARA = 116.6020682
    PARB = 2.769034857

    # Parameters to model temperature and humidity dependence
    CORA = 0.00035
    CORB = 0.02718
    CORC = 1.39538
    CORD = 0.0018
    CORE = -0.003333333
    CORF = -0.001923077
    CORG = 1.130128205

    # Atmospheric CO2 level for calibration purposes
    ATMOCO2 = 397.13


    def __init__(self, pin):
        self.pin = pin

    def get_correction_factor(self, temperature, humidity):
        """Calculates the correction factor for ambient air temperature and relative humidity

        Based on the linearization of the temperature dependency curve
        under and above 20 degrees Celsius, asuming a linear dependency on humidity,
        provided by Balk77 https://github.com/GeorgK/MQ135/pull/6/files
        """

        if temperature < 20:
            return self.CORA * temperature * temperature - self.CORB * temperature + self.CORC - (humidity - 33.) * self.CORD

        return self.CORE * temperature + self.CORF * humidity + self.CORG

    def get_resistance(self):
        """Returns the resistance of the sensor in kOhms // -1 if not value got in pin"""
        adc = ADC(self.pin)
#@soggy         value = adc.read()
        value = adc.read_u16()
        if value == 0:
            return -1

        return (1023./value - 1.) * self.RLOAD

    def get_corrected_resistance(self, temperature, humidity):
        """Gets the resistance of the sensor corrected for temperature/humidity"""
        return self.get_resistance()/ self.get_correction_factor(temperature, humidity)

    def get_ppm(self):
        """Returns the ppm of CO2 sensed (assuming only CO2 in the air)"""
#@soggy         return self.PARA * math.pow((self.get_resistance()/ self.RZERO), -self.PARB)
        return self.PARA * (self.get_resistance()/ self.RZERO)**-self.PARB

    def get_corrected_ppm(self, temperature, humidity):
        """Returns the ppm of CO2 sensed (assuming only CO2 in the air)
        corrected for temperature/humidity"""
#@soggy         return self.PARA * math.pow((self.get_corrected_resistance(temperature, humidity)/ self.RZERO), -self.PARB)
        return self.PARA * (self.get_corrected_resistance(temperature, humidity)/ self.RZERO)**-self.PARB

    def get_rzero(self):
        """Returns the resistance RZero of the sensor (in kOhms) for calibratioin purposes"""
        return self.get_resistance() * math.pow((self.ATMOCO2/self.PARA), (1./self.PARB))

    def get_corrected_rzero(self, temperature, humidity):
        """Returns the resistance RZero of the sensor (in kOhms) for calibration purposes
        corrected for temperature/humidity"""
        return self.get_corrected_resistance(temperature, humidity) * math.pow((self.ATMOCO2/self.PARA), (1./self.PARB))


def mq135lib_example():
    """MQ135 lib example"""
    # setup
    temperature = 21.0
    humidity = 25.0

    mq135 = MQ135(29) # Ghange to your analog PIN 

    # loop
    while True:
        rzero = mq135.get_rzero()
        corrected_rzero = mq135.get_corrected_rzero(temperature, humidity)
        resistance = mq135.get_resistance()
        ppm = mq135.get_ppm()
        corrected_ppm = mq135.get_corrected_ppm(temperature, humidity)

        print("MQ135 RZero: " + str(rzero) +"\t Corrected RZero: "+ str(corrected_rzero)+
              "\t Resistance: "+ str(resistance) +"\t PPM: "+str(ppm)+
              "\t Corrected PPM: "+str(corrected_ppm)+"ppm")
        time.sleep(0.3)

if __name__ == "__main__":
    mq135lib_example()
Capture.JPG
Capture.JPG (104 KiB) Viewed 6690 times

Re: MQ135 sensor Attribute Error

Posted: Sun Apr 03, 2022 1:22 pm
by tepalia02
Thanks a lot. Now it will help many who are facing this problem.

Re: MQ135 sensor Attribute Error

Posted: Thu Apr 07, 2022 12:28 am
by ash_a
tepalia02 wrote:
Sat Apr 02, 2022 1:12 pm
Hi, is this library properly installed in your computer? https://github.com/rubfi/MQ135
I am a mac user and new to Micropython.
I am using Thonny with ESP32 and trying to figure out how to get sensor readings from an MQ135.
Could anyone help me out on how to install the "mq135" package into my MacBook!

Thanks in advance.

Re: MQ135 sensor Attribute Error

Posted: Thu Apr 07, 2022 2:07 pm
by tepalia02
ash_a wrote:
Thu Apr 07, 2022 12:28 am
tepalia02 wrote:
Sat Apr 02, 2022 1:12 pm
Hi, is this library properly installed in your computer? https://github.com/rubfi/MQ135
I am a mac user and new to Micropython.
I am using Thonny with ESP32 and trying to figure out how to get sensor readings from an MQ135.
Could anyone help me out on how to install the "mq135" package into my MacBook!

Thanks in advance.
I didn't have the opportunity to use Macbook. I think you'll get a better number of responses if you post your problem here: https://github.com/rubfi/MQ135/issues