BME680 Dar­stel­lung LCD und Web

Dar­stel­lung auf LCD

#include "bsec.h"
#include "LCDIC2.h"

// 4-zeiliges LCD
LCDIC2 lcd(0x27, 20, 4);

// Objekt (iaqSensor) der Klasse Bsec definieren
Bsec iaqSensor;

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

  // auf Serielle Verbindung warten
  while (!Serial);
  delay(1000);
  
  // LCD starten
  lcd.begin();

  // Cursor "verstecken"
  lcd.setCursor(false);

  // Hex-Adresse des BME680
  // BME68X_I2C_ADDR_HIGH = 0x77 (Standard)
  // BME68X_I2C_ADDR_LOW = 0x76 (Verbindung SDO zu GND)
  iaqSensor.begin(BME68X_I2C_ADDR_HIGH, Wire);

  // Array der verfügbaren Sensoren
  bsec_virtual_sensor_t sensorList[13] = 
  {
    BSEC_OUTPUT_IAQ,
    BSEC_OUTPUT_STATIC_IAQ,
    BSEC_OUTPUT_CO2_EQUIVALENT,
    BSEC_OUTPUT_BREATH_VOC_EQUIVALENT,
    BSEC_OUTPUT_RAW_TEMPERATURE,
    BSEC_OUTPUT_RAW_PRESSURE,
    BSEC_OUTPUT_RAW_HUMIDITY,
    BSEC_OUTPUT_RAW_GAS,
    BSEC_OUTPUT_STABILIZATION_STATUS,
    BSEC_OUTPUT_RUN_IN_STATUS,
    BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_TEMPERATURE,
    BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_HUMIDITY,
    BSEC_OUTPUT_GAS_PERCENTAGE
  };

  // BSEC_SAMPLE_RATE_ULP: Ultra Low Powermode -> Messung alle 5 Minuten
  // BSEC_SAMPLE_RATE_LP: Low Powermode -> Messung alle 3 Sekunden
  iaqSensor.updateSubscription(sensorList, 13, BSEC_SAMPLE_RATE_LP);
}

void loop() 
{
  // wenn der Sensor arbeitet ...
  if (iaqSensor.run()) 
  {
    // Messwerte ermitteln, in Strings umwandeln, . durch , ersetzen
    String Temperatur = String(iaqSensor.temperature);
    Temperatur.replace(".", ",");

    String Luftfeuchtigkeit = String(iaqSensor.humidity);
    Luftfeuchtigkeit.replace(".", ",");

    String Luftdruck = String(iaqSensor.pressure / 100);
    Luftdruck.replace(".", ",");

    String IAQ = String(iaqSensor.iaq);
    IAQ.replace(".", ",");

    String StatischerIAQ = String(iaqSensor.staticIaq);
    StatischerIAQ.replace(".", ",");
    
    String CO2 = String(iaqSensor.co2Equivalent);
    CO2.replace(".", ",");

    String VOC = String(iaqSensor.breathVocEquivalent);
    VOC.replace(".", ",");

    String GasInProzent = String(iaqSensor.gasPercentage);
    GasInProzent.replace(".", ",");

    String WiderstandMOXSensor = String(iaqSensor.gasResistance / 1000);
    WiderstandMOXSensor.replace(".", ",");

    // Ausgabe Serieller Monitor
    Serial.println("Statusmeldungen:");
    Serial.println("-----------------------------");
    Serial.println("Sensor bereit (0-1): " + String(int(iaqSensor.runInStatus)));
    Serial.println("Genauigkeit IAQ (0-3): " + String(int(iaqSensor.iaqAccuracy)));
    Serial.println("-----------------------------");
    Serial.println("Messwerte:");
    Serial.println("-----------------------------");
    Serial.println("Temperatur: " + Temperatur + " °C");
    Serial.println("Feuchtigkeit: " + Luftfeuchtigkeit + " %");
    Serial.println("Luftdruck: " + Luftdruck + " hPa");
    Serial.println("IAQ: " + IAQ);
    Serial.println("Statischer IAQ: " + StatischerIAQ);
    Serial.println("Schätzung CO2: " + CO2 + " ppm");
    Serial.println("Gas (0-100): " + GasInProzent + " %");
    Serial.println("Widerstandswert MOX-Sensor: " + WiderstandMOXSensor + " kOhm");
    Serial.println("VOC: " + VOC);
    Serial.println("-----------------------------");

    // Ausgabe LCD
    lcd.setCursor(0, 0);
    lcd.print("Temperatur: " + Temperatur + "\337C");
    lcd.setCursor(0, 1);
    lcd.print("Feuchtigkeit: " + Luftfeuchtigkeit + "%");
    lcd.setCursor(0, 2);
    lcd.print("IAQ: " + IAQ);
    lcd.setCursor(0, 3);
    lcd.print("CO2: " + CO2 + " ppm");
  }
}

Dar­stel­lung im Web

#include "bsec.h"
#include "WiFi.h"
#include "WebServer.h"
#include "time.h"

// Objekt (iaqSensor) der Klasse Bsec definieren
Bsec iaqSensor;

char Router[] = "Router_SSID";
char Passwort[] = "xxxxxxxx";

// ip und gateway müssen an das lokale Netz angepasst werden
IPAddress ip(192, 168, 1, 100);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);

/*
  öffentliche DNS-Server
  -----------------------------------------------
  OpenDNS 208, 67, 222, 222 (USA)
  Google 8, 8, 8, 8 (USA)
  Cloudfare 1, 1, 1, 1 (USA)
  DNSWWatch 84, 200, 69, 80 (Deutschland)
  Quad9 9, 9, 9, 9 (Schweiz)
  Neustar UltraDNS 56, 154, 70, 3 (USA, gefiltert)
  Deutsche Telekom 217, 5,100, 185
  ------------------------------------------------
  oder die im Router eingetragene IP
  im Beispiel: 192, 168, 1, 20
*/
IPAddress primaryDNS(192, 168, 1, 20);
IPAddress secondaryDNS(9, 9, 9, 9);

// NTP-Server aus dem Pool
#define Zeitserver "de.pool.ntp.org"

/*
  Liste der Zeitzonen
  https://github.com/nayarsystems/posix_tz_db/blob/master/zones.csv
  Zeitzone CET = Central European Time -1 -> 1 Stunde zurück
  CEST = Central European Summer Time von
  M3 = März, 5.0 = Sonntag 5. Woche, 02 = 2 Uhr
  bis M10 = Oktober, 5.0 = Sonntag 5. Woche 03 = 3 Uhr
*/
#define Zeitzone "CET-1CEST,M3.5.0/02,M10.5.0/03"

// time_t enthält die Anzahl der Sekunden seit dem 1.1.1970 0 Uhr
time_t aktuelleZeit;

/* 
  Struktur tm
  tm_hour -> Stunde: 0 bis 23
  tm_min -> Minuten: 0 bis 59
  tm_sec -> Sekunden 0 bis 59
  tm_mday -> Tag 1 bis 31
  tm_wday -> Wochentag (0 = Sonntag, 6 = Samstag)
  tm_mon -> Monat: 0 (Januar) bis 11 (Dezember)
  tm_year -> Jahre seit 1900
  tm_yday -> vergangene Tage seit 1. Januar des Jahres
  tm_isdst -> Wert > 0 = Sommerzeit (dst = daylight saving time)
*/
tm Zeit;

WebServer server(80);

// benötigte Strings
String Nachricht;
String Temperatur;
String Luftfeuchtigkeit;
String Luftdruck;
String CO2;
String IAQ;
String StatischerIAQ;

void setup() 
{
  // Zeitzone: Parameter für die zu ermittelnde Zeit
  configTzTime(Zeitzone, Zeitserver);

  // localtime_r -> Zeit in die lokale Zeitzone setzen
  localtime_r(&aktuelleZeit, &Zeit);
  Serial.begin(9600);

  // auf Serielle Verbindung warten
  while (!Serial);
  delay(1000);

  // WiFi starten
  WiFi.begin(Router, Passwort);

  WiFi.config(ip, gateway, subnet, primaryDNS, secondaryDNS);
  Serial.print("Verbunden mit ");
  Serial.println(Router);

  // IP anzeigen
  Serial.print("Statische IP: ");
  Serial.println(ip);

  server.begin();
  server.on("/", handleRoot);

  // Hex-Adresse des BME680
  // BME68X_I2C_ADDR_HIGH = 0x77
  // BME68X_I2C_ADDR_LOW = 0x76
  iaqSensor.begin(BME68X_I2C_ADDR_HIGH, Wire);

  // Array der verfügbaren Sensoren
  bsec_virtual_sensor_t sensorList[13] = 
  {
    BSEC_OUTPUT_IAQ,
    BSEC_OUTPUT_STATIC_IAQ,
    BSEC_OUTPUT_CO2_EQUIVALENT,
    BSEC_OUTPUT_BREATH_VOC_EQUIVALENT,
    BSEC_OUTPUT_RAW_TEMPERATURE,
    BSEC_OUTPUT_RAW_PRESSURE,
    BSEC_OUTPUT_RAW_HUMIDITY,
    BSEC_OUTPUT_RAW_GAS,
    BSEC_OUTPUT_STABILIZATION_STATUS,
    BSEC_OUTPUT_RUN_IN_STATUS,
    BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_TEMPERATURE,
    BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_HUMIDITY,
    BSEC_OUTPUT_GAS_PERCENTAGE
  };

  // BSEC_SAMPLE_RATE_ULP: Ultra Low Powermode -> Messung alle 5 Minuten
  // BSEC_SAMPLE_RATE_LP: Low Powermode -> Messung alle 3 Sekunden
  iaqSensor.updateSubscription(sensorList, 13, BSEC_SAMPLE_RATE_LP);
}

void loop() 
{
  // wenn der Sensor arbeitet ...
  if (iaqSensor.run()) 
  {
    // aktuelle Zeit holen
    time(&aktuelleZeit);

    // localtime_r -> Zeit in die lokale Zeitzone setzen
    localtime_r(&aktuelleZeit, &Zeit);

    // es kann bis zu 30 Sekunden dauern
    // bis die Zeit ermittelt wird
    // Name des Wochentages 0-6
    switch (Zeit.tm_wday) {
      case 0:
        Serial.print("Sonntag");
        break;
      case 1:
        Serial.print("Montag");
        break;
      case 2:
        Serial.print("Dienstag");
        break;
      case 3:
        Serial.print("Mittwoch");
        break;
      case 4:
        Serial.print("Donnerstag");
        break;
      case 5:
        Serial.print("Freitag");
        break;
      case 6:
        Serial.print("Samstag");
        break;
    }

    Serial.print(",");
    if (Zeit.tm_mday < 10) Serial.print("0");
    Serial.print(Zeit.tm_mday);
    Serial.print(".");

    // Monat: führende 0 ergänzen
    if (Zeit.tm_mon < 10) Serial.print("0");

    // Zählung beginnt mit 0 -> + 1
    Serial.print(Zeit.tm_mon + 1);
    Serial.print(".");

    // Anzahl Jahre seit 1900
    Serial.print(Zeit.tm_year + 1900);
    Serial.print(" ");

    // Stunde: wenn Stunde  10 -> 0 davor setzen
    if (Zeit.tm_hour < 10) Serial.print("0");
    Serial.print(Zeit.tm_hour);
    Serial.print(":");

    // Minuten
    if (Zeit.tm_min < 10) Serial.print("0"); 
    Serial.println(Zeit.tm_min);

    server.handleClient();

    // Messwerte ermitteln, in Strings umwandeln, . durch , ersetzen
    Temperatur = String(iaqSensor.temperature);
    Temperatur.replace(".", ",");

    Luftfeuchtigkeit = String(iaqSensor.humidity);
    Luftfeuchtigkeit.replace(".", ",");

    Luftdruck = String(iaqSensor.pressure / 100);
    Luftdruck.replace(".", ",");

    IAQ = String(iaqSensor.iaq);
    IAQ.replace(".", ",");

    StatischerIAQ = String(iaqSensor.staticIaq);
    StatischerIAQ.replace(".", ",");

    CO2 = String(iaqSensor.co2Equivalent);
    CO2.replace(".", ",");

    String VOC = String(iaqSensor.breathVocEquivalent);
    VOC.replace(".", ",");

    String GasInProzent = String(iaqSensor.gasPercentage);
    GasInProzent.replace(".", ",");

    String WiderstandMOXSensor = String(iaqSensor.gasResistance / 1000);
    WiderstandMOXSensor.replace(".", ",");

    // Ausgabe Serieller Monitor
    Serial.println("Statusmeldungen:");
    Serial.println("-----------------------------");
    Serial.println("Sensor bereit (0-1): " + String(int(iaqSensor.runInStatus)));
    Serial.println("Genauigkeit IAQ (0-3): " + String(int(iaqSensor.iaqAccuracy)));
    Serial.println("-----------------------------");
    Serial.println("Messwerte:");
    Serial.println("-----------------------------");
    Serial.println("Temperatur: " + Temperatur + " °C");
    Serial.println("Feuchtigkeit: " + Luftfeuchtigkeit + " %");
    Serial.println("Luftdruck: " + Luftdruck + " hPa");
    Serial.println("IAQ: " + IAQ);
    Serial.println("Statischer IAQ: " + StatischerIAQ);
    Serial.println("Schätzung CO2: " + CO2 + " ppm");
    Serial.println("Gas (0-100): " + GasInProzent + " %");
    Serial.println("Widerstandswert MOX-Sensor: " + WiderstandMOXSensor + " kOhm");
    Serial.println("VOC: " + VOC);
    Serial.println("-----------------------------");
  }
}

void handleRoot() 
{
  // Seite zusammenbauen
  // Kopf der HTML-Seite: aktualisierung alle 60 Sekunden
  // kann angepasst werden
  Nachricht = "<head><meta http-equiv=\"refresh\" content=\"60\"></head>";
  Nachricht += "<h1>Messwerte BME680</h1><hr>";

  // Datum anzeigen
  // formatieren: Schrift 14pt, ohne Serifen, Zeilenhöhe
  Nachricht += "<div style = \"font-size:14pt; font-family:sans-serif; line-height:1.8em\">";
  Nachricht += "Letzte Aktualisierung: ";

  // wenn der Tag < 10
  if (Zeit.tm_mday < 10) Nachricht += "0";
  Nachricht += String(Zeit.tm_mday) + ".";

  // wen der Monat < 10, Zählung beginnt mit 0
  if ((Zeit.tm_mon + 1) < 10) Nachricht += "0";
  Nachricht += String(Zeit.tm_mon + 1) + ". ";

  // Zeit anzeigen
  // wenn die Stunde < 10
  if (Zeit.tm_hour < 10) Nachricht += "0";
  Nachricht += String(Zeit.tm_hour) + ":";

  // wenn die Minute < 10
  if (Zeit.tm_min < 10) Nachricht += "0";
  Nachricht+= String(Zeit.tm_min) + " Uhr<br><hr>";
  
  Nachricht += "Temperatur: " + Temperatur + " &degC<br>";
  Nachricht += "Luftfeuchtigkeit: " + Luftfeuchtigkeit + " %<br>";
  Nachricht += "Luftdruck: " + Luftdruck + " hPa<br>";
  Nachricht += "IAQ: " + IAQ + "<br>";
  Nachricht += "Statischer IAQ: " + StatischerIAQ + "<br>";
  Nachricht += "Sch&auml;tzung CO2: " + CO2 + " ppm<br>";
  Nachricht += "Genauigkeit IAQ (0-3): " + String(int(iaqSensor.iaqAccuracy)) + "</div>";

  // Button aktualisieren
  Nachricht += "<hr><input style=\"font-size:16pt; font-weight:bold;";
  Nachricht += "background-color:#55A96B;";
  Nachricht += "display:block; cursor:pointer;\"type=\"button\"";

  // IP für den Button aktualisieren (location.href)
  // muss mit dem Wert für IPAdress übereinstimmen (. statt ,)
  Nachricht += " onClick=\"location.href='http://192.168.1.100'\" value=\"aktualisieren\">";
  Nachricht += "<hr>";

  // Nachricht senden -> Seite anzeigen
  server.send(200, "text/html", Nachricht);
}

Letzte Aktualisierung: Aug 28, 2024 @ 9:43