SparkFun Forums 

Where electronics enthusiasts find answers.

Have questions about a SparkFun product or board? This is the place to be.
By GTBecker
I've spent some time working with the MQ-7 CO sensor ( ... ts_id=9403 ) in a hydrogen application. This sensor requires a varying heater voltage (the documentation ... c/MQ-7.pdf suggests alternating between 5v for 60 seconds and 1.4v for 90 seconds). Apparently the heater needs to drive off adsorbed moisture and gases but the active element is desensitized while it is hot. The specs suggest sampling at the end of each of the two alternating periods (and, perhaps, using two different load values for each period - if I interpret the poor Engrish correctly) and it suggests using several 2.5-minute-total sample periods, presumably averaging the samples. That makes the sensor sampling slow. Further, when the heater voltage switches, the sensor produces immediate spikes as the element temperature changes quickly.

I've found another method to use the sensor by driving the heater with a slow sine. I chose a 285-second period (based on reaching 90% of the steady-state heater temperature) of a 2-volt-to-5-volt PWM'd sine drive. The sensor seems to saturate more easily at lower heater temperatures, so a 3-volt low end - or a smaller load resistance - might reduce that behavior.

The MQ-7 is sold as a CO sensor, but is actually more sensitive to hydrogen than it is to carbon monoxide, according to the documentation. Here is the response using the suggested 5v/1.4v rectangular heater drive. I made two small hydrogen releases of unknown concentration: ... ogen_2.GIF

Here is a ~200ppm hydrogen release (25cc into a 30-gallon container) using sine drive: ... 0kLoad.GIF

The obvious advantage of the sine method is that the sensor output is continuously available using a predictive filter to watch the resulting sine signal, not just single samples at 2.5-minute intervals.

Anyone else working with these sensors?

By MontyD
I've been messing around with this sensor for a little while, but I too am finding the noise a problem. I'm trying to drive the 1.4v reading phase via PWM on an Arduino pin then through a transistor hooked up to 5v and that seems to impart a huge amount of wobble, although the 5v heating phase gives a pretty stable output.


Readings are taken at approx. 1s intervals, and each reading is the average of 20 individual readings taken 1/20s apart. There seems to be a regular cycle of around 25s which is still there even when I average readings taken over several hours.

So far the only way I've found to get rid of this cycling is to turn off the heater completely during the low phase instead of dropping it to 1.4v (i.e. I cycle 60s at 5v then 90s at 0v) which gives me a far more stable result:


(In both the above charts blue shows the 60 second heating phase and pink the 90 second reading phase. The scale on the left represents the raw analogue readings from the Arduino).
By GTBecker
Where did you learn the "1.4v reading phase"? That's the way the document seems to suggest using it, but I thought both sampling at the end of the hot period and at the end of the cooler period. How to interpret the documentation was my largest challenge.

Experimentally, it seems that the hot phase is intended to vaporize absorbed gasses, and the following cooler period is most sensitive, so your reading phase makes sense. The document, though, seems to suggest that data points should be taken at the end of each phase.

"c. Adjust the load resistance RL until you get a signal value which is respond to a certain carbon monoxide concentration at the end of 90 seconds. [Cool]

"d. Adjust [the] another load resistance RL until you get a signal value which is respond to a CO concentration at the end of 60 seconds." [Hot]

That says, to me, two samples per cycle - each independently calibrated by using different switched loads to achieve the same output in a constant gas concentration - or perhaps a different calibration factor for each phase with a single load.

Is that what you read?
By MontyD
You're right the document is "difficult" to read, but I shouldn't have called the low power phase on the heating circuit the "reading phase." I started calling it that in my head the first couple of times I read through the datasheet and it sort of stuck, even though I've been aiming to get two stable points for reading as a starting point. Anyway, here are a couple of further points I've learned:

1. Solder all connections well. I had the sensor held in one of the Sparkfun breakout boards, and as it was a tight fit I had assumed that all the connections were good. But soldering everything down has got rid of all the noise I had.

2. Although I think that you're right in the way you're reading the datasheet, the reading at the end of the cool period is slightly more stable. I tried running everything for a while on double the intervals, i.e. 120s at 5v then 180s at 1.4v. Readings in the cool period had flatlined by the end of 60 seconds, while readings in the hot period were still drifting marginally.


3. Right now I'm tempted to proceed using just the cool period readings. I don't think that this sensor will ever be suitable for continuous measurement, but there may be potential for trimming back both the cool and hot periods, the hot especially, to the period in which they are actually changing the resistance rather than just flatlining.

4. You can probably drop the load resistor below 5k if necessary. The graph below shows (from left to right successively) 10K, 8K2, 5K6, 3K9 and 15K, just plotting the raw data from an Arduino analogue pin. The 10K resistor seems to me to be a bit too close to the maximum value of 1023. Actually the 3K9 looks a bit high too, but I'm wary of going much lower and burning out the sensor.

By GTBecker
I've gone as low as 1k load and settled on 10k. The sensor saturates not far above that and has insufficient sensitivity below that for my intended application.

Are you only exposing the sensor to air so far?
By Kira
GTBecker wrote:I've gone as low as 1k load and settled on 10k. The sensor saturates not far above that and has insufficient sensitivity below that for my intended application.

Are you only exposing the sensor to air so far?
hi am working on a project for school with the sensor MQ-7 and do not know what voltage value for each ppm to get into the ADC, and being able to express in an LCD screen, I would be grateful if you could help with this .
By GTBecker
I think I can probably help a little.

The sensor heater needs to be driven with sufficient current to warm it so that absorbed gasses and moisture are driven off, then it must be allowed to cool. During the cooling period you can measure the sensor resistance to determine the gas concentration to which it is exposed. The document suggests driving the heater with 5v for 60 seconds, then 1.4v for 90 seconds. It was unclear when the manufacturer suggests taking a sample, but it can probably be inferred to be at the end of the 1.4v cooling period. You'll be able to take a sample only once per 150 seconds, if that is correct. I eventually chose to drive the heater with a slow 3vpp sine wave that I generated with PWM.

The effective sensor resistance can be measured by wiring the sensor element in series with a fixed resistor, putting a known voltage across the two - using them as a voltage divider - and reading the voltage at their junction with an ADC input. With the sine heater drive, I chose to use a 10k resistor which yielded (0.65*5.0v)= 3.25v at 200ppm of Hydrogen (I used the part to sense battery gassing, not CO concentration). Zero H2 concentration was apparently indicated by (0.43*5.0v)= 2.15v so, if the relationship is reasonably linear, using 5v and a 10k series resistance and driven with a sine wave on the heater as I did ... 0kLoad.GIF, the output is apparently (3.25v-2.15v)/200ppm= 0.0055v/ppm. The part is a little less sensitive to CO according to the documentation. You will probably find it easier to drive the heater with the suggested 5v/1.4v squarewave as a starting point, but the sensitivity at the end of the cool period should be similar if you also use 5v and 10k.

You should probably establish your own testing method to determine the actual sensitivity for the gas of your choice. Perhaps you can locate and borrow a calibrated CO sensor, or generate a known concentration of CO chemically. For my H2 testing, I electrolyzed water and collected the liberated gas, filled a 25ml syringe and released that into a closed 30-gallon trash container with a small fan inside to mix it well. 25ml in 30 gallons is ~200ppm.

Tom VHF Lightning, spherics
By Virginia
Hi! I have looking to this thread for a long time, as I am still trying to use the MQ-7 properly. I cannot generate a proper sin function, so I decided to go with the 5-0V. I tried to do as you said making double the periods of time, so 120 sec of 5V and 180 sec of 0V, because if not I was getting values always increasing. Then, before the 0V period is finished, the last 20 sec I take samples and then average them. But I am having a problem here, my readings go from 0-4095, in fcat during the 5V period I get readings that go increasing, stablish at aprox. 1500 and then go decreasing until the 0V period begin. The problem is that during that 0V period, and so, the reading period, I get readings of aprox 400, which, taking into account that I have an RL=10K, give a Rs of aprox 90K, which I am guessing is too much for normal air. Plus, I have no idea how to interpret the datasheet to move this to ppm, as I was reading and 50ppm is already dangerous, and the datasheet says 100ppm in clean air. I post my code here, hope someone can help me, thanks!:
Code: Select all
if (cont_GasV==120){           //PUT GAS INPUT TO 1.4V DURING 180sec
      P4OUT&=~BIT6;             //SETTING OUT AS 1 MAKES TRANSISTOR GIVE 0V         
    //  P7OUT&=~0x08;
      else if (cont_GasV>=280&&cont_GasV<=299){
      ADC12IE = 0x01;                           // Enable ADC12IFG.3
      Gas_val=SavedADC12MEM0+Gas_val;        // Store the sampled data
     else if (cont_GasV==300){    //PUT GAS INPUT TO 5.0V DURING 120sec
        P4OUT|=BIT6;                  //SETTING OUT AS 0 MAKES TRANSISTOR GIVE +5V
         Gas_val=(5.0*Gas_val)/4095.0;    //COMPUTE VRL
        Gas_val=10.0*((5.0-Gas_val)/Gas_val);               //COMPUTE RS
       char gas[20];
      sprintf(gas,"GAS: %.4f ",Gas_val);
Last edited by Virginia on Fri Apr 15, 2011 4:28 am, edited 1 time in total.
By esklar81

First, welcome to our virtual family!

Disclaimer: I haven't used this particular sensor. However, I've been pushing electrons around for sport for more than 40 years and (in my professional work) have a fair amount of experience with gas detectors.

I read the sensor manufacturer's Technical Data and I agree that it's a bit difficult to interpret. That said, here are a few suggestions:
  1. Check the resistance of the heating element. It's nominally 33 Ω. At 5 V, that should allow a current of:
    I = V/R = 5 V/33 Ω = ~150 mA
    The power at 5 V should be:
    P = V*I = 5 V * 150 mA = 750 mW (Note, this is substantially higher than the 350 mW the vendor states, but the resistance probable changes as the heater heats and the stated power may be averaged over the heating and cooling periods.)
  2. Monitor (with a voltmeter) the voltage across the heater for a few cycles to ensure that your heater power circuit is behaving as you intend.
  3. Try using 1.4 V, rather than 0 V, as the low side of your heater power.
  4. Repeat the 48 hour heating period the manufacturer specifies for initializing the unit.
  5. Monitor the voltage across the sensor during a few heat/cool cycles to ensure that your controller and its software are reporting correct values.
  6. Obtain an ~100 ppm source of a gas the sensor will detect and see what response you get.

The manufacturer is profoundly vague about the actual value of the resistance. The only response curve (in units of (resistance at concentration)/(resistance at 100 ppm)) provided shows a change in Rs of a factor of ~5 for each order of magnitude in CO concentration. Combining the reported value of "2-20 k in 100 ppm CO" with an extrapolation of the calibration curve suggests an Rs of 50 to 500 kΩ at 1 ppm (a reasonable value for indoor air in the absence of combustion), so your 90 kΩ does seem reasonable.

FWIW, I believe the "100 ppm CO in the clean air" means that the calibration gas was 100 ppm of CO in air without any other gases the sensor can detect.

Lastly, if you use the "Code" formatting (available above the field in which you enter text), it will preserve indentation and make your code much easier to read.

Happy Hunting,
By Virginia
wowo, thanks a lot. That was a relly clarifying and useful answer. Thanks a lot! :D
(I willt ake the code thing into account, sorry, befoer I did not know how to do it)
By Virginia
Well, I have done all the needed changes, so now I put 5V during 60 sec and 1.4V during 90sec, and I take average sample during the last 10 sec of 1.4V. My question now is, in the following formulas:
Gas_val=(Vc*Gas_val)/4095.0; //COMPUTE VRL
Gas_val=10.0*((Vc-Gas_val)/Gas_val); //COMPUTE RS

I get Gas_val=12, that is Rs=12K now, so I am not getting anymore between 50-500k, I am getting like if I had 100ppm, but I'm in my room!
the things is, when I make the readings, at the beginning of the 90sec phase, I get low ADC values, which correspond to to high RS, but by the end of the 90sec phase (when u are supposed to measure), these values increaase, there is like a drop in voltage at the beginning, and then it goes increasing until the 90sec end
By esklar81

For me to be of any more help, it appears I need some more information, inlcuding:
  1. the various data I suggested, in my previous reply, you collect, such as the voltage across the heater during a couple of cycles,
  2. time series (that is, not averaged) resistance data for a few cycles, including both the heating and measurement phases. (Recording the resistance every 10 seconds during heating is probably enough.), and
  3. a complete wiring diagram, including the power source(s)

If you post those things, I'll see if I can provide further hints.

By hozone
i'm playing with this sensor too.

what i do is
heat for 60 seconds at 5.0v, put the sensor at 1.4v for 90 seconds. when i'm in the reading status, i read values from seconds 60 to 90, every seconds (30 value), then avarage those values to get a consistent one.

i use a circuit like this
alternating ouput to PD6 and PD7, to get heat and read status.

my question is:
1) i'm i operating right?
2) to get ppm value from adc raw value, i use this formula
//get the resistence of the sensor, based on the balace resitor used in the circuit (RL = 2700ohm in my example)
res = 1024*RL/adcreadvalue-RL
//compute ppm, derived from datasheet forumla Rs\RL = (Vc-VRL) / VRL and datasheet draw (fig3 Rs/Ro realted to ppm)
ppm = res/RO
//the guess here is to find a right RO, which i suppose it means calibrate the sensor
By Mee_n_Mac
Looks correct so far as I can tell. There was another thread here about this sensor and your use of diodes to get the 1.4V heater voltage is the same as one circuit referenced in that thread. I question whether you'll get the needed voltage drop through those diodes at what I'd expect for heater current but if you've measured it and it's good ...
long long title how many chars? lets see 123 ok more? yes 60

We have created lots of YouTube videos just so you can achieve [...]

Another post test yes yes yes or no, maybe ni? :-/

The best flat phpBB theme around. Period. Fine craftmanship and [...]

Do you need a super MOD? Well here it is. chew on this

All you need is right here. Content tag, SEO, listing, Pizza and spaghetti [...]

Lasagna on me this time ok? I got plenty of cash

this should be fantastic. but what about links,images, bbcodes etc etc? [...]