Ich arbeite schon länger mit Arduino, bin aber kein Programmierer!
Mein Code wertet über eine UART Kommunikation eine BMS aus
und gibt die Daten per serial aus.
void SOC_Check() // Auswertung SOC
{
memset(EmpfArray1, 0, sizeof(EmpfArray1)); // leeren des Eingangs Arrays
Serial2.write(AkkuU_I_SOC, sizeof(AkkuU_I_SOC)); // senden anfrage U/I/SOC
startIndex = 0;
delay(50); // warte 50ms zum abarbeiten für die BM
ReadNext1: // Sprung Adresse für Multi Zeichen Auswertung
while (Serial2.available()) // Routine, wenn neue Daten an UART2 anliegen
{
inByte = Serial2.read(); // das gerade empfangenen Zeichen ins inByte kopieren
EmpfArray1[startIndex] = inByte; // Empfangenes Zeichen ins Array übertragen
// startIndex = die Stelle die kopiert werden soll
startIndex++; // hochzählen counter um dann die Position für nächstes Zeichen definieren
}
}
Der Code ist stark vereinfacht, weil ich den Fehler finden wollte
Aber immer wieder kommt ein:
*Decoding 6 results* 0x400d0c8d: **SOC_Check()** at C:\Empfang\BMS_Read-3/**SOC.ino** line **10** 0x400d0cb5: **loop()** at C:\Empfang\BMS_Read-3/**BMS_Read-3.ino** line **40** 0x400d16d9: **loopTask(void*)** at C:\Users\sdell\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.3\cores\esp32/**main.cpp** line **19** 0x4008a0a1: **vPortTaskWrapper** at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/freertos/**port.c** line **355 (discriminator 1)**
ReadNext1: // Sprung Adresse für Multi Zeichen Auswertung
while (Serial2.available()) // Routine, wenn neue Daten an UART2 anliegen
{
inByte = Serial2.read(); // das gerade empfangenen Zeichen ins inByte kopieren
EmpfArray1[startIndex] = inByte; // Empfangenes Zeichen ins Array übertragen
// startIndex = die Stelle die kopiert werden soll
startIndex++; // hochzählen counter um dann die Position für nächstes Zeichen definieren
if ( startIndex < 13 ) // für Checksum berechnung und Loop für 0-12 Zeichen
{
Wert = inByte; // Wert dient zur Checksum Bildung
Check = (Check + Wert) & 0xFF; // zusammen addieren aller einzelnen Zeichen = Checksum muss mit 13. Zeichen übereinstimmen
goto ReadNext1;
}
beim kürzen etwas rausgenommen was wichtig war
frage warum läuft es dann 3 Minuten?
der Hinweis kam schon mehrfach. Überlege einmal was mit startIndex++;
in der Schleife passiert?
Wo wird der Index auf 0 gesetzt?
Schreibe dir eine saubere Einlesefunktion und alles wird gut.
void SOC_Check() // Auswertung SOC
{
memset(EmpfArray1, 0, sizeof(EmpfArray1)); // leeren des Eingangs Arrays
Serial2.write(AkkuU_I_SOC, sizeof(AkkuU_I_SOC)); // senden anfrage U/I/SOC
*startIndex = 0;*
delay(50); // warte 50ms zum abarbeiten für die BM
ReadNext1: // Sprung Adresse für Multi Zeichen Auswertung
while (Serial2.available()) // Routine, wenn neue Daten an UART2 anliegen
{
inByte = Serial2.read(); // das gerade empfangenen Zeichen ins inByte kopieren
EmpfArray1[startIndex] = inByte; // Empfangenes Zeichen ins Array übertragen
// startIndex = die Stelle die kopiert werden soll
startIndex++; // hochzählen counter um dann die Position für nächstes Zeichen definieren
}
}
das Problem ist, * ist auch ein Dereferenzierungsoperator.
Sowas verwirrt nur.
Du hast aber wieder keine Kontrolle über den Index. Wenn der Empfangsbuffer von Serial2 immer gefüllt ist, zählt startIndex++ munter weiter hoch. Erstmal wenn der Buffer einmal leer sein sollte wird er bei Eintritt in die Funktion SOC_Check() auf 0 gesetzt. Es fehlt jede Kontrolle über den Index und der Länge deines Arrays zum Datenempfang. Übrigens wann soll das einlesen unter normalen Umständen beendet werden? Was wird eingelesen? Gibt es ein Protokoll?
Wie gesagt mit dem Fetzen kann man fast nichts anfangen.
du musst deinen eigenen Code Zeile für Zeile durchgehen. Wenn das zu kompliziert ist, baue dir Serielle Debugausgaben ein, damit du siehst was deine Funktion machen.
void SOC_Check() // Auswertung SOC
{
memset(EmpfArray1, 0, sizeof(EmpfArray1)); // leeren des Eingangs Arrays
Serial2.write(AkkuU_I_SOC, sizeof(AkkuU_I_SOC)); // senden anfrage U/I/SOC
startIndex = 0;
delay(50); // warte 50ms zum abarbeiten für die BM
while (Serial2.available()) // Routine, wenn neue Daten an UART2 anliegen
{
inByte = Serial2.read(); // das gerade empfangenen Zeichen ins inByte kopieren
EmpfArray1[startIndex] = inByte; // Empfangenes Zeichen ins Array übertragen
// startIndex = die Stelle die kopiert werden soll
startIndex++; // hochzählen counter um dann die Position für nächstes Zeichen definieren
if (startIndex > sizeof(EmpfArray1))
{
Serial.println(F("Schluß mit lustig!"));
Serial.println(F("startindex ist voll"));
Serial.println(F("lösche den Puffer und fange von vorn an"));
memset(EmpfArray1, 0, sizeof(EmpfArray1));
startIndex = 0;
}
}
}
Du hast 3 Annahmen, von denen ich überzeugt bin, das 2 definitiv nicht zutreffen.
Die gehts ohne Wissen was Du auf der seriellen Schnittstelle an Daten bekommst immer davon aus, das Byte 10 und 11 Deine Information enthalten
Du gehst immer davon aus - und das ist Dein Problem - das die Übertragung nach Byte 13 zu Ende ist, nie mehr was kommt und damit
irgendwann falsch wird.
Annahme 2 ist dann der auch Dein Problem. Denn wenn die nicht zutrifft, trifft auch Deine Annahme 3 nicht zu, das Du vor Ende des Arrays aus der Schleife raus kommst.
Verstanden?
Wie sieht denn das Telegramm aus?
Hat es einen Marker für Anfang oder Ende?
nein ist nicht ganz so!
bin gerade dabei , den Fehler zu suchen und lass mir immer den Wert vom Startindex ausgeben.
sieht so aus wie es sein sollte!
jetzt stürzt der ESP aber auch nicht mehr ab!
muss es wohl selber mit Test Ausgaben herausfinden
ich mach aber auch nur die SOC Ausgabe und Auswertung
vorher habe ich hintereinander noch 2 weitere geprüft?!?
Doch ist genau so.
Solange Du mehr als 13 bytes ohne Abbruchfunktion liest, ist Deine Routine kaputt.
Wenn der Sender mehr als 13 bytes sendet, gehts Du fälschlich davon aus, das nach 13 bytes Schluß ist.
Das dem nicht so ist hast Du mehrfach erfahren.
Du könntest es alternativ mit meinem Codeschnipsel überprüfen.
Kommt die Serielle Ausgabe nicht, liege ich falsch.
Dann ist der Fehler aber auch an einer ganz anderen Stelle...