Guten Abend,
der Versuch mit dem Raspberry sollte lediglich zur Überprüfung des Zählers / IR-Leskopf dienen.
Im Netz findet man einige Beispiele wie Leute den Zähler mit dem Pi erfolgreich ausgelesen haben.
Übrigens muss ich gestehen, dass ich erst jetzt bemerkt habe, dass ich einen Easymeter Q3BA und keinen Q3D habe 
Der Q3D überträgt mit 7E1 9600bd und der Q3B mit 8n1 9600bd.
Großer Fehler meinerseits.
Lt. Hersteller überträgt mein Zähler auch nicht in Klartext (ASCII) sondern im SML1.03 Format.
Ich vermute ja, dass die Nachricht die ich empfang nicht komplett ist.
Könnte es daran liegen, dass ich den IR-Lesekopf per SoftSerial auslese und das Ergebnis per Serial (USB) weiterschicke?
Laut einigen Beiträgen soll die SoftSerial lib nicht für zeitkritische Anwendungen geeignet sein.
Ich würde jetzt versuchen, dass ganze zu drehen und den Zähler mit der "normalen" Seriellen Schnittstelle auszulesen und im Anschluss per SoftSerial an meinen PC zu schicken.
Was meint ihr?
Gruß
Maestrox
Guten Abend,
leider ist das Projekt "smartMeter" zwischenzeitlich etwas eingeschlafen 
Ich hatte heute Abend mit folgendem Aufbau einen ersten großen erfolg:
IR-TTL Lesekopf --> RX Pin Arduino (P0)
Dann verwende ich den Code wie schon zu Anfang und schicke mir die Ausgabe per SoftSerial an einen FTDI Adapter.
Nun bekomme ich zum ersten mal eine komplette SML Ausgabe 
Scheinbar lag es an der SoftSerial und dem TTL Lesekopf ..?
Jetzt muss ich die Ausgabe noch etwas zerpflücken ....
Ich werde mich dann noch einmal melden wenn es die nächsten Erfolge gibt.
Gruß
maestrox
Hallo zusammen,
ich habe es jetzt hinbekommen die SML Ausgabe so zu zerteilen, dass ich die HEX Werte für den Zählerstand und die momentane Leistung in ein char[] bekomme.
Die Werte kann ich wie folgt ausgeben:
Beispiel:
Leistung HEX: 00004529
Zähler HEX: 00000002192D7B4E
Jetzt habe ich etwas Probleme bei der Konvertierung um die Werte richtig darzustellen bzw. um sie später per MQTT weiterzuleiten.
Bei der Leistung mache ich das per
long l_leistung = strtol(leistung, NULL, 16);
Bsp.:
HEX: 00004529 --> 17705 --> 17705 --> 177,05 W
Hier gibt es kein Problem.
Bei dem Zählerstand will es nicht so recht klappen, da die HEX Zahl zu groß ist
Bsp.:
HEX: 00000002192D7B4E--> 9012345678--> 901,23KW
Ich scheitere aktuell daran, dass ich die HEX Werte aus dem Char Array nicht in eine float Variable konvertiert bekomme 
Mein Versuch mit einer direkten Konvertierung funktioniert nicht...
//char_zaehlerstand[] = "00000002192D7B4E";
float f_zaehlerstand = *((float *)char_zaehlerstand);
Habt ihr einen Tip wie ich den Zählerstand am besten in DEC konvertiere ?
Vielen Dank im Voraus.
Gruß
maestrox
So z.B. könnte es gehen
union {
struct {
uint32_t partLow;
uint32_t partHigh;
} words;
uint64_t beide;
} test;
float value;
char inHex[] = "00000002192D7B4E"; // 9012345678--> 901,23KW
void setup() {
Serial.begin(115200);
char swap = inHex[8];
inHex[8] = 0;
test.words.partHigh = strtoul(inHex, nullptr, 16);
inHex[8] = swap;
test.words.partLow = strtoul(inHex + 8, nullptr, 16);
value = test.beide / 100000L;
value /= 100;
Serial.println(value);
}
void loop() {}
901.23
Hallo Whandall,
vielen Dank für deine schnelle und ausführliche Antwort !
Jetzt muss ich nur noch verstehen wie dein Vorschlag funktioniert ;D
char inHex[] = "00000002192D7B4E";
void setup() {
Serial.begin(115200);
char swap = inHex[8]; // [b]wird hier nicht das achte Zeichen ( 2 ) in den swap verschoben?[/b]
inHex[8] = 0; // [b]und durch eine null ersetzt? [/b]
test.words.partHigh = strtoul(inHex, nullptr, 16);
inHex[8] = swap;
test.words.partLow = strtoul(inHex + 8, nullptr, 16);
value = test.beide / 100000L;
value /= 100;
Serial.println(value);
}
Was genau hat das mit dem Swap aufsich? Somit würde doch immer das achte Zeichen durch eine null erstetzt werden oder?
Das mit dem union habe ich auch noch nicht ganz raus werde mich aber heute Abend belesen.
Gruß
maestrox
Das 9. Zeichen wird gegen eine 0 ausgetauscht, damit das Einlesen der ersten Hälfte der 64 Bit weiss wo es aufhören muss.
Ich tausche den Wert wieder zurück, dazu dient swap.
Wenn der Inhalt des Strings verändert werden darf, muss man nicht tauschen,
dann liest man zuerst den zweiten Teil, schreibt eine 0 auf dessen erstes Zeichen und
liest dann den ersten Teil.
Eine union ist eine struct, bei der alle Elemente an der selben Stelle anfangen,
was es in diesem Fall ermöglicht die beiden uint32_t Teile der uint64_t Variablen einzeln anzusprechen.
Noch eine Alternative:
char inHex[] = "00000002192D7B4E"; // 9012345678--> 901,23KW
uint64_t wert;
float value;
void setup() {
Serial.begin(115200);
byte* store = ((byte*)&wert) + 7;
for (byte i = 0; i < 8; i++, store--) {
*store = (nibble(inHex[i * 2]) << 4) | nibble(inHex[i * 2 + 1]);
}
value = wert / 100000L;
value /= 100;
Serial.println(value);
}
byte nibble(char in) {
byte rval = 0;
in = toupper(in);
if (in >= '0' && in <= '9') {
rval = in - '0';
} else if (in >= 'A' && in <= 'F') {
rval = in - 'A' + 10;
}
return rval;
}
void loop() {}
901.23
Hallo Whandall,
ich habe deinen ersten Vorschlag in meinen Code eingebaut und es funktioniert prima 
Vielen Dank nochmal !!
Jetzt muss ich den restlichen Code noch etwas aufhübschen und die mqtt Anbindung
fertigstellen.
Gruß
maestrox