From 017fac3d2ba29578ddf2aad581fbc055ca996914 Mon Sep 17 00:00:00 2001 From: 3020772 <3020772@stud.hs-mannheim.de> Date: Tue, 13 Oct 2026 11:19:49 +0200 Subject: [PATCH] CCS811: Adresserkennung, Serial-Debug und eigener Testsketch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - dht11_lcd: CCS811 an 0x5A und 0x5B probieren, I2C-Scan und Serial-Ausgabe zum Debuggen - ccs811_test: eigener Sketch nur für den CCS811 mit Konsolenausgabe Co-Authored-By: Claude Sonnet 5.5 --- firmware/ccs811_test/ccs811_test.ino | 75 ++++++++++++++++++++++++++++ firmware/dht11_lcd/dht11_lcd.ino | 67 ++++++++++++++++++++++++- 2 files changed, 140 insertions(+), 2 deletions(-) create mode 100644 firmware/ccs811_test/ccs811_test.ino diff --git a/firmware/ccs811_test/ccs811_test.ino b/firmware/ccs811_test/ccs811_test.ino new file mode 100644 index 0000000..4c53974 --- /dev/null +++ b/firmware/ccs811_test/ccs811_test.ino @@ -0,0 +1,75 @@ +#include +#include "Adafruit_CCS811.h" + +// Reiner CCS811-Test (CJMCU-811) ohne LCD und DHT11. Ausgabe im Serial Monitor (9600 Baud). +// I2C: SDA = A4, SCL = A5 (Arduino Uno). WAK und ADD des Moduls an GND -> Adresse 0x5A. +// Mit ADD an VCC lautet die Adresse 0x5B. + +Adafruit_CCS811 ccs; +bool ccsOk = false; + +// Sucht alle Geräte am I2C-Bus. 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, WAK, Loetstellen pruefen")); + } +} + +void setup() { + Serial.begin(9600); + Serial.println(F("--- CCS811-Test ---")); + + Wire.begin(); + scanneI2C(); + + // Erst 0x5A (ADD an GND), dann 0x5B (ADD an VCC) + uint8_t adresse = 0x5A; + ccsOk = ccs.begin(0x5A); + if (!ccsOk) { + adresse = 0x5B; + ccsOk = ccs.begin(0x5B); + } + + if (ccsOk) { + Serial.print(F("CCS811 OK bei 0x")); + Serial.println(adresse, HEX); + Serial.println(F("Aufwaermphase: die ersten Werte sind oft 400 ppm / 0 ppb.")); + } else { + Serial.println(F("CCS811 begin() fehlgeschlagen (0x5A und 0x5B)")); + } +} + +void loop() { + delay(1000); + + if (!ccsOk) { + Serial.println(F("CCS811: nicht initialisiert")); + return; + } + + if (!ccs.available()) { + Serial.println(F("CCS811: noch keine neuen Daten")); + return; + } + + if (ccs.readData()) { + Serial.println(F("CCS811: Lesefehler")); + return; + } + + Serial.print(F("eCO2: ")); + Serial.print(ccs.geteCO2()); + Serial.print(F(" ppm TVOC: ")); + Serial.print(ccs.getTVOC()); + Serial.println(F(" ppb")); +} diff --git a/firmware/dht11_lcd/dht11_lcd.ino b/firmware/dht11_lcd/dht11_lcd.ino index 693a100..0672b74 100644 --- a/firmware/dht11_lcd/dht11_lcd.ino +++ b/firmware/dht11_lcd/dht11_lcd.ino @@ -18,23 +18,69 @@ DHT dht(DHTPIN, DHTTYPE); // 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(); - // CCS811 starten + // 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); @@ -51,7 +97,14 @@ void loop() { 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!"); @@ -64,6 +117,7 @@ void loop() { lcd.clear(); if (!ccsOk) { + Serial.println(F("CCS811: nicht initialisiert")); lcd.setCursor(0, 0); lcd.print("CCS811 Fehler!"); return; @@ -72,7 +126,14 @@ void loop() { // Temperatur/Feuchte zur Kompensation an den CCS811 geben ccs.setEnvironmentalData(h, t); - if (ccs.available() && !ccs.readData()) { + 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()); @@ -83,6 +144,8 @@ void loop() { 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.."); }