GruppeC/firmware/dht11_lcd/dht11_lcd.ino

170 lines
4.6 KiB
C++

#include <LiquidCrystal.h>
#include "DHT.h"
#include <Wire.h>
#include "Adafruit_CCS811.h"
// --- LCD Setup ---
// Initialisierung des LCDs mit den Pins aus deinem Schaltplan
// RS = 7, E = 8, D4 = 9, D5 = 10, D6 = 11, D7 = 12
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
// --- DHT11 Setup ---
#define DHTPIN 2 // Der DHT11 Daten-Pin ist an Pin 2 angeschlossen
#define DHTTYPE DHT11 // Sensortyp festlegen
DHT dht(DHTPIN, DHTTYPE);
// --- CJMCU-811 (CCS811) Setup ---
// I2C: SDA = A4, SCL = A5 (Arduino Uno). Der WAK-Pin des Moduls muss an GND liegen.
// Standardadresse 0x5A (ADDR an GND), alternativ 0x5B.
Adafruit_CCS811 ccs;
bool ccsOk = false;
uint8_t ccsAdresse = 0;
// Anzeige wechselt zwischen zwei Seiten, da das LCD nur 2 Zeilen hat
bool zeigeLuftqualitaet = false;
// Debug: sucht alle Geräte am I2C-Bus und gibt die Adressen im Serial Monitor aus.
// Der CCS811 muss bei 0x5A oder 0x5B auftauchen.
void scanneI2C() {
Serial.println(F("I2C-Scan..."));
uint8_t gefunden = 0;
for (uint8_t adr = 1; adr < 127; adr++) {
Wire.beginTransmission(adr);
if (Wire.endTransmission() == 0) {
Serial.print(F(" Geraet bei 0x"));
Serial.println(adr, HEX);
gefunden++;
}
}
if (gefunden == 0) {
Serial.println(F(" KEIN Geraet gefunden -> SDA/SCL, GND, VCC, Loetstellen pruefen"));
}
}
void setup() {
// Serial Monitor (9600 Baud) für Debug-Ausgaben
Serial.begin(9600);
Serial.println(F("--- Start ---"));
// LCD initialisieren (16 Spalten, 2 Zeilen)
lcd.begin(16, 2);
// DHT Sensor starten
dht.begin();
// I2C-Bus durchsuchen (nur zum Debuggen)
Wire.begin();
scanneI2C();
// CCS811 starten: erst 0x5A (ADDR an GND), dann 0x5B (ADDR an VCC)
ccsOk = ccs.begin(0x5A);
if (ccsOk) {
ccsAdresse = 0x5A;
} else if (ccs.begin(0x5B)) {
ccsOk = true;
ccsAdresse = 0x5B;
}
if (ccsOk) {
Serial.print(F("CCS811 OK bei 0x"));
Serial.println(ccsAdresse, HEX);
} else {
Serial.println(F("CCS811 begin() fehlgeschlagen (0x5A und 0x5B)"));
}
// Kurze Startnachricht
lcd.setCursor(0, 0);
lcd.print("Sensor startet..");
lcd.setCursor(0, 1);
if (ccsOk) {
lcd.print("CCS811 @0x");
lcd.print(ccsAdresse, HEX);
} else {
lcd.print("CCS811 nicht da");
}
// Der DHT11 braucht nach dem Start einen Moment
delay(2000);
lcd.clear();
}
void loop() {
// WICHTIG: Der DHT11 ist ein langsamer Sensor.
// Er benötigt ca. 2 Sekunden Pause zwischen den Messungen.
delay(2000);
// Werte für Luftfeuchtigkeit und Temperatur auslesen
float h = dht.readHumidity();
float t = dht.readTemperature();
// Überprüfen, ob das Auslesen fehlgeschlagen ist (z.B. Kabel locker)
Serial.print(F("DHT11: T="));
Serial.print(t, 1);
Serial.print(F(" C, H="));
Serial.print(h, 1);
Serial.println(F(" %"));
if (isnan(h) || isnan(t)) {
Serial.println(F("DHT11 FEHLER: NaN -> Daten-Pin 2, VCC/GND, Pull-up pruefen"));
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Sensor Fehler!");
return; // Loop hier abbrechen und von vorne starten
}
// --- Seite 2: CO2 und TVOC vom CCS811 ---
if (zeigeLuftqualitaet) {
zeigeLuftqualitaet = false;
lcd.clear();
if (!ccsOk) {
Serial.println(F("CCS811: nicht initialisiert"));
lcd.setCursor(0, 0);
lcd.print("CCS811 Fehler!");
return;
}
// Temperatur/Feuchte zur Kompensation an den CCS811 geben
ccs.setEnvironmentalData(h, t);
bool bereit = ccs.available();
bool lesefehler = bereit ? ccs.readData() : false;
if (bereit && !lesefehler) {
Serial.print(F("CCS811: eCO2="));
Serial.print(ccs.geteCO2());
Serial.print(F(" ppm, TVOC="));
Serial.print(ccs.getTVOC());
Serial.println(F(" ppb"));
lcd.setCursor(0, 0);
lcd.print("CO2: ");
lcd.print(ccs.geteCO2());
lcd.print(" ppm");
lcd.setCursor(0, 1);
lcd.print("TVOC: ");
lcd.print(ccs.getTVOC());
lcd.print(" ppb");
} else {
Serial.println(bereit ? F("CCS811: Lesefehler")
: F("CCS811: noch keine Daten (Aufwaermphase)"));
lcd.setCursor(0, 0);
lcd.print("CCS811 wartet..");
}
return;
}
// --- Seite 1: Ausgabe auf dem LCD Display ---
zeigeLuftqualitaet = true;
// Zeile 1: Temperatur
lcd.setCursor(0, 0); // Spalte 0, Zeile 0
lcd.print("Temp: ");
lcd.print(t, 1); // Die ", 1" sorgt dafür, dass nur eine Nachkommastelle gezeigt wird
lcd.print(" C "); // Leerzeichen am Ende überschreiben eventuelle alte Zeichen
// Zeile 2: Luftfeuchtigkeit
lcd.setCursor(0, 1); // Spalte 0, Zeile 1
lcd.print("Luft: ");
lcd.print(h, 1);
lcd.print(" % ");
}