Friday 10 March 2017

Detect CO with a MQ-7 sensor module

How to detect carbon monoxide with a MQ-7 sensor module

How gas sensors work

I found an excellent thesis paper on how Tin Dioxide (SnO2) gas sensors work here. It also goes into the details of it's temperature dependency. (See details further down)


Watch my video on the tests here.

The module from ICStation

You can get this module here. (Use code andyics for 15% off your order)
The intended mode of operation is to apply 5V to the module and either read analog values from AOUT or set the threshold of the comparator to the desired value and read from the DOUT pin if it has tripped.

The terminals

Comparator and trimmer

It seems to me that ICStation treats all MQ-series sensors the same way. But the MQ-7 is different from the rest. According to the data sheet, it gives the best results on the following cycle:

  • Pre-heat sensor for 48h 
  • Heat heater with 5V for 60 seconds
  • Heat at 1.4V for 90 seconds
  • Read the sensor near the end of the 90 seconds
On 5V alone, the module does "sortof" work.

You can see me breathing at the sensor

I am quite sure there is no siginificant quantity of CO in my breath. And I not a smoker. The sensor reacts to a wide range of gases, as well as moisture and ambient temperature,

Tricking the module into datasheet-like conditions

To build this, you need the following components:

The IRLZ34N is a very common N-Channel MosFET what already has a very low (0.046 Ohm) source-drain resistance with 5V at the gate. It can handle currents way beyond our reqirements for the flimsy heater on the module.
The heater can run on DC or AC, so PWM should be ok. I can then set the duty cycle of the PWM so that it is the equivalent of 1.4V. (See code below.)

The 10k resistor is optional

The setup with the "switching" mosfet.
Setup with Mosfet

The Arduino code

The code for the "proper" usage cycle:

 MQ-7 cheater  
 Uses PWM and an N-Channel MosFET to trick an ICSTATION MQ-7 CO detector  
 into measuring CO according to the datasheet of the manufaturer.  
 int sensorPin = A0;  // select the input pin for the CO sensor  
 int sensorValue = 0; // variable to store the value coming from the sensor  
 // Initial setup  
 void setup() {  
  // initialize digital pin LED_BUILTIN as an output  
  // initialize the serial port  
 // the loop function runs over and over again forever  
 void loop() {  
  analogWrite(LED_BUILTIN, 255);  // turn the heater fully on  
  delay(60000);            // heat for 60 second  
 // now reduce the heating power  
  analogWrite(LED_BUILTIN, 72);  // turn the heater to approx 1,4V  
  delay(90000);            // wait for 90 seconds  
 // we need to read the sensor at 5V, but must not let it heat up. So hurry!  
  digitalWrite(LED_BUILTIN, HIGH);  
  delay (50); //don't know how long to wait without heating up too much. Getting an analog read apparently takes 100uSec  
   // read the value from the sensor:  
  sensorValue = analogRead(sensorPin);  

Increased sensitivity

Under the same conditions (candle suffocated under jar), the FET-Pulsed version showed a significantly higher peak.
FET-Pulsed heater

Heater on 5v constantly
While the pulsed version of the detector has a slower detection rate (once every 2.5 minutes), the signal's signal-to-noise ratio is signigicantly better (400:14 vs 220:28), resulting in better sensitivity.

Other options:

Cut the traces on the PCB and rewire, so the heater and the sensor don't run from the same power source. (I.e. run cycle the heating element at 5/1.4, while keeping constant 5V on the sensing element's voltage divider)


  1. If I understood your method, the heating delays would be delay(60000) and delay(90000) instead of 6000 and 9000 isn't it?

  2. Yes you are correct Herve !

    1. Quite right. I have corrected the sketch.

  3. Thank for the tutorial... I was confused with this sensor

  4. This comment has been removed by a blog administrator.

  5. Sir, I want to make a CO sensor to tune an engine. So I think the sensor which I used should be very fast. Could you please tell me whether this sensor is suitable for this purpose. If not let me know a better sensor suit to that.

    1. I don't think that is the right sensor for that purpose. It is too sensitive to other contents of the exhaust fumes.

    2. Could you please suggest me a good sensor for this.

  6. This comment has been removed by a blog administrator.

  7. Your source comment says the sensor has to be read at 5V but you do not switch to 5V before reading.

    1. It is at 5V when the LED-Pin is on HIGH. There is actually never really 1.4V at any given time, but a PWM-Signal with an effective voltage (True RMS) of around 1,4V.

  8. Can you just send the code of normal calibration of mq7 without any leds and lcd

    1. The code above is pretty much the minimum config you need. The LED is irrelevant and you can ignore it. (It is simply the one on the Leonardo board and doesn't affect the circuit.)

  9. can i add lcd and bluetooth module for this so i can see the result on a lcd and to android?
    sir pls hepl me for our capstone

    1. To save GPIOs, you should go for a I2C display. These OLED displays are very well supported by Arduino libraries:
      I have no experience with bluetooth modules. I'd interface it with an ESP8266, if necessary to read the data from a web server.

  10. What exactly is the units of the output? ppm CO?
    I have seen a capacitor added in a similar project. Can you suggest which kind? Is it just added between 5V and MQ-7?

    1. It is an analog output and I thinbk you can't reliably measurethe CO concentration, because it also reacts to other substances. You might use the table in the datasheet to get an approximate PPM value.

  11. This comment has been removed by the author.

  12. Thank you for the tutorial. i was more helpful to me.

  13. Thank you for the code and the explications.

  14. Sir, I was trying to implement this, but I am bit confused by the MOSFET to be used. There are some variations like IRLZ34N-Pbf and IRFZ34N available. Can you please clarify this and if possible, provide the values of Vd, Id and Rd for best results as used by you.

    Also does having a slight difference in the current have any effect on the process?


    1. sir, i bought the IRFZ44N mosfet. Does this works as same as the mosfet that is used in your project?

      Also, Mr.Prabthuva, have you already succeed doing this mini project? Please reply as i am a total beginner in arduino community. You can also contact me on my email,


  15. Are the values ​​on the serial monitor expressed in ppm? Or should we apply an equation to leave them in that unit? Thanks!

    1. You'd need an environment (test chamber?) that can run through several CO concentrations to calibrate the readings. As it is, the values are just voltage readings, not PPM or concentration values.

  16. I am doing reading with an arduino nano and an arduino one, they give me different analog readings, because could it be that nano reads more voltage to me than one?

  17. Hello. Can the mosfet be replaced by a (pnp) transistor? I cannot buy parts in the area here, hence my question.
    Thanks for a reaction.

    1. You can try that, but have to take the additional voltage drop into account. That is not necessarily a problem, as you can compensate for that in software. The 150mA heater current might be a bit high for a small signal transistor.

  18. Hello Andy just wanted to know the values shown in the serial graph, i see X = time, but Y i am not sure off can you advise?

    1. Just raw readings from the ADC. I have no means of calibrating the setup.

  19. Hey Andy ,is it the same for atmega concerning the value for the built in led