Air Quality Sensor
-
a little update on the MICS-6814:
NO2: sensible
CO: flat
NH3 flat

For the HCHO:

sorry for the flat part, some arduino issues at this time
-
I have had some questions about converting from mg/m3 to ppm gases, here are the weight values and a proposed method:
NH3 17.03 g/mol
CO2 44.01
CO 28.01
H2S 34.08
NO2 46.01
NO 30.01
O3 48.00
C6H6 78.11
C7H8 92.14you have:
NO2 50 μg/m3 gives 26,5868821 ppm
O3 27 μg/m3 = 0.027 mg/m3 -> (8,31441298,15)/(48101,325)*27=13,7617025 ppmcorrect me if I'm wrong
-
2016 is where IoT for gas sensors are moving to more maturity, Cooking Hacks / Libellium proposed so far Fibaro sensors, but are now proposing more pricey one that are calibrated.
-
CO2 with MH-Z14

NO2 MICS-6814

HCHO sensor

-
In MQ135 sensor's datasheet , which line on the curve is used to find out the concentration of benzene?
@bhavika said:
In MQ135 sensor's datasheet , which line on the curve is used to find out the concentration of benzene?
MQ135 is sensitive to particle size, benzene is one of these. I rememer someone who used the chinese datasheet and found a chinese to translate it.
-
@epierre I am testing a stripped-down version of your code from your AirQuality-MQ135.ino. I stripped it to make it run just stand-alone.
What I don't understand is how to do the calibration. When I run it in outside environment (with 10k resistor), I get these values:valr 223 Vrl / Rs / ratio:13387 / 20875.00 / 0.00What would be the next step for calibration?
-
@epierre I am testing a stripped-down version of your code from your AirQuality-MQ135.ino. I stripped it to make it run just stand-alone.
What I don't understand is how to do the calibration. When I run it in outside environment (with 10k resistor), I get these values:valr 223 Vrl / Rs / ratio:13387 / 20875.00 / 0.00What would be the next step for calibration?
@supersjimmie replace MQ135_DEFAULTRO by your value 20875 in the sketch
-
@supersjimmie replace MQ135_DEFAULTRO by your value 20875 in the sketch
@epierre Thanks, I thought it would be something like that, but that didn't work.
I then gotvalr 242 Vrl / Rs / ratio:5464 / 8520.00 / 0.00Nothing like around 400ppm.
-
yes for the code must be updated, the value is the CO2 (or something else) detected above the 399 in atmosphere
gw.send(msg.set(MQ135_DEFAULTPPM+(int)ceil(valAIQ))); -
Thanks, but when calibrating something strange happens when I put the module outside:
valr 270 Vrl / Rs / ratio / ppm 61355 / 95673.00 / 0.00 / 399.00 valr 265 Vrl / Rs / ratio / ppm 62928 / 98126.00 / 0.00 / 399.00 valr 260 Vrl / Rs / ratio / ppm 64561 / 100673.00 / 0.00 / 399.00 valr 256 Vrl / Rs / ratio / ppm 378 / 589.00 / 0.00 / 399.00 valr 252 Vrl / Rs / ratio / ppm 1773 / 2764.00 / 0.00 / 399.00As you can see, the valr decreases slowly, but suddenly Vlr and Rs jump over.
Vlr is the value of 'val', which is: uint16_t val = ((float)22000*(1023-valr)/valr);
uint16_t is 16bit, so max 65535. It looks like my environment needs more than that?
(in fact, your code defines the defaultro as 68550, which is also too much for a uint16?) -
Thanks, but when calibrating something strange happens when I put the module outside:
valr 270 Vrl / Rs / ratio / ppm 61355 / 95673.00 / 0.00 / 399.00 valr 265 Vrl / Rs / ratio / ppm 62928 / 98126.00 / 0.00 / 399.00 valr 260 Vrl / Rs / ratio / ppm 64561 / 100673.00 / 0.00 / 399.00 valr 256 Vrl / Rs / ratio / ppm 378 / 589.00 / 0.00 / 399.00 valr 252 Vrl / Rs / ratio / ppm 1773 / 2764.00 / 0.00 / 399.00As you can see, the valr decreases slowly, but suddenly Vlr and Rs jump over.
Vlr is the value of 'val', which is: uint16_t val = ((float)22000*(1023-valr)/valr);
uint16_t is 16bit, so max 65535. It looks like my environment needs more than that?
(in fact, your code defines the defaultro as 68550, which is also too much for a uint16?)@supersjimmie said:
Vlr is the value of 'val', which is: uint16_t val = ((float)22000*(1023-valr)/valr);
yes and this is why I did rewrite it to https://github.com/empierre/arduino/blob/master/AirQuality-Multiple_Gas_Sensor1_4.ino but did not updated this one...
-
@supersjimmie said:
Vlr is the value of 'val', which is: uint16_t val = ((float)22000*(1023-valr)/valr);
yes and this is why I did rewrite it to https://github.com/empierre/arduino/blob/master/AirQuality-Multiple_Gas_Sensor1_4.ino but did not updated this one...
@epierre I striped-down that AirQuality-Multiple_Gas_Sensor1_4.ino to use only MQ135.
When used inside, the analogRead is 473, so a reasonble value.
But the MQCalibration function returns 0. Which means the MQResistanceCalculation also returns 0.MQResistenceCalculation only does one calc:
return (long)((long)(1024 * 1000 * (long)rl_value)/raw_adc-(long)rl_value);
rl_value = float RL4 = 0.990
raw_adc = 473 (measured as said above)
(1024 * 1000 * 0.990) / 473 - 0.990 = 2142.266
I checked that raw_adc is filled with the correct value (to be sure it is not lost somewhere).What looks to fix this, I changed everything to float . So:
return (float)((float)(1024 .* 1000. * (float)rl_value)/raw_adc-(float)rl_value);
Which can be simplyfied as:
return ((1024 * 1000*rl_value)/raw_adc-rl_value);
I went to float, because the function is created as float MQResistenceCalculation.This now gives some ppm values that are within a reasonable range (about 2000 here).
Now I have to figure out how to do calibration on this method again...
-
looks like I have to rework something... but not in the todo list right now... Imperihome is now back on top, and Particle on lipo/solar also...
-
@tantt2810 as explained above, if the datasheet has a logarithmic scale, you can use the power regression to approximate the curve. One tool for example to do this calculus:http://www.xuru.org/rt/powr.asp
for a sensor discussed above I read this on the datasheet:
H2
1.3 50
0.8 100
0.28 400
0.16 1000
0.05 4000The xuru website gives me this:
y = 73.59123879 x-1.355617483
Residual Sum of Squares: rss = 87393.44418and thus I have::
H2Curve[3] = {73.5912, -1.355617}; -
@tantt2810 as explained above, if the datasheet has a logarithmic scale, you can use the power regression to approximate the curve. One tool for example to do this calculus:http://www.xuru.org/rt/powr.asp
for a sensor discussed above I read this on the datasheet:
H2
1.3 50
0.8 100
0.28 400
0.16 1000
0.05 4000The xuru website gives me this:
y = 73.59123879 x-1.355617483
Residual Sum of Squares: rss = 87393.44418and thus I have::
H2Curve[3] = {73.5912, -1.355617}; -
So tonight with these new formulae, I updated my mega sketch to get :
MQ2 :LPG :0ppm CO :0ppm SMOKE :0ppm MQ6 :LPG :0ppm CH4 :0ppm MQ131 :CL2 :1ppm O3 :1ppm TGS2600:H2 :0ppm C2H5OH:0ppm C4H10 :0ppmGoing through the "clean air calibation" I have:
float MQResistanceCalculation(int raw_adc) { return ( ((float)RL_VALUE*(1023-raw_adc)/raw_adc)); }Here are the readings without:
MQ2:5.28 MQ6:36.94 MQ131:3.61 TGS2600:0.04and with all is 0... BTW...
What do you think of that ? nothing indicated that MQ6 should be so big, and tgs so low... same for MQ131 that should be 100k-200k per datasheet....
-
Hello,
I'm don't understand the recipe below. Why RL_Value(Load Resistance)(1023-raw_adc)/raw_adc)? Can you explain for me?
Thank you so much !!!
/***************** MQResistanceCalculation ****************************************
Input: raw_adc - raw value read from adc, which represents the voltage
Output: the calculated sensor resistance
Remarks: The sensor and the load resistor forms a voltage divider. Given the voltage
across the load resistor and its resistance, the resistance of the sensor
could be derived.
***********************************************************************************/
float MQ2::MQResistanceCalculation(int raw_adc)
{
return ( ((float)RL_VALUE(1023-raw_adc)/raw_adc));
}
