Hallo liebes Forum,
ich habe aktuell das Problem das der ESP32, welche als Wetterstation genutzt wird, immer an einer bestimmten Stelle abstürzt. Die Abstürze an sich sind unregelmäßig. Tatsächlich bin ich hier überfragt, das übersteigt meine Kenntnisse und bin über jede Hilfe sehr dankbar
Vom ESP-Exception-Decoder bekomme ich diese Fehlermeldung:
Decoding stack results
0x40101a5a: isNumeric(char const*) at D:\Migel\OneDrive\Cloud Dokumente\Projekte\EPS32 Wetterstation\EPS32 Wetterstation\Empfanger/Empfanger.ino line 138
0x400d2196: teileDaten(String) at D:\Migel\OneDrive\Cloud Dokumente\Projekte\EPS32 Wetterstation\EPS32 Wetterstation\Empfanger/Empfanger.ino line 184
0x400d28b6: loop() at D:\Migel\OneDrive\Cloud Dokumente\Projekte\EPS32 Wetterstation\EPS32 Wetterstation\Empfanger/Empfanger.ino line 105
0x400da921: loopTask(void*) at D:\Apps\arduino-1.8.19\portable\packages\esp32\hardware\esp32\2.0.14\cores\esp32\main.cpp line 50
Der Code der Basisstation:
/*****************************************************************************************
HC12 ----------------------> G26>RX // G27>TX
RTC DS3231 ----------------> G21>SDA // G22>SCL
TFT ILI9488 ---------------> G23>MOSI // G18>SCK // G4>RESET // G2>DC // G32>CS // G15>LED
DHT22 ---------------------> G25>DHT
BEWEGUNGSSENSOR -----------> G12>PIR
******************************************************************************************/
#include <Wire.h>
#include "DHT.h"
#include <SoftwareSerial.h>
SoftwareSerial HC12Serial(26, 27);
#define DHTPIN 25
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
#include "RTClib.h"
RTC_DS3231 rtc;
#include <TFT_eSPI.h>
TFT_eSPI tft = TFT_eSPI();
#include "GfxUi.h"
GfxUi ui = GfxUi(&tft);
#define AA_FONT_FONT1 "fonts/NirmalaUI-Bold-45"
#define AA_FONT_FONT2 "fonts/Calibri-Light-25"
#define AA_FONT_FONT3 "fonts/Calibri-25"
const int pirSensorPin = 33; // Pin, an dem der PIR-Sensor angeschlossen ist
const int ledPin = 15; // Pin für die LED
bool motionDetected = false;
unsigned long motionTimestamp = 0;
const unsigned long motionDuration = 15000; // 15 Sekunden
unsigned long lastSensorUpdateTime = 0;
const unsigned long sensorUpdateInterval = 120000; // 300000 = 5 minutes in milliseconds
boolean isSummer; // Globale Variable deklarieren
unsigned long lastReceiveTimestamp = 0; // Zuletzt empfangener Zeitstempel
void adjustForDST(DateTime &d)
{
if (isSummer)
{
d = d + TimeSpan(0,1,0,0);
}
}
void setup()
{
SPIFFS.begin();
HC12Serial.begin(4800);
Serial.begin(115200);
Wire.begin(SDA, SCL);
dht.begin();
rtc.begin();
pinMode(pirSensorPin, INPUT); // PIR-Sensor als Eingang konfigurieren
pinMode(ledPin, OUTPUT);
tft.init();
tft.setRotation(3);
tft.fillScreen(TFT_WHITE);
tft.fillRect(6, 6, 468, 308, TFT_GOLD); // Darstellungsfläche, Rechteck abzüglich der Ränder
tft.fillRect(6, 105, 468, 6, TFT_WHITE); // Erster Querteiler
tft.fillRect(6, 209, 468, 6, TFT_WHITE); // Zweiter Querteiler
tft.fillRect(234, 105, 6, 234, TFT_WHITE); // Längsteiler
tft.setTextColor(TFT_BLACK);
tft.loadFont(AA_FONT_FONT3);
tft.drawString("Feuchtigkeit", 307, 123); // Außen Feuchtigkeit
tft.drawString("Temperatur", 71, 123); // Außen Temperatur
tft.drawString("Temperatur", 71, 225); // Innen Temperatur
tft.drawString("Feuchtigkeit", 307, 225); // Innen Feuchtigkeit
if (SPIFFS.exists("/bilder/OUT.bmp") == true)
ui.drawBmp("/bilder/IN.bmp",247, 222+0); // Innen Feuchtigkeit
ui.drawBmp("/bilder/OUT.bmp",247, 119+0); // Außen Feuchtigkeit
ui.drawBmp("/bilder/OUT.bmp",14, 119+0); // Außen Temperatur
ui.drawBmp("/bilder/IN.bmp",14, 222+0); // Innen Temperatur
lastSensorUpdateTime = millis(); // Initialize the update time
readAndPrintSensorData(); // Initial display of DHT sensor values
}
void loop()
{
if (HC12Serial.available())
{
String receivedData = HC12Serial.readString();
lastReceiveTimestamp = millis(); // Aktualisiere den Zeitstempel
teileDaten(receivedData); ////////////////////////////////////////////////////////////////////
}
unsigned long currentMillis = millis();
int motionState = digitalRead(pirSensorPin); // PIR-Sensor abfragen
if (motionState == HIGH && !motionDetected)
{
digitalWrite(ledPin, HIGH); // LED einschalten, bei bewegung
motionDetected = true; // Bewegung gesetzt
motionTimestamp = millis(); // Zeitstempel für die Bewegung speichern
}
if (motionDetected && (currentMillis - motionTimestamp >= motionDuration))
{
digitalWrite(ledPin, LOW); // LED ausschalten, nach der angegebenen Zeit
motionDetected = false; // Zurücksetzen der Bewegungserkennung
}
if (currentMillis - lastSensorUpdateTime >= sensorUpdateInterval) // Sensordaten aktualisieren
readAndPrintSensorData(), lastSensorUpdateTime = currentMillis;
readAndPrintRTC();
}
void motionInterrupt()
{
motionDetected = true;
}
bool isNumeric(const char *str)
{
bool hasDigit = false; // Flag für Ziffern
for (int i = 0; str[i] != '\0'; i++)
{
if (!isdigit(str[i]) && str[i] != '-' && str[i] != '.' && str[i] != ',') ////////////////////////////////////////////////////////////////////
{
return false; // Andere Zeichen sind nicht erlaubt
}
else if (isdigit(str[i]))
{
hasDigit = true; // Setze das Flag für Ziffern
}
}
return hasDigit; // Es muss mindestens eine Ziffer vorhanden sein
}
String removeNonPrintableAndSpaces(String data) {
String result = "";
for (char c : data) {
if (isprint(c) && c != ' ') {
result += c;
}
}
return result;
}
void teileDaten(String daten)
{
// Entferne alle nicht druckbaren Zeichen aus dem Datenstring
daten = removeNonPrintableAndSpaces(daten);
char *daten2 = new char[daten.length() + 1];
strcpy(daten2, daten.c_str());
if (daten.length() > 17) // Überprüfung der maximalen Länge des Datenstrings
{
delete[] daten2;
return;
}
char *Part0 = strtok(daten2, ","); // Für Temp
char *Part1 = strtok(NULL, ","); // Für Humidity
char *Part2 = strtok(NULL, ","); // Für VCC
if (Part0 == NULL || Part1 == NULL || Part2 == NULL || !isNumeric(Part0) || !isNumeric(Part1) || !isNumeric(Part2)) // Weitere Überprüfungen für die numerischen Werte
{
delete[] daten2;
return;
}
float tempValue = atof(Part0);
int humidityValue = atoi(Part1);
float vccValue = atof(Part2);
// Weitere Verarbeitung der Daten, da sie gültig sind
float maxVcc = 4.87; // Maximaler VCC-Wert
float minVcc = 3.3; // Minimaler VCC-Wert
int vccPercentage = int(((vccValue - minVcc) / (maxVcc - minVcc)) * 100); // Umrechnung des VCC-Werts in Prozent mit Berücksichtigung des Minimalwerts
vccPercentage = max(0, min(100, vccPercentage)); // Begrenzen des Prozentwert auf den Bereich von 0 bis 100
tft.setTextDatum(BR_DATUM);
tft.loadFont(AA_FONT_FONT1);
tft.setTextColor(TFT_BLACK, TFT_WHITE);
tft.setTextPadding(tft.textWidth("88.8 88"));
String tempString = String(Part0);
if (tempString.toFloat() < 0)
{
tempString = "-" + tempString.substring(1);
}
tft.drawString(tempString + " °C", 223, 201); // OUT Temp
tft.setTextPadding(tft.textWidth("888 8"));
tft.drawString(String(Part1) + " %", 463, 201); // OUT Humidity
DateTime now = rtc.now();
check_SummerTime(); // Aufruf der Funktion zur Überprüfung der Sommerzeit
adjustForDST(now);
char timeDisplay[16];
sprintf(timeDisplay, "%.02d:%02d", now.hour(), now.minute());
tft.setTextDatum(CC_DATUM);
tft.loadFont(AA_FONT_FONT2);
if (vccValue < 3.3)
{
tft.setTextPadding(tft.textWidth("88888888888888."));
tft.setTextColor(TFT_BLACK, TFT_GOLD); // Text in Rot einfärben
tft.drawString("Status: " + String(timeDisplay) + ", Batt is low: " + String(Part2) + " V, " + String(vccPercentage) + "% ", 240, 85 );
} else {
tft.setTextColor(TFT_BLACK, TFT_GOLD);
tft.setTextPadding(tft.textWidth("888888888888888."));
tft.drawString("Status: " + String(timeDisplay) + ", Batt Voltage: " + String(Part2) + " V, " + String(vccPercentage) + "% ", 240 , 85);
Serial.println(String(Part2) + " V, " + String(vccPercentage) + "% "); // Ausgabe auf dem seriellen Monitor, zur überprüfung
}
tft.unloadFont(); // Aufräumen
tft.setTextPadding(0);
delete[] daten2;
}
void readAndPrintSensorData()
{
float Temperatur = dht.readTemperature();
float Luftfeuchtigkeit = dht.readHumidity();
tft.setTextDatum(BR_DATUM);
tft.loadFont(AA_FONT_FONT1);
tft.setTextColor(TFT_BLACK, TFT_WHITE);
tft.setTextPadding(tft.textWidth("88.8 88"));
tft.drawString(String(Temperatur, 1) + " °C", 223, 305); // IN Temp
tft.setTextPadding(tft.textWidth("888 8"));
tft.drawString(String((int)Luftfeuchtigkeit) + " %", 463 , 305); // IN Humidity
tft.unloadFont();
tft.setTextPadding(0);
}
void check_SummerTime()
{
DateTime now = rtc.now();
isSummer = summertime_EU(now.year(), now.month(), now.day(), now.hour(), 1);
}
boolean summertime_EU(int year, byte month, byte day, byte hour, byte tzHours)
{
if (month < 3 || month > 10) return false;
if (month > 3 && month < 10) return true;
if (month == 3 && (hour + 24 * day) >= (1 + tzHours + 24 * (31 - (5 * year / 4 + 4) % 7)) || month == 10 && (hour + 24 * day) < (1 + tzHours + 24 * (31 - (5 * year / 4 + 1) % 7)))
return true;
else
return false;
}
void readAndPrintRTC()
{
DateTime now = rtc.now();
check_SummerTime(); // Aufruf der Funktion zur Überprüfung der Sommerzeit
adjustForDST(now);
char dateDisplay[15];
char timeDisplay[15];
sprintf(dateDisplay, "%.02d.%.02d.%.2d", now.day(), now.month(), now.year());
if (millis() % 1000 < 500) // Uhrzeit Doppelpunkt im Sekundentakt blinken lassen
{
sprintf(timeDisplay, "%.02d:%02d", now.hour(), now.minute());
}
else
{
sprintf(timeDisplay, "%.02d %02d", now.hour(), now.minute());
}
tft.setTextDatum(CC_DATUM);
tft.loadFont(AA_FONT_FONT1); // Datum
tft.setTextColor(TFT_BLACK, TFT_GOLD);
tft.setTextPadding(tft.textWidth("88.88.88"));
tft.drawString(String(timeDisplay) + " " + String(dateDisplay), 240, 45);
tft.unloadFont(); // Font entladen und TextPadding zurücksetzen
tft.setTextPadding(0);
}
Ich sage schonmal vielen Dank für jede Hilfe die ich bekommen kann🙂