EHZ Zähler auslesen

Auf die Idee mit Teilen war ich auch schon gekommen, aber ich hatte ganz vergessen, dass ich die Nachkommastellen wieder hinzufügen muss :roll_eyes:.
Hat jemand noch eine Idee zu der HEX-> Int Umwandlung, ich bin mir sicher, dass man das noch optimieren kann?!

Gruss

Klar gibt es da Ideen. Aber schreib doch bitte zuerst einmal genau was Du von einer HEX->INT Konvertierung erwartest. Also wie sieht der Input aus und wie der gewünschte Output? Und vor allem: warum ist Dir Deine aktuelle Lösung nicht gut genug?

Und bitte keien Spec der Art: "so wie ich es jetzt implementiert" habe. Das zwingt jeden Leser Deinen Code zu verstehen obwohl Du selber damit nicht zufrieden bist.

Da hast du recht, wenn man selber weiß was man reinbekommt und raus haben will, übersieht man leicht, dass die anderen Nutzer da nicht so drin sind.
Ich bekomme jetzt serielle Hexwerte (char Array) in folgendem Format rein:
62 1E Unit 1E = Wh
52 FF Scale
56 000014FDEF Zählerstand, berechnet mit Scaler und Unit (14FDEF = 137572,7 kWh!)
die Umwandlung mache ich ja durch Multiplikation:
unsigned long stand =(int(buffer[144])*65536);
unsigned long stand2=(int(buffer[145])*256);
unsigned long stand3=(int(buffer[146]));
unsigned long summe=stand+stand2+stand3;
das hochwertigste Byte lasse ich schon weg, da die Multiplikation ja einen Overflow geben würde.

Was ich suche wäre eine direkte Umwandlung von den Hexwerten in den Kommawert, ohne die Zwischenvariablen.

Gruss
Norbert

Ich würde diese Methode nehmen: Union in C++. Nur solltest Du für ein unsigned long eben 4 Bytes benutzen, also etwa so:

union {
    struct {
        unsigned char b0;
        unsigned char b1;
        unsigned char b2;
        unsigned char b3;
    } part;
    unsigned long value;
} converter;

   converter.part.b3 = 0;  
   converter.part.b2 = buffer[144];
   converter.part.b1 = buffer[145];
   converter.part.b0 = buffer[146];

  unsigned long result = converter.value;
}

Wenn die Werte andersrum im Speicher stehen würden, also niedrigstes Byte in buffer[144] und weiterhin eine 0 in buffer[147], dann könntest Du den Wert auch direkt auslesen, also etwas so:

unsigned long result = *((unsigned long *)(& buffer[144]));

gelesen werden. Falls Du das hochwertigstes Byte mitbenutzt gibt es bei der Methode garantiert keinen Overflow :wink:

Guten morgen,

genau sowas hab ich gesucht, ich hab es jetzt so gemacht:

    for(int i=3;i>=0;i--){
      Stand[3-i]=(buffer[143+i]);
      Aktuell[3-i]=buffer[204+i];
    }
unsigned long result = *((unsigned long *)(& Stand[0]));
Serial.println(result);
double Result = result/10000;
Serial.println(Result);
int Rest = int(result);
Rest = Rest%10000;
Serial.println(Rest);

Mein Problem ist jetzt nur noch die Ausgabe mit Modulo, weil da immer Werte rauskommen, die ich mir nicht erklären kann. Könntest du mir da noch einen Tip geben? Es ist mir auch wichtig den Wert wirklich als Kommazahl zu haben, da dies die Nachverarbeitung erheblich vereinfacht.

Gruss und schonmal vielen Dank

Norbert

[quote author=Nobi link=topic=108865.msg819336#msg819336 date=1339137563 ]

 ...
int Rest = int(result);
Rest = Rest%10000;
Serial.println(Rest);

Mein Problem ist jetzt nur noch die Ausgabe mit Modulo, weil da immer Werte rauskommen, die ich mir nicht erklären kann.[/quote]

Wundert Dich das, wenn Du ein unsigned long in ein vorzeichenbehaftetes int zwängst? :wink:

aber der Wert ist doch so klein, dass er in dem INT noch Platz finden sollte, oder? :~

Auf dem ATmega ist ein int nur 16 Bit groß und geht somit nur bis ca. 32000.

aber der Rest ist doch <10000, damit müsste er doch passen

int Rest = int(result);
Rest = Rest%10000;

Du kopierst aber vorher den Wert von result nach Rest und machst erst danach die Division.
Probiers mal so:

int Rest = unsigned long(result)%10000;

Jetzt läuft's so wie ich es mir gewünscht hab, der Arduino ließt die Daten ein und stellt sie per HTML Seite zur Verfügung.
Ich hab's mal hier reingestellt, das können bestimmt auch andere noch gebrauchen.
Vielen Dank für die Unterstützung!

Gruss
Norbert

eHZy_Arduino_1_HTML.ino (8.71 KB)

Hallo zusammen,

ich will das Projekt nun auch mal angehen.
Habe das script geladen und die IP angepasst, leider gibt mein Mega nichts aus, webseite kann nicht gefunden werden.
Des Weiteren habe ich noch die Frage an welcher stelle im Script die Daten eingelesen werden?
Ich habe einen Seriellen Lesekopf!

Danke und Grüße
Simon

Hi,

fangen wir mal vorne an, welchen Zähler hast Du, welchen Lesekopf?
Bekommst du etwas angezeigt, wenn du nur eine einfache HTML Seite ausgibst (siehe Beispiele)?
Ist der Arduino pingbar?

Gruss
Norbert

Moin Nobi,

ich klinke mich hier auch mal ein, weil es mich stark interessiert :astonished:.
Volkszaehler.org habe ich mehrfach studiert und begriffen, dass es SmartMeter gibt wie Sand am Meer und wohl ebenso viele Unterschiede zwischen den Geräten, auch wenn sie alle gemäß IEC62056-21 spezifiziert sind.
Wenn ich mir Deinen Code ansehe (vielen Dank für die .ino!!), dann scheint Dein Zähler ständig unaufgefordert zyklisch zu senden, ist das richtig verstanden?
Wenn das so richtig wäre, käme ich mit Deinem Sketch wahrscheinlich nicht weiter:
ich habe einen NZR-LZQJ Zähler, der standardmäßig erst einmal schweigt. Mit einem Terminalprogramm wird er gesprächig, wenn ich ihn mit "/?! " freundlich überrede. Dann erhalte ich ein mal einen Kompletten Datensatz der historischen Verbrauchsdaten der vergangenen 15 Monate. Und dann ist er wieder ruhig.
Ich habe es bisher noch nicht geschafft, ihn zum Dauersabbeln zu bringen.
Er meldet sich jedenfalls mit "/EMH4@01LZQJC0018E".
Habe einen seriellen optischen Lesekopf (bzw. zwei: TTL und RS232).

Hi Reinhardt,

auch wenn du deinen Zählertyp nicht gepostet hast und ich nur schätzen kann wieviele Daten dein Zähler rauswirft, würde ich mal spontan tippen, dass du mit dem Arduino da nicht wirklich weiterkommst. Die Volkszähler.org Sachen habe ich damals trotz viel Fummelei auf meinem Raspi nicht ans laufen bekommen und habe deshalb ein winziges python script geschrieben, dass mir die Werte einliest und an Openhab übergibt, was auch auf dem gleichen Pi läuft. Die Frage ist ja auch was man mit den Werten machen will, nur die aktuellen Werte anschauen, evtl. übergeben, in eine Datenbank speichern, Diagramme erzeugen..... da gibt es ja sehr viele Möglichkeiten und wenn du etwas aufwändigeres machen möchtest, bräuchtest du eh ein zweites System, da könnte es sich anbieten direkt auf einen Raspi, BeagleBone oder sowas umzusteigen.

Gruss
Norbert

Moin Norbert,

was genau meinst Du mit "Zählertyp", wenn meine Angaben nicht präzise genug sind? :blush:
Hier ist das Produkthandbuch zu finden, aber hilft das weiter?
http://www.nzr.de/download.php?id=427
Einen Download (vom Zählerinhalt) siehe im Anhang.
Was ich eigentlich nur haben möchte, ist jeweils der aktuelle Leistungsbezug und ggf. der aktuelle Zählerstand.

Zähler_.txt (1.62 KB)

Achso, noch einmal zu meiner Frage: sendet Dein Zähler unaufgefordert zyklisch?

Ja meinte den Hersteller/Typ, ja mein Zähler sendet zyklisch, aber so wie ich das Handbuch Seite 45 verstehe, kann man auch nur bestimmte Werte zyklisch ausgeben lassen.

Moin Norbert,

danke, dann habe ich diesbezüglich (zyklische Übertragung) mehr Klarheit und muss mir das - bezogen auf meinen Zähler - noch einmal genauer ansehen.