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)
Video
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
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:- Leonardo (or clone thereof), an UNO works just as well
- ICStation's MQ-7 module
- 10k resistor (optional)
- IRLZ34N N-Channel Mosfet
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
pinMode(LED_BUILTIN, OUTPUT);
// initialize the serial port
Serial.begin(9600);
}
// 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);
Serial.println(sensorValue);
}
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 |
If I understood your method, the heating delays would be delay(60000) and delay(90000) instead of 6000 and 9000 isn't it?
ReplyDeleteYes you are correct Herve !
ReplyDeleteQuite right. I have corrected the sketch.
DeleteThank for the tutorial... I was confused with this sensor
ReplyDeleteThis comment has been removed by a blog administrator.
ReplyDeleteSir, 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.
ReplyDeleteI don't think that is the right sensor for that purpose. It is too sensitive to other contents of the exhaust fumes.
DeleteCould you please suggest me a good sensor for this.
DeleteThis comment has been removed by a blog administrator.
ReplyDeleteYour source comment says the sensor has to be read at 5V but you do not switch to 5V before reading.
ReplyDeleteIt 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.
DeleteCan you just send the code of normal calibration of mq7 without any leds and lcd
ReplyDeleteThe 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.)
Deletecan i add lcd and bluetooth module for this so i can see the result on a lcd and to android?
ReplyDeletesir pls hepl me for our capstone
To save GPIOs, you should go for a I2C display. These OLED displays are very well supported by Arduino libraries: http://www.banggood.com/0_96-Inch-4Pin-IIC-I2C-Blue-OLED-Display-Module-For-Arduino-p-969147.html?p=NT1005763073201409DA
DeleteI have no experience with bluetooth modules. I'd interface it with an ESP8266, if necessary to read the data from a web server.
What exactly is the units of the output? ppm CO?
ReplyDeleteI have seen a capacitor added in a similar project. Can you suggest which kind? Is it just added between 5V and MQ-7?
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 https://www.sparkfun.com/datasheets/Sensors/Biometric/MQ-7.pdf to get an approximate PPM value.
DeleteThis comment has been removed by the author.
ReplyDeleteThank you for the tutorial. i was more helpful to me.
ReplyDeleteThank you for the code and the explications.
ReplyDeleteSir, 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.
ReplyDeleteAlso does having a slight difference in the current have any effect on the process?
Thanks!
sir, i bought the IRFZ44N mosfet. Does this works as same as the mosfet that is used in your project?
DeleteAlso, 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, ridhuanismail01@gmail.com
ReplyDeleteAre the values on the serial monitor expressed in ppm? Or should we apply an equation to leave them in that unit? Thanks!
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.
DeleteI 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?
ReplyDeleteHello. Can the mosfet be replaced by a (pnp) transistor? I cannot buy parts in the area here, hence my question.
ReplyDeleteThanks for a reaction.
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.
DeleteHello 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?
ReplyDeleteJust raw readings from the ADC. I have no means of calibrating the setup.
DeleteHey Andy ,is it the same for atmega concerning the value for the built in led
ReplyDeleteHey, Andy in your circuit diagram your sensor breakout has h1,a1 connections but actually sensor pinout is a0,d0,vcc,gnd.
ReplyDeleteCan you please explain this as I am unable to understand the connections from circuit setup photo
The problem with this module is, that is feels like the pcb was not designed for that specific sensor. The method I describe works around the problem. If you have the sensor and design your circuit, better stick to the recommendations in the data sheet.
Delete