Configure and read out the Raspberry Pi gas sensor (MQ-X)

Sensors are necessary to detect the components of the air. These are used e.g. in smoke detectors. However, instructions for using these gas sensors at the Raspberry Pi are rare, which is why in this tutorial the general use of such MQ modules at the Raspberry Pi is shown. Thus, e.g. smoke detectors or air quality testers can be built.

How to configure any MQ sensor and read it out with the Pi will be shown on the example of the Raspberry Pi gas sensor MQ2 in this tutorial. All other sensors (MQ3, MQ-135, etc.) can also be adapted with a few additional steps.

 

Accessories

All MQ-X sensors return analogue signals, which we can not easily read at the Raspberry Pi. One possibility would be to use an Arduino, but we can also use an analog-to-digital converter (ADC), which can be read out via the I2C bus. In addition, we also need a logic level converter.

  • Analog-Digital Converter (8 Ports): US / UK
  • 5V to 3.3V Logic Level Converter: US / UK
  • Breadboard: US / UK
  • Jumper wire: US / UK

These components are independent of the selected gas sensor. There are also many different sensors for the Raspberry Pi, which are already available for a few bucks and are suitable for different gases:

  • MQ-2 (Methane, Butane, LPG, smoke): US / UK
  • MQ-3 (Alcohol, Ethanol, smoke): US / UK
  • MQ-4 (Methane, CNG Gas): US / UK
  • MQ-5 (Natural gas, LPG): US / UK
  • MQ-6 (LPG, butane gas): US / UK
  • MQ-7 (Carbon Monoxide): US / UK
  • MQ-8 (Hydrogen Gas): US / UK
  • MQ-9 (Carbon Monoxide, flammable gasses): US / UK
  • MQ-131 (Ozone): US / UK
  • MQ-135 (Benzene, Alcohol, smoke): US / UK
  • MQ-136 (Hydrogen Sulfide gas): US / UK
  • MQ-137 (Ammonia): US / UK
  • MQ-138 (Benzene, Toluene, Alcohol, Acetone, Propane, Formaldehyde gas): US / UK
  • MQ-214 (Methane, Natural gas): US / UK
  • MQ-216 (Natural gas, Coal gas): US / UK
  • MQ-303A (Alcohol, Ethanol, smoke): US / UK
  • MQ-306A (LPG, butane gas): US / UK
  • MQ-307A (Carbon Monoxide): US / UK
  • MQ-309A (Carbon Monoxide, flammable gasses): US / UK
  • MG811 (Carbon Dioxide (CO2)): US / UK
  • AQ-104 (air quality): US / UK
  • AQ-2 (Flamable gasses, smoke): US / UK
  • AQ-3 (Alcohol, Benzine): US / UK
  • AQ-7 (Carbon Monoxide): US / UK

You can find the full list with additional information here.

I recommend to use a sensor with a soldered PCB, because no further cabling and the use of resistors and capacitors is necessary.

Details on the individual Raspberry Pi gas sensors can also be found in the corresponding data sheets. Simply google the name of the sensor including “datasheet”. There is also the voltage at which the sensor operates mentioned.

If someone wants to build an alcohol tester or something similar, you should also be aware that these modules are not absolutely accurate and can not compete with a professional measurement.

 

Connection between MQ-2 and Raspberry Pi

In this example, we use a 5V voltage as output. This is too much for the GPIOs, which is why we use a logic level converter (TTL) that cuts down the voltage. If you use a sensor other than the MQ-2 and it has a different voltage, the setup must of course be adjusted.

After the MCP3008 is correctly connected, we use port 0 and connect it to RX0 of the TTL. On the opposite side is RX1, which is connected to the analog pin (A0) of the MQ2 sensor. Also connect 3.3V from the Raspberry Pi (LV) and 5V (HV) to the TTL. And also 5V to the VCC pin of the gas sensor and GND from the Raspberry Pi comes to GND on the LV and HV side of the TTL, as well as to GND of the MQ2.

Schematically the whole looks as follows:

Raspberry Pi Gas Sensor MQ2 Steckplatine

I use the 5V of the Raspberry Pi’s. However, an external power supply is recommended if other sensors and modules or input devices (keyboard, mouse, touchscreen) are used. For this, the sensor is simply supplied with current from the external source (HV side of the TTL) and the ground connection (Minus / GND) is connected to GND of the Raspberry Pi.

 

Configuration of the Raspberry Pi Gas Sensor – Preparation

The concentration of a gas is given in PPM (parts per million). One difficulty of the MQ-2 is that a single analog value is given with which the gas content in the air has to be calculated for the various supported gases. However, the sensor must be configured for this purpose. Since this manual is also applicable to another Raspberry Pi gas sensor, the procedure is as follows:

First, we have to see the data sheet of the respective module, which contains a diagram:

Raspberry Pi Gas Sensor MQ-2 Datasheet

The specified values are in logarithmic scale.

However, the scaling of the values is not linear but logarithmic to the base 10 (log). so, the first stroke on the X axis is 200, then 300, etc. The first stroke after 1000 is 2000, etc. The distance between is linear. The idea behind this script for calibration and reading is to create a straight line and calculate the amount of gas (in ppm). To do this, we need two points to calculate the slope.

Let us take the example of LPG. We therefore take the point P1 (x = 200, y = ~ 1.62) and P2 (x = 10000, y = ~ 0.26). To calculate the “real” values, we apply the ten logarithm. Using the two-point form, we can calculate the slope, which in our case is -0.47 (link to the calculation). With the slope and the calculated logarithm from the left point (x = 2.3, y = 0.21), we can now determine the straight line.

For the remaining gases the calculation is equivalent and can be carried out in the same way. Anyone who wants to have more reading material can do this here.

 

Calibration of the Raspberry Pi Gas Sensor  – Code

Enough of the theory – we want to use the sensor now. For this purpose you can use the code I have customized, which is located in a GitHub repository. Also included is a class for reading the MCP3008. First we clone the directory:

git clone https://github.com/tutRPi/Raspberry-Pi-Gas-Sensor-MQ

Then we change to the directory and run the existing Python test file.

cd Raspberry-Pi-Gas-Sensor-MQ
sudo python example.py

The calibration is started automatically during initialization. It is important that the sensor is in good / fresh air as smoke / other gases would falsify the calibration. The process takes a few seconds, but the gas content can already be measured thereafter (see video). Some sensors are quite hot, but this should not be a cause for concern.

 

Some users reported that the values become accurate only after some time. I can not verify this, because I do not have a professional measuring device. If someone can confirm or verify, since he has such a device at home, I would be pleased about feedback as a comment 🙂

121 Responses

  1. I have thanks in raspberry programming for Gas sensor MQ 7 can i ask for help sir ?? Especially in entering calculations for CO gas

    Reply
    • If you want to use another sensor, you have to adjust the formula, depending on the sensor’s datasheet (cf. my example).

      Reply
  2. Hello !
    Thank you for your work ! Also I have a question.
    Does the calibration have to be for 48 hours, does the sensor has to be pluged for 48 hours ? And how do you know the value of the load resistance ?

    Reply
    • Hi,
      usually the calibration needs about 10 seconds (enough precision for my applications). The value was given (you can change it, depending on your sensor).

      Reply
      • Thank you for your response 🙂 !
        I am using a MQ-7 sensor, do you happen to know what is the load resistance of it ? Or do you put it manualy in series with the sensor ? (in witch case it could be what you want)

  3. Hi I’m using the same setup as yours and din’t change code also. But in the terminal i’m getting something like
    “Press CTRL+C to abort.
    Calibrating…
    Calibration is done…

    Ro=0.000000 kohm

    Abort by user”
    Please let me know what to do.

    Reply
  4. I keep getting this

    pi@octopi:~/Raspberry-Pi-Gas-Sensor-MQ $ sudo python example.py
    Traceback (most recent call last):
    File “example.py”, line 1, in
    from mq import *
    File “/home/pi/Raspberry-Pi-Gas-Sensor-MQ/mq.py”, line 6, in
    from MCP3008 import MCP3008
    File “/home/pi/Raspberry-Pi-Gas-Sensor-MQ/MCP3008.py”, line 1, in
    from spidev import SpiDev
    ImportError: No module named spidev

    Reply
  5. Hi Can You Help Me Put Condition For Example Smoke Is Greater Than 1? then my buzzer will turn on..Its A Big Help For Me to Finish My Project..Godbless

    Reply
  6. i am not using mcp. i have directly connected the sensor to board without any converter.what kind of changes I have to do in code?

    Reply
  7. i need help i am not using mcp. i have directly connected the sensor to board without any converter.what kind of changes I have to do in code?

    Reply
  8. always show “Abort by user”, i’ll tried wiring like this tutorial and use code same on this. anyone can help?

    Reply
  9. Hi, I am using an ADS1115 analog to digital converter instead of MCP and MQ-2 sensor
    My code is based on https://github.com/adafruit/Adafruit-Raspberry-Pi-Python-Code

    import time, signal, sys
    from Adafruit_ADS1x15 import ADS1x15
    
    ADS1115 = 0x01 # 16-bit ADC
    
    # Select the gain
    # gain = 6144 # +/- 6.144V
    gain = 4096 # +/- 4.096V
    # gain = 2048 # +/- 2.048V
    # gain = 1024 # +/- 1.024V
    # gain = 512 # +/- 0.512V
    # gain = 256 # +/- 0.256V
    
    # Select the sample rate
    # sps = 8 # 8 samples per second
    # sps = 16 # 16 samples per second
    # sps = 32 # 32 samples per second
    # sps = 64 # 64 samples per second
    # sps = 128 # 128 samples per second
    sps = 250 # 250 samples per second
    # sps = 475 # 475 samples per second
    # sps = 860 # 860 samples per second
    
    # Initialise the ADCs using the default mode (use appropriate I2C address)
    adc = ADS1x15(ic=ADS1115)
    #adc2 = ADS1x15(ic=ADS1115, address=0x49)
    #adc3 = ADS1x15(ic=ADS1115, address=0x4a)
    
    # read analog sensor on channel Ax [0-3]
    result = adc.readADCSingleEnded(1, gain, sps) / 1000
    
    # print result
    print "MQ-2: %.6f" % (result)

    my return result is only one value for ex. 0.095875. Can you help me get those 4 values like yourself in the video (Ro, LPG, CO, smoke)?

    Regards

    Reply
  10. i am using mcp3008 with mq2. but i am facing difficulty in wiring as my mcp has only 5 pins. So I am confuse what to do now.

    Reply
    • With only 5 pins I don’t think it could be a mcp3008. Google ‘mcp3008 datasheet’, and you’ll see that they all have the same layout. There’s a 3004 but even that has more pins than 5.

      Reply
  11. Sorry as I’m new, but I’m unsure of how this could work. Any documentation I can find on a logic level coverter says that they canot be used for analog conversions. They are only on/off. You’d have to take the output from the sensor and divide it using 2 resistors.

    Reply
  12. I want to put an active buzzer in the project once the gas quality detected by the sensor get too high. In what part should I put the code for the buzzer?

    Reply
  13. have you a better diagram? mine aborts straight after running it.

    Im not sure if i wired the vcc right, were you two red wires merge into one, I placed my sensor in the board and have the two wires in the same row as the vcc connection of the sensor

    Reply
  14. Hii frds iam anand….iam using mq135 sensor….i read the value from the sensor by raspberry but I want to sent the data to cloud…and I want sent msg to the particular person…so guys help me
    My mail
    Krishnan10497kmb@gmail.com

    Reply
  15. el conversor de nivel logico lo conectan a la salida de dato analogo o digital?

    Reply
  16. Hello Everyone.. Can you help us with our Capstone we are using a MQ-6 instead of MQ-2 is it posible that it had a the same output later? Thanks in advance

    Reply
      • Press CTRL+C to abort.
        Calibrating…

        abort by user

        and im using mq6 sensor
        i got an error from this line of code can you please help me?
        def MQResistanceCalculation(self, raw_adc):
        return float(self.RL_VALUE*(1023.0-raw_adc))/float(raw_adc);

  17. Do you have codes please programming my mq 5 gas sensor to python using raspberry pi? Need much help about it.

    Reply
  18. Hi, I’m using an MQ135 and the only output I am seeing at the moment is:
    Press CTRL+C to abort.

    Abort by user
    Is anyone experiencing something similar?
    Thanks

    Reply
  19. im using mq-2
    output i get

    Press CTRL+C to abort.
    Calibrating…

    Abort by user

    Reply
  20. may i connect 5v or 3.3v of pi with sensor mq2 and
    im using mq-2
    output i get

    Press CTRL+C to abort.
    Calibrating…

    Abort by user

    Reply
  21. I have everything setup like in the tutorial, I’ve enabled exception logging in python:
    Press CTRL+C to abort.
    Calibrating…
    ERROR:root:message
    Traceback (most recent call last):
    File “example.py”, line 7, in
    mq = MQ();
    File “/root/Raspberry-Pi-Gas-Sensor-MQ/mq.py”, line 48, in __init__
    self.Ro = self.MQCalibration(self.MQ_PIN)
    File “/root/Raspberry-Pi-Gas-Sensor-MQ/mq.py”, line 83, in MQCalibration
    val += self.MQResistanceCalculation(self.adc.read(mq_pin))
    File “/root/Raspberry-Pi-Gas-Sensor-MQ/mq.py”, line 69, in MQResistanceCalculation
    return float(self.RL_VALUE*(1023.0-raw_adc)/float(raw_adc));
    ZeroDivisionError: float division by zero

    Any ideas?

    Reply
    • Your ADC gives values of zero back, so probably there is something wront (check connections and read the value per hand)

      Reply
  22. Hi, i was getting error while running this code, so i commented the try and except,and started from while True:

    after executing i got this error

    Press CTRL+C to abort.
    Calibrating…
    Traceback (most recent call last):
    File “example.py”, line 7, in
    mq = MQ();
    File “/home/pi/Desktop/Raspberry-Pi-Gas-Sensor-MQ/mq.py”, line 48, in __init__
    self.Ro = self.MQCalibration(self.MQ_PIN)
    File “/home/pi/Desktop/Raspberry-Pi-Gas-Sensor-MQ/mq.py”, line 83, in MQCalibration
    val += self.MQResistanceCalculation(self.adc.read(mq_pin))
    File “/home/pi/Desktop/Raspberry-Pi-Gas-Sensor-MQ/mq.py”, line 69, in MQResistanceCalculation
    return float(self.RL_VALUE*(1023.0-raw_adc)/float(raw_adc));
    ZeroDivisionError: float division by zero

    Reply
  23. Hey, i ran the code and got

    Press CTRL+C to abort.

    Abort by user

    then i tried to log the exception to figure out why it is not calibrating and than i got this error, pls help

    Press CTRL+C to abort.

    Abort by user
    ERROR:root:message
    Traceback (most recent call last):
    File “/home/pi/Raspberry-Pi-Gas-Sensor-MQ/example.py”, line 8, in
    mq = MQ();
    File “/home/pi/Raspberry-Pi-Gas-Sensor-MQ/mq.py”, line 32, in __init__
    self.adc = MCP3008()
    File “/home/pi/Raspberry-Pi-Gas-Sensor-MQ/MCP3008.py”, line 7, in __init__
    self.open()
    File “/home/pi/Raspberry-Pi-Gas-Sensor-MQ/MCP3008.py”, line 10, in open
    self.spi.open(self.bus, self.device)
    FileNotFoundError: [Errno 2] No such file or directory

    Reply
  24. HI Felix thanks for your help and support. I.m having this errrr can you please help me..
    pi@raspberrypi:~/Desktop/MQ2/Raspberry-Pi-Gas-Sensor-MQ $ sudo python example.pyPress CTRL+C to abort.
    Traceback (most recent call last):
    File “example.py”, line 14, in
    mq = MQ();
    File “/home/pi/Desktop/MQ2/Raspberry-Pi-Gas-Sensor-MQ/mq.py”, line 32, in __init__
    self.adc = MCP3008()
    File “/home/pi/Desktop/MQ2/Raspberry-Pi-Gas-Sensor-MQ/MCP3008.py”, line 7, in __init__
    self.open()
    File “/home/pi/Desktop/MQ2/Raspberry-Pi-Gas-Sensor-MQ/MCP3008.py”, line 10, in open
    self.spi.open(self.bus, self.device)
    IOError: [Errno 2] No such file or directory

    Thanks in advance..

    Reply
    • thanks to both, I had several problems like not enabling the SPI but it still does not work, I’m trying now the other URL, thank you very much.

      Reply
      • New error
        Press CTRL+C to abort.
        Calibrating…
        Traceback (most recent call last):
        File “/home/pi/Desktop/MQ2/Raspberry-Pi-Gas-Sensor-MQ/examplewithdebug.py”, line 14, in
        mq = MQ();
        File “/home/pi/Desktop/MQ2/Raspberry-Pi-Gas-Sensor-MQ/mq.py”, line 48, in __init__
        self.Ro = self.MQCalibration(self.MQ_PIN)
        File “/home/pi/Desktop/MQ2/Raspberry-Pi-Gas-Sensor-MQ/mq.py”, line 83, in MQCalibration
        val += self.MQResistanceCalculation(self.adc.read(mq_pin))
        File “/home/pi/Desktop/MQ2/Raspberry-Pi-Gas-Sensor-MQ/mq.py”, line 69, in MQResistanceCalculation
        return float(self.RL_VALUE*(1023.0-raw_adc)/float(raw_adc));
        ZeroDivisionError: float division by zero

  25. have you installed the Adafruit library? yup these ports are confirmed, i have also updated the github readme on this with videos

    Reply
  26. Press CTRL+C to abort.

    Abort by user

    the result after i run the example.py
    any help?
    im using putty

    Reply
  27. Hello,
    when I run the program it is immediately aborting by user after printing calibrating.
    I have rebuilt the device a few times with different parts to minimize the potential for a broken piece. The errors that keep appearing are blank read adc values, no calibration and spi not available even though SpiDev has been enabled. while trying to run the program in Thonny IDE on the Pi, Errors keep appearing on lines 49,72, and 89. Any help would be greatly appreciated!

    Reply
    • Turns out I had the ADC chip in backwards. The values are now starting to populate but the program will now randomly exit after only displaying values for a second or two.

      Reply
  28. this is my output
    Press CTRL+C to abort.
    Calibrating…

    Abort by user

    how to solve this

    Reply
  29. Thank you Felix for this awesome tutorial, it helped me a lot! I admire your patience to answer all these Googleable questions.

    Reply
  30. i have problems
    debugger
    ‘mq’._init_(), line 32:self.adc=MCP3008()
    ‘MCP3008’._init_(), line 7: self.spi.max_speed_hz=1000000 #1MHz
    please i need help

    Reply
  31. unbound method read() must be called with MCP3008 instance as first argument (got int instance instead)

    this is the error im getting what could be the fix

    Reply
  32. unbound method read() must be called with MCP3008 instance as first argument (got int instance instead)

    this is the problem im having

    Reply
  33. Hi … I tell you that thanks to you my sensor works. My new question is. how could i conect another sensor, could it be done conecting it to other gate on the same to mc3008 gate, how should i modified the code .. some idea or suggestion

    Reply
  34. Why don’t you use the digital output from the mq-2 sensor; but use the analog output + ADC?

    Reply
    • Was just researching this as well, looks like the DO will only alert if gas is detected and wont give you specific values. You can only measure the amount of gas using analog output + converter

      Reply
  35. How can I connect two mq sensors to the same raspberry pi, please can someone help me with the code, thanks

    Reply
  36. May i know how can you get the value of P1 (x = 200, y = ~ 1.62) —–1.62 from the datasheet?

    Reply
  37. I am trying to setup a MQ-4 measuring Methane

    self.CH4Curve = [2.3,0.24,-0.55] … my Winsen MQ-4 sensor spec indicates lg200 is 0.24 and lg10000 is 0.027 …through wolfram I get ( Log10(0.027) – log10(0.24) ) / ( log10(10000) – log10(200) ) = -0.558

    how did you get the 2.3 value ?

    Reply
  38. why we used MCP3008? i saw mq-135 sensor have already digital pin why we cannot direct digital pin.

    Reply
  39. Hello sir,
    I love this project and i want to make this project. You explain everything in this video but could you please provide me schematic diagram of this project?

    Reply

Leave a Comment

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Subscribe to Raspberry Pi Tutorials and don't miss any new Tutorial!