Manchmal muss beim Hochladen des Programms auf den des ESP32 der Reset-Knopf des ESP gedrückt gehalten werden.
 
Downloads:
Software

Um die Uhrzeit des RTC-Moduls zu setzen muss das Programm "DS3231_set" aus dem Software Ordner benutzt werden.
Anleitung:
1. Climate Cube per Kabel mit dem PC verbinden und dieses Programm hochladen
2. Seriellen Monitor mit der Baud-Rate 57600 öffnen
3. Über die Kommandozeile folgenden Text an den ESP schicken:
    Im Format YYMMDDwHHMMSS mit einem "x" am Ende die aktuelle Uhrzeit senden
    z.B. 28.02.2024 07:52:00 entspricht 2402283075200x
    Die Zeichen setzen sich zusammen aus:
      YY -> Jahr -> 24
      MM -> Monat -> 02
      DD -> Tag -> 28
      w -> Wochentag -> 3 (1=Montag, 2=Dienstag, 3=Mittwoch, 4=Donnerstag, 5=Freitag, 6=Samstag, 0=Sonntag)
      HH -> Stunde -> 07
      MM -> Minute -> 52
      SS -> Sekunde -> 00


Hier als Beispiel der Code zum loggen der Daten auf einer SD-Karte

// Climate Cube V2 Code by Luca Ermentraut - lufraerm@gmail.com

#include "Wire.h"               //I2C library
#include "SHT2x.h"              //URL: https://github.com/RobTillaart/SHT2x
#include "SparkFunCCS811.h"     //Click here to get the library: http://librarymanager/All#SparkFun_CCS811
#include "RTClib.h"             //libraray for real time clock (RTC)
#include "FS.h"                 
#include "SD.h"                 //https://RandomNerdTutorials.com/esp32-microsd-card-arduino/
#include "SPI.h"                //SPI lib to communicate with SD-card module
#include <Adafruit_NeoPixel.h>  //Bibliothek zum Ansteuern der LEDs
#include <BH1750.h>             //Lichtsensor library

#define LED_PIN 2               // Pin zum ansteuern der LEDs
#define LED_COUNT 2             // Anzahl der anzusteuernden LEDs
Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_RGB + NEO_KHZ800); // zum Ansteuern der LEDs

RTC_DS3231 rtc;   //rtc Objekt erstellen

char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}; //Array zum Speichern der Wochentage, werden im seriellen Monitor ausgegeben
String ErrorCodes[10] = {"kein Fehler","schreiben auf SD-Karte Fehler","CO2 Sensor Fehler","schreiben auf SD-Karte Fehler","CO2 Sensor Init Fehler","RTC Fehler","SD Init Fehler","SD-Karte nicht gefunden","RTC Connection lost",""}; //Array für Fehlercodes, werden im seriellen Monitor ausgegeben

const int PIR1_PIN = 4; //Pin für Bewegungssensor
bool movement = false;  //speichert Bewegung (0 oder 1) bis zum nächsten loggen

float temperatureVariable = 25.0; //in degrees C
float humidityVariable = 65.0;    //in % relative
#define CCS811_ADDR 0x5A          //I2C Address for gas sensor
int CO2, CO2_1max, CO2_1min, CO2_2max, CO2_2min, CO2_state;   //CO2 = Speicher CO2 Wert, Genzwerte für CO2 Ampel, CO2_state = aktuelle Farbe der Ampel (0 oder 1 oder 2)


int prevTime = 0;     //Millisekundenspeicher für main loop
int duration = 5000;  //Intervall zum loggen in ms

SHT2x sht;    // sht Objekt erstellen

CCS811 myCCS811(CCS811_ADDR); //CCS811 Objekt erstellen

extern int ErrorCode = 0;   //Speicher für ErrorCodes
bool LedState = false;      //zum Blinken der LEDs im Fehlerfall

BH1750 lightMeter;          //lightMeter Objekt erstellen
float lux = 0;

void setup()
{
  Serial.begin(115200);   //Beginn des seriellen Monitors mit Baudrate
  pinMode(PIR1_PIN, INPUT);   //pinMode Definition für Bewegungssensor

  Wire.begin();   //I2C Initialisierung
  sht.begin();    //SHT Initialisierung
  CCS811_Init();  //CCS811 Initialisierung, siehe unten
  RTC_Init();     //RTC Initialisierung, siehe unten
  SD_Init();      //SD Initialisierung, siehe unten
  strip.begin();  //LED Initialisierung
  lightMeter.begin();   //Lichtsensor Initialisierung

  strip.clear();  // LEDs standardmäßig auf "aus" setzten
  strip.show();   // eingestellte LED-Farbe freigeben

  CO2_1max = 900;   //Grenzwerte für CO2 Ampel
  CO2_1min = 750;
  CO2_2max = 1500;
  CO2_2min = 1350;
  CO2_state = 0;
}


void loop()
{
  if (digitalRead(PIR1_PIN) == 1){    //wird dauerhaft überprüft
  movement = true;
  }
  if ((millis() - prevTime) > duration) {   //alles in Klammer wird im Intervall von duration ausgeführt, siehe https://docs.arduino.cc/built-in-examples/digital/BlinkWithoutDelay/
    prevTime = millis();

  if (ErrorCode == 0){    //wird nur ausgeführt wenn kein Error Code vorhanden ist

    DateTime now = readSensors();   //Sensoren auslesen und aktuelle Uhrzeit zurückgeben
    SerialDebug(now);   //Funtion zur Ausgabe aller Daten auf dem seriellen Monitor, siehe unten
    logData(now);   //Funktion zum loggen auf SD-Karte
    movement = false;   //nach dem loggen wieder auf false setzen
      if ((now.month() > 12) || (now.day() > 31) || (now.hour() > 24) || (now.minute() > 60)){
        ErrorCode = 8;
      }
    }
    LedControl();   // Funktion zum Ansteuern der LEDs
  }
}

DateTime readSensors(){

  sht.read();
  temperatureVariable = sht.getTemperature(); //in degrees C
  humidityVariable = sht.getHumidity();       //in % relative

  myCCS811.setEnvironmentalData(humidityVariable, temperatureVariable);   //für genauere Mesuung werden Werte an Gas Sensor übergeben
  myCCS811.readAlgorithmResults(); //Dump a reading and wait
  delay(1000);

  //temperatureVariable = temperatureVariable - (temperatureVariable * 0.15);
 
  if (myCCS811.dataAvailable()) {
    myCCS811.readAlgorithmResults();  //Calling readAlgorithmResults() function updates the global tVOC and CO2 variables
  }
  else {
    Serial.println("CCS811 Error");
    ErrorCode=2;
  }
  lux = lightMeter.readLightLevel();    //Lichtsensor auslesen
  return rtc.now();
}

void LedControl(){
    if (ErrorCode == 0){
      CO2 = myCCS811.getCO2();

      if ((CO2 > CO2_1max) && (CO2_state == 0)){    //wenn CO2 größer als erster Maximalwert ist -> Ampel von grün auf gelb
        CO2_state = 1;
      }
      if ((CO2 > CO2_2max) && (CO2_state == 1)){    //wenn CO2 größer als zweiter Maximalwert ist -> Ampel von gelb auf rot
        CO2_state = 2;
      }
      if ((CO2 < CO2_1min) && (CO2_state == 1)){    //wenn CO2 kleiner als erster Minimalwert ist -> Ampel von gelb auf grün
        CO2_state = 0;
      }
      if ((CO2 < CO2_2min) && (CO2_state == 2)){    //wenn CO2 kleiner als zwiter Minimalwert ist -> Ampel von rot auf gelb
        CO2_state = 1;
      }

      if (CO2_state == 0){
        strip.setPixelColor(0, strip.Color(0, 10, 0));   // LED_1 soll dauerhaft grün leuchten
        strip.setPixelColor(1, strip.Color(0, 10, 0));   // LED_2 soll dauerhaft grün leuchten
        strip.show();                                     // Freigabe der LEDs
      }
      if (CO2_state == 1){
        strip.setPixelColor(0, strip.Color(10, 8, 0));   // LED_1 soll dauerhaft gelb leuchten
        strip.setPixelColor(1, strip.Color(10, 8, 0));   // LED_2 soll dauerhaft gelb leuchten
        strip.show(); 
      }
      if (CO2_state == 2){
        strip.setPixelColor(0, strip.Color(10, 0, 0));   // LED_1 soll dauerhaft rot leuchten
        strip.setPixelColor(1, strip.Color(10, 0, 0));   // LED_2 soll dauerhaft rot leuchten
        strip.show(); 
      }
    }

    else if (ErrorCode > 0){
      duration = 500;   //Blinkintervall 
      Serial.print("Error Code: ");
      Serial.println(ErrorCode);    //Error Code aufgeben
      Serial.println(ErrorCodes[ErrorCode]);    //Fehler ausgeben

      if (LedState){    //LEDs sollen rot blinken
        strip.setPixelColor(0, strip.Color(255, 0, 0));   //LEDs an
        strip.setPixelColor(1, strip.Color(255, 0, 0));   
        strip.show();
        LedState = !LedState;
      }
      else {
        strip.setPixelColor(0, strip.Color(0, 0, 0));   //LEDs aus
        strip.setPixelColor(1, strip.Color(0, 0, 0));   
       strip.show();
        LedState = !LedState;
      }
    }
}

void SerialDebug(DateTime now){

    

    Serial.println("---------------------------------------");
    Serial.print("Humidity: ");
    Serial.print(humidityVariable);
    Serial.println("% relative");
    Serial.print("Temperature: ");
    Serial.print(temperatureVariable);
    Serial.println(" degrees C");

    Serial.print("CO2[");
    Serial.print(myCCS811.getCO2());
    Serial.print("] tVOC[");
    Serial.print(myCCS811.getTVOC());
    Serial.print("]");
    Serial.println();
    Serial.print("Movement: ");
    Serial.println(movement);
    Serial.print("light intensity: ");
    Serial.print(lux);
    Serial.println(" lux");

    Serial.print(now.year(), DEC);
    Serial.print('/');
    Serial.print(now.month(), DEC);
    Serial.print('/');
    Serial.print(now.day(), DEC);
    Serial.print(" ");
    Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
    Serial.print(" ");
    Serial.print(now.hour(), DEC);
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.print(':');
    Serial.print(now.second(), DEC);
    Serial.println();

    /*Serial.print(" since midnight 1/1/1970 = ");
    Serial.print(now.unixtime());
    Serial.print("s = ");
    Serial.print(now.unixtime() / 86400L);
    Serial.println("d");*/
}

void logData(DateTime now){

    

    String dataString = "";   // String zum Speichern der Daten
	  dataString += String(now.unixtime());   //Daten anhängen
    dataString += ",";                      //durch Komma getrennt -> als CSV importierbar
    dataString += String(myCCS811.getCO2());
    dataString += ",";
    dataString += String(myCCS811.getTVOC()); 
    dataString += ",";
    dataString += String(movement);
    dataString += ",";
    dataString += String(temperatureVariable);
    dataString += ",";
    dataString += String(humidityVariable);
    dataString += ",";
    dataString += String(lux);
    dataString += "\r\n";   //nächste Zeile
    appendFile(SD, "/datalog.txt", dataString.c_str()); //zu Datei auf SD-Karte hinzufügen

}

void appendFile(fs::FS &fs, const char * path, const char * message){
  Serial.printf("Appending to file: %s\n", path);

  File file = fs.open(path, FILE_APPEND);
  if(!file){
    Serial.println("Failed to open file for appending");
    ErrorCode=3;

    return;
  }
  if(file.print(message)){
      Serial.println("Message appended");
  } else {
    Serial.println("Append failed");
    ErrorCode=1;
  }
  file.close();
}

void CCS811_Init(){
  if (myCCS811.begin() == false)
  {
    Serial.print("CCS811 error. Please check wiring. Freezing...");
    ErrorCode=4;
  } 
}

void RTC_Init(){
  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    Serial.flush();
    ErrorCode=5;
  }
}

void SD_Init(){
  if(!SD.begin(5)){
    Serial.println("Card Mount Failed");
    ErrorCode=6;
    return;
  }
  uint8_t cardType = SD.cardType();

  if(cardType == CARD_NONE){
    Serial.println("No SD card attached");
    ErrorCode=7;
    return;
  }
}

//  -- END OF FILE --
Zuletzt geändert: Donnerstag, 29. Februar 2024, 09:57