Anonymous
ESP32S3 Тайм-аут WDT и сбой ядра с модулем LoRa rfm95w
Сообщение
Anonymous » 11 фев 2026, 23:41
Привет, сообщество Stack!
Последние пару недель я работаю над проектом, и меня постоянно что-то поражает. Я использую плату rfm95w для передачи данных других станций и собственных данных станций на центральный сервер esp32. При использовании указанного кода реле происходит сбой либо из-за тайм-аута WDT, либо из-за паники ядра 1 после некоторого времени отправки двух пакетов данных. вот указанный код.
Код: Выделить всё
#include
#include
#include "SHTSensor.h"
#include
#include
#include
// -------- Konstanten --------
#define ID 0x00
#define MAX_SENSORS 5
#define PACKET_TYPE_SENSOR 0xA1
#define MASTER_NAME "Schulgarten"
// -------- Datenstrukturen --------
typedef struct __attribute__((packed)) {
int8_t id = -1;
float temperatur;
float humidity;
int32_t pressure;
char name[15] = "X";
} sensorDaten;
typedef struct __attribute__((packed)) {
sensorDaten sensors[MAX_SENSORS];
} finalDaten;
// -------- Globale Variablen --------
sensorDaten daten;
finalDaten unified;
SHTSensor sht(SHTSensor::SHT3X);
Adafruit_BME280 bme;
unsigned long lastSendTime = 0;
const unsigned long SEND_INTERVAL = 30000;
bool shtAvailable = false;
bool bmeAvailable = false;
bool loraAvailable = false;
// -------- Setup --------
void setup() {
Serial.begin(115200);
delay(2000);
Serial.println("\n\n====================================");
Serial.println(" LoRa Sensor Mittelmann");
Serial.println(" (Interrupt-Fix Version)");
Serial.println("====================================");
Serial.printf("✓ Heap: %d bytes\n\n", ESP.getFreeHeap());
// Strukturen initialisieren
memset(&unified, 0, sizeof(unified));
for (int i = 0; i < MAX_SENSORS; i++) {
unified.sensors[i].id = -1;
}
// I2C
Wire.begin();
Wire.setClock(100000);
delay(50);
// SPI
SPI.begin(12, 13, 11, 10);
SPI.setFrequency(1000000);
delay(50);
// SHT3X Sensor
if (sht.init()) {
sht.setAccuracy(SHTSensor::SHT_ACCURACY_MEDIUM);
shtAvailable = true;
Serial.println("✓ SHT3X bereit");
} else {
Serial.println("✗ SHT3X nicht gefunden");
}
// BME280 Sensor
if (bme.begin(0x76)) {
bmeAvailable = true;
Serial.println("✓ BME280 bereit");
} else {
Serial.println("✗ BME280 nicht gefunden");
}
// LoRa Modul - OHNE DIO0 Interrupt!
LoRa.setPins(10, 3, -1); // CS=10, Reset=3, DIO0=-1 (deaktiviert!)
LoRa.setSPIFrequency(1000000);
delay(100);
if (LoRa.begin(868E6)) {
LoRa.setSpreadingFactor(7);
LoRa.setSignalBandwidth(125E3);
LoRa.setSyncWord(0x12);
LoRa.enableCrc();
delay(50);
LoRa.receive();
loraAvailable = true;
Serial.println("✓ LoRa bereit (868 MHz, SF7, polling mode)");
} else {
Serial.println("✗ LoRa FEHLER - KRITISCH!");
}
Serial.println("\n====================================");
Serial.printf("Sensoren: SHT=%d | BME=%d | LoRa=%d\n",
shtAvailable, bmeAvailable, loraAvailable);
Serial.printf("Heap: %d bytes\n", ESP.getFreeHeap());
Serial.println("====================================\n");
if (!loraAvailable) {
Serial.println("FEHLER: System gestoppt - LoRa erforderlich!");
while (1) {
delay(5000);
}
}
Serial.println("System gestartet - Sende-Intervall: 30s\n");
}
// -------- Hauptloop --------
void loop() {
static uint32_t cycleCount = 0;
// Status alle 10 Sekunden
if (++cycleCount % 100 == 0) {
Serial.printf("[System] Läuft | Heap: %d bytes\n", ESP.getFreeHeap());
}
// Senden alle 30 Sekunden
if (millis() - lastSendTime >= SEND_INTERVAL) {
lastSendTime = millis();
Serial.println("\n========== SENDE-ZYKLUS ==========");
sendSensorData();
Serial.println("==================================\n");
}
// Empfangen (non-blocking polling)
receiveData();
delay(100);
}
// -------- Sensordaten senden --------
void sendSensorData() {
if (!loraAvailable) {
Serial.println("Fehler: LoRa nicht verfügbar");
return;
}
// Sensoren auslesen
float temp = 0, hum = 0;
if (shtAvailable && sht.readSample()) {
temp = sht.getTemperature();
hum = sht.getHumidity();
}
int32_t pressure = 0;
if (bmeAvailable) {
pressure = bme.readPressure() / 100;
}
// Struktur füllen
unified.sensors[0].id = ID;
unified.sensors[0].temperatur = temp;
unified.sensors[0].humidity = hum;
unified.sensors[0].pressure = pressure;
strncpy(unified.sensors[0].name, MASTER_NAME, 14);
unified.sensors[0].name[14] = '\0';
Serial.printf("Daten: %.1f°C | %.1f%% | %d hPa\n", temp, hum, pressure);
// LoRa vorbereiten
LoRa.idle();
delay(10);
// Paket erstellen
if (!LoRa.beginPacket()) {
Serial.println("✗ Senden fehlgeschlagen (beginPacket)");
LoRa.receive();
return;
}
// Header
LoRa.write(PACKET_TYPE_SENSOR);
LoRa.write(ID);
// Größe
uint16_t size = sizeof(unified);
LoRa.write((size >> 8) & 0xFF);
LoRa.write(size & 0xFF);
// Daten schreiben
uint8_t *ptr = (uint8_t *)&unified;
for (uint16_t i = 0; i < size; i += 32) {
uint16_t chunk = min(32, size - i);
LoRa.write(ptr + i, chunk);
yield(); // System-Tasks Zeit geben
}
// Senden - jetzt ohne Interrupt-Probleme
bool success = LoRa.endPacket(true); // synchron ist jetzt OK
if (success) {
Serial.println("✓ Erfolgreich gesendet");
} else {
Serial.println("✗ Senden fehlgeschlagen (endPacket)");
}
// Zurück zu Empfangsmodus
delay(100);
LoRa.receive();
}
// -------- Daten empfangen (Polling-Modus) --------
void receiveData() {
if (!loraAvailable) return;
// Polling statt Interrupt
int packetSize = LoRa.parsePacket();
if (packetSize == 0) return;
Serial.printf("\n[Empfang] %d bytes | RSSI: %d dBm\n",
packetSize, LoRa.packetRssi());
// Paket zu klein
if (packetSize < 4) {
Serial.println("✗ Paket zu klein");
while (LoRa.available()) LoRa.read();
return;
}
// Header lesen
byte type = LoRa.read();
byte senderID = LoRa.read();
// Validierung
if (type != PACKET_TYPE_SENSOR) {
Serial.printf("✗ Falscher Typ: 0x%02X\n", type);
while (LoRa.available()) LoRa.read();
return;
}
if (senderID >= MAX_SENSORS || senderID == ID) {
Serial.printf("✗ Ungültige Sender-ID: %d\n", senderID);
while (LoRa.available()) LoRa.read();
return;
}
// Größe lesen
if (LoRa.available() < 2) {
Serial.println("✗ Größenfeld fehlt");
while (LoRa.available()) LoRa.read();
return;
}
uint16_t size = (LoRa.read() = sizeof(sensorDaten)) {
uint8_t *ptr = (uint8_t *)&daten;
for (size_t i = 0; i < sizeof(sensorDaten); i++) {
if (LoRa.available()) {
ptr[i] = LoRa.read();
}
}
// Daten speichern wenn ID stimmt
if (daten.id == senderID) {
unified.sensors[senderID] = daten;
Serial.printf("✓ Sensor-ID %d: %.1f°C | %.1f%% | %d hPa | '%s'\n",
senderID, daten.temperatur, daten.humidity,
daten.pressure, daten.name);
} else {
Serial.printf("✗ ID-Konflikt: Header=%d, Daten=%d\n", senderID, daten.id);
}
} else {
Serial.printf("✗ Größenfehler: Erwartet %d, Empfangen %d\n",
sizeof(sensorDaten), size);
}
// Restlichen Puffer leeren
while (LoRa.available()) {
LoRa.read();
}
}
Я уже искал помощь через github copilot, откуда и приходят комментарии на немецком языке. К сожалению, ИИ не смог мне помочь, но я думаю, что сбой тайм-аута WDT как-то связан с прерываниями DIO0 для приема пакетов, хотя он всегда вылетает в LoRa.endPacket(true);
Надеюсь, вы поможете с моей ошибкой.
Подробнее здесь:
https://stackoverflow.com/questions/798 ... ule-rfm95w
1770842460
Anonymous
Привет, сообщество Stack! Последние пару недель я работаю над проектом, и меня постоянно что-то поражает. Я использую плату rfm95w для передачи данных других станций и собственных данных станций на центральный сервер esp32. При использовании указанного кода реле происходит сбой либо из-за тайм-аута WDT, либо из-за паники ядра 1 после некоторого времени отправки двух пакетов данных. вот указанный код. [code]#include #include #include "SHTSensor.h" #include #include #include // -------- Konstanten -------- #define ID 0x00 #define MAX_SENSORS 5 #define PACKET_TYPE_SENSOR 0xA1 #define MASTER_NAME "Schulgarten" // -------- Datenstrukturen -------- typedef struct __attribute__((packed)) { int8_t id = -1; float temperatur; float humidity; int32_t pressure; char name[15] = "X"; } sensorDaten; typedef struct __attribute__((packed)) { sensorDaten sensors[MAX_SENSORS]; } finalDaten; // -------- Globale Variablen -------- sensorDaten daten; finalDaten unified; SHTSensor sht(SHTSensor::SHT3X); Adafruit_BME280 bme; unsigned long lastSendTime = 0; const unsigned long SEND_INTERVAL = 30000; bool shtAvailable = false; bool bmeAvailable = false; bool loraAvailable = false; // -------- Setup -------- void setup() { Serial.begin(115200); delay(2000); Serial.println("\n\n===================================="); Serial.println(" LoRa Sensor Mittelmann"); Serial.println(" (Interrupt-Fix Version)"); Serial.println("===================================="); Serial.printf("✓ Heap: %d bytes\n\n", ESP.getFreeHeap()); // Strukturen initialisieren memset(&unified, 0, sizeof(unified)); for (int i = 0; i < MAX_SENSORS; i++) { unified.sensors[i].id = -1; } // I2C Wire.begin(); Wire.setClock(100000); delay(50); // SPI SPI.begin(12, 13, 11, 10); SPI.setFrequency(1000000); delay(50); // SHT3X Sensor if (sht.init()) { sht.setAccuracy(SHTSensor::SHT_ACCURACY_MEDIUM); shtAvailable = true; Serial.println("✓ SHT3X bereit"); } else { Serial.println("✗ SHT3X nicht gefunden"); } // BME280 Sensor if (bme.begin(0x76)) { bmeAvailable = true; Serial.println("✓ BME280 bereit"); } else { Serial.println("✗ BME280 nicht gefunden"); } // LoRa Modul - OHNE DIO0 Interrupt! LoRa.setPins(10, 3, -1); // CS=10, Reset=3, DIO0=-1 (deaktiviert!) LoRa.setSPIFrequency(1000000); delay(100); if (LoRa.begin(868E6)) { LoRa.setSpreadingFactor(7); LoRa.setSignalBandwidth(125E3); LoRa.setSyncWord(0x12); LoRa.enableCrc(); delay(50); LoRa.receive(); loraAvailable = true; Serial.println("✓ LoRa bereit (868 MHz, SF7, polling mode)"); } else { Serial.println("✗ LoRa FEHLER - KRITISCH!"); } Serial.println("\n===================================="); Serial.printf("Sensoren: SHT=%d | BME=%d | LoRa=%d\n", shtAvailable, bmeAvailable, loraAvailable); Serial.printf("Heap: %d bytes\n", ESP.getFreeHeap()); Serial.println("====================================\n"); if (!loraAvailable) { Serial.println("FEHLER: System gestoppt - LoRa erforderlich!"); while (1) { delay(5000); } } Serial.println("System gestartet - Sende-Intervall: 30s\n"); } // -------- Hauptloop -------- void loop() { static uint32_t cycleCount = 0; // Status alle 10 Sekunden if (++cycleCount % 100 == 0) { Serial.printf("[System] Läuft | Heap: %d bytes\n", ESP.getFreeHeap()); } // Senden alle 30 Sekunden if (millis() - lastSendTime >= SEND_INTERVAL) { lastSendTime = millis(); Serial.println("\n========== SENDE-ZYKLUS =========="); sendSensorData(); Serial.println("==================================\n"); } // Empfangen (non-blocking polling) receiveData(); delay(100); } // -------- Sensordaten senden -------- void sendSensorData() { if (!loraAvailable) { Serial.println("Fehler: LoRa nicht verfügbar"); return; } // Sensoren auslesen float temp = 0, hum = 0; if (shtAvailable && sht.readSample()) { temp = sht.getTemperature(); hum = sht.getHumidity(); } int32_t pressure = 0; if (bmeAvailable) { pressure = bme.readPressure() / 100; } // Struktur füllen unified.sensors[0].id = ID; unified.sensors[0].temperatur = temp; unified.sensors[0].humidity = hum; unified.sensors[0].pressure = pressure; strncpy(unified.sensors[0].name, MASTER_NAME, 14); unified.sensors[0].name[14] = '\0'; Serial.printf("Daten: %.1f°C | %.1f%% | %d hPa\n", temp, hum, pressure); // LoRa vorbereiten LoRa.idle(); delay(10); // Paket erstellen if (!LoRa.beginPacket()) { Serial.println("✗ Senden fehlgeschlagen (beginPacket)"); LoRa.receive(); return; } // Header LoRa.write(PACKET_TYPE_SENSOR); LoRa.write(ID); // Größe uint16_t size = sizeof(unified); LoRa.write((size >> 8) & 0xFF); LoRa.write(size & 0xFF); // Daten schreiben uint8_t *ptr = (uint8_t *)&unified; for (uint16_t i = 0; i < size; i += 32) { uint16_t chunk = min(32, size - i); LoRa.write(ptr + i, chunk); yield(); // System-Tasks Zeit geben } // Senden - jetzt ohne Interrupt-Probleme bool success = LoRa.endPacket(true); // synchron ist jetzt OK if (success) { Serial.println("✓ Erfolgreich gesendet"); } else { Serial.println("✗ Senden fehlgeschlagen (endPacket)"); } // Zurück zu Empfangsmodus delay(100); LoRa.receive(); } // -------- Daten empfangen (Polling-Modus) -------- void receiveData() { if (!loraAvailable) return; // Polling statt Interrupt int packetSize = LoRa.parsePacket(); if (packetSize == 0) return; Serial.printf("\n[Empfang] %d bytes | RSSI: %d dBm\n", packetSize, LoRa.packetRssi()); // Paket zu klein if (packetSize < 4) { Serial.println("✗ Paket zu klein"); while (LoRa.available()) LoRa.read(); return; } // Header lesen byte type = LoRa.read(); byte senderID = LoRa.read(); // Validierung if (type != PACKET_TYPE_SENSOR) { Serial.printf("✗ Falscher Typ: 0x%02X\n", type); while (LoRa.available()) LoRa.read(); return; } if (senderID >= MAX_SENSORS || senderID == ID) { Serial.printf("✗ Ungültige Sender-ID: %d\n", senderID); while (LoRa.available()) LoRa.read(); return; } // Größe lesen if (LoRa.available() < 2) { Serial.println("✗ Größenfeld fehlt"); while (LoRa.available()) LoRa.read(); return; } uint16_t size = (LoRa.read() = sizeof(sensorDaten)) { uint8_t *ptr = (uint8_t *)&daten; for (size_t i = 0; i < sizeof(sensorDaten); i++) { if (LoRa.available()) { ptr[i] = LoRa.read(); } } // Daten speichern wenn ID stimmt if (daten.id == senderID) { unified.sensors[senderID] = daten; Serial.printf("✓ Sensor-ID %d: %.1f°C | %.1f%% | %d hPa | '%s'\n", senderID, daten.temperatur, daten.humidity, daten.pressure, daten.name); } else { Serial.printf("✗ ID-Konflikt: Header=%d, Daten=%d\n", senderID, daten.id); } } else { Serial.printf("✗ Größenfehler: Erwartet %d, Empfangen %d\n", sizeof(sensorDaten), size); } // Restlichen Puffer leeren while (LoRa.available()) { LoRa.read(); } } [/code] Я уже искал помощь через github copilot, откуда и приходят комментарии на немецком языке. К сожалению, ИИ не смог мне помочь, но я думаю, что сбой тайм-аута WDT как-то связан с прерываниями DIO0 для приема пакетов, хотя он всегда вылетает в LoRa.endPacket(true); Надеюсь, вы поможете с моей ошибкой. Подробнее здесь: [url]https://stackoverflow.com/questions/79887706/esp32s3-wdt-timeout-and-core-crash-with-lora-module-rfm95w[/url]