3x S0 Strommessung mit RPi und FHEM (per GPIO) ist manchmal ungenau

Begonnen von awe, 14 März 2015, 14:17:16

Vorheriges Thema - Nächstes Thema

awe

Hallo zusammen,

seit ein paar Wochen beschäftige ich mich jetzt mit dem Raspberry Pi B+, soweit klappt auch alles bestens.
Nun möchte ich an drei GPIO Ports die S0-Impulse von 3 Swissnox Stromzählern (http://swissnox.de/stromzahler/swissnox-digitaler-wechselstromzahler-230v-5-50-a-1-phasig-fur-hutschienen-35mm-lcd.html) messen und mittels FHEM verarbeiten. Dazu habe ich die S0-Leitungen entsprechend an die Pins 17, 18, 27 (GPIO.0-.2) angeschlossen, um damit die S0-Signalezu erfassen (Impulslänge: 90ms, Zählimpulse   2000imp/kWh).

Leider klappt das Zählen der S0-Signale der Stromzähler nicht so richtig (ich nutze in FHEM die RPI_GPIO und interrupt = both).
Ich habe über mehrere Zeitfenster die in FHEM gemessenen Impulse mit den auf den Zählern angezeigten Zählerständen verglichen (Faktor 20 berücksichtigt). Ergebnis: bei niedriger Last OK, bei höherer Last NICHT OK.
Letztlich ist die Frequenz der Signale bei mittlerer bis hoher Last wohl zu hoch, so dass die Software trotz Interrupt-Verarbeitung nicht hinterher kommt.

Nun frage ich mich, wie ich dieses Problem lösen könnte. Spontan habe ich nur 2 Ideen:
1. Variante: An den Eingang der GPIOs jeweils einen Zählerbaustein vorschalten, der den Takt auf 2, 4 oder 8 teilt.
2. Variante: Mittels eines anderen (C-)Programmes die Signale zählen und FHEM irgendwie (alle x-Minuten) zur Verfügung stellen. Bloß wie würde das funktionieren?

Habt Ihr Anmerkungen oder andere Ideen zur Lösung dieses Problems?
Würde mich übrigens wundern, wenn ich der erste mit einer solchen Fragestellung bin, habe aber bei meiner Suche nur ähnliche Probleme mit Arduino-Vorschaltungen(?) - wenn ich es richtig verstanden habe - gefunden. Sowas will ich ja nicht machen. Und auch keine Daten mittels PanStamp  übertragen.

Gruß,
Axel

Otto123

Hallo Axel,

ich denke das nur mit Raspi zu  machen wird immer etwas unzuverlässig sein.
Schau mal hier gibt es eine Sammlung zum lesen.

Aber ich habe da schon oft über Projekte gelesen, dass Problem haben schon viele angepackt. Auch hier im Forum

Gruß Otto


Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

awe

Moin Otto,

danke für den Link, jene Seite kannte ich bereits. Dort war direkt nichts für mich dabei.
Letzte Woche hatte ich dann eine Schaltung entworfen, die ich dem GPIO vorschalten wollte.
Für jeden S0-Kanal einen n:1-Teiler, zusätzlich noch einen 4. ebensolchen Eingang für eine Wasseruhr (die womöglich auch recht hoch getaktet sein könnte bei 1 imp/Liter - noch nicht vorhanden). Der 5. Eingang ist für den Gaszähler und geht direkt auf ein Reed-Relais.
Für n habe ich 20 gewählt, das hat den Vorteil, dass die 2000 Impulse pro kWh damit genau der Anzeige im Display entsprechen (0.01 kWh).
Die Schaltung ist jetzt seit ein paar Tagen in Betrieb und funktioniert prinzipiell.
Allerdings geht der ein oder andere Impuls offensichtlich immer noch verloren. Die Abweichung ist zwar gering, aber leider vorhanden. 100% wäre schon schön, auch wenn ich die Übersichten nur für mich als Übersicht haben möchte.
Ich bin jetzt am Optimieren der HourCounter-, Notify- und Logfile-Funktionen, um die Last am RPi niedriger zu bekommen.
Schade finde ich allerdings, dass das Interrupt-Management des RPi bzw. GPIO bzw. der WiringPi-Bibliothek nicht so funktioniert, wie ich es mir vorgestellt hatte. Selbst bei der nun relativ geringen Frequenz gehen immer noch Impulse verloren.

Wenn ich demnächst etwas Zeit finde, kann ich ja mal ein paar Details zu meiner Schaltung hier im Forum posten, falls Interesse besteht.

Gruß,
Axel

Otto123

Hallo Axel,

ich habe mir vor Jahren All3691 für den Zweck gekauft. Das Ding ist auch Schrott. Am Ende ist es besser Zähler mit MOD Bus einzusetzen.
Ich wollte das auch mal umstellen auf Raspi und den ALL3691 wieder rausschmeißen. Aber bisher gab es andere Prios. Und Deine Erfahrung stimmt mich auch nicht zuversichtlich. ::)

Viel Erfolg

Gruß Otto
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

klausw

Hi Axel,

es ist zwar schon eine Weile her ... aber was solls :)

Zitat von: awe am 23 März 2015, 21:14:55
Schade finde ich allerdings, dass das Interrupt-Management des RPi bzw. GPIO bzw. der WiringPi-Bibliothek nicht so funktioniert, wie ich es mir vorgestellt hatte. Selbst bei der nun relativ geringen Frequenz gehen immer noch Impulse verloren.

Das Interrupt Managment in der RPI_GPIO Bibliothek ist halt nicht hardwarenah in C programmiert und daher nur bedingt zuverlässig.
Vorteil ist, das keine weiteren Komponenten installiert werden müssen. Den Nachteil hast du selbst mitbekommen.
Du kannst versuchen nur auf eine Flanke zu triggern.
S0 sind Impulse fester Breite?
Wenn ja dann kann es sein, das nur die letzte der beiden Flanken abgearbeitet wird, wenn das System während des Impulses gerade ausgelastet war. Die Interruproutine ist ja auch nur in Perl geschrieben und wird vermutlich blockiert wenn FHEM das System gerade auslastet (Plots zeichen oder so). Aber ich vermute das trotzdem der jeweils letzte GPIO Interrupt abgearbeitet wird.

evtl kann man die einzelnen GPIOs auch forken. Aber da bräuchte ich bisschen Unterstützung.

Klaus
RasPi B v2 mit FHEM 18B20 über 1Wire, LED PWM Treiber über I2C, Luchtdruck-, Feuchtesensor und ein paar Schalter/LED\'s zum testen
Module: RPI_GPIO, RPII2C, I2C_EEPROM, I2C_MCP23008, I2C_MCP23017, I2C_MCP342x, I2C_PCA9532, I2C_PCF8574, I2C_SHT21, I2C_BME280

efyzz

Nabend,

ich habe ebenfalls das Problem, dass mein Raspi gelegentlich Pulse verliert. Ich lese meinen Stromzähler aus, indem ein Arduino per Lichtschranke die Scheibe abtastet und den Strich erkennt. Er sendet dann einfach Pulse zum Raspberry, die von einem Hourcounter gezählt werden. Nachdem ich gemerkt habe, dass in meinem Hourcounter die CountsOverall immer wieder vom realen Zählerstand abweichen, habe ich den Arduino selbst mitzählen lassen und kann nach einem Tag eine Differenz feststellen. Z. B. hatte der Raspi an einem Tag von ca. 7000 Pulsen 22 verloren.

Gibt es inzwischen eine bessere Lösung?

Ich habe schon versucht, die Pulse des Arduino zu verlängern (auf 500 ms), aber das hat scheinbar auch nichts gebracht. Vielleicht könnte ich Mehrfach-Pulse senden, die dann über debounce_in_ms zu einem Puls gefiltert werden. Aber so bekäme der Arduino dann vielleicht mehr Aufmerksamkeit  ;D
RaspberryPi3B, Bookworm Lite
Homematic Funkmodul HM-MOD-RPI-PCB
------------------------------------------------------------------------
Ich bin kein Programmierer ... aber ich weiß, auf welcher Seite der Lötkolben heiß ist.

Otto123

Hi,

ich lasse die Impulse vom ArduCounter zählen. Da laufen zwar zwei Arduinos aber was solls. Der zweite zählt noch andere S0 Zähler.

Gruß Otto
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

Wernieman

Könntest Du nicht beides in einem Arduino zusammenführen?
- Bitte um Input für Output
- When there is a Shell, there is a Way
- Wann war Dein letztes Backup?

Wie man Fragen stellt: https://tty1.net/smart-questions_de.html

Otto123

Ja.  ;D
Aber das war mir bisher aufwendiger als einfach zwei Drähte zu verbinden.  ;)
Beide haben einen separaten Programmcode, den müsste ich modifizieren. Aber es läuft doch ohne Probleme ...  8)
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

efyzz

Nabend,

danke Dir, Otto!

Der ArduCounter ist ein guter Tipp, aber zwischen RasPi und Arduino liegen etwa 10m. Mal eben USB-Kabel dazwischen ist also nicht. Ansonsten mit USB-to-Serial-Converter am RasPi und dann über 10m Kabel direkt an RXD/TXD vom Arduino ...  ::)

Aber es muss doch auch über den GPI gehen!  >:(

Also mit Mehrfach-Puls und debounce_in_ms geht's nicht, wie ich gerade praktisch erfahren und anschließend im Wiki gelesen habe:
Wartezeit in ms bis nach ausgelöstem Interrupt der entsprechende Pin abgefragt wird.
Ich bräuchte für meine Idee ja eine Funktion, die den Mehrfach-Puls wieder zu einem "filtert". So hätte ich mir eine Entprell-Funktion erst mal vorgestellt ... Funktioniert aber leider anders  ;D

Ich muss sagen, dass mich das ziemlich nervös macht, dass der RasPi scheinbar durchaus mal einen Puls übersehen kann. Beispielsweise meine Rauchmelder hängen auch an einem GPI ...

Zitat von: klausw am 11 Mai 2015, 11:34:54
Das Interrupt Managment in der RPI_GPIO Bibliothek ist halt nicht hardwarenah in C programmiert und daher nur bedingt zuverlässig.
Vorteil ist, das keine weiteren Komponenten installiert werden müssen. Den Nachteil hast du selbst mitbekommen.

Gibt es irgendwelche Alternativen zu dieser Bibliothek?
RaspberryPi3B, Bookworm Lite
Homematic Funkmodul HM-MOD-RPI-PCB
------------------------------------------------------------------------
Ich bin kein Programmierer ... aber ich weiß, auf welcher Seite der Lötkolben heiß ist.

klausw

Zitat von: efyzz am 15 Januar 2018, 20:34:18
Also mit Mehrfach-Puls und debounce_in_ms geht's nicht, wie ich gerade praktisch erfahren und anschließend im Wiki gelesen habe:
Wartezeit in ms bis nach ausgelöstem Interrupt der entsprechende Pin abgefragt wird.
Ich bräuchte für meine Idee ja eine Funktion, die den Mehrfach-Puls wieder zu einem "filtert". So hätte ich mir eine Entprell-Funktion erst mal vorgestellt ... Funktioniert aber leider anders  ;D

Ich weiss ja nicht was du unter prellen verstehst, aber Taster prellen gewöhnlich im Nanosekunden bis unteren Millisekundenbereich und das bei einem Pegelwechsel. Die Funktion kann genau das, jedenfalls wenn das System nicht gerade blockiert ist  8).
Die Mehrfachpulse müssen in ihrer Gesamtlänge kürzer als debounce_in_ms sein und danach muss der Pegel natürlich invers im Vergleich zu vor den Pulsen sein.

Zitat von: efyzz am 15 Januar 2018, 20:34:18
Ich muss sagen, dass mich das ziemlich nervös macht, dass der RasPi scheinbar durchaus mal einen Puls übersehen kann. Beispielsweise meine Rauchmelder hängen auch an einem GPI ...

Gibt es irgendwelche Alternativen zu dieser Bibliothek?

Naja, eine Möglichkeit wäre es das ganze nonblocking zu machen.
Im Moment ist die Interruptauswertung blind wenn FHEM was anderes macht. Je nach Pi Variante und FHEM Ausbaustufe kommt das unterschiedlich häufig vor.
Ich komme aber derzeit nicht dazu mich darum zu kümmern.
RasPi B v2 mit FHEM 18B20 über 1Wire, LED PWM Treiber über I2C, Luchtdruck-, Feuchtesensor und ein paar Schalter/LED\'s zum testen
Module: RPI_GPIO, RPII2C, I2C_EEPROM, I2C_MCP23008, I2C_MCP23017, I2C_MCP342x, I2C_PCA9532, I2C_PCF8574, I2C_SHT21, I2C_BME280

efyzz

Vielen Dank für die ausführliche Antwort, Klaus!

Zitat von: klausw am 15 Januar 2018, 23:25:56
Ich weiss ja nicht was du unter prellen verstehst, aber Taster prellen gewöhnlich im Nanosekunden bis unteren Millisekundenbereich und das bei einem Pegelwechsel. Die Funktion kann genau das, jedenfalls wenn das System nicht gerade blockiert ist  8).
Die Mehrfachpulse müssen in ihrer Gesamtlänge kürzer als debounce_in_ms sein und danach muss der Pegel natürlich invers im Vergleich zu vor den Pulsen sein.

Natürlich funktioniert das für prellende Taster, aber eben anders, als ich es mir vorgestellt hatte. Meine Gedanke war: "Wenn ein Puls aufgetreten ist, ignoriere alle weiteren für xx ms". Aber so ist es halt nicht ;)

Die Idee, den Pegel danach zu halten ist gut (bzw. ja die logische Schlussfolgerung ;D)! Aber erreiche ich denn auf diese Art überhaupt mein Ziel, nämlich die Chance zu erhöhen, dass der RasPi  zumindest einen der Mehrfach-Pulse registriert? Müsste ja eigentlich ...

Also beispielsweise 3 Pulse und den letzten für mindestens debounce_in_ms halten. Ich werde das mal testen.

Zitat von: klausw am 15 Januar 2018, 23:25:56
Naja, eine Möglichkeit wäre es das ganze nonblocking zu machen.
Im Moment ist die Interruptauswertung blind wenn FHEM was anderes macht. Je nach Pi Variante und FHEM Ausbaustufe kommt das unterschiedlich häufig vor.
Ich komme aber derzeit nicht dazu mich darum zu kümmern.

Was könnte man denn tun, um Dich zu motivieren?  8)
RaspberryPi3B, Bookworm Lite
Homematic Funkmodul HM-MOD-RPI-PCB
------------------------------------------------------------------------
Ich bin kein Programmierer ... aber ich weiß, auf welcher Seite der Lötkolben heiß ist.

klausw

Zitat von: efyzz am 16 Januar 2018, 20:19:21
Also beispielsweise 3 Pulse und den letzten für mindestens debounce_in_ms halten. Ich werde das mal testen.
Das müsste gehen, aber
1. Die Pulse müssen kürzer als debounce_in_ms sein
2. Während FHEM auf debounce_in_ms wartet ist es blockiert... sollte also nicht zu lange sein.

Zitat von: efyzz am 16 Januar 2018, 20:19:21
Was könnte man denn tun, um Dich zu motivieren?  8)
Motivation ist da, aber keine Zeit
Mit childs anlegen und zurück holen habe ich mich bisher nicht befasst.
Ich weiss auch nicht, ob das ganze mit der Except Fn von FHEM funktioniert.
Konkrete Vorschläge werde ich gern testen und einpflegen, alles andere wird vermutlich noch bisschen dauern.
Wenn du dich schlau machen magst, nur zu  8)
RasPi B v2 mit FHEM 18B20 über 1Wire, LED PWM Treiber über I2C, Luchtdruck-, Feuchtesensor und ein paar Schalter/LED\'s zum testen
Module: RPI_GPIO, RPII2C, I2C_EEPROM, I2C_MCP23008, I2C_MCP23017, I2C_MCP342x, I2C_PCA9532, I2C_PCF8574, I2C_SHT21, I2C_BME280

efyzz

Nabend,

habe 10 Pulse eingebaut, die zusammen 200 ms lang sind. Außer der letzte natürlich, der wird 300 ms gehalten. debounce_in_ms steht auf 250 ms. Funktioniert soweit und der RasPi verliert auf jeden Fall wesentlich weniger Pulse. Ob es wirklich gegen 0 geht, bedarf noch ein paar Tage Beobachtung.

Aber der RasPi ist dann jedes Mal für die 250 ms nicht ansprechbar? Mmh, die Pulse kommen ja nicht gerade selten ... so alle 2-10 s, je nach Stromverbrauch.

Zitat von: klausw am 17 Januar 2018, 00:00:02
Mit childs anlegen und zurück holen habe ich mich bisher nicht befasst.
Ich weiss auch nicht, ob das ganze mit der Except Fn von FHEM funktioniert.
Konkrete Vorschläge werde ich gern testen und einpflegen, alles andere wird vermutlich noch bisschen dauern.
Wenn du dich schlau machen magst, nur zu  8)

Meine Programmierkenntnisse reichen leider bei weitem nicht aus, um zu verstehen, von was Du da redest.  ::) Assembler kann ich und ein bisschen C, sodass es gerade für den Arduino reicht ... Aber wenn Du mal ein Hardware-Problem hast, kann ich schon eher unterstützen.

Zitat von: klausw am 11 Mai 2015, 11:34:54
evtl kann man die einzelnen GPIOs auch forken.

Ist das ein anderer Plan oder hat das mit "childs anlegen" zu tun?  :o

Könnte man nicht vielleicht mit einem Shell-Skript mittels WiringPi auf GPIO-Interrupts reagieren und einen Befehl an FHEM senden?

RaspberryPi3B, Bookworm Lite
Homematic Funkmodul HM-MOD-RPI-PCB
------------------------------------------------------------------------
Ich bin kein Programmierer ... aber ich weiß, auf welcher Seite der Lötkolben heiß ist.

klausw

Genau, die 250ms wird FHEM blockiert.
Beim Forken bekommst du einen Child Prozess dieser ist vom Hauptprozess abgekoppelt, läuft also Parallel und blockieren sich nicht gegenseitig.
Bei bestimmten Ereignissen im Child kann dieses Informationen zum Hauptprozess zurückliefern.
Ob das alle Probleme lösen würde weiss ich nicht.
Am besten wäre sicherlich ein eigener Mikrocontroller am Stromzähler der selbst zählt und zyklisch per Bus oder Funk an FHEM berichtet.
Ein eigenes Script, ob python, shell, perl oder was auch immer geht vielleicht auch.
RasPi B v2 mit FHEM 18B20 über 1Wire, LED PWM Treiber über I2C, Luchtdruck-, Feuchtesensor und ein paar Schalter/LED\'s zum testen
Module: RPI_GPIO, RPII2C, I2C_EEPROM, I2C_MCP23008, I2C_MCP23017, I2C_MCP342x, I2C_PCA9532, I2C_PCF8574, I2C_SHT21, I2C_BME280