Benziner:
Und was soll ich sagen.... 100%( Okay hab jetzt nicht jeden einzelen kontrolliert) aber er macht noch immer was er soll und das ohne offensichtliche Fehler.
Ja, das habe ich erwartet und wäre hochgradig enttäuscht gewesen, wenn das nicht mit meinem Sendesketch funktioniert hätte....
Für Erklärungen bin ich immer zu haben, darf nur nicht kompliziert werden
Du wolltest es nicht anders!
Ich werde mich versuchen zu beschränken!
Darum gehe ich nicht auf das verkürzte in der Auswertung ein, sondern nur und ausschliesslich auf die Datenerfassung:
Ok. Fangen wir mit dem Code aus #67 an.
void readSerial()
{
const int breakTimeRead = 500; // Abbruchzeit in ms
char readChar; // Einzelnes Zeichen
byte x = 0; // Position im Array
char buf[30] = "\0"; // Zwischenspeicher
unsigned long lastmillis = millis(); // Startzeit merken...
while (Serial.available() > 0 && millis() - lastmillis < breakTimeRead)
{
readChar = Serial.read();
if (readChar == ';')
{
ausgabe = true;
Serial.print("Teile "); Serial.println(buf);
teileBuf(buf);
x = 0;
}
else
{
buf[x] = readChar;
x++;
}
}
}
Das ist schick. Vorgesehen ist, das solange gelesen wird, bis ein ; kommt und dann ausgewertet.
Zu dem Zeitpunkt, als dieser Code entstand war ich einem Aufbau noch nicht habbar und hab das trocken gemacht - also sowohl senden als auch empfangen auf dem Serial-Port getestet und zugleich habe ich den Inhalt bei der Übergabe auf einen Datensatz beschränkt und alle nacheinander "händisch" übergeben.
Das funktioniert auch.
Was jetzt aber dazu kommt, sind zwei Faktoren:
a) Die Gesamtzahl der zu empfangenen Daten "am Stück"
b) Während der Übertragung ein Serial.available < 1 - sprich, wenn schneller ausgelesen, als Daten reinkommen.
Fange ich mit b) an:
Im Gegensatz zu agmue habe ich mich auf die lokale Verarbeitung konzentriert und meinen Puffer auch nur lokal deklariert.
char buf[30] = "\0"; // Zwischenspeicher
In dem Moment, wo die Leseroutine schneller ist als die einkommenden Daten, wird die Funktion verlassen.
Mit dem Verlassen der Funktion verlieren die Variablen aber auch ihren Inhalt.
Das bedeutet, das buf schon einen Teil aufgenommen hat und dieser Teil gelöscht wird.
Beim nächsten Umlauf wird neu gefüllt, aber der erste Teil ist verloren.
Das heisst, das die Daten niemals zur Auswertung kommen.
Das ist Dein
17:15:02.839 -> RZ3:0,0 hier müsste jetzt 5,5 stehen
in #76
Das vermeide ich, in dem ich jetzt sage, das der Puffer zwar noch immer lokal läuft, aber der Inhalt beim verlassen der Funktion erhalten bleibt:
static char buf[30] = {0}; // Zwischenspeicher
Gleichzeitig mit dem static für den Puffer muss natürlich auch die Position gemerkt werden:
static byte x = 0; // Position im Array
Soweit - so gut.
Was jetzt passiert:
Es wird gelesen - ggfls. auch mit Unterbrechung - bis der Satz komplett da ist.
Davor und danach passiert was, was ich bei der Übergabe im SerMon nicht habe:
Es werden Steuerzeichen mit eingelesen.
Das heisst, wenn das letzte Feld (F4) inhaltlich übergeben wurde, folgen Steuerzeichen.
Wird die Übertragung vorher angestossen OHNE Inhalt, kommen nur Steuerzeichen.
Diese Steuerzeichen bewirken, das Serial.available() > 0 erfüllt ist.
Und weil die Zeichen auch gelesen werden können readChar = Serial.read(); // Einlesen werden die auch in den Puffer übernommen:
buf[ x ] = readChar; // Dann aufnehmen
Und genau hier(!) findet sich wieder, was Du auch in #76 beschrieben hast.
17:15:02.792 -> BRZ: 0,0 zeigt keine Werte an.
Das habe ich bei der Übergabe mit dem Seriellen Monitor nicht.
Da kommen also VOR dem eigentlichen Set, sowie danach Steuerzeichen, die nicht aufgenommen werden dürfen. Denn sonst geht das:
if (!strncmp(c, "BRZ", 3)) {
definitiv in die Hose.
Der Puffer fängt mit Steuerzeichen an - nicht mit 'BRZ' - damit ist ein Vergleich IMMER falsch.
Das lässt sich lösen, indem keine Steuerzeichen in den Puffer genommen werden:
if (!isControl(readChar))
es geht alles an Zeichen und Zahlen, solange sie keine Steuerzeichen sind.
Jetzt könnte man fragen, warum nicht isPrintable - also alles was druckbar ist.
???
Versuch es selbst.
Es behindert oder verändert die Lesefunktionalität nicht.
Nur der Inhalt des Puffers wird anders gehandhabt.....
Hier meine Funktion aus #86, deren Inhalt Du jetzt von !isControl nach isPrintable ändern sollst (edit: extra nochmal markiert)
void readSerial()
{
const int breakTimeRead = 500; // Abbruchzeit in ms
char readChar; // Einzelnes Zeichen
static byte x = 0; // Position im Array
static char buf[30] = {0}; // Zwischenspeicher
unsigned long lastmillis = millis(); // Startzeit merken...
while (Serial1.available() > 0 && millis() - lastmillis < breakTimeRead)
{
readChar = Serial1.read(); // Einlesen
Serial.print(readChar);
if (readChar == ';') // Feldende
{
buf[x] = '\0'; // CharArray abschliessen
teileBuf(buf); // Übergeben zum teilen
x = 0; // Position im Array rücksetzen
}
else
{ if (!isControl(readChar)) // Zeichen ist kein Steuierzeichen
{
buf[x] = readChar; // Dann aufnehmen
x++; // neue Position setzen
}
}
}
}
Schreibe, was Du erkannt hast.
Beste Grüße!