ArduCounter Support und neue Versionen (war: Stromzähler mit S0 Schnitt...)

Begonnen von StefanStrobel, 26 Januar 2014, 12:08:13

Vorheriges Thema - Nächstes Thema

AxelSchweiss

Ah .. Danke .. habe ich nicht gefunden.
Mal sehen ob ich den Code so ändern kann das er die Werte ins EEPROM schreibt ... programmieren is ja nicht so meins  :)

AxelSchweiss

Moment ... dann müsste es doch mit einem Arduino Micro und einem FTDI Wandler funktionieren ... mal probieren

Otto123

lohnt sich nicht. Der Zähler läuft eh irgendwann über.
Mach ein userreadings mit monotonic BeispielZaehlerHzg monotonic {ReadingsVal("AC","pin4",0)/400}

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

StefanStrobel

... oder nimm die neue Version des Fhem-Moduls, die hat einen zusätzlichen Zähler, der weiterzählt und beim Neustart nicht auf 0 geht.
(verboseReadings muss dafür je Zähler auf 1 gesetzt sein)
Anbei eine Version, die hoffentlich keine neuen Bugs hat ;-)

Wenn keine neuen Probleme auftreten, checke ich die Version wieder ein.

Gruss
    Stefan

birdy

Hallo Stefan

Das Webinterface funktioniert nun auch wenn ich verboseReadingsX auf  1 setze.

Internals:
   CounterResetTime 1507233774.81938
   DEF        /dev/ttyUSB0@38400
   DeviceName /dev/ttyUSB0@38400
   FD         4
   Initialized 1
   NAME       AC
   NOTIFYDEV  global
   NR         21
   NTFY_ORDER 50-AC
   PARTIAL
   STATE      opened
   TYPE       ArduCounter
   VersionFirmware 1.8
   VersionModule 4.9 - 3.10.2017
   buffer
   CounterInterpolated:
     4          1
   READINGS:
     2017-10-05 22:04:24   countDiff4      2
     2017-10-05 22:04:24   lastMsg4        R4 C2 D2 T4840 N90522 F0 L4840

     2017-10-05 22:04:24   long4           54
     2017-10-05 22:04:24   pin4            2
     2017-10-05 22:04:24   power4          0.149
     2017-10-05 22:04:24   reject4
     2017-10-05 22:02:52   state           opened
     2017-10-05 22:04:24   timeDiff4       4840
Attributes:
   factor     100
   flashCommand avrdude -p atmega328P -c arduino -P [PORT] -D -U flash:w:[HEXFILE] 2>[LOGFILE]
   pin4       falling pullup
   userattr   pin4 verboseReadings4
   verbose    5
   verboseReadings4 1


Ich habe jetzt auch das Reading longX welches nach einen Reset munter weiter zählt.
Aber der erste Impuls wir weiterhin unterschlagen.

Was muss ich beachten, damit jeweils auch der erste Impust gezählt wird?

Ich habe immer noch einen Versuchsaufbau mit Impulsgeber= Taster
FHEM  @Debian bullseye @Proxmox VE 8.1.3
@intelNUC's  (i5)
CUL 433(a-culfw), CUL 868(SlowRF), Max-Cube CUN geflash, HM-CFG-USB-2 (HMALND)

StefanStrobel

Hallo birdy,

wenn Du verboseReadings das erste mal auf 1 setzt dann wird der erste Impuls noch für den Start der Messung verwendet und nicht gezählt. Sobald aber einmal das Reading existiert, sollte auch nach einem Restart von Fhem jeder Impuls gezählt werden.

Anbei nochmal eine neue Version, in der auch der allererste Impuls gezählt wird wenn verboseReadings das erste mal definiert wurde.

Schau doch mal ob das bei Dir jetzt auch so klappt.

Gruss
   Stefan

birdy

#201
Hallo Stefan

Vielen Dank für Deine Bemühungen.

Ich konnte das folgende Verhalten feststellen. Dieses lässt sich auch jederzeit zuverlässig reproduzieren. Meine manuellen Impulse sehen meiner Meinung nach ,,sauber" aus, so dass davon eigentlich kein Problem ausgehen sollte.

  • Ein set reset oder ein Restart von FHEM führt immer zu einer Erhöhung des Readings longX auch ohne irgendeinen Impuls. Am Ende des ersten Zyklus nach dem Reset wird der Wert um 1 erhöht. Für mich etwas ungünstig, da ich den AdruCounter u.a. als Ölzähler einsetzen möchte. Währen den Sommer benötige ich über mehrere Monate keinen Tropfen Öl. Aber in dieser langen Zeit ist durchaus mit mehreren Restarts zu rechnen.

  • Nach dem Restart wird immer mindestens 1 Impuls unterdrückt. Unter Umständen auch deren zwei.
    Beispiel: Restart, ohne Impuls abwarten bis zum Ende des ersten Zyklus (+1). Danach mit Impulsen starten. Da werden dann immer die ersten beiden Impulse unterschlagen, und erst ab den 3. wird zuverlässig gezählt.

Wo wird der erste Impuls unterdrückt, geschieht dies im der Firmware des Arduino oder im AdruCounter Modul?


Internals:
   CounterResetTime 1507381057.041
   DEF        /dev/ttyUSB0@38400
   DeviceName /dev/ttyUSB0@38400
   FD         4
   Initialized 1
   NAME       AC
   NOTIFYDEV  global
   NR         21
   NTFY_ORDER 50-AC
   PARTIAL
   STATE      opened
   TYPE       ArduCounter
   VersionFirmware 1.8
   VersionModule 4.10 - 6.10.2017
   buffer
   CounterInterpolated:
     4          1
   READINGS:
     2017-10-07 15:28:36   countDiff4      0
     2017-10-07 15:28:36   lastMsg4        R4 C1 D0 T60000 N1860521

     2017-10-07 15:28:36   long4           147
     2017-10-07 15:28:36   pin4            1
     2017-10-07 15:28:36   power4          0.000
     2017-10-07 15:28:36   reject4
     2017-10-07 14:57:35   state           opened
     2017-10-07 15:28:36   timeDiff4       60000
Attributes:
   factor     100
   flashCommand avrdude -p atmega328P -c arduino -P [PORT] -D -U flash:w:[HEXFILE] 2>[LOGFILE]
   pin4       falling pullup
   userattr   pin4 verboseReadings4
   verbose    5
   verboseReadings4 1


Update:
Ich habe wieder meinen 10uF Kondensator dazu geschaltet und nochmals ein paar Tests gemacht.
Restart von FHEM führt nicht zu einer Erhöhung des longX Wertes.
Ab den ersten Impuls wird korrekt gezählt.

Ich trenne den Arduino vorübergehend von Pi(Strom) und schliesse ihn dann wieder an. Jetzt verschwinden die ersten beiden Impulse wieder im schwarzen Loch.
Anscheinend ist es schwieriger Impulse zu zählen als ich gedacht hätte.

Gruss birdy

FHEM  @Debian bullseye @Proxmox VE 8.1.3
@intelNUC's  (i5)
CUL 433(a-culfw), CUL 868(SlowRF), Max-Cube CUN geflash, HM-CFG-USB-2 (HMALND)

StefanStrobel

Hallo birdy,

ich möchte das Problem mit dem ersten Impuls nach einem Neustart nochmal versuchen in Perspektive zu setzen.

der Arducounter versucht eben nicht einfach nur Impulse in einem vorgegebenen Intervall zu zählen und diese an Fhem weiter zu geben.
Das machen andere Sketches. Das Problem ist dabei dass der aktuelle Verbrauch nicht exakt ermittelt werden kann und das Verbrauchs-Ergebnis (Impulse / Zeit) ständig leicht hin und her schwankt.

Die Idee beim Arducounter ist statt dessen, dass möglichst genaue Zeitintervalle von einem Startimpuls bis zu einem Endimpuls gemessen und weiter gegeben werden. Damit bekommt man eine glattere Verbrauchskurve.

Das bedeutet aber auch, dass man nicht direkt nach einem Reset des Arduino mit dem Zählen beginnen kann, da der Beginn des Intervalls seit dem letzten Impuls ja noch unbekannt ist. Deshalb beginnt der Arducounter nach einem Neustart erst nach dem ersten Impuls zu zählen.

Solange der Arducounter läuft, funktioniert das gut. Wenn der Arduino aber neu gestartet wird, muss man wieder bis zu einem ersten Impuls warten, bevor das Zeitmessen und Zählen beginnen kann.

Problematisch sind also die Neustarts des Arduino.

Der ganze Mechanismus mit dem longCount ist ein zum Scheitern verurteilter Versuch, den Zählerstand korrekt zu halten, auch wenn der Arduino zwischendrin neu startet und dabei gar nicht zählen kann und somit der Zählerstand nicht mehr korrekt sein kann.
Das Fhem-Modul berechnet dafür einen Mittelwert aus der letzten Messung vor dem Neustart und der ersten Messung nach dem Neustart und interpoliert für den Zeitraum dazwischen die vermutlich verpassten Impulse.
Diese Interpolation kann manchmal stimmen, sie kann aber auch falsch sein.

In jedem Fall ist es nicht besser als eine Näherung. Wer es genauer braucht, muss hardwareseitig dafür sorgen, dass der Arduino dauerhaft läuft und nicht neu startet.

Das Problem ist also folgendes:
1) Wenn der Arduino nicht läuft oder gerade neu startet, zählt er noch nicht.
2) Wenn der Arduino neu startet, gehen die Zählerstände und die gemessenen Zeitintervalle im Arduino verloren,
    sofern sie noch nicht an Fhem weiter gegeben wurden.
3) Wenn Fhem neu startet und der Arduino nicht hardwareseitig verändert wurde, startet auch der Arduino neu. -> 2)

Wenn verboseReadings noch nicht gesetzt ist, fehlen Readings, die für die Interpolation beim Neustart benötigt werden. Deshalb klappt es in diesem aller ersten Fall noch schlechter.
In der letzten Modulversion habe ich für diesen Fall statt der Interpolation (die noch nicht möglich ist) einfach einen Impuls als angenommenen Startimpuls auf longCount addiert. Das ist aber natürlich Unsinn, wenn gar keine Impulse gekommen sind. Das habe ich jetzt nochmal geändert.

So oder so ist aber jede Zählung falsch wenn der Arduino neu startet und somit Impulse verliert.

Wenn man nun Impulse zum Testen von Hand gibt, kann man bei Starten des Arduinos "Fehler" bemerken.
In der Praxis ist das aber völlig irrelevant, da der "Fehler" durch die verlorenen Impulse beim Neustart viel größer ist.

Um die Internas besser zu verstehen, kann man entweder verbose auf 4 oder sogar 5 setzen, dann schreibt das Modul einige Internas und vor allem die Meldungen vom Arduino ins Log, oder man kann den Quellcode vom Modul und dem Sketch lesen. Beides ist recht kurz und überschaubar.

Anbei nochmal eine neue Version, die für den ersten Neustart des Arduino (wenn verboseReadings zum ersten Mal gesetzt wird und die Readings für die Interpolation noch fehlen) nochmal etwas besser rät.

Ich habe es nicht mit Impulsen per Taster getestet, da mein Arducounter am Stromzähler hängt. Im laufenden Betrieb sieht es für mich gut aus und der Sonderfall für den ersten Start sollte für jeden Anwender eh nur einmal überhaupt relevant sein.
Sobald ich wieder etwas mehr Zeit habe, versuche ich nochmal einen Test-Arduino mit Taster aufzusetzen und das mit den zwei Impulsen nachzustellen.

Für weitere Bug-Reports wäre ein Auszug aus dem Log mit verbose 5 hilfreich. Da sehe ich dann was der Arduino gemeldet hat.

Gruss und vielen Dank für's Testen
   Stefan




StefanStrobel

Ergänzung:

Inzwischen konnte ich nachstellen, dass nach einem Restart des Arduino dieser erst mit dem zweiten Impuls zu zählen beginnt.
Das muss ein Bug bei der Initialisierung sein. Liegt auf jeden Fall im Arduino-Sketch und nicht im Fhem-Modul.
Neue Version kommt, sobald ich die Zeit hatte, den Fehler zu beheben.

Gruss
    Stefan

birdy

Hallo Stefan

Vielen Dank für Deine Arbeit. Es ist wirklich toll was Du hier gebaut hast. Deine Erklärung verstehe ich durchaus. Ich habe erst mal mit einem manuellen Aufbau getestet, denn ich möchte im Detail verstehen wie das Ganze funktioniert. So wird mir klar auf was ich mich ,,einlasse", denn ich möchte nicht im Nachhinein enttäuscht sein. Das nicht immer alles nach meinen Vorstellungen funktioniert ist mir klar. Wenn das aber so ist, möchte ich wissen was abweicht, damit ich mich bewusst dafür oder dagegen entscheiden kann.
Zitat von: StefanStrobel am 08 Oktober 2017, 19:37:00
der Arducounter versucht eben nicht einfach nur Impulse in einem vorgegebenen Intervall zu zählen und diese an Fhem weiter zu geben.
Das ist ja genau der Vorteil von Deiner Lösung, dass die noch mehr kann. Darum habe ich Sie ja auch gewählt. Ich bin aber davon ausgegangen, dass er ,,eben einfach nur Impulse Zählen" auch kann, und das ohne Probleme.

Zitat von: StefanStrobel am 08 Oktober 2017, 19:37:00
Deshalb beginnt der Arducounter nach einem Neustart erst nach dem ersten Impuls zu zählen.
Meine Meinung: Zählen sollte er schon, aber noch nicht rechnen.

Zitat von: StefanStrobel am 08 Oktober 2017, 19:37:00
Wenn der Arduino aber neu gestartet wird, muss man wieder bis zu einem ersten Impuls warten, bevor das Zeitmessen und Zählen beginnen kann.
Zeitmessen ist klar.

Möglicherweise hast Du hier einen anderen Standpunkt und dies ist bei Dir nicht die erste Priorität. Wenn das so ist, werde ich damit leben müssen und können. Ich für mich sehe es etwas anders. Ein korrektes Zählen ist für mich die Grundlage und das sollte so korrekt wie nur irgendwie möglich erledigt werden.

Zitat von: StefanStrobel am 08 Oktober 2017, 19:37:00
auch wenn der Arduino zwischendrin neu startet und dabei gar nicht zählen kann und somit der Zählerstand nicht mehr korrekt sein kann.
Evtl. gibt es in dieser Zeit auch gar nichts zu zählen. Es muss also nicht zwingend so sein, dass der Zählerstand abweichen muss.

Wie auch schon geschrieben ist jeder ignorierte Impuls, ein Fehler der sich bis in alle Ewigkeit weiter zieht. Ein beim Re- /Start falsch oder ungenau errechneter Momentanverbrauch ist für mich nicht von Bedeutung weil sich dieser nur auf den ersten Zyklus auswirkt und danach bereits Geschichte ist.
Toll das Du es mit einer Interpolation versuchst. Ich für mich sehe keinen wirklichen Bedarf. Ist es nicht so, dass Du hier viel Aufwand für etwas fast unmögliches betreibst. Ob sich dieser Einsatz auch auszahlt. Ich hoffe es.

Zitat von: StefanStrobel am 08 Oktober 2017, 19:37:00
1) Wenn der Arduino nicht läuft oder gerade neu startet, zählt er noch nicht.
Das ist mir klar.
Zitat von: StefanStrobel am 08 Oktober 2017, 19:37:00
2) Wenn der Arduino neu startet, gehen die Zählerstände und die gemessenen Zeitintervalle im Arduino verloren, sofern sie noch nicht an Fhem weiter gegeben wurden. 
Klar, Wie ich verstanden habe kann hier jeder Einfluss auf die Zeitintervalle und somit auf die Weitergabe nehmen.
Zitat von: StefanStrobel am 08 Oktober 2017, 19:37:00
3) Wenn Fhem neu startet und der Arduino nicht hardwareseitig verändert wurde, startet auch der Arduino neu. -> 2) 
Dafür habe ich den 10uF im Einsatz.

Zitat von: StefanStrobel am 08 Oktober 2017, 19:37:00
Wenn man nun Impulse zum Testen von Hand gibt, kann man bei Starten des Arduinos "Fehler" bemerken.
In der Praxis ist das aber völlig irrelevant, da der "Fehler" durch die verlorenen Impulse beim Neustart viel größer ist.
Kein Zweifel, bei einem Neustart könne natürlich Impulse verloren gehen, müssen aber nicht. Das hängt davon ab wie lange der Neustart dauert bzw. in welchen Abständen die Impulse daher kommen.

Evtl. nochmals kurz meine Vorstellung. Ob Du diese mit ArduCounter abdecken kannst oder willst, liegt natürlich bei Dir.
Möglichst korrektes Zählen der Impulse.

  • Alle real existierenden Impulse (ohne Ausnahme) zählen.
  • Nur die real existierenden Impulse zählen


Schon mal vielen Dank für die neuen Versionen. 
Ich werte testen und meine Erkenntnisse bekannt geben..

Gruss birdy
FHEM  @Debian bullseye @Proxmox VE 8.1.3
@intelNUC's  (i5)
CUL 433(a-culfw), CUL 868(SlowRF), Max-Cube CUN geflash, HM-CFG-USB-2 (HMALND)

StefanStrobel

Hallo,

anbei eine neue Version des Moduls und ein neuer Arduino-Sketch bzw. die Firmware für den Arduino Uno dazu zum Testen.

In der Firmware war ein Bug in der Verarbeitung der Pin-Change-Interrupts, wodurch gelegentlich der erste Impuls nach einem Restart des Arduino ignoriert wurde (zusätzlich zu dem zweiten Impuls, der dann erst das Intervall gestartet hat).

Die neue Modulversion ist nicht mehr kompatibel zur alten Firmware. Sie zählt jetzt alle Impulse. Auch nach einem Restart des Arduino. Nur für die Berechnung des Verbrauchs wird im ersten Intervall der erste Impuls nicht für die Puls-Differenz verwendet sondern als Intervall-Start. Gezählt wird er aber dennoch.
So kann es nach dem Start sein, dass die erste Berechnung nach 30 Sekunden mit 4 Impulsen in 22 Sekunden erfolgt, der Zähler aber von 0 auf 5 geht.

Wen Ihr keine neuen / alten Bugs meldet, checke ich Firmware und Modul in den nächsten Tagen ein.

Gruss
    Stefan

FunkOdyssey

Ich habe Modul und Firmware aktualisiert. Aber mal ne kurze Frage:

Muss ich bei mir evtl. nach einer anderen Ursache suchen, wenn mein Zähler in FHEM größer ist als der Wert am Gaszähler? Bei mir ist FHEM anscheinend schneller. Also sollte das bei mir doch sicherlich ein anderes Problem sein, oder?

StefanStrobel

Hallo,

Bei jedem Fhem-Neustart wird ja interpoliert, wie viele Impulse der Zähler möglicherweise verpasst hat. Dadurch können Abweichungen entstehen.
Wenn es aber um größere Abweichungen geht, dann würde ich auch nach anderen Fehlerquellen suchen.
Hast Du eine minimale Pulsweite angegeben?
Das ist sinnvoll um Störimpulse auszufiltern.

Gruss
   Stefan

birdy

Hallo Stefan

Vielen Dank für das Bereitstellen der neuen Versionen.

Ich bin gerade dabei die zu testen.

Zitat von: StefanStrobel am 15 Oktober 2017, 18:57:47
Bei jedem Fhem-Neustart wird ja interpoliert, wie viele Impulse der Zähler möglicherweise verpasst hat.
Was oder wie wird interpoliert? Es wäre hilfreich wenn Du dazu noch ein paar erklären Worte liefern könntest.

Ist es (nur) der Wert des Long Readings?
Ich denke da habe ich ,,willkürliche" Sprünge nach vorne gesehen.

Was ist die Grundlage für die Interpolation.
Kann es sein, dass einfach der letzte Zyklus vor den Restart verwendet wird?
Angenommen der Physische -Zähler steht 1-2 Zyklen vor den Restart von FHEM. Muss ich dann mit einer ,,künstlichen" Erhöhung von irgendwelchen Readings rechnen?

Besten Dank und Gruss
birdy
FHEM  @Debian bullseye @Proxmox VE 8.1.3
@intelNUC's  (i5)
CUL 433(a-culfw), CUL 868(SlowRF), Max-Cube CUN geflash, HM-CFG-USB-2 (HMALND)

StefanStrobel

Hallo birdy,

die Interpolation betrifft nur den longCounter. Es wird der Mittelwert für Impulse / Intervall aus der letzten Messung vor dem Restart und der ersten Messung nach dem Restart genommen und mit der Dauer der Unterbrechung (Ende der letzten erfolgreichen Messung bis zur Started-Meldung des Arduino multipliziert.
Im Log wird das entsprechend protokolliert.
Siehe 98_Arducounter.pm in den Zeilen 626 bis 643.

Ich kann gerne alternative Interpolationen einbauen, sofern sie mit den vorhandenen Readings / Werten mit vertretbarem Aufwand machbar sind ;-)
Ebenso kann ich noch ein Attribut einbauen, mit dem die Interpolation ganz abgeschaltet wird.

Gruss
   Stefan