[Tutorial] analoge Strom- Gas- und Wasserzähler auslesen und Daten auswerten

Heute ist Stammtischzeit:
Jeden Donnerstag 20:30 Uhr hier im Chat.
Wer Lust hat, kann sich gerne beteiligen. ;)
  • Für den gerade veröffentlichten RPi 4, hab ich keine Ahnung.

    (danke an tonklon)

    Schöne ausführliche Anleitung, :thumbup: aber ist dir ist bewusst, dass der Pi 4 seit Juni 2019 verfügbar ist? Da ist das „gerade“ nicht wirklich zutreffend

  • [Tutorial] analoge Strom- Gas- und Wasserzähler auslesen und Daten auswerten? Schau mal ob du hier fündig wirst!

  • Hallo Hofei. Hm. Ja, das ist ein wunder Punkt. Aber in der Anleitung zur bcm2835 (Link siehe oben) ist auch kein Hinweis zu finden. Man könnte aber annehmen, dass es beim Raspi4 genauso geht wie beim Raspi2 und 3. Da ich keinen zum Testen habe, gilt hier: Ausprobieren. Dieses Zählerprojekt funktioniert aber einwandfrei mit einem RaspI 1B+ . Also ist es auch gut, um ältere und schwächere, dafür aber Strom-sparsamere Pi's noch zu verwenden. Dennoch: Ein wenig Experimentierfreude ist bei diesem Projekt schon nötig. Aber wer sowas nachbauen will, der hat die ja in der Regel. Ich gehe davon aus, dass sich alle Probleme irgendwie lösen lassen.

  • Hallo, danke für die Anleitung. Ich hab Informatik aber nahezu keinen Elektronikhintergrund, darum gefiel mir dein Ansatz irgend ein Signal zu bekommen, welches dann per Software verarbeitet wird. ich habe Probleme beim Auslegen des Kondensators und der LED Lichtquelle. Die Entladung des Kondensators (100nF) benötigt bei Zimmerhelligkeit in der Größenordnung von 300ms zum Entladen; Im Dunkel des Sicherungskasten braucht ein Tastzyklus mehrere Sekunden -- viel zu lang um in sinnvoller Frequenz die Helligkeit abzutasten. Kann ich daran was ändern ohne eine andere lichtstärkere LED zu kaufen?

  • Ja. Du könntest einfach einen kleineren Kondensator verwenden. z.B. 50nF oder 20nF. Dann entläd der sich schneller. Allerdings sind Millisekunden schon recht lange. Da hat der Raspberry Pi wohl einen sehr hohen Innenwiderstand. Welche Version des Pis ist es denn?

    Wenn es nur daran liegt, dann kannst Du du einen echten 50kOhm Widerstand einbauen, so wie im Schaltplan. Aber ich fürchte , dann unterscheiden sich die Zeiten für Hell und Dunkel nicht mehr so gut. ALso würde ich dann den Phototransistor / Photodiode gegen einen anderen tauschen.

  • Hallo zusammen,

    vielen Dank für die Anleitung. Ich möchte mit meinem Raspberry 4 meinen Gaszähler auslesen, habe aber bislang keine Kenntnisse über Raspberry, Linux oder C. Ich habe es geschafft, die Quelldateien zu kompilieren, so dass im Verzeichnis gaszaehler/src eine Datei "gaszaehler" liegt (auch wenn ein paar Warnmeldungen wegen write/fwrite erschienen sind). Wenn ich diese mit ./gaszaehler starten will, erscheint eine Fehlermeldung:

    pi@raspberrypi:~/gaszaehler/src $ ./gaszaehler

    open() failed.

    Segmentation fault

    Was kann ich da machen? Kann das daran liegen, dass ich beim Raspberry 4 #define ST_BASE (0x3f003000) angegeben habe und das nicht stimmt?


    Dankeschön!

    EDIT: Ich bin etwas weitergekommen. Der Debugger sagt folgendes:

    Code
    main (argc=1, argv=0xbefff654) at gaszaehler.c:71
    (gdb) print st
    $1 = -4683755824282101576
    (gdb) print ot
    $2 = 400431460093984
    (gdb) print timer
    $3 = (long long *) 0x0

    Zeile 71:

    Code
      st=ot=*timer;

    4 Mal editiert, zuletzt von toom (21. September 2022 um 12:19)

  • Hallo toom,

    aus der Fehlermeldung würde ich eher ein permission error rauslesen, aber das mit der Timer-Adresse kann natuerlich auch sein.

    Hast Du gaszaehler mit "sudo" gestartet?

    Probier mal, ob /dev/mem vorhanden ist und lesbar für den user pi. Wenn nicht lesbar, dann muss gaszaehler mit sudo gestartet werden.

    bei mir:

    Code
    crw-r----- 1 root kmem 1, 1 Jul 21  2021 /dev/mem

    Ich starte den gaszaehler mit:

    Code
    screen -m -d sudo /home/pi/gaszaehler/src/gaszaehler
  • Dankeschön. Ich wollte gerade noch schreiben, dass die erste if-Abfrage in timer.c greift. Natürlich nicht mit sudo gestartet... *seufz* naja, jetzt weiß ich wenigstens, was gdb ist... ;)

    Jetzt bekomme ich keine Fehlermeldung mehr. Ich werde mir jetzt einen Reed-Kontakt und Widerstand besorgen (habe erstmal probiert, ob ich das mit der Software hinbekomme) und mal schauen, ob es funktioniert. Anscheinend muss der GPIO Offset für den Timer noch geändert werden.

  • Nachtrag:

    Jetzt bekomme ich Werte angezeigt. Muss man den Kontakt für eine bestimmte Anzahl von Sekunden herstellen?

    52791.2 0.000944 0.000944 0 2

    53546.3 755.087 755.088 1 3

    53546.4 0.108794 755.196 0 3

    53549 2.6504 2.7592 1 4

    53549.1 0.107344 2.75775 0 4

    53552.4 3.29385 3.40119 1 5

    53552.5 0.107346 3.40119 0 5


    Heute sind endlich Widerstände und Reedkontake gekommen. Leider komme ich nicht weiter. Ich habe der Einfachheit GPIO 27 (Pin 13) und GND (Pin 09) über einen 1k Ohm Widerstand verbunden, um einen geschlossenen Reedkontakt zu simulieren. Leider passiert nichts, wenn ich die Pins verbinde.

    gas-019263.dat

    # Datennahme gestartet am 28.09.2022 15:22:16 Zaehlerstand: 0

    # Sekunde timer delta v cnt

    51736.9 0 0 0 0

    # Datennahme gestartet am 28.09.2022 15:29:48 Zaehlerstand: 1

    # Sekunde timer delta v cnt

    52188.2 0.000668 0.000668 0 1

    Beim Programmstart wird die Datennahme gestartet und das File erzeugt (oben die Version mit offset 0x3F000000, unten mit offset 0xFE000000). Allerdings werden keine Werte geschrieben, wenn ich die Pins verbinde. Da ich zumindest unten Werte habe, scheint der Offset 0xFE000000 für den RPi 4 der richtige zu sein.

    Irgendwelche Ideen?

    2 Mal editiert, zuletzt von toom (28. September 2022 um 18:50)

  • Da, funktioniert doch alles:

    52791.2 0.000944 0.000944 0 2

    53546.3 755.087 755.088 1 3

    53546.4 0.108794 755.196 0 3

    53549 2.6504 2.7592 1 4

    53549.1 0.107344 2.75775 0 4

    53552.4 3.29385 3.40119 1 5

    53552.5 0.107346 3.40119 0 5

    5 Pulse wurden gezählt. Um 14:46 UTC, etwas unregelmaessig mit etwa 3 Sekunden zwischen den Pulsen...

    Einmal editiert, zuletzt von wend (28. September 2022 um 17:52)

  • Bei mir sieht das (für den Gaszähler) heute so aus:

    Die erste Spalte hat die Sekunden ab Mitternacht UTC. 16559 s ist also ca. 04:35 Uhr.

    In der nächsten Spalte die Zeit seit dem letzten Puls (0-zu-1 oder 1-zu-0) in Sekunden.,

    in der nächsten Spalte die Zeit seit dem letzten Puls mit der gleichen Flanke (0-zu-0 oder 1-zu-1) in Sekunden,

    danach die Flanke des Pulses (0 oder 1),

    dann die Gesamtzahl der bereits gezählten Pulse. (= Zählerstand*100)

    Also: Mein Zählerstand ist heute bei 3150.700 Kubikmeter, und der Verbrauch um 04:40 war etwa bei 31 Kubikmeter/Tag (natürlich nur Kurzzeitig, wenn der Warmwasserbeuler morgens ab 04:35 aufheizt).

    0.01 pro 28 Sekunden, also 0.01/28*60*60*24=30.85...


    Wenn Du den Zählerstand über die Zeit auftragen willst, dann Spalte 5 gegen Spalte 1,

    Wenn Du den Momentanverbauch auftragen willst, dann 1 durch Spalte 3 gegen Spalte 1.

    2 Mal editiert, zuletzt von wend (28. September 2022 um 18:00)

  • Beitrag von toom (28. September 2022 um 18:40)

    Dieser Beitrag wurde gelöscht, Informationen über den Löschvorgang sind nicht verfügbar.
  • Ich nehme an, Du guckst Dir das Datenfile an, während die Datennahme noch läuft.

    Die Datenfiles sind erst dann vollständig, wenn entweder der Tag vorbei ist oder das gaszähler-Programm beendet wurde (CTRL-c).

    An der Konsole kann man das ebenfalls nicht beurteilen, da nicht jede Zeile immer sofort ausgegeben wird.

    Probier mal folgendes:

    gaszaehler programm frisch starten, dann genau 5 Pulse geben, dann mit CTRL-c beenden, dann das File anschauen.

    Beziehungsweise kleine Ergänzung: Der letzte Puls wird sofort in das File geschrieben, wenn der davor mehr als 30 Sekunden her ist.

    Das soll verhindern, dass zu oft auf eine (empfindliche) SD-Karte geschrieben wird. Deshalb werden normalerweise vom Betriebsystem aus immer 4096 Bytes gesammelt, bis die dann auf die SSD geschrieben werden.


    Wenn Du sicher bist, dass es das nicht ist, dann achte noch drauf, dass die System-load < 1 ist, also dass nicht noch zu viele andere Programme das System auslasten. Allerdings ist das bei diesen langsamen Pulsen unwahrscheinlich, dass welche verloren gehen. Da muss der Prozessor schon total überlastet sein.

    3 Mal editiert, zuletzt von wend (28. September 2022 um 19:38)

  • Klappt leider nicht. Was mich insbesondere wundert, weil ich vorhin bei jedem Kontakt der Pins sofort einen Datensatz in der shell gesehen habe. Sollte es mich wundern, dass die Rechte der Messwertdatei 640 sind?

    1. Löschen der Messwertdatei

    2. Start des Programms

    Code
    pi@raspberrypi:~ $ cd gaszaehler/src/
    pi@raspberrypi:~/gaszaehler/src $ sudo ./gaszaehler
    63554.9 0.000517 0 0 0

    5x GND (fünfter Pin von oben (innen)) und GPIO 27 (siebter Pin von oben (innen)) über 1kΩ Widerstand verbunden

    60 Sekunden warten und Abbruch mit ^C

    Code
    pi@raspberrypi:~/gaszaehler/src $ cd ..
    pi@raspberrypi:~/gaszaehler $ cd ..
    pi@raspberrypi:~ $ cd data
    pi@raspberrypi:~/data $ sudo pico gas-019263.dat

    ergibt nur das:

    Code
    Datennahme gestartet am 28.09.2022 18:39:14 Zaehlerstand: 0
    # Sekunde timer delta v cnt
    63554.9 0.000517 0 0 0

    Nachtrag: Anscheinend wird die Bedingung bei

    Code
    if(a!=oa) {

    nie erfüllt und das Programm spingt immer in den else-Teil, der nichts schreibt.

    Einmal editiert, zuletzt von toom (28. September 2022 um 20:12)

  • Hm. Nach den 60 Sekunden warten nochmal einen Puls nachschicken und dann abbruch. (?)

    Sicher, dass es der richtige Pin ist? GPIO 27 ?

    Sicher, dass der Widerstand auch 1kOhm ist und nicht etwa >10kOhm ?

    Du kannst probehalber den GPIO auch mal (mit dem 1kOhm Widerstand) mit den 3.3V verbinden. Vielleicht sind die internen Pull-Down widerstaende eingeschaltet....


    Es hat doch mal funktioniert, oder?


    Ansonsten um das zu debuggen, füge in den Programmcode noch zeilen ein wie:

    printf("Hier im If Block\n");

    oder

    printf("Hier im else Block\n");

  • Du kannst probehalber den GPIO auch mal (mit dem 1kOhm Widerstand) mit den 3.3V verbinden. Vielleicht sind die internen Pull-Down widerstaende eingeschaltet....

    Mich wundert nämlich, dass der erste gelesene Wert des Pins nicht 1 ist. Sondern quasi sofort ne 0 liefert. Das soll eigentlich nicht so sein.

    Einmal editiert, zuletzt von wend (28. September 2022 um 20:50)

Jetzt mitmachen!

Du hast noch kein Benutzerkonto auf unserer Seite? Registriere dich kostenlos und nimm an unserer Community teil!