Hi
Ich verrenne mich gerade in Kleinigkeiten, will’s wohl zu schön machen :o
Momentan versuche ich, einen Sketch zum Auslesen meines eHz-Zähler zusammen zu bekommen und stolpere wohl darüber, daß Das ‘perfekt’ werden soll.
Der ganze Sketch (kompilerbar mit Warnungen, allerdings so nicht lauffähig) im 2.ten Post
… und wohl dem Unvermögen, Zeigern auf dem Arduino eine Logik abzugewinnen …
Zuerst erstelle ich die zu suchenden Sequenzen (Teile des Sketch aus dem Nachbar-Thread klick extrahiert)
const byte startSequenz[] = { 0x1B, 0x1B, 0x1B, 0x1B, 0x01, 0x01, 0x01, 0x01 }; //start sequence of SML protocol
const byte stopSequenz[] = { 0x1B, 0x1B, 0x1B, 0x1B, 0x1A }; //end sequence of SML protocol
const byte powerSequenz[] = { 0x07, 0x01, 0x00, 0x10, 0x07, 0x00, 0xFF, 0x01, 0x01, 0x62, 0x1B, 0x52, 0x00, 0x55 }; //Sequenz folgt "Wirkleistung" (4 Bytes)
const byte verbrauchSequenz[] = { 0x07, 0x01, 0x00, 0x01, 0x08, 0x00, 0xFF, 0x65, 0x00, 0x00, 0x01, 0x82, 0x01, 0x62, 0x1E, 0x52, 0xFF, 0x59 }; //Sequenz folgt "Gesamtverbrauch" (8 Bytes)
Daraus erstelle ich mir ein Array mit den relevanten Daten
typedef struct {
byte laenge; //Länge der zu suchenden Sequenz
uint16_t pointer; //dort ist der Anfang der Sequenz
byte bereitsgefunden; //aktuell zu Testendes Byte aus der Sequenz
byte folgebytes; //wenn wir die Sequenz gefunden haben, noch x Byte einlesen
} sequenzen;
const sequenzen sequenz[] = {
{sizeof(startSequenz), startSequenz, 0, 0},
{sizeof(stopSequenz), stopSequenz, 0, 0},
{sizeof(powerSequenz), powerSequenz, 0, 4},
{sizeof(verbrauchSequenz), verbrauchSequenz, 0, 8},
};
Die Daten des eHz-Zähler werden in einem Ring-Puffer per CNY70 eingelesen, wobei nur jeweils der Schreib und Lese-Zeiger entsprechend versetzt wird, wodurch ich ‘unendlich’ schreiben kann.
if (mySerial.available()) {
anzahl++; // für Debug, die Anzahl wird bei Pausen >500ms (const) genullt
digitalWrite(LED_BUILTIN, HIGH); //Daten vorhanden - Was für's Auge
lastIRempfang = millis(); //Zeitpunkt merken um das TimeOut zu erkennen
empfangsPuffer[writePos] = mySerial.read(); //in Puffer schreiben
writePosPlus(); //Schreib-Zeiger erhöhen
}
Solange ich mit dem Lesen hinterher komme - wenn nicht, wird der Lese-Zeiger mit weggeschoben.
//####################
//erhöht die Lese-Position im Ringspeicher
void readPosPlus() {
readPos++; //Lesezeiger verschieben
if (readPos > maxPos) { //ist der Lesezeiger am Ende angekommen?
readPos = 0; //dann Den wieder auf Anfang setzen
}
}
//####################
//erhöht die Schreib-Position im Ringspeicher
//Der Lese-Zeiger wird 'vorher geschoben'
void writePosPlus() {
writePos++; //Schreib-Porision erhöhen
if (writePos > maxPos) { //am Ende angekommen?
writePos = 0; //auf Anfang setzen
}
if (writePos == readPos) { //Schreibzeiger auf Lese-Zeiger aufgelaufen?
readPosPlus();
}
}
Wenn ich ungelesene Zeichen habe, möchte ich das Nächste davon einlesen und mit allen Sequenzen vergleichen.
if (readPos != writePos) {
//Es sind auszuwertende Bytes vorhanden
byte readbyte = empfangsPuffer[readPos]; //nächstes Byte aus dem Puffer einlesen
readPosPlus();
for (byte i = 0; i < sizeof(sequenz) / sizeof(sequenz[0]); i++) { //mit jeder Sequenz prüfen, ob diese Byte als Nächstes dort gefunden wurde
if (sequenzbyte(sequenz[i].pointer+sequenz[i].bereitsgefunden)==readbyte){
//Byte in der Sequenz entspricht dem gelesenem Byte
}
}
}
In der letzten IF möchte ich Überprüfen, ob das aktuelle Byte dem nächstem Byte dieser Sequenz entspricht.
(wenn, ‘bereitsgefunden’ erhöhen, sofern nicht die Anzahl korrekter Bytes bereits gefunden wurde aka ‘laenge’)
Meinem Verständnis nach übergebe ich der Funktion sequenzbyte() die Start-Position des i-ten Array plus das zu Suchende Byte dieser Sequenz (bereitsgefunden) - also die Adresse/Speicherposition des bereitsgefunden’en Bytes des i-ten Array.
Die Funktion
//####################
// soll das Byte aus dem Speicher auslesen, berechnet wird die Position zuvor durch Start-Array + Zeichennummer
byte sequenzbyte(uint16_t pointer){
return &pointer;
}
soll mir eigentlich dieses gesuchte Zeichen zurück geben, laut Compiler-Warnungen wird Das aber nicht passieren, denn
C:\...\CNY70_E21_Testmessung.ino:144:27: warning: address of local variable 'pointer' returned [-Wreturn-local-addr]
C:\...\CNY70_E21_Testmessung.ino:44:1: warning: invalid conversion from 'const byte* {aka const unsigned char*}' to 'uint16_t {aka unsigned int}' [-fpermissive]
Meine Pointer im Struct mag Er auch nicht - zumindest interpretiere ich Das so - Zeile 44 ist die schließende Klammer des Struct.
Zeile 144 das ‘return &pointer;’