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)

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
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  
  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
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)