Arduino CO Monitor Using MQ-7 Sensor

21,386

44

161

Posted

Introduction: Arduino CO Monitor Using MQ-7 Sensor

A few words why this instructable was created: one day my girlfriend's mother phoned us at the middle of the night because she felt really sick - she had dizziness, tachycardia, nausea, high blood pressure, she even fainted for unknown time (probably ~5 minutes, but there is no way to tell), all without any apparent reason. She lives in a small village far away from hospitals (60 km from our place, 30 km to the closest hospital, 10 km without any normal road in between), so we rushed to her and got there soon after the ambulance. She got hospitalized and in the morning she felt almost well, but doctors weren't able to find the cause of it. The next day we had an idea: it could have been CO poisoning, since she has gas water boiler (on the photo), and was sitting close to it for the whole evening when it happened.
We recently bought MQ-7 CO sensor, but never had time to assemble a schematics for it, so this was the perfect time to do so. After an hour of searching internet for any instructions, I realized that I can't find any guide that at the same time follows sensor manufacturer's instructions provided in its datasheet and explains anything at all (one example seemed to have quite good code, but it wasn't clear how to apply it, others were oversimplified and wouldn't work well). So we spent about 12 hours for developing schematics, making and printing 3d case, testing and calibrating the sensor, and the next day went to the suspicious boiler. It turned out that CO levels there were extremely high, and could be fatal if CO exposure time were longer. So I believe anyone who has similar situation (like gas boiler or other combustion happening inside a living space) should get such sensor to prevent something bad from happening.

All that happened two weeks ago, since then I improved schematics and program quite a lot, and now it seems to be reasonably good and relatively simple (not 3-lines-of-code simple, but still). Although I hope that someone with precise CO meter will provide me some feedback on default calibration that I put in the sketch - I suspect it is far from good.
Here is a complete guide with some experimental data.

Step 1: Bill of Materials

You will need:

0. Arduino board. I prefer Chinese clone of Arduino Nano for its outstanding price of $3, but any 8-bit arduino will work here. Sketch uses some advanced timers operation, and was tested only on atmega328 microcontroller - although probably it will work well on others too.

1. MQ-7 CO sensor. Most commonly available with this Flying Fish sensor module, it has to run through a small modification, details in the next step, or you can use a separaten MQ-7sensor.

2. NPN bipolar transistor. Virtually any NPN transistor that can handle 300 mA or more will work here. PNP transistor won't work with a mentioned Flying Fish module (because it has heater pin soldered to sensor's output), but can be used with a discrete MQ-7 sensor.

3. Resistors: 2 x 1k (from 0.5k to 1.2k will work fine), and 1 x 10k (that one is best kept precise - although if you absolutely must use a different value, adjust reference_resistor_kOhm variable in the sketch accordingly).

4. Capacitors: 2 x 10uF or more. Tantalum or ceramic ones are required, electrolytic won't work well due to high ESR (they won't be able to provide enough current to smooth high-current ripple).

5. Green and red LEDs to indicate current CO level (you can also use a single dual-color LED with 3 terminals, as we used in our yellow box prototype).

6. Piezo buzzer to indicate high CO level.

7. Breadboard and wires (you also can solder everything to Nano pins or squeeze into Uno sockets, but it's easy to make a mistake this way).

Step 2: Module Modification or Discrete Sensor Wiring

For module, you must desolder resistor and capacitor, as shown on the photo. You can desolder basically everything if you want - module electronics is totally useless, we use it only as holder for the sensor itself, but these two components will prevent you from getting correct readings,

If you are using discrete sensor, attach heater pins (H1 and H2) to 5V and transistor's collector correspondingly. Attach one sensing side (any of A pins) to 5V, another sensing side (any of B pins) to 10k resistor, just like the analog pin of the module in schematics.

Step 3: Operation Principle

Why we need all these complications at all, why not to attach 5V, ground, and just get readings?
Well, you won't get anything useful this way, unfortunately.
According to MQ-7 datasheet, sensor has to run through high- and low-heating cycles in order to get proper measurements. During low temperature phase, CO is absorbed on the plate, producing meaningful data. During high temperature phase, absorbed CO and other compounds evaporate from the sensor plate, cleaning it for the next measurement.

So in general operation is simple:

1. Apply 5V for 60 seconds, don't use these readings for CO measurement.

2. Apply 1.4V for 90 seconds, use these readings for CO measurement.

3. Go to step 1.

But here's the problem: Arduino can't provide enough power to run this sensor from its pins - sensor's heater requires 150 mA, while Arduino pin can provide no more than 40 mA, so if attached directly, Arduino pin will burn and sensor still won't work. So we must use some kind of current amplifier that takes small input current to control large output current.
Another problem is getting 1.4V. The only way to reliably get this value without introducing a lot of analog components is to use PWM (Pulse Width Modulation) approach with feedback that will control output voltage.

NPN transistor solves both problems: when it is constantly turned on, voltage across the sensor is 5V and it is heating for high-temperature phase. When we apply PWM to its input, current is pulsing, then it is smoothed by the capacitor, and the average voltage is kept constant. If we use high frequency PWM (in the sketch it has frequency of 62.5KHz) and average a lot of analog readings (in the sketch we average over ~1000 readings), then the result is quite reliable.

It is critical to add capacitors according to schematics. Images here illustrate difference in signal with and without C2 capacitor: without it, PWM ripple is clearly visible and it significantly distorts readings.

Step 4: Schematics and Breadboard

Here is the schematics and breadboard assembly.

WARNING! Modification of a standard breakout module is required! Without modification module is useless. Modification is described in the second step.

It is important to use pins D9 and D10 for LEDs, since there we have outputs of hardware Timer1, it will allow to smoothly change their colors.
Pins D5 and D6 are used for buzzer, because D5 and D6 are outputs of hardware Timer0. We will configure them to be inverse one to another, so they will switch between (5V, 0V) and (0V, 5V) states, thus producing sound on buzzer. Warning: this affects Arduino's main timing interrupt, so all time-dependent functions (like millis() ) won't produce correct results in this sketch (more on this later).
Pin D3 has hardware Timer2 output connected to it (as well as D11 - but it's less convenient to put wire on D11 than on D3) - so we are using it to provide PWM for voltage controlling transistor.
Resistor R1 is used to control brightness of LEDs. It can be anywhere from 300 to 3000 Ohm, 1k is rather optimal in brightness/power consumption.
Resistor R2 is used to limit transistor's base current. It shouldn't be lower than 300 Ohms (to not overload Arduino pin), and not higher than 1500 Ohms. 1k there is a safe choice.

Resistor R3 is used in series with sensor's plate in order to create a voltage divider. Voltage on sensor's output is equal to R3 / (R3 + Rs) * 5V, where Rs is current sensor's resistance. Sensor resistance depends on CO concentration, so voltage changes accordingly.
Capacitor C1 is used to smooth input PWM voltage on MQ-7 sensor, the higher is its capacitance the better, but also it has to have low ESR - so ceramic (or tantalum) capacitor is preferred here, electrolytic one won't perform well.

Capacitor C2 is used to smooth sensor's analog output (output voltage depends on input voltage - and we have quite a high current PWM here, that affects all schematics, so we need C2). The simplest solution is to use the same capacitor as C1.
NPN transistor either conducts current all the time to provide high current on sensor's heater, or works in PWM mode thus reducing heating current.

Step 5: Arduino Program

WARNING: SENSOR REQUIRES MANUAL CALIBRATION FOR ANY PRACTICAL USE. WITHOUT CALIBRATION, DEPENDING ON PARAMETERS OF YOUR PARTICULAR SENSOR, THIS SKETCH MIGHT TURN ON ALARM IN CLEAN AIR OR NOT DETECT LETHAL CARBON MONOXIDE CONCENTRATION.

Calibration is described in the following steps. Rough calibration is very simple, precise is quite complex.

On the general level, program is rather simple:

First we calibrate our PWM in order to produce stable 1.4V required by sensor (proper PWM width depends on a lot of parameters like exact resistor values, this particular sensor's resistance, transistor's VA curve etc etc - so the best way is to try various values and use one that fits best).
Then, we continuously run through cycle of 60 seconds heating and 90 seconds measurement.
In implementation it gets somewhat complicated. We have to use hardware timers because everything that we have here needs high-frequency stable PWM in order to function properly.

The code is attached here and can be downloaded from our github, as well as schematics source in Fritzing.

In the program there are 3 functions that handle timers: setTimer0PWM, setTimer1PWM, setTimer2PWM.
Each of them sets timer in PWM mode with given parameters (commented in the code), and sets pulse width according to input values.
Measurement phases are switched using functions startMeasurementPhase and startHeatingPhase, they handle everything inside. and set proper timer values for switching between 5V and 1.4V heating.
LEDs state is set by function setLEDs which accepts green and red brightness on its input (in linear 1-100 scale) and converts it into corresponding timer setting.

Buzzer state is controlled using functions buzz_on, buzz_off, buzz_beep. On/off functions turn sound on and off, beep function produces specific beeping sequence with period of 1.5 seconds if it is periodically called (this function returns immediately so it doesn't pause the main program - but you have to call it again and again to produce beeping pattern).

Program first runs function pwm_adjust that finds out proper PWM cycle width in order to achieve 1.4V during measurement phase. Then it beeps a few times to indicate that sensor is ready, switches into measurement phase, and starts the main loop.

In the main loop, program checks if we spent enough time in current phase (90 seconds for measurement phase, 60 seconds for heating phase) and if yes, then changes current phase. Also it constantly updates sensor readings using exponential smoothing: new_value = 0.999*old_value + 0.001*new_reading. With such parameters and measuring cycle, it averages signal over approximately last 300 milliseconds.

WARNING: SENSOR REQUIRES MANUAL CALIBRATION FOR ANY PRACTICAL USE. WITHOUT CALIBRATION, DEPENDING ON PARAMETERS OF YOUR PARTICULAR SENSOR, THIS SKETCH MIGHT TURN ON ALARM IN CLEAN AIR OR NOT DETECT LETHAL CARBON MONOXIDE CONCENTRATION.

Step 6: First Run: What to Expect

If you assembled everything properly, after running sketch you will see something like this in Serial monitor:

adjusting PWM w=0, V=4.93

...

adjusting PWM w=17, V=3.57
PWM result: width 17, voltage 3.57

and then a series of numbers representing current sensor readings.
This part is adjusting PWM width in order to produce sensor's heater voltage as close to 1.4V as possible, measured voltage is deducted from 5V, so our ideal measured value is 3.6V. If this process never ends or ends after a single step (resulting in width equal to 0 or 254) - then something is wrong. Check if your transistor is really NPN and is properly connected (make sure you used base, collector, emitter pins right - base goes to D3, collector to MQ-7 and emitter to ground, don't count on Fritzing breadboard view - it is wrong for some transistors) and make sure that you connected sensor's input to Arduino's A1 input.

If everything is fine, you should see in Serial Plotter from Arduino IDE something similar to the image. Heating and measurement cycles of 60 and 90 seconds length are running one after another, with CO ppm measured and updated at the end of each cycle. You can take some open flame close to the sensor when measurement cycle is almost finished and see how it will affect readings (depending on flame type, it can produce up to 2000 ppm CO concentration in open air - so even though only a small portion of it actually goes into sensor, it still will turn on the alarm, and it won't go off until the end of the next cycle). I showed it on the image, as well as the response to fire from the lighter.

Step 7: Sensor Calibration

According to manufacturer's datasheet, sensor should be running heating-cooling cycles for 48 hours in a row before it can be calibrated. And you should do it if you intend to use it for a long time: in my case, sensor reading in clean air changed for about 30% over 10 hours. If you won't take this into account, you can get 0 ppm result where there is actually 100 ppm of CO. If you don't want to wait for 48 hours, you can monitor sensor output at the end of measurement cycle. When over an hour it won't change for more than 1-2 points - you can stop heating there.

Rough calibration:

After running sketch for at least 10 hours in clean air, take raw sensor value in the end of the measurement cycle, 2-3 seconds before heating phase starts, and write it into sensor_reading_clean_air variable (line 100). That's it. Program will estimate other sensor parameters, they won't be precise, but should be enough to distinguish between 10 and 100 ppm concentration.

Precise calibration:

I highly recommend to find a calibrated CO meter, make 100 ppm CO sample (this can be done by taking some flue gas into syringe - CO concentration there can easily be in the range of several thousands ppm - and slowly putting it into closed jar with calibrated meter and MQ-7 sensor), take raw sensor reading at this concentration and put it into sensor_reading_100_ppm_CO variable. Without this step, your ppm measurement can be wrong several times in either direction (still ok if you need alarm for dangerous CO concentration at home, where normally there should be no CO at all, but not good for any industrial application).

As I didn't have any CO meter, I used a more sophisticated approach. First I prepared high concentration of CO using combustion in isolated volume (first photo). In this paper I found the most useful data, including CO yield for different flame types - it isn't in the photo, but the final experiment used propane gas combustion, with the same setup, resulting in ~5000 ppm CO concentration. Then it was diluted 1:50 in order to achieve 100 ppm, as illustrated in the second photo, and used to determine sensor's reference point.

Step 8: Some Experimental Data

In my case, sensor worked quite well - it is not very sensitive for really low concentrations, but good enough for detecting anything higher than 50ppm. I tried to increase concentration gradually, taking measurements, and built a set of charts. There are two sets of 0ppm lines - pure green before CO exposure and yellow green after. Sensor seems to slightly change its clean air resistance after exposure, but this effect is small. It doesn't seem to be able to clearly distinguish between 8 and 15, 15 and 26, 26 and 45 ppm concentrations - but the trend is very clear, so it can tell whether concentration is in 0-20 or 40-60 ppm range. For higher concentrations dependence is much more distinctive - when exposed to exhaust of an open flame, curve goes up from the start without going down at all, and its dynamics is totally different. So for high concentrations there is no doubt that it works reliably, although I can't confirm its precision since I don't have any rated CO meter.
Also, this set of experiments was done using 20k load resistor - and after that I decided to recommend 10k as the default value, it should be more sensitive this way.

That's it. If you have a reliable CO meter and will have assembled this board, please share some feedback about sensor precision - it would be great to collect statistics over various sensors and improve default sketch assumptions.

5 People Made This Project!

Recommendations

  • Microcontroller Contest

    Microcontroller Contest
  • Science of Cooking

    Science of Cooking
  • Pocket-Sized Contest

    Pocket-Sized Contest
user

We have a be nice policy.
Please be positive and constructive.

4 Tips

Hi, I tried to compensate the effect of humidity and temperature by measuring them with a DHT22. In principle I was successful, but then I did a trial with CO (a candle in a closed box). For my surprise the DHT22 is not only sensitive for humidity, but for CO, too. As the reaction time of the DHT22 is different from the MQ-7 I can not calculate the real CO value out of the data.

But there is a solution, which seems to work well:

The best results (op to now) I get by comparing the sensor value at the beginning of the 90s sense period with the value at the end of this period. Only if I start at high humidity and perform a very fast temperature decrease I get false CO results; most probably I am reaching the dew point locally in the sensor. Therefore you are totally right, using only the value at the end of the sensing period is the wrong way. Maybe the maximum gradient is even better. I will collect some data...

Interesting! Intuitively I would expect that DHT22 is sensitive only to very high CO concentrations (500+ ppm) - can you confirm whether it's true? Overall, by analyzing dynamics it could be possible to estimate concentration quite well even if humidity and temperature are unknown - I saw indications of it in my experiments, but never really studied it well. If you can record a set of data in different conditions, I would be happy to analyze them and we can publish the result :)

Hi,

thanks for this very detailed and very good instruction.

Some remarks:

- You do not need to modify the sensor. The trick is: as you switch on/off the sensor ground (PWM), you have to switch the sensor (and therefore the heater) 100% on to read the value. This means, you can not read the value during the 90s "sensing" time. But this doesn't matter; the only valid reading is at the end of the 90s sensing period. And this is directly remark two:

- Only read the sensor at the end of the 90s sensing period, do not calculate a moving mean along these 90s. The Sensor is collecting CO during these 90s and the only valid value is at the end of these 90s. Just put the heater on an within the next ms read the sensor value (or sample some values to reduce noise, but as the heater is 100% on, there is nearly no noise)

- With this modification you do not need C2 any longer.

- If you start using the sensor after some time of not using it, the sensor produces higher readings in the first loops. Therefore you need several loops to get stable readings. This time can be reduced significantly by extending the firs 60s heating period. I read the sensor value at the end of the fist 60s and wait for another 10s and read the value again. I repeat 10s periods as long as the values are decreasing. This is much faster than the 60+90s loops.

- The sensor value is depending on humidity and temperature, too. The resistor value changes approx 0.5% for every 1% change in rel. humidity and 1% for every 1°C of temperature change. Depending on the operation purpose you have to compensate these effects. I just collecting data for this purpose. Older trials with a DHT11 failed due to missing accuracy of this sensor; now I am using a DHT22 which performs much better. As I want to use the sensor as CO Warner in a small aircraft I am also checking, if the absolute air pressure has a effect. If yes, a bme280 seem to be ideal (it can measure temperature, humidity and air pressure).


Last remark: I have different sensors with different resistors soldered on (the one you replaced by R3). Therefore different sensors can produce very different raw values.

Best regards, and again thank you for this good project,
MakerMaik

Hi! Excellent point about modification, really we can just turn on 100% to get value, haven't thought of that! Will use it for sure.

But can't agree with reading at 90s only - in this case we lose signal dynamics, which tells a lot about actual concentration. It's possible to detect high CO level much earlier than in 90 seconds, and it's possible to estimate low level more precise looking at the whole curve. I wasn't using it in this instructable, but these data are generally useful. It's not complicated to adjust program so PWM cycle is stopped each second for 5...10 ms to get sample at that moment.
- great idea about 60+10+10... cycles, really can make it fully independent this way. Will use it too, thanks :)
- yeah, I even made a 2nd version with DHT11 and its own PCB, but still haven't run full experiment with it, but I will one day ))
- as for raw values, that's for sure, I just hope that relative change of resistance is more or less consistent across different sensors (so with proper initial value adjusted in the code, result will be fine). But I haven't checked, if it's not true, then I see no way to get accurate readings without full calibration of each particular one

13 Questions

This may be a stupid question, but the serial value should increase as CO concentrations increase right? For some reason mine seems to be working in reverse, I.e. in clean air I get a reading of around 300, then when I introduce CO the reading drops to around 220(I'm assuming ppm?). Any idea what could be the cause here, or is this normal operation?
In any case, great work! This is the first implementation I've seen that actually follows the specifications and operation guidelines from the data sheet rather than just incredibly over simplifying

0

hi. what do you mean "Need to check atmega2560 datasheet to see whether timer code will work, and which pins will be affected."?

Why are all the other components on the CO sensor able to be ignored? What's their original purpose?

0

They wanted to make a digital output that switches at given CO concentration but failed to do so, because haven't followed sensor datasheet

Ah makes sense. Thank you!

0

Hi,

thanks for this very detailed and very good instruction.

Warning: I am high on nooby scale & experiencing the steep learning curve.

I have flying fish with shield & A.Uno.

I desoldered the R and cap, connected the way you indicated, &downloaded the ino-file.

When uploaded & connected no alarming things...

---- one question: looks like the D0 connection from the flying fish is not connected & free floating? Or has it to be connected with a1 port, collector and capacitor? The reading I got is that the heating cyclus works OK. but nothing more.

The capacitors are some 90uF instead of 10. The disc ones have no polarity?

Best regards, Wiemer

0

Hi! DO connection is left unused, that's right.
90uF are fine, as for polarity - caps that have polarity have some markings on their case, if you are not sure you can try to google by how it looks.
You should see raw data output in serial monitor. Also, after you'll run your sensor for ~10 hours, you'll need to write this raw value in .ino sketch to calibrate the sensor (each sensor is a bit different, so program doesn't know what is "zero" before you fill it - this code works for my particular sensor).

Would this be pretty accurate without calibrating it against an actual meter?

1

I have no idea, for my particular sensors it seems +-10 ppm precise for low concentrations (haven't tested much past 100 ppm), but I tested only with 2 units bought at the same time - who knows, maybe for different ones from different production lines it will be much worse

Can i use a 0.1uF capacitor instead of the 10uF ones??

70 Comments

For those interested in the data my sensor has been collecting in an urban suburban area, you can find it here :

https://www.datascapeindustrial.com/live

Instructions and comments on the MQ7 sensor have been valuable. Thanks

Solar Air Quality Dash.PNG

My MQ7 has been running for a while now. It has gathered some interesting data over the days, even indicating peak traffic hours and leisure fires in the area. The live and historic data can be found here:

https://www.datascapeindustrial.com/live

I'm not using an Arduino but found the info on the MQ7 sensor very useful especially the suggestions. Instead, using a Ion LoRa module...

Solar Air Quality Dash.PNG

Hi, as the tips are not sorted chronologically, I just copy our conversation as a comment to keep them sorted and readable:

Hi,

thanks for this very detailed and very good instruction.

Some remarks:

-
You do not need to modify the sensor. The trick is: as you switch
on/off the sensor ground (PWM), you have to switch the sensor (and
therefore the heater) 100% on to read the value. This means, you can not
read the value during the 90s "sensing" time. But this doesn't matter;
the only valid reading is at the end of the 90s sensing period. And this
is directly remark two:

- Only read the sensor at the end of the
90s sensing period, do not calculate a moving mean along these 90s. The
Sensor is collecting CO during these 90s and the only valid value is at
the end of these 90s. Just put the heater on an within the next ms read
the sensor value (or sample some values to reduce noise, but as the
heater is 100% on, there is nearly no noise)

- With this modification you do not need C2 any longer.

-
If you start using the sensor after some time of not using it, the
sensor produces higher readings in the first loops. Therefore you need
several loops to get stable readings. This time can be reduced
significantly by extending the firs 60s heating period. I read the
sensor value at the end of the fist 60s and wait for another 10s and
read the value again. I repeat 10s periods as long as the values are
decreasing. This is much faster than the 60+90s loops.

- The
sensor value is depending on humidity and temperature, too. The resistor
value changes approx 0.5% for every 1% change in rel. humidity and 1%
for every 1°C of temperature change. Depending on the operation purpose
you have to compensate these effects. I just collecting data for this
purpose. Older trials with a DHT11 failed due to missing accuracy of
this sensor; now I am using a DHT22 which performs much better. As I
want to use the sensor as CO Warner in a small aircraft I am also
checking, if the absolute air pressure has a effect. If yes, a bme280
seem to be ideal (it can measure temperature, humidity and air
pressure).


Last remark: I have different sensors with
different resistors soldered on (the one you replaced by R3). Therefore
different sensors can produce very different raw values.

Best regards, and again thank you for this good project,
MakerMaik

Tip by the_3d6 5 days ago

Hi! Excellent point about modification, really
we can just turn on 100% to get value, haven't thought of that! Will use
it for sure.

But can't agree with reading at 90s only - in this
case we lose signal dynamics, which tells a lot about actual
concentration. It's possible to detect high CO level much earlier than
in 90 seconds, and it's possible to estimate low level more precise
looking at the whole curve. I wasn't using it in this instructable, but
these data are generally useful. It's not complicated to adjust program
so PWM cycle is stopped each second for 5...10 ms to get sample at that
moment.
- great idea about 60+10+10... cycles, really can make it fully independent this way. Will use it too, thanks :)

- yeah, I even made a 2nd version with DHT11 and its own PCB, but still
haven't run full experiment with it, but I will one day ))
- as for
raw values, that's for sure, I just hope that relative change of
resistance is more or less consistent across different sensors (so with
proper initial value adjusted in the code, result will be fine). But I
haven't checked, if it's not true, then I see no way to get accurate
readings without full calibration of each particular one

Hello! Thank you very much for this comprehensive tutorial. No other tut on the web handles this subject with such depth.

One minor question I'm struggling with: If I want to make this project without the module modification what change do I need to introduce to the code in order to turn the heater 100% ON just before the measurement?

Right now I'm doing this:

if(phase == 0 && sec10 - low_on > 900) //90 seconds of measurement ended?

{

setTimer2PWM(0, 255);

delay(50);

last_CO_ppm_measurement = raw_value_to_CO_ppm(sens_val);

startHeatingPhase();

But as a total novice to arduino and electronics I don't know if this is right.

by MakerMaik 23 hours ago


Hi, I tried to compensate the effect of
humidity and temperature by measuring them with a DHT22. In principle I
was successful, but then I did a trial with CO (a candle in a closed
box). For my surprise the DHT22 is not only sensitive for humidity, but
for CO, too. As the reaction time of the DHT22 is different from the
MQ-7 I can not calculate the real CO value out of the data.

But there is a solution, which seems to work well:

The
best results (op to now) I get by comparing the sensor value at the
beginning of the 90s sense period with the value at the end of this
period. Only if I start at high humidity and perform a very fast
temperature decrease I get false CO results; most probably I am reaching
the dew point locally in the sensor. Therefore you are totally right,
using only the value at the end of the sensing period is the wrong way.
Maybe the maximum gradient is even better. I will collect some data...

by the_3d6 24 minutes ago

Interesting! Intuitively I would expect that
DHT22 is sensitive only to very high CO concentrations (500+ ppm) - can
you confirm whether it's true? Overall, by analyzing dynamics it could
be possible to estimate concentration quite well even if humidity and
temperature are unknown - I saw indications of it in my experiments, but
never really studied it well. If you can record a set of data in
different conditions, I would be happy to analyze them and we can
publish the result :)

Hi,

Enclosed an actual measurement. X-Axis is in s. All readings belong to the right y-axis, only actCoRaw (the raw sensor value) belongs to the left y-axis. The csv file is attached, too. There is also a bmp180 in my actual measurement system, therefore I have two different temperature sensors working.

In this trial I extended the heating phases even in later loops if the raw value is still decreasing; a bad idea in a atmosphere with decreasing CO or humidity...

My CO source is a candle in a closed environment. Therefore I do not know, if the DHT22 reacts on CO or on other fumes. But it reacts heavily. The DHT22 is very different from the DHT11. The DHT11 is much less sensitive to humidity in low humidity conditions.

In the plot I put the sensor at my balcony as well indoor below a vase together with a burning candle (which went out quickly in most cases).

At ~700s I put it outdoor and 1300s I ignited the candle. Due to not perfectly closed vase it burned up to 2500s. At 3560s I removed the vase. Due to sun the ambient temperature was increased meanwhile.

At 4200s I closed the vase again and I ignited the candle, which went out fast. At 5400s I removed the vase.

At 6700s I put it indoor and at 9000s I ignited the candle and put the vase on (the candle went out). At 10100s I removed the vase.

The best CO interpretation I get from comparing the raw value at the end of the heating compared to the end of the sensing period.

As soon as I find time I will do some high humidity trials as this is the most critical situation to get false CO warnings, especially it the temperature drops down quickly (sonsor gets below dew point).

Best regards,
MakerMaik

co.png

Hi,

I recorded some more data with CO created by candle and match. The DHT22 reacts much more on the candle than on the match. Therefore it does not react only on CO. Bat again, the delta of the measurement at the end of the heating period and the measurement at the end of the sensing period seem to be the best CO measurement. Maybe for the absolute value temperature and/or humidity have an effect, but as a warning system this delta should be sufficient. Therefore for a warning system just an arduino, one transistor, one resistor and one capacitor are needed (plus a led/resistor or a beeper).

One open point is a measurement in high humidity with temperature shock to reach the dew point.

Attached you can find some 600s readings in normal and high humidity with candle or match (in a closed vase, therefore the flame went out quickly). I marked the heating periods red and the sensing periods blue. I added green or red boxes in the sensing period to highlight the delta of the sensor signal.

coReadings.png

Great experiment, thanks! It's very interesting that absolute values of sensor readings are affected by humidity really a lot, but shape of the curve remains very similar. Can you send the data too? Plain difference between beginning and end of 90s period works, but I believe much better result can be obtained by analyzing first 30-40 seconds, I still think neural network could be the best solution here (although that requires confirmation).
If you have time/inspiration to make more quantitative CO samples (like I did, using syringe and putting in 5, 10, 20, 40 cc of high-CO sample into a known sensor's air volume), for several humidity levels - then I can promise that I will make NN-based part and share its code really soon :) I wanted to make such set of measurements myself for quite a while already, but just can't find enough time and will for it