Android-Arduino Air Quality Monitor with MQ135 Multiple Gas Sensor


The MQ135 is a cheap air quality sensor used for measure of different gases, like alcohol, carbon monoxide and carbon dioxide, after doing some research and using the info provided by Davide Gironi, the way to measure ppm of gases according datasheet is this:
The graphic above shows a exponential function for each gas, then the x axes starts in 10 ppm and ends in 1000 ppm and the y axes starts in 0.1 and ends in 10 which it is basically the measured resistance from the analog output of the sensor and the resistance zero (rs/ro), provided by data sheet. We need some engineering knowledge for properly read the graphic. If you need more info about this, take a look to wikipedia link(log-log scale).

Then we need the slope from each function, for that, we can measure the start and end points digitally with a
very util tool: WebPlotDigitizer http://arohatgi.info/WebPlotDigitizer/app/, only download the log graphic above, upload to WPD  tell to it where x and y axes starts-end and putting log scale in the checkbox..


The values obtained by me are:
  • AIR (10, 3.58),(200, 3.58)
  • CO (10, 2.8351) ,(200,1.3464)
  • CO2 (10, 2.3),(200,0.8)
  • ETHANOL (10, 1.90),(200,0.73)
  • NH4 (10,2.55),(200,0.765)
  • TOLUENE (10, 1.54),(200, 0.64)
  • ACETONE (10, 1.44), (200,0.583)
And for sure you´re asking, How he knew it was ethanol, toluene and acetone from the poor description by the data sheet? And the answer is the translation, because the origin of the sensor is china, and there speak chinese and real mq135 datasheet comes in that language, then I used google digital translator for see what that symbols really are. The weirds symbols are:





back to the calculus, the first formula to calculate the slope is m=(y2-y1)/(x2-x1) but we are in log scale then the formula with logarithmic laws comes from m = (log y2 - log y1) / (logx2 - logx1) to m = log (y2/y1) / log (x2/x1) then we need this formula:
The formula says if you previously read wikipedia info than f(x) = (y1 / x1^m) * x^m where we already calculate the slope (m). For example, we going to calculate the function for CO2, we have the points measured by WPD
  • CO2 (10, 2.3),(200,0.8) 
Where 

x1 = 10 
x2 = 200
y1 = 2.3
y2 = 0.8

m = log(0.8/2.3) / log(200/10) = -0.4586/1.3010 = -0.3525
and the function is y = [2.3/10^(-0.3525)] * x ^ (-0.3525) = 5.0152 * x ^(-0.3525)
y is our final function buuut, respect to x, we need respect to y , because y is (rs/ro) and we need x(ppm)
clearing the equation (I'd recomend wolfram) the final function is...
voila! the aproximate form an final formula is  
x = 96.9691 * y^(-2.83688) or ppm = 96.9691 * (rs/ro)^-2.83688
comparing with the Davide Gironi equation, the scale factor is different
ppm = 116.6020682 (Rs/Ro)^-2.769034857
all depends of measured slope

I measured the points manually on the plot with WPD, and I compared them with my calculated function (with matlab and plotly) and this is the result:

Plotly link
https://plot.ly/~zesters/0/co2-real-co2-equation-co-real-co-equation-ethanol-real-ethanol-equation-nh4-real/


CO2 Comparison 
 
Where blue is the real graphic from datasheet and orange is the equation. The conclusion is: You not need power regression for this, you only need slope and the log formula.

With respective rs and ro calculated from the Georgk Library you can measure all gases.

My formulas to calculate all datasheet gases are:
  • CO2: ppm = 114.3544 * (rs/ro)^-2.93599
  • CO ppm = 662.9382 * (rs/ro)^-4.0241
  • Ethanol ppm = 75.3103 * (rs/ro)^-3.1456
  • Ammonium NH4 ppm = 102.694 * (rs/ro)^-2.48818
  • Toluene ppm = 43.7748 * (rs/ro)^-3.42936
  • Acetone ppm = 33.1197 * (rs/ro)^-3.36587
Comparing with Empierre Values
float CO2Curve[2] = {113.7105289, -3.019713765}; //MQ135 float CO_secCurve[2] = {726.7809737, -4.040111669}; //MQ135 float NH4Curve[2] = {84.07117895, -4.41107687}; //MQ135 float C2H50H_Curve[2] = {74.77989144, 3.010328075}; //MQ135 float CH3Curve[2] = {47.01770503, -3.281901967}; //MQ135 float CH3_2COCurve[2] = {7.010800878, -2.122018939}; //MQ135

 

The next update of this post I will upload my library for MQ135 for obtain ppm for all gases and how to obtain more precission for this cheap sensor and a way to measure with 50m of distance using rf 433mhz module. Also my Android Bluetooth Arduino App to show all values ;)
There is  a couple of screenshots:






obviously you need an arduino, mq135 sensor, bmp180, hc05 module and dht11 sensor to test it, but with time I will upload it.

The app source code and arduino is located in my github:https://github.com/zesteros/ArduinoAirQualityMonitor


And this is the resources where Im taking all info and knowledge
Arduino MQ135 Library George Krocker
https://github.com/GeorgK/MQ135
Davide Gironi MQ135 Post
Empierre Research MQ135 and others Sensors 
Empierre Sketch Air Quality Multiple Gas Sensor Arduino 

If you have questions please ask to me!

Comentarios

  1. Hello, thank you for quote my MQ135 blog post.
    You have made a great job. I like your method to find out the function parameters.
    WebPlotDigitizer is really a great tool for extraction the points, unluckly I doesn't know that tool at the time I write my post. I realized about WebPlotDigitizer a few times ago when a hackaday post write about this.
    I still find the power regression method the simpler one. Anyway it's a matter of practice :)

    ResponderEliminar
    Respuestas
    1. thank you for take your time to respond and and for see my post, and the reason of why im not using power regression is because I dont know how to do it, but I really admire your capabilities to determine all mathematical job for this, finally, I have a question that I would like you answer it, and it is about the temperature and humidity, I calculated the equation of both functions on figure 2 in data sheet of this sensor, the first is the 33% humidity function:

      (rs/ro) = 1.5359 * 0.9896 ^ Temperature

      and the second is for humidity an 85%

      (rs/ro) = 1.3917 * 0.9895 ^ Temperature

      My question is: how to apply this to correction of the sensor resistance reading? do you know something about?
      I compared both functions with the data sheet functions and the 85% humidity function is the only what doesnt match so much
      Thank you so much for spend time reading this. Regards

      Eliminar
  2. Can u please upload the arduino code as the library is changed or u can also post the library function

    ResponderEliminar
    Respuestas
    1. Course, the library is located on my github https://github.com/zesteros/MQ135

      Eliminar
    2. can you explain it ?

      scaleFactorNH4 * pow((getResistance()/r0NH4), -exponentNH4);

      i get from your github, i hope u answer my question more fast. thanks

      Eliminar
    3. Of course, the constants scaleFactor, r0 and exponent are constants of nh4 calculated equation Ammonium NH4 ppm = 102.694 * (rs/ro)^-2.48818 where rs is the resistance read from arduino analogic input (mq135)

      Eliminar
  3. Hello Angelo, i wonder how to know if an air quality is considered as "bad air", "normal", "good air", and "dangerous"? do you know the ppm range value?

    ResponderEliminar
    Respuestas
    1. The level of normal ppm in air of gases, depends of your country laws. here in mexico, the co2 level is below of 400ppm.

      Eliminar
    2. Hola Angelo,

      I am trying to use your Arduino-sketch from github, but I get some errors.


      The errors are:

      Arduino: 1.8.5 (Windows 7), Board: "Arduino/Genuino Mega or Mega 2560, ATmega2560 (Mega 2560)"

      C:\Users\JRGEN~1\AppData\Local\Temp\ccHcqWin.ltrans0.ltrans.o: In function `main':

      C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/main.cpp:43: undefined reference to `setup'

      C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/main.cpp:46: undefined reference to `loop'

      collect2.exe: error: ld returned 1 exit status

      Do you have any suggestions ?

      I am using AnalogPin 0 für the sensor.

      Saludos,
      Jürgen

      Eliminar
    3. Este comentario ha sido eliminado por el autor.

      Eliminar
    4. Hola Angelo, me again,

      could it be, that I get the errors because I copy/pasted the file into the Arduino IDE and then uploaded it.

      Do I have to change some values to do that ?

      Muchas gracias por una respuesta
      Jürgen

      Eliminar
    5. Yes, but for avoid Future problems I'm going to upload a simple example and the library That I used. Wait me until I upload it please.

      Eliminar
    6. https://github.com/zesteros/ArduinoAirQualityMonitor/tree/master/Arduino/AirMonitor
      import the .zip libraries in library folder with Arduino IDE "import from zip" option

      Eliminar
  4. hi i cant understand from where this is comming from x = 96.9691 * y^(-2.83688)

    ResponderEliminar
    Respuestas
    1. Change variables of the equation(pass x to left side) with a Math tool like wolfram. And you will get it.

      Eliminar
    2. Of this initial equation:
      y = [2.3/10^(-0.3525)] * x ^ (-0.3525) = 5.0152 * x ^(-0.3525)

      Eliminar
  5. Este comentario ha sido eliminado por el autor.

    ResponderEliminar
    Respuestas
    1. y = [2.3/10^(-0.3525)] * x ^ (-0.3525) = 5.0152 * x ^(-0.3525)
      wolfram is giving: y = [2.3/10^(-0.3525)] * x ^ (-0.3525) =5.17878/(x^0.3525)

      Eliminar
    2. You need to put:

      solve y=5.0152 * x ^(-0.3525) for x

      in aproximmate form

      Eliminar
  6. I cant get 5.0152 all calculations are showing y = 5.17878*x^(-0.3525)
    but not 5.0152 * x ^(-0.3525)

    ResponderEliminar
    Respuestas
    1. Sorry, so my calculus is wrong, but the co2 ppm read is approximate

      Eliminar
  7. would you please to explain how to get that value x = 96.9691 * y^(-2.83688) or ppm = 96.9691 * (rs/ro)^-2.83688 from y = [2.3/10^(-0.3525)] * x ^ (-0.3525) = 5.0152 * x ^(-0.3525) ?

    ResponderEliminar
    Respuestas
    1. Hi, my process says that y= 5.0152 * x ^(-0.3525) if we change x and y for ppm and resistance, we found (rs/r0) =*5.0152 * ppm ^(-0.3525) and we need the ppm in the left side of equation, if you use wolfram you will obtain ppm(x in equation) in Mexico this process of change position of the variable in the equation is called clear.

      Eliminar
  8. Sir, could you tell me where you get the normal amounts of concentration in the atmosphere from the different gases?
    if I understand correctly, that data in the library is used in "ppm" parts per million

    #define atmCO2 407.57
    (approaching January 2018: 407.54 ppm (Recent Global CO2) from www.esrl.noaa.gov)

    #define atmNH4 15
    Now 15ppm in the atmosphere can not be, it is a mistake, the values in the atmosphere for the NH3 and many other gas is measured in "ppb" or parts per billion.
    I can not find where to officially get that information and also consider it is a mistake in the library, which goes unnoticed because it is a very small value.

    Could you clarify these points? Thank you

    ResponderEliminar
    Respuestas
    1. Of course, according the datasheet the Ammonium molecule is NH3 but the inaccuracy of the sensor does not give to us the opportunity to sense that gas, but it is noticeable, instead ppb NH3 I am using NH4 (with aproximate sensing) in ppm, but if I had a laboratory for put a known concentration of each gas and making tests constantly I would get the real values. The constant values that I am actually using is located in this academic articles:
      https://drive.google.com/open?id=1pVTG4mifNPiQuxEvFYsF6swJlc9p4nTD

      Eliminar
  9. how to calculate rs/ro?
    please help, asap

    ResponderEliminar
  10. Hi Angelo. nice blog. Thank you for sharing us reading methods. My question is.. In real world can this sensor be used to measure ammonia alone if it goes above threshold level... ?
    For instance, if environment has high CO2 it should not alarm and does alarm only for ammonia...can it be programmed like that?

    Thanks in advance..

    ResponderEliminar
  11. Hi, how can I generate the apk? Thanks! Good work!

    ResponderEliminar
  12. wow,i really like your blog,your blog give me a good information related to the Pocket Calculator.Thanks for this good one.......
    https://www.cycalculator.com/

    ResponderEliminar
  13. wow,i really like your blog,your blog give me a good information related to the Pocket Calculator.Thanks for this good one.......
    Desktop Calculator Suppliers

    ResponderEliminar
  14. Hello,
    float MQ135::getResistance() {
    int val = analogRead(_pin);
    return ((1024./(float)val) * 5. - 1.)*RLOAD;
    }
    I didn't understand why you multiple with 5 the equation. I think it has to be ((1024./(float)val)-1)*RLOAD, and can you explain how you calculate CORA, CORB, CORC, CORD values?

    ResponderEliminar
    Respuestas
    1. its because need to be multiplied by 5v for analog/digital conversion

      Eliminar
  15. Hi, I just want to ask if this sensor can use the 5V from the Arduino board and if the current output from the Arduino is enough for the MQ-135 sensor?

    ResponderEliminar
  16. can u tell me the value of Ro for CO MQ135?

    ResponderEliminar
  17. Hola Angelo. Muy bueno tu blog. He obtenido respuestas a varias preguntas que me han surgido. Una pregunta adicional. Que debo ajustar en el Sketch que tienes en Github si quiero que los datos me aparezcan por el minitor serial? ¿o en una lcd 16x2? Gracias!!!

    ResponderEliminar
    Respuestas
    1. claro puedes usar la libreria LCD de Arduino e imprimir los datos directamente sin problema.

      Eliminar
  18. Borgata Hotel Casino & Spa - JTHub
    Borgata Hotel 경산 출장샵 Casino 천안 출장마사지 & Spa in Atlantic City 제주도 출장안마 is 부산광역 출장안마 a 4-star 구미 출장샵 property located in Atlantic City with a 2.2 acre pool deck and 2 indoor pool areas. Borgata Hotel Casino

    ResponderEliminar

Publicar un comentario