Sensors:

MH-Z19
MH-Z19 Pinout Cable
Pin Function
1 HD
2 Analog Output Vo
3 Negative Pole(GND)
4 Positive Pole(Vin)
5 UART(RXD)TTL Level data input
6 UART(TXD)TTL Level data output
7 PWM
BME 280
AZDelivery 5V RGB LED Ring WS2812B
AZDelivery 0,96 Zoll OLED Display I2C

Boards:

ESP-32 Dev Kit C V2
Sketch (click to download) – ESP-32 Dev Kit C V2, Arduino 2.0-beta, WebServer, Adafruit NeoPixel, BME 280, MH-Z19
/* CO2-Messung mit dem Sensor MH-Z19B
 * per Pulsweitenmodulation (PWM)
 *
 * Anzeige der Messwerte als CO2-Ampel
 *
 */
// NodeMCU Wroom -> Board: DOIT ESP32 DEVKIT V1 https://dl.espressif.com/dl/package_esp32_index.json (ESP32 by Espressif Systems)
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>

#include <WiFiClient.h>
#include <WebServer.h>

String float2string(float f);

const char* ssid     = "MyWLAN";
const char* password = "MyPAss";
WebServer server(80);

#define SEALEVELPRESSURE_HPA (1013.25)
Adafruit_BME280 bme; // I2C

#include <Adafruit_NeoPixel.h>
int leds = 12; //Anzahl der LEDs
int ledPin = 4; // 
//NeoPixel als "pixels" instanziieren
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(leds, ledPin, NEO_GRB + NEO_KHZ800);

#define red 0xFF0000
#define green 0x00FF00
#define yellow 0XFFFF00
#define orange 0XFFA500
#define blue 0x0000FF
#define black 0x000000
#define magenta 0xFF00FF

/* ------------------------------------------------------------
 * MH-Z19B
 * ------------------------------------------------------------ */
#include <Arduino.h>
#include <MHZ19.h>
// Nutzung der Schnittstelle UART2 an den Default-Pins RX 16, TX 17
//#define RX2 16
//#define TX2 17
#define RX2 16
#define TX2 17
#define MHZ19_BAUDRATE 9600
#define MHZ19_PROTOCOL SERIAL_8N1
#define MHZ19_RANGE 5000  // Obergrenze des Messbereichs des Sensors
#define MHZ19_PWM_PIN 14
#define INTERVALL 997  // Standard: 1004
MHZ19 mhz19b;  // Sensor-Objekt

void setup(void) {
  int i;
  bool error = false;
  char mhz19_version[4];  

  pinMode (ledPin, OUTPUT);
  pixels.begin();
  pixels.setBrightness(100); //Helligkeit: 0 (aus) - 255
  // Übertragungsrate zum seriellen Monitor setzen
  Serial.begin(MHZ19_BAUDRATE);
  Serial2.begin(MHZ19_BAUDRATE, MHZ19_PROTOCOL, RX2, TX2);
  mhz19b.begin(Serial2);  // MH-Z19B-Sensor eine Schnittstelle zuweisen
  // ein paar Daten der Sensor-Konfiguration ausgeben
  mhz19b.getVersion(mhz19_version);
  Serial.print("--------------------\nMH-Z19B Firmware Version: ");
  for(i = 0; i < 4; i++) {
    Serial.print(mhz19_version[i]);
    if(i == 1)
      Serial.print(".");
  }
  Serial.print("\nMH-Z19B Messbereich: ");
  Serial.println(mhz19b.getRange());   
  mhz19b.autoCalibration(true);
  mhz19b.calibrate();
  Serial.print("MH-Z19B Autokalibrierung (ABC): ");
  mhz19b.getABC() ? Serial.println("AN") :  Serial.println("AUS");
  Serial.println("--------------------");
 
  // im Fehlerfall Programm nicht fortsetzen (leere Dauerschleife))
  if(error) {
    for(;;);
  }

  //testscrolltext(); 

  // Connect to WiFi network
  WiFi.mode(WIFI_STA); 
  WiFi.begin(ssid, password);
  Serial.print("\n\r \n\rWorking to connect");
  
  // Wait for connection
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  
  Serial.println("");
  Serial.print("Connected to ");
  Serial.println(ssid);
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
  
  server.on("/", handle_root);

  server.on("/temp", [](){
    server.send(200, "text/plain", float2string(bme.readTemperature()));
  });
  server.on("/hum", [](){
    server.send(200, "text/plain", float2string(bme.readHumidity()));
  });
  server.on("/press", [](){
    server.send(200, "text/plain", float2string(bme.readPressure()/100.0));
  });
  server.on("/allvalues", allvalues);
  server.begin();
  Serial.println("HTTP server started");
  
  if (!bme.begin(0x76)) {
		Serial.println("Could not find a valid BME280 sensor, check wiring!");
		while (1);
	}
  
}
void loop() {
  int ppm;
  // Verwendung der einfachen Formel; allerdings wird - sofern
  // bekannt - mit dem Wert von INTERVALL die tatsächliche
  // Intervalllänge des Sensors berücksichtigt
  ppm = (pulseIn(MHZ19_PWM_PIN, HIGH, 2200000UL) / 1000 - 2) * MHZ19_RANGE / (INTERVALL - 4);
  // Ausgabe des CO2-Werts in ppm im seriellen Monitor
  Serial.print("PPM CO2: ");
  Serial.println(ppm);
  // je nach Wert die passende LED an- und die anderen
  // beiden ausschalten
  if (ppm < 800) {
    for (int i = 0; i < 12; i++) {
      pixels.setPixelColor(i, green);
      pixels.show();
      //delay(200);
    }
    Serial.print("Ampel green\n");
  }
   else if ( (ppm <= 800) && (ppm <=  1000) ) {
    for (int i = 0; i < 12; i++) {
      pixels.setPixelColor(i, yellow);
      pixels.show();
      //delay(200);
    }
    Serial.print("Ampel gelb\n");
   }
   else if ( (ppm <=  1000) && (ppm <=  1400) ) {
    for (int i = 0; i < 12; i++) {
      pixels.setPixelColor(i, orange);
      pixels.show();
      //delay(500);
    }
    Serial.print("Ampel orange\n");
   }
   else if (ppm >  1400) {
    for (int i = 0; i < 12; i++) {
      pixels.setPixelColor(i, red);
      pixels.show();
      //delay(500);
    }
    Serial.print("Ampel rot *** ALARM ***\n");
   }
  server.handleClient();

  delay(2500);  // vor der nächsten Messung etwas warten
}

void handle_root() { 
  Serial.print("\n\r \n\rHandle root"); 
  int ppm;
  // Verwendung der einfachen Formel; allerdings wird - sofern
  // bekannt - mit dem Wert von INTERVALL die tatsächliche
  // Intervalllänge des Sensors berücksichtigt
  ppm = (pulseIn(MHZ19_PWM_PIN, HIGH, 2200000UL) / 1000 - 2) * MHZ19_RANGE / (INTERVALL - 4);
  // Ausgabe des CO2-Werts in ppm im seriellen Monitor
  Serial.print("PPM CO2: ");
  Serial.println(ppm);
  String reply = "";
  reply += "Temperature: " + float2string(bme.readTemperature())    + " *C\n";
  reply += "Humidity:    " + float2string(bme.readHumidity())       + " %\n";
  reply += "Pressure: " + float2string(bme.readPressure()/100.0) + " hPa\n";
  reply += "PPM CO2: " + float2string(ppm);
  server.send(200, "text/plain", reply);
  delay(100);
}
void allvalues() { 
  Serial.print("\n\r \n\rHandle root"); 
  int ppm;
  // Verwendung der einfachen Formel; allerdings wird - sofern
  // bekannt - mit dem Wert von INTERVALL die tatsächliche
  // Intervalllänge des Sensors berücksichtigt
  ppm = (pulseIn(MHZ19_PWM_PIN, HIGH, 2200000UL) / 1000 - 2) * MHZ19_RANGE / (INTERVALL - 4);
  // Ausgabe des CO2-Werts in ppm im seriellen Monitor
  Serial.print("PPM CO2: ");
  Serial.println(ppm);
  String reply = "";
  reply += float2string(bme.readTemperature())+"\n";
  reply += float2string(bme.readHumidity())+"\n";
  reply += float2string(bme.readPressure()/100.0)+"\n";
  reply += float2string(ppm);
  server.send(200, "text/plain", reply);
  delay(100);
}
String float2string(float f) {
  int ipart = (int) f;
  int fpart = ((int)(fabs(f)*10)) % 10;
  return String(ipart) + "." + String(fpart);
}

Wiring- ESP-32 Dev Kit C V2, Arduino 2.0-beta, WebServer, Adafruit NeoPixel, BME 280, MH-Z19
ESP-32 Dev Kit BME 280
GPIO22 SCL
GPIO21 SDA
GND GND
+5V VIN
ESP-32 Dev Kit MH-Z19
GND GND
+5V VIN
GPIO14 PWM
GPIO16 RX
GPIO17 TX
ESP-32 Dev Kit RGB LED Ring
GND GND
+5V VCC
GPIO4 IN
ESP-32 Dev Kit Oled Display
GND GND
+5V VCC
GPIO22 SCL
GPIO21 SDA
Einiges übernommer von https://unsinnsbasis.de/.

Ampel – von verbrauchter bis unverbrauchter Luft.

Kommentar hinterlassen