Saturday, March 29, 2014

CO (Carbon Monoxide) Gas Sensor Using the Arduino Uno

This simple project uses the Arduino Uno and the MQ7 Gas Sensor to sense the concentration of CO (Carbon Monoxide) in the air. The MQ7 requires a heater voltage that cycles between 5v (60s) and 1.4v (90s), drawing approximately 150mA at 5v which exceeds the power capacity of the Uno, so I use the KA278RA05C adjustable voltage regulator to drive this. The default voltage of the KA278RA05C with Vadj (pin 4) disconnected is 5v which serves for the heater high voltage part of the cycle. I use a 50k potentiometer to adjust the voltage down to 1.4v for the heater high voltage part of the cycle. I use an LH1546 optical solid state relay to switch the adjustable voltage of the potentiometer on for the 1.4v heater low voltage. Pin 8 on the Arduino Uno drives the optical solid state relay and when high turns the relay on, adjusting the voltage of the regulator down to 1.4v. When this pin is low it turns off the relay causing the regulator to go back up to 5v. Analog pin 0 on the Arduino Uno is used to sense the voltage level out of the MQ7 which serves to measure the concentration of CO (Carbon Monoxide) in the air. Below is the diagram of the circuit on Fritzing.

Below is the actual circuit:

Below is the Arduino Uno sketch used:

#define VOLTAGE_REGULATOR_DIGITAL_OUT_PIN 8
#define MQ7_ANALOG_IN_PIN 0

#define MQ7_HEATER_5_V_TIME_MILLIS 60000
#define MQ7_HEATER_1_4_V_TIME_MILLIS 90000

#define GAS_LEVEL_READING_PERIOD_MILLIS 1000

unsigned long startMillis;
unsigned long switchTimeMillis;
boolean heaterInHighPhase;

void setup(){
  Serial.begin(19200);
  
  pinMode(VOLTAGE_REGULATOR_DIGITAL_OUT_PIN, OUTPUT);
  
  startMillis = millis();
  
  turnHeaterHigh();
  
  Serial.println("Elapsed Time (s), Gas Level");
}

void loop(){
  if(heaterInHighPhase){
    // 5v phase of cycle. see if need to switch low yet
    if(millis() > switchTimeMillis) {
      turnHeaterLow();
    }
  }
  else {
    // 1.4v phase of cycle. see if need to switch high yet
    if(millis() > switchTimeMillis) {
      turnHeaterHigh();
    }
  }
  
  readGasLevel();
  delay(GAS_LEVEL_READING_PERIOD_MILLIS);
}

void turnHeaterHigh(){
  // 5v phase
  digitalWrite(VOLTAGE_REGULATOR_DIGITAL_OUT_PIN, LOW);
  heaterInHighPhase = true;
  switchTimeMillis = millis() + MQ7_HEATER_5_V_TIME_MILLIS;
}

void turnHeaterLow(){
  // 1.4v phase
  digitalWrite(VOLTAGE_REGULATOR_DIGITAL_OUT_PIN, HIGH);
  heaterInHighPhase = false;
  switchTimeMillis = millis() + MQ7_HEATER_1_4_V_TIME_MILLIS;
}

void readGasLevel(){
  unsigned int gasLevel = analogRead(MQ7_ANALOG_IN_PIN);
  unsigned int time = (millis() - startMillis) / 1000;
  
  Serial.print(time);
  Serial.print(",");
  Serial.println(gasLevel);
}



The screenshot below shows the CSV data points of time in seconds against the MQ7 output voltage graphed into Excel.

The point at which to read the MQ7 level is at the end of the high 5v heating phase just before transitioning to the low 1.4v heating voltage. I found mine stabilized in an indoor home environment around 211 after the second heating cycle, corresponding to an analog voltage out of the MQ7 of (211/2013) * 5v = 1.03v. To calibrate I'll need a CO gas meter. Next item on the purchase list :-) Enjoy. Feel free to post below if you build some additional cool stuff on this.

34 comments:

  1. Hello,

    I'm working on the MQ7 CO sensor for one of my project. While doing some research I came across your project and thought you could help me answersing few of my questions.

    Unlike the one you have used, the MQ7 that I bought has 4 pins, Pls see the link below:
    http://www.amazon.com/Sensitivity-Carbon-Monoxide-Detector-Arduino/dp/B00JF69TLQ/ref=sr_1_15?ie=UTF8&qid=1398400991&sr=8-15&keywords=mq7+co+sensor

    My questions: (I'm using Arduino MEGA ADK)
    1. Which pin is giving constant 5v to the heater in the MQ7?
    2. Which pin is giving the 1.4v low heating voltage to the heater while the sensor is sensing (outputting) the CO values.?
    3. What is the role of the Potentiometer here.? Does this lower the voltage from 5v to 1.4v? If Yes, doesn't the circuit need 5v to operate.?

    ReplyDelete
  2. Hi Shivanand, I am not familiar with the product you referenced. I recommend direct questions specifically on that to the seller. I also recommend you carefully review the datasheet for the MQ7 linked in my blog above, and ensure the product you referenced uses it in the configuration you need. I don't from the product listing how this board changes heater voltage to 1.4v during low part of heater cycle, and it specifies working voltage of 3-5V so I'd be cautious about using this product. I did see that the product you referenced uses the LM393 which you can read about at http://www.ti.com.cn/cn/lit/ds/symlink/lm393-n.pdf . It is a comparator, and so the potentiometer on this board could be comparing the signal voltage output Aout of the sensor to a threshold set by the potentiometer and giving a digital high or low voltage output on the Dout pin. See the second image on the product you reference for the pinout. Have fun.

    ReplyDelete
  3. Hi David, thank you very much for getting back on this.
    I will get in touch with the seller regarding the product working.

    ReplyDelete
  4. Hello, I hope you're fine. I'm actually doing this project too, but even though you've already explained the circuit, I still have little doubts about it, and I was hoping you could answer them. I'm using the same MQ7 sensor and I've read it has mirror configuration but still I don't know which pin is wired to 5V and where the others should be connected in. Another doubt i have is if the 12V DC is really requiered, I mean, can I connect a 5V source instead of a 12V source?

    ReplyDelete
    Replies
    1. Hi, regarding the wiring of the MQ7 have a look at Fig 1 top of page 2 at https://www.sparkfun.com/datasheets/Sensors/Biometric/MQ-7.pdf The A pins can be wired to a constant 5V and don't require a lot of current so you can connect to your Arduino 5V output. The heater high pin (between the A pins) needs to have 5V for 60s and 1.4V for 90s and needs 150mA at 5V so needs to go to your voltage regulator. On the other side of the MQ7 are your B pins and heater ground. One of the B pins goes 10k resistor to ground. The other is your signal output which you can connect to your Arduino analog input. The regulator output needs to be a max of 5V for the 60s MQ7 heater high phase. To supply 5V output the regulator needs 7V or higher up to a max of 35V http://www.fairchildsemi.com/ds/KA/KA278RA05C.pdf. Unfortunately if the heater is connected directly to the Arduino it will not be able to deliver the required 5V / 150mA output. I used an old AC to 12V DC (2A) power supply from an old electronic appliance to deliver my 12V input. Have fun.

      Delete
  5. Hi again, thanks for replying my message. The wiring of the MQ7 is ready but I'm still having troubles with the circuit, I couldn't get anywhere the Adjustable Voltage Regulator nor the LH1546 you used, instead i bought KIA278R050PI and LH1520AB with their respective datasheets (http://www.dz863.com/downloadpdf-vdkijunaju-KIA278R050PI.pdf) and (http://www.vishay.com/docs/83818/lh1520ab.pdf). I finally got the the 12V DC source but still it's not working. I'd be very thankful if you can help me once again.

    ReplyDelete
  6. I'm not familiar with the regulator or solid state relay you reference, but check the datasheets carefully to ensure they can take the input voltage you supply and give the output voltages (5 and 1.4V), and deliver the 150mA current. You will also have to see how to adjust the voltage on the regulator per the datasheet. The solid state relay you reference looks similar to the one I used, only that its a dual so you will only need one side for this circuit. Again, you will have to look carefully at the datasheet for the SSR you are using to determine the wiring. On state resistance looks fine. I recommend first create your regulator circuit and verify it is giving 5V required voltage outputs, then only connect your gas sensor because if you accidentally send a higher than 5V through the gas sensor you will fry it.

    ReplyDelete
  7. Hello,

    I'm attempting to construct a similar circuit and I'm somewhat confused about the heating aspect of the MQ7 monitor. I know it has to be heated cyclically between 5V and 1.4V, but I don't really understand the part about the UNO not supplying enough power. I understand that the sensor requires 5V at 140 mA, but how is the voltage regulator used to drive this?

    ReplyDelete
    Replies
    1. Hi Panda, have a look at the current limits at http://arduino.cc/en/Main/arduinoBoardUno [DC Current per I/O Pin 40 mA]. This means that the Uno can't deliver the 150mA directly. The regulator has a much higher max current limit and can deliver the required 150mA. The regulator needs to be powered by a capable power source. For my project I used an old 12v DC power supply from an old appliance. Whatever power supply you use to power your regulator make sure it can supply enough current, ie its max current rating is higher than 150mA. Hope that helps. Have fun!

      Delete
    2. Thanks a bunch, David. I asked because I noticed my voltage regulator was outputting 600 mA. I was wondering if I had to input exactly 150 mA, but it sounds like as long as it is supplying more than 140 mA then it should work.

      Delete
    3. If your power supply you are using on the input to the regulator has a max current output of 600mA this should suffice. However, if you have measured the current out of the regulator and through the MQ7 heater at 600mA there could be a problem. Did you take a voltage reading across the heater of the MQ7? Note that the MQ7 according to its datasheet at https://www.sparkfun.com/datasheets/Sensors/Biometric/MQ-7.pdf should have a heater resistance of about 33ohms. If your regulator is doing 5v across this the equation I = V/R tells us that the current should be about 152mA. If the voltage you put across the heater is significantly higher than 5V, even momentarily, .... as could be the case if you are seeing a much higher current through the heater ie 600mA instead of 150mA expected, then it could fry the sensor. It is good to test the output of your regulator across a resistor first to ensure the right voltage behavior before you connect the MQ7. If you do find the voltage output of the regulator is too high then check its wiring and you may also have to adjust the potentiometer for the 1.4v part of the heating cycle.

      Delete
    4. Thanks David. Sorry for the late response I've been busy with other projects. I'm still having trouble getting the right voltages to come out at node 34.I've made all the right connections (the only difference is that I'm using a coil relay powered by a 9V battery). When off, I get 5V at node 34, but when switched on I get the relay's supply voltage (~9V). The potentiometer doesn't seem to be doing anything. I'm not sure what I'm doing wrong.

      Delete
    5. Hi Panda, can you provide more details on your circuit? Are you using a coil relay instead of the solid state relay that I used to connect the potentiometer to the voltage adjust input on the regulator? Are you using the KA278RA05C regulator? Note that you have to adjust the potentiometer to get the desired output voltage when the potentiometer is connected by the relay.

      Delete
    6. Yes I'm using the Omron G2R coil relay and wiring each of the throws to either the pot or the KA278RA05C. The potentiometer doesn't seem to be adjusting the voltage and I've verified it's not burnt out. When off, the voltage at the output is the same as the battery. Perhaps I am just wiring the pot incorrectly...

      Delete
    7. Check you have a good connection with the relay when it is closed. Also double check you didn't accidentally get the KA278R05C ... if you have the KA278RA05C with "RA" in the name then you should be fine. I have seen the symptom you describe where the output of the regulator goes to the input voltage of the regulator when I had an KA278R05C instead of an KA278RA05C. Otherwise double check the pot high is wired to the output of the regulator, the pot low should be to ground, and the middle (adjustable) pot output should go to the input of your relay (with the other side of your relay going to the Vadj (pin 4) of the regulator ... check the datasheet. Hope that helps. Good luck. Have fun.

      Delete
    8. Thank you David for the tips and advice. My pot starts burning every time I wire it up and doesn't seem to be capable of regulating the voltage down to 1.4, but I'll find another way to get the heater circuit. This circuit looks like a lot of fun though I wish I could have implemented it correctly.

      Delete
    9. What is the resistance of your pot? I used 50k but anything over about 1k should be ok. If your resistance is higher than this and your pot is still getting hot then you may want to double check its connections. If for example you wired the middle / adjustable terminal of the pot to the output of your regulator and adjusted the pot low then you would effectively be shorting your regulator to ground through the pot which would result in the pot over heating.

      Delete
    10. It is a 20k PTV09A potentiometer. I wired terminal 1 to ground, 2 to the relay, and 3 to the output of the regulator. The voltage I'm reading at the output of the regulator isn't changing regardless of how much I'm adjusting the potentiometer. I am thoroughly at a loss of understanding now haha.

      Delete
    11. 20k pot should be fine. Try decoupling the terminal from the regulator and connect instead to voltmeter and verify as you adjust pot the voltage changes from 0v to the positive high voltage connected to the other terminal of the pot. If this works and the pot is not over heating then your pot is wired correctly. If not then either different wiring is needed or the pot may be faulty.

      Delete
    12. I believe my pots may be faulty and that I may have burned them out through too much trial and error.One of them stays cool while the other continues to keep overheating with the same wiring. I'll order some more and try it again. In the mean time, how could I drive this heater with a transistor? I've been trying to learn about them and understand the concepts but I'm failing to make it work. Sorry if this is taking up your time.

      Delete
    13. Makes sense. Regarding transistor idea, see question below from tiffy and my response.

      Delete
    14. This comment has been removed by the author.

      Delete
  8. Why not use a transistor to power the heater? That would be a much easier method of adjusting voltage and using a outside power source.

    ReplyDelete
    Replies
    1. You could go down this path. You would need to sample the output voltage and ensure it was as required, either 5v or 1.4v, and adjust your transistor to achieve this. This would depend on the input voltage and resistance of the heater which can vary within tolerance. I suspect if you used this approach you would eventually end up implementing a simple version of a voltage regulator. Since voltage regulators are cheap and also can help isolate noise. Hard to beat them for regulating voltage, which is what we are doing in this circuit.

      Delete
  9. Or just use a resistor in series to bring 12v down to 5v, and then have a additional potentiometer to bring voltage down to 1.4

    ReplyDelete
    Replies
    1. Similar response to above. Resistors may also need to dissipate a lot of heat / power since they would drop the input voltage at full current. Again, hard to beat a voltage regulator for regulating voltage. If you were concerned about maximum efficiency, eg if you were battery powered, you may want to look at a DC to DC buck converter which will regulate voltage and do so even more efficiently than linear voltage regulators we use in this circuit.

      Delete
  10. OK I see.
    So how did you go about turning this voltage into a ppm, i have some ideas but i was wondering what you did. Also did you do anything to adjust for changes in temp/ humility.

    ReplyDelete
    Replies
    1. For calibration you will likely need a calibration meter that you can use to give you the actual accurate concentration of CO which you can then use to determine how your project is measuring this level. The datasheet at https://www.sparkfun.com/datasheets/Sensors/Biometric/MQ-7.pdf, near the end, does say one should compensate for temperature and humidity. The datasheet doesn't give a formula for this though. I recommend contacting them at the contact information given at the end of the datasheet. Let us know how it goes. Have fun.

      Delete
  11. Hi David,

    thanks very much for this useful post - I've taken your code and modified it slightly. Instead of using a voltage regulator, I power the heater of the MQ7 via a TIP122 transistor, fed a PWM signal from the Arduino to give 5V and 1.4V heating cycles. I'm not using an MQ7 on its own, I've got one on a Gas Sensor v1.3 module, which I think has the load resistor wired in (no datasheet available though, so I'm just guessing!). When I plot the response from the MQ7 module, I get this:

    https://drive.google.com/file/d/0B_fYK-ebo_xoQmdBcEFLcHpZT2s/edit?usp=sharing

    Any ideas what's going on? The general form is the same as your response, but I seem to be getting spurious saturation of the sensor output :(

    Thanks again for your guide :)

    ReplyDelete
    Replies
    1. Hi Clu, glad you found the post useful. Thanks for sharing. A couple of questions below that may help us diagnose potential issues with your sensor output.

      Did you check with the MQ7 manufacturer if the heater can be powered with a PWM signal? If not I'd recommend checking. The datasheet I have shows a constant 5v / 1.4v signals during respective heating cycle phases.

      How are you powering the "A" pins of the MQ7? I used constant 5v from Arduino as these are low current (unlike heater high voltage pin). These should not be driven with a PWM signal.

      Delete
  12. hi David,
    plz tell me abt preheating of co sensor which i bought from ebay recently http://www.ebay.com/itm/MQ-7-CO-Gas-Sensor-natural-gas-sensor-Module-MQ7-Analog-TTL-output-for-Arduino-/110950893359 we dnt hav enough time plz do rply....

    ReplyDelete
    Replies
    1. Hi Mohamed, you can read about preheating requirements on the data sheet for the MQ7 at https://www.sparkfun.com/datasheets/Sensors/Biometric/MQ-7.pdf . Basically it needs at least 48 hours of preheat time to ensure that the readings you get once deployed are consistent for a given concentration of gas, temperature and humidity. Once you have the circuit described in this blog done you can just run the heating high low cycle through the heater for 48 hours to complete the preheat time. Let us know how it goes.

      Delete
  13. Hi David,

    I was wondering what is the orientation of pins of the MQ sensor since the 6 pins at the bottom are not labelled, I have no idea which pin corresponds to which on the datasheet. Thanks

    ReplyDelete
  14. Hi Tom, good question. The MQ7 has two clusters of 3 pins. One cluster is A-H-A and the other B-H-B (see datasheet linked above). The middle ones are always the heater pins. On one cluster the two other pins are A's and on the other cluster the two other pins are B's. It is flexible which ones are the A's and which ones are the B's, and which way current flows through the heater, so pick one of the 3 pin clusters and call this your A-H-A cluster, and the other your B-H-B cluster and wire them up accordingly. Hope that helps.

    ReplyDelete