CO and LPG gas sensor with Arduino and LCD

 Posted by:   Posted on:   Updated on:  2023-01-23T20:39:51Z

Build a CO, LPG and CH4 gas detector with the MQ-9 sensor, an Arduino compatible board and a LCD, all on a custom made PCB

In a previous post I looked at a MQ-9 sensor module. Unfortunately, although the sensor can detect CO and LPG, it cannot be used as it is wired in the module. After analyzing the datasheet I figured the best thing to do is remove it from existing PCB and build my own. In short, like other sensors from MQ family, MQ-9 has a heater resistor inside. In order to get any useful reading from it, this resistor must be heated at 5 V for 60 seconds, then cooled at 1.4 V for 90 seconds. The same is true for MQ-7. The issue with modules is that all sensors from MQ family are fitted on the same PCB design.

In this post, I'll share two other methods of powering the heater resistor and I will design a PCB. Sensor readings will be displayed on an alphanumeric LCD powered by Arduino. Since real ppm is temperature and humidity dependent, I will provide a PCB header for DHT sensor. I already tested the sensor with the LM317 power supply I built in the previous post, and I did some measurements.

CO and LPG gas sensor with Arduino and LCD

Heater power supply

Keep it simple

Heater is a resistor made of nichrome wire. It has about 33 ohms according to datasheet (mine has 31 ohms when cold). I did some recordings of heater current during 5 V and 1.4 V cycles and I found it to be quite stable. Therefore, the easiest way to get it powered at 1.4 V is to add a series resistor. A current of 42 mA will flow through this resistor and it must drop 3.6 V (dissipated power is about 150 mW). And, finally, the resistance value is 82 ohms (well, 85 in theory, but with standard 82 you still get heater voltage within datasheet specs).

Series resistor power supply for MQ-7 and MQ-9
Series resistor power supply for MQ-7 and MQ-9

To get 5 V to the heater, we can short the series resistor with a transistor. You can use a general purpose NPN (which is what I used, because this is what I had) or an N-channel MOSFET. Which is better? Well, it depends on the voltage drop across it, specifically CE voltage for NPN transistor, or DS voltage for FET transistor.

According to datasheet, (S)S8050 has VCE(sat) < 0.5 V, while, for example, 2N7000 has RDS(on) = 1.7 ohms (yet it can be as high as 5.3 ohms and still be within specs). This means, in the best case, there will be a voltage drop of 245 mV. Therefore, if you decide to use FET transistor, get one with low RDS(on). The switching transistors from SMPS have the lowest RDS(on), however some of them require more than 5 V at gate.

VCE at saturation of SS8050 (adapted from datasheet)
VCE at saturation of SS8050 (adapted from datasheet)

Further reading of SS8050 datasheet shows that VCE is proportional to collector current. Therefore, at a maximum of 150 mA, voltage drop is about 67 mV. Way less than 2N7000, which makes S8050 the choice for this project. The transistor must be fully saturated to achieve this, with at least 15 mA base current. Assuming 1 V drop on BE junction, we get a theoretical base resistor of maximum 266 ohms, which will drop the remaining 4 V at 15 mA.

Unfortunately, both NPN and MOSFET transistors can easily drop the heater voltage out of datasheet requirements. However, by choosing parts with care, heater will be powered with voltage within specs.

Switching supply

Even though it is more complicated, a switching power supply may be used as well. To keep the schematic as simple as possible, I designed one controlled by Arduino.

Switching power supply for MQ-7 and MQ-9
Switching power supply for MQ-7 and MQ-9

Component values are not critical, however is worth mentioning the control method. The MOSFET transistor from the left is doing the switching and must be fed with PWM. To get 1.4 V to heater, there must be a PWM signal applied to the base of it, while the right one is off. Why is there a second transistor? Well, when 5 V are required, the switching transistor (PWM) can be continuously on. But there will be a voltage drop across the inductor. The second transistor (SW) shorts the inductor, therefore to get 5 V, left transistor (PWM) should be off while the right one (SW) is on. All precautions regarding VCE drop are the same as above.

Output of the switching power supply
Output of the switching power supply

An oscilloscope recording proves the converter is working. Note, that if taking ground as reference, output of the buck converter is 3.6 V. The heater gets the voltage difference. Above, the PWM factor still needs a bit of tweaking according to the oscilloscope. The recorded pulse has been produced with the following code:

void setup() {
  TCCR2B = TCCR2B & B11111000 | B00000001; // set PWM frequency 31372.55 Hz on D3
  pinMode(3, OUTPUT); // PWM
  pinMode(2, OUTPUT); // SW


void loop() {
  // 5 V output
  digitalWrite(3, LOW); // PWM = off
  digitalWrite(2, HIGH); // SW = on


  // 1.4 V output
  digitalWrite(2, LOW); // SW = off 
  analogWrite(3, 72); // PWM switching enabled


I had to increase PWM frequency, because by default it is too low.

Complete schematic and PCB

When it comes to integrating all these ideas into a reliable design, I chose the simple approach (most of the time, this work best). I designed a circuit which uses the series resistor to drop heater voltage to 1.4 V. I included an Arduino Pro Mini (or compatible board) and an alphanumeric 16x2 LCD. Note there is also a temperature and humidity sensor, useful to adjust gas sensor readings according to environment. To avoid overloading ATmega digital pins, I added transistor driver for buzzer.

Schematic of MQ-7/9 gas sensor with Arduino and LCD
Schematic of MQ-7/9 gas sensor with Arduino and LCD

The transistor which drives the heater resistor should be D type (with high gain). This shouldn't be hard to find, I got mine from a transistor kit, and all included S8050 are actually S8050D with measured hFE of 260 at low collector current. R3 value is expected to be 470 ohms for high gain transistor. If you get more than 150 mV between collector and emitter of Q2 when it is on, R3 can be replaced by lower value, yet not less than 220 ohms. R1 is the pull-up of DHT sensor and its value is according to the datasheets I found (however a module I own with this sensor uses 10k resistor). 

The resulting PCB is 73 by 82 mm, double sided. Some parts are placed beneath LCD and Arduino board, therefore it is expected to fit those two on 2.54 mm pin sockets and corresponding headers. The load resistor is 10 kilo-ohms. Note there is a big 2 W resistor on the PCB. That is heater series resistor and it does not have to be that big (0.5 W is just fine, however I didn't have any smaller than what I used). With 82 ohms, the heater gets about 1.44 V, which is within datasheet specs. Voltage drop across transistor is a bit higher than what the datasheet says (I measured about 93 mV), but the heater is still powered with voltages within datasheet requirements.

R6 is not really needed and R10 can be omitted if button pin is configured as INPUT_PULLUP. MPS2222A is a direct replacement for buzzer driver transistor (Q1). In fact, any other general purpose NPN will do, just make sure to place it correctly, since pin order may differ. Q2 needs to be a NPN transistor with a relative high gain and low VCEsat. Because I used the D variant of S8050 (with highest gain), I can drive its base with a lower current (note the 470 ohms R3 vs. 266 ohms I previously calculated).


Do NOT take the measurements of this sensor as good and accurate. If in doubt, always buy a professionally manufactured gas alarm device, which is accurate and calibrated.


KiCad schematic and PCB design, with Gerber files, ready to send to manufacturing:


Release 1.0 (2023.01.15)

  • Initial release: (includes source and binary).
  • Designed for MQ-9 (it also reads sensor resistance with high heater voltage, for LPG and CH4).
  • No alarm function, just displays estimated ppm.
  • No temperature and humidity compensation, just displays them.
  • Keep the button pushed for about 3 seconds to store sensor resistance in clean air in EEPROM. It allows you to do that after a single heater power cycle (although it should be done at least 48 h after power-up). This is used as a reference to estimate ppm.

No comments :

Post a Comment

Please read the comments policy before publishing your comment.