Überwachung von CO2, Temperatur und Luftfeuchtigkeit mit MQ-135 und DHT11 - AZ-Delivery

El siguiente post fue enviado por el lector Miguel Torres Gordo. Después de que Bernd Albrecht comenzara la serie de blogs sobre un tema similar con MQ-2 y DHT22 en ESP8266, aquí hay una alternativa para microcontroladores ATmega328 y sensores MQ-135 / DHT11. ¡Que se divierta leyendo y probando!

Como es muy importante conocer el nivel de saturación del ambiente, por ejemplo, en el lugar de trabajo, busqué en internet un sensor que se pueda utilizar con Arduino para medir el contenido de CO2. Afortunadamente, encontré un sensor que mide la calidad del aire. Se trata del MQ-135, que, como se puede ver en la ficha técnica, puede medir determinadas sustancias, tales como NH3, alcohol, benceno, humo, CO2, etc. Así es como me encontré con este sensor.

Sabiendo que existía la posibilidad de utilizarlo junto con nuestro microcontrolador ATmega328, lo primero que hice fue buscar los límites de seguridad de CO2 en partes por millón (ppm) para viviendas, habitaciones y edificios, que según diversos estudios pueden oscilar entre 400 y 800 ppm. Ahora que ya conocía el sensor adecuado y los límites de seguridad, era el momento de diseñar un proyecto útil que nos mostrara esta información y que además nos informara sobre la temperatura y la humedad.

Por tanto, el objetivo de este proyecto es medir la concentración de CO2 en partes por millón, para mostrar los datos en una pantalla y que nos avise con una señal acústica cuando alcance una concentración peligrosa, además de informarnos sobre la temperatura y la humedad. Para alargar la vida útil de la pantalla, pensé que sería una buena opción instalar tres LEDs de diferentes colores para darnos una información visual rápida sobre el nivel de concentración de CO2 sin tener que necesariamente ver los datos. Una vez instalado todo esto, podemos comenzar a trabajar.

Hardware necesario

número Componente
1 Microcontrolador ATmega328P Nano V3.0 CH340
1 Sensor de calidad de aire MQ-135
1 Sensor de temperatura y humedad DHT-11
1 Adaptador DC-DC MT3608
1 LED 1x rojo, 1x amarillo, 1x verde, 1x azul, 1x blanco
1 Pantalla OLED I2C 128x64 píxeles (1,3 pulgadas)
2 Kit de Resistencias 525 piezas, 0 Ohm - 1M Ohm
1 Resistencia 220 ohmios
1 Sensor de Alarma de Buzzer

    El software necesario

    Descripción del funcionamiento del circuito

    El funcionamiento de este circuito es muy sencillo. El sensor MQ-135 mide la concentración de CO2 en partes por millón, y el sensor DHT-11 mide la temperatura y la humedad. Estos tres datos se envían a una pantalla OLED de dos tonos de 0,96 pulgadas para mostrar cada valor durante 3 segundos a intervalos de 1 minuto. La pantalla permanece apagada durante este tiempo. Estos valores de tiempo se pueden configurar. Mientras la pantalla permanece apagada, los tres LEDs nos informan visualmente de los valores de CO2 presentes. El LED verde se enciende cuando la concentración es igual o inferior a 550. El LED amarillo se enciende cuando la concentración está entre 551 y 799 partes por millón de CO2 y el LED rojo se enciende junto con un sonido de zumbido cuando la concentración supera las 799 partes por millón. Estos tres valores también se pueden configurar.

    Preparación y ajuste de la referencia de resistencia RZERO para el contenido de CO2 atmosférico

    En primer lugar, se debe preparar el sensor MQ-135 para que mida los valores correctos que utilizaremos en el siguiente paso. Para este propósito, el sensor debe funcionar a 5 voltios durante aproximadamente 2 horas cuando es nuevo para eliminar las impurezas producidas durante su fabricación. Después, lo mejor es hacer el ajuste de referencia de la resistencia RZEO en el circuito final, ya que se hace con las tensiones de alimentación y funcionamiento normalmente utilizadas y la medición es óptima.

    estructura de circuito

    estructura de circuito

    El objetivo de esta calibración es ajustar la resistencia del nivel de CO2 atmosférico para que el sensor MQ-135 mida una concentración entre 300 y 450 ppm, que corresponde a la concentración normal de este gas en el ambiente. Es muy importante alimentar el sensor de forma independiente con 5 VDC, ya que consume 850 mW.

    Cuando todo está conectado, iniciamos el Arduino IDE, cargamos y ejecutamos el sketch "MQ135_calibration.ino". Antes se debe instalar la librería MQ135. Abrimos el monitor serie y vemos la lectura de ppm; tenemos que cambiar el valor de RZERO en el archivo MQ135.h de la carpeta librería del Arduino IDE y guardar hasta que la lectura de ppm sea la que queremos dejar como referencia de trabajo del circuito. El valor a modificar es el valor de color verde.

     /// resistencia de calibración a nivel de CO2 atmosférico
     /// cambiar este valor hasta que el valor de PPM es 450.
     rzero #define 22500

    Para realizar el ajuste, se debe cambiar el valor de RZERO, guardar los cambios en el archivo MQ135.h de la librería en su carpeta Arduino IDE y volver a cargar el sketch de calibración, comprobar el nuevo valor de concentración de CO2 en el monitor serie y repetir el procedimiento para ajustar RZERO con el valor que queremos dejar como referencia de la concentración de CO2 en el aire para los límites de aviso en el sketch de nuestro proyecto.

    Sketch MQ135_Calibration para el ajuste de RZERO (descargar):

     # include "mq135.h"
     #define rzero 1
     
     MQ135 Gasser = MQ135(A0);
     En t Val;
     En t sensorpin = A0;
     En t SensorValue = 0;
     
     vacío configurar() {
       De serie.Empezar(115200);
       pinMode(sensorpin, Aporte);
     }
     
     vacío círculo() {
       Val = analogead(A0);
       De serie.impresión ("RAW =");
       De serie.println (Val);
       flotador cero = Gasser.basura();
       De serie.impresión ("Rzero:");
       De serie.println (cero);
       flotador ppm = Gasser.GETPPM();
       De serie.impresión ("PPM");
       De serie.println (ppm);
       demora(2000);
     }

    Cuando hemos leído correctamente la concentración de CO2 en partes por millón, es el momento de cargar el sketch CO2_monitor.ino, que nos proporciona la información sobre esta concentración, la humedad y la temperatura en el lugar donde queremos medir los valores.

    Sketch CO2_monitor (descargar):

     / ************* BIBLIOTECAS necesario para el proyecto **************************** /
     # include
     # include
     # include
     # include
     # include "pitches.h"
     
     / ************* parámetros de la pantalla ********************************** *** ********* /
     #define screen_width 128
     #define screen_height 64
     Adafruit_ssd1306 monitor(Screen_width, Screen_height, &Cable, -1);
     
     / ****** humedad y la temperatura del sensor de DHT-11 parámetros y variables ***** /
     #define dhtpin 2
     #define DHTTYPE DHT11
     DHT DHT(DHTPIN, DHTTYPE);
     flotador t, H;
     
     / ****************** MQ-135 Sensor parámetros y variables *************** /
     #define rzero 1
     # include "mq135.h"
     MQ135 Gasser = MQ135(A0);
     En t Val;
     En t sensorpin = A0;
     En t SensorValue = 0;
     flotador ppm, cero;
     
     / ***************** LEDs ******************************* *********************
     #define led_verde 3
     #define led_amarillo 4
     #define led_rojo 5
     
     no firmado largo Tiempo_anterior;  // contador de tiempo
     
     / *********************** CONFIGURACIÓN DEL BLOQUE ************************ *************** /
     vacío configuración( )
     {
       De serie.empezar(115200);
       DHT.empezar();              // DHT-11 de inicialización
       
       si(!monitor.empezar(SSD1306_SWITCHCAPVCC, 0x3C)) { // pantalla Comprobación presente
         De serie.println(F("SSD1306 asignación no se pudo"));
         por(;;);
      }
       demora(2000);
       monitor.clearDisplay();        // pantalla de inicialización y
       monitor.SetTextColor(BLANCO);  // color del texto config
       
       pinMode(sensorPin, APORTE);    // MQ-135 datos del PIN
     
       pinMode(led_verde, PRODUCCIÓN);
       pinMode(led_amarillo, PRODUCCIÓN);
       pinMode(led_rojo, PRODUCCIÓN);
       digitalWrite(led_verde, BAJO);
       digitalWrite(led_amarillo, BAJO);
       digitalWrite(led_rojo, BAJO);
     
     }
     
     / *********************** BUCLE DE BLOQUE ************************ ************* /
     vacío círculo( ) {
     
       t = DHT.readTemperature();    // Leer la temperatura
       h = DHT.readHumidity();        // Leer Humedad
     
       si (isnan(h) || isnan(t)) {    // Si no son la temperatura y
         De serie.println("Fallo de lectura del sensor de DHT !!!"); // lectura de humedad, el mensaje espectáculo para informar
      }
     
       val = analogRead(A0);        // lectura de CO2
       cero = gasSensor.getRZero();  // Valor de calibración del sensor MQ-135
       ppm = gasSensor.getPPM();      // Fórmula en la biblioteca para obtener el ppm de CO2
     
       chequeo_led ();              // Go y correr a LEDs comprobar método
       
       De serie.impresión( "T =" );        // Mostrar los valores por el puerto serie
       De serie.impresión(t);
       De serie.impresión("ºC, H =");
       De serie.impresión(h);
       De serie.impresión( "%, " );
       De serie.impresión ("= primas");
       De serie.impresión (val);
       De serie.impresión ("Rzero:");
       De serie.impresión (cero);
       De serie.impresión ("Ppm:");
       De serie.println (ppm);
       demora (1000);
     
       si ( Millis()-tiempo_anterior >= 60000) { // Si el tiempo pasado es más o igual que 60 sg
             encendido_pantalla();    // Ejecutar la vuelta en el método de pantalla.
             tiempo_anterior = Millis(); // Guardar el tiempo real.
      }
     }
     
     vacío chequeo_led() {
       si (ppm >= 800) {              // Si la concentración de CO2 es igual o mayor que 800
         digitalWrite(led_rojo, ELEVADO);        // Activar el LED de color rojo
         tono(8, NOTE_C5, 5000);            // sonido del zumbador
         monitor.clearDisplay();            // establecer los parámetros de la pantalla para mostrar el valor de PPM
         monitor.SetTextSize(2);
         monitor.setCursor(7,0);
         monitor.impresión("CO2 (PPM):");
         monitor.SetTextSize(3);
         monitor.setCursor(40,35);
         monitor.impresión(ppm,0);
         monitor.monitor();
         demora(10000);
      } demás {
         digitalWrite(led_rojo, BAJO);
         monitor.clearDisplay();
         monitor.monitor(); }
       
       si (ppm >= 551 && ppm <= 799) {
         digitalWrite(led_amarillo, ELEVADO); // El turno LED amarillo en si la concentración de CO2
      } demás {
         digitalWrite(led_amarillo, BAJO); }    // es de entre 551 y 799
       
       si (ppm <= 550) {
         digitalWrite(led_verde, ELEVADO); // El LED verde a su vez en cuando el CO2
      } demás {
         digitalWrite(led_verde, BAJO); }      // concentración es más baja que 551
     }
     
     vacío encendido_pantalla() {    // Activar el método de pantalla
       monitor.clearDisplay();              // establecer los parámetros de la pantalla y mostrar el valor de PPM
       monitor.SetTextSize(2);
       monitor.setCursor(7,0);
       monitor.impresión("CO2 (PPM):");
       monitor.SetTextSize(3);
       monitor.setCursor(40,35);
       monitor.impresión(ppm,0);
       monitor.monitor();
       demora(3000);
       
       monitor.clearDisplay();              // Establecer los parámetros de la pantalla y mostrar el valor de la humedad
       monitor.SetTextSize(2);
       monitor.setCursor(20,0);
       monitor.impresión("HUMEDAD:");
       monitor.SetTextSize(3);
       monitor.setCursor(20,35);
       monitor.impresión(h,1);
       monitor.setCursor(90,35);
       monitor.impresión("%");
       monitor.monitor();
       demora(3000);
       
       monitor.clearDisplay();              // establecer los parámetros de la pantalla y mostrar el valor de la temperatura
       monitor.SetTextSize(2);
       monitor.setCursor(40,0);
       monitor.impresión("TEMPERATURA:");
       monitor.SetTextSize(3);
       monitor.setCursor(5,35);
       monitor.impresión(t,1);
       monitor.setCursor(85,35);
       monitor.cp437(cierto);
       monitor.escribir(167);
       monitor.setCursor(107,35);
       monitor.impresión("C");
       monitor.monitor();
       demora(3000);
       
       monitor.clearDisplay();
       monitor.monitor();
     }

    estructura de circuito
    estructura de circuito

    Gracias a Miguel Torres Gordo por su contribución.

    DisplaysFür arduinoProjekte für anfängerSensoren

    12 comentarios

    Georg Franke

    Georg Franke

    Fazit vorweg: Der MQ135 kann kein CO2 (Kohlenstoffdioxid, Kohlendioxid) messen.
    Ich habe zunächst auch gehofft und geglaubt, dass der MQ135 dies könnte. Ich hatte aus Laubabfällen im Garten Biogas hergestellt, das mitunter brennbar ist oder nicht. Biogas kann u.a. Methan(brennbar) und CO2 enthalten. Um das Gasgemisch zu analysieren, habe ich einen Gaschromatographen(GC) von CMA gekauft und wollte den MQ135 als Gasdetektor verwenden. Der GC trennt die einzelnen Gaskomponenten und führt sie nacheinander zum Detektor. Das hat bei mir bei allen brennbaren Gasen (z.B. Wasserstoff, Propan, Butan, Alkoholdampf, Azetondampf) funktioniert nur eben nicht mit CO2. Im Nachhinein ist mir auch klar geworden, warum es auch theoretisch gar nicht geht: Der MQ135 besitzt eine SnO2-Schicht zur Detektion reduzierender Substanzen. Dieses SnO2 wird dabei teilweise reduziert und dadurch elektrisch leitfähiger, d.h. der Widerstand sinkt. Leider ist CO2 keine reduzierende Verbindung und kann daher nicht mit dem SnO2 reagieren. In einigen früheren Kommentaren wurde bereits darauf hingewiesen, worauf Miguel Torres auf das Datenblatt verwies. Ich habe das Datenblatt gesehen. In einem Diagramm wird der Zusammenhang zwischen Gaskonzentration verschiedener Gase in ppm und dem Widerstand des MQ135 dargestellt. Meine Lehrer hätten mir wahrscheinlich eine glatte 6 gegeben, In der Legende rechts oben stehen einige Gase: Al R oder AI R soll vermutlich Luft (Air) bedeuten, dann kann man mit etwas Fantasie CO2 und CO erkennen, sowie NH4 (soll vielleicht Ammoniak sein, also NH3), den Rest kann ich mir gar nicht zusammenreimen. Es wurden 3 Messpunkte pro Gas eingezeichnet. Über die Messunsicherheit (Toleranzen), sowie Quelle und Reinheit der verwendeten Gase wurden keine Angaben gemacht. Wie gesagt, wir messen im ppm-Bereich, da wirken sich geringste Verunreinigungen stark auf das Messergebnis aus und gaukeln z. B. beim CO2 etwas vor, was gar nicht vorhanden ist.
    Übrigens: Anbieter des MQ135, wie AZ-Delivery oder Reichelt verzichten auf die Nennung von CO2 als detektierbares Gas

    Mario Bluhm

    Mario Bluhm

    Hallo,

    Ich habe den MQ-135 am Pico-w.
    Habe die PI Daten herunter geladen, angeglichen und er liefert werte. Habe zusätzlich einen DHT-11 angeschlossen.

    Jetzt komme ich mit den gelieferten Werten nicht klar. was wird mir angezeigt. Temperatur und Luftfeuchte ist mir klar.

    DHT11 Temperature: 22 Humidity: 48
    MQ135 RZero: 90.50353 Corrected RZero: 92.92871 Resistance: 56.37128 PPM: 261.504 Corrected PPM: 236.589ppm

    Was soll da CO2 sein? Das sollte ein Wert um die 412ppm sein.

    Andreas Wolter

    Andreas Wolter

    @Sirko: könnten Sie bitte so nett sein und dazu schreiben, was aus Ihrer Sicht nicht korrekt ist und was Sie geändert haben?
    Ich kann das an den Autoren weiterleiten und wir korrigieren das dann im Beitrag.
    Vielen Dank.

    Grüße,
    Andreas Wolter
    AZ-Delivery Blog

    Sirko

    Sirko

    Das ganze mal etwas Richtiger (achte auf die auswahl dhd 11 oder dht 22)

    #include
    #include

    /* MQ135 + DHT Temp Sensor

    Combination of the MQ135 air quality sensor and a DHT11/22 temperature sensor to accurately measure ppm values through the library correction. Uses the Adafruit DHT Sensor Library: https://github.com/adafruit/DHT-sensor-library Written by: https://github.com/Phoenix1747/MQ135

    */

    #define PIN_MQ135 A2 // MQ135 Analog Input Pin
    #define DHTPIN 2 // DHT Digital Input Pin
    #define DHTTYPE DHT22 // DHT11 or DHT22, depends on your sensor

    MQ135 mq135_sensor(PIN_MQ135);
    DHT dht(DHTPIN, DHTTYPE);

    float temperature, humidity; // Temp and Humid floats, will be measured by the DHT

    void setup() {
    Serial.begin(9600);

    dht.begin();

    }

    void loop() {
    humidity = dht.readHumidity();
    temperature = dht.readTemperature();

    // Check if any reads failed and exit early (to try again). if (isnan(humidity) || isnan(temperature)) { Serial.println(F(“Failed to read from DHT sensor!”)); return; } float rzero = mq135_sensor.getRZero(); float correctedRZero = mq135_sensor.getCorrectedRZero(temperature, humidity); float resistance = mq135_sensor.getResistance(); float ppm = mq135_sensor.getPPM(); float correctedPPM = mq135_sensor.getCorrectedPPM(temperature, humidity); Serial.print("MQ135 RZero: "); Serial.print(rzero); Serial.print("\t Corrected RZero: "); Serial.print(correctedRZero); Serial.print("\t Resistance: "); Serial.print(resistance); Serial.print("\t PPM: "); Serial.print(ppm); Serial.print(“ppm”); Serial.print("\t Corrected PPM: "); Serial.print(correctedPPM); Serial.print(“ppm”); Serial.print( "\t T = " ); Serial.print(temperature); Serial.print("\t ºC, H = "); Serial.print(humidity); Serial.println( "%, " ); delay(10000);

    }

    Andreas Wolter

    Andreas Wolter

    @Erik Huber: Danke für den Hinweis. Ich habe das an den Autoren weitergegeben. Wir checken das und ändern das dann.

    Grüße,
    Andreas Wolter
    AZ-Delivery Blog

    Erik Huber

    Erik Huber

    Hi, Im Code ist ein Fehler.
    #define RZERO 1
    Es ist zwar definiert, aber nirgends wird es angewendet. Der Korrekte Befehl lautet daher nicht: MQ135 gasSensor = MQ135;
    Sondern: MQ135 gasSensor(A0, RZERO);

    Erst dann kann man den RZERO Wert nutzen.
    Also, den Wert von RZERO auf 1 lassen, dann 12 Stunden den Sensor an der guten Luft lassen mit Stormversorgung. Danach den RZERO Wert ablesen und den Wert im Code bei "#define RZERO " eintragen. Also nur die “1” mit dem Wert austauschen.

    iberotecno

    iberotecno

    Good work, but the problem is the library. The library author Georg Krocker’s says “The library also provides functions to apply the temperature/humidity correction that is shown in Fig 4 of the datasheet, but I do not trust the datasheet there, so this should not be used for the moment.” Source: https://hackaday.io/project/3475-sniffing-trinket/log/12363-mq135-arduino-library I also tryed with this method and the measures are inaccurate. More inaccurate than measures without temperature and humidity correction. We need another solution.

    Miguel Torres

    Miguel Torres

    Hello Philipp,

    The difference in price of the MQ-135 sensor versus the MHZ-19 is very significant for Arduino projects.

    Miguel Torres

    Miguel Torres

    According to the data sheet for this sensor, this also measures CO2. I leave a link where it shows the sensitivity for different gases.
    https://www.olimex.com/Products/Components/Sensors/Gas/SNS-MQ135/resources/SNS-MQ135.pdf

    mi

    mi

    hmmmm – kann es sein, dass der MQ-135 kein CO2 sondern nur CO misst ?

    Philipp Landhäußer

    Philipp Landhäußer

    Hallo,
    ein sehr guter Bericht aber das Problem ist, dass der MG-135 nur CO misst und kein CO2. Dafür wäre eher der MHZ-19 geeignet.

    Mfg

    Andreas Waldbrenner

    Andreas Waldbrenner

    Wäre super, wenn man mit einem Knopfdruck alle Teile im Warenkorb hätte. Oder habe ich diese Funktion übersehen? Andi

    Deja un comentario

    Todos los comentarios son moderados antes de ser publicados