Gaszähler auslesen
Auslesen eines Gaszählers über den eingebauten Impulsmagneten
Zeitraum: Oktober 2020 - März 2021
Zuletzt aktualisiert am 15.02.2023- Ideenursprung
- Schaltplan
- Lesekopf
- Materialliste
- Zählerstände abfragen
- Downloads
- Aktualisierungsverlauf
Bisher wurden die Zählerstände des Gaszählers einmal die Woche manuell ermittelt. Dieser Prozess soll nun automatisiert werden.
Glücklicherweise verfügt der Gaszähler (Typ: BK-G4) über einen eingebauten Impulsmagneten. Dieser ist in der dritten Nachkommastelle des Zählwerks eingebaut,
sodass man einen Impuls pro 0,01 m³ Gas erhält. Ein Mikrocontroller soll mit Hilfe eines magnetoresistiven Sensors die Impulse des Magneten registrieren und daraus den Zählerstand berechnen.
Die Zählerstände sollen täglich von einem Raspberry-Pi abgefragt und in eine MariaDB-Datenbank abgelegt werden. Über dem Raspberry-Pi können die Zählerstände schließlich abgefragt werden.
Ein magnetoresistiver Sensor (Ausnutzung des AMR-Effekts, BE1) erkennt das Magnetfeld des im Gaszähler eingebauten Impulsmagneten. (Ursprünglich war ein Reed-Kontakt für diese Aufgabe vorgesehen. Allerdings hat der Lesekopf damit nicht sicher funktioniert.)
Der Lesekopf muss über die Anschlussklemme (XZ1) mit maximal +24/DC versorgt werden. Ein LDO-Spannungsregler (TA1) stellt damit 5V/DC für die restliche Schaltung zur Verfügung. Ein Mosfet (P-Kanal; QA1) schützt die Schaltung, falls die Spannungsversorgung verpolt werden sollte. Eine Schottky-Diode (RA2) schützt den Spannungsregler, wenn die Eingangsspannung kleiner als die Ausgangsspannung ist.
Als Netzausfallsicherung dient eine 3V-Knopfzelle (Ø: 16mm; Halter: UA1). So kann der Lesekopf auch bei Störung der Spannungsversorgung weiterhin die Impulse des Gaszählers registrieren. Ein Mosfet (P-Kanal; QA2) trennt die Batterie, wenn die externe Spannungsversorgung verfügbar ist. Dies ist notwendig, da eine solche Batterie nicht aufgeladen werden darf. Dies würde zur Zerstörung der Knopfzelle führen. Ein Spannungserhöhung der Knopfzelle ist nicht notwendig, da der verwendete Mikrocontroller (AtTiny861A, AF1) eine Spannungsversorgung von 1,8V bis 5,5V erlaubt. Für den magnetoresistiven Sensor ist die Batteriespannung ebenfalls ausreichend.
Der Lesekopf stellt über den MAX485-IC (TF1) eine RS485-Schnittstelle zur Verfügung. Diese wird mit dem ModBus-RTU-Protokoll betrieben. Darüber kann der aktuelle Zählerstand abgefragt oder vorgegeben werden.
Zum Einstellen der ModBus-Adresse sind zwei Drehkodierschalter (SF1, SF2) vorhanden. Der Abschlusswiderstand (RA3, RB1) kann über einen Jumper (XG1) (de-)aktiviert werden.
Des Weiteren kann über eine Stiftleiste (XD1) die Baudrate angegeben werden. Möglich ist dabei eine Baudrate von 9600, 19200 oder 38400 Baud.
Zum Programmieren des Mikrocontrollers ist ein ISP-Header (In-System-Programmierung, XZ2) vorgesehen. Über eine LED (PF1) kann der aktuelle Status des Lesekopfes (Impuls vom Gaszähler erhalten, Datensatz gesendet, o.Ä.) angezeigt werden.
Abbildung 1: Schaltplan des Lesekopfes.
Die Platine hat eine Größe von 40,5x30mm. Bestellt habe ich sie bei JLCPCB für 3,00€.
Das Gehäuse wird an dem Gaszähler angesteckt und mit einer Schraube befestigt. Zusätzlich ist ein Haltebügel für das Hinweisschild des Gaszählers vorgesehen. Die Anschlussleitung wird mit einer 16x1,5mm-Kabelverschraubung zugentlastet und aus dem Lesekopf herausgeführt.
Als Anschlussleitung wird eine UNITRONIC® Li2YCY (TP) 2x2x0,22 empfohlen. Allerdings habe ich mich für ein Cat6-Netzwerkkabel entschieden, da mein verwendeter Versandhändler die empfohlene Leitung nicht verkauft. Aber das Netzwerkkabel sollte für die Heimanwendung die Aufgabe genauso erfüllen können.
Die vier Aderpaare werden für folgende Aufgaben benötigt:
- 2x Spannungsversorgung: +24V (maximal), GND
- 1x Zuleitung: A, B
- 1x Ggf. Ableitung: A, B
Der Deckel und die Platine werden mit drei Blechschrauben (2,9x25mm) befestigt. Ein Lichtleiter leitet das Licht der Status-LED nach außen.
Abbildung 7: Komplett montierter Lesekopf. |
Abbildung 8: Einsatz des Lesekopfes am Gaszähler. |
Abbildung 9: Explosionszeichnung des Lesekopfes.
Die Programmierung des Mikrocontrollers erfolgt in Atmel-Studio mit der Sprache C über die ISP-Schnittstelle.
Wichtige Hinweise
- Die verfügbaren Register sind mit den Adressen 0x00 und 0x01 erreichbar. Diese beiden Register enthalten den Zählerstand.
- Der Lesekopf arbeitet mit Integer-Zahlen. Die Einheit ist daher 10-2m3. Soll ein Zählerstand vorgegeben werden (FC16, siehe unten), dann müssen ebenfalls zwei Nachkommastellen mit angegeben werden.
- Die zwei Register erlauben einen maximalen Zählerstand von 4.294.967.295 10-2m3.
- Die maximale Länge einer Anfrage darf 16 Bytes nicht überschreiten. Andernfalls ist eine Änderung des Codes notwendig.
- Für die CRC-Berechnung wird der CRC-16/MODBUS Algorithmus verwendet (Nützlicher Onlinerechner). Wichtig ist, dass zuerst das niedrigere Byte und dann das höhere Byte der Checksumme übertragen wird.
UART Schnittstelle
Zum Betrieb der UART-Schnittelle habe ich eine eigene, kleine Bibliothek geschrieben. Mehr Informationen dazu gibt es hier:
USI als UART nutzen
Die dort beschriebene Bibliothek wurde geringfügig für die hiesige Verwendung angepasst. So wird zusätzlich der TXE/!RXE-Pin des RS485-ICs von den Funktionen passend angesteuert.
Der vollständige, angepasste Code kann am Ende dieser Seite heruntergeladen werden.
Modbus Funktionen
Es werden folgende Funktionen unterstützt:
-
Read Holding Registers (FC03):
Mit dieser Funktion kann der aktuelle Zählerstand von dem Lesekopf abgefragt werden. Eine entsprechende Anfrage schaut so aus:
0x05 0x03 0x00 0x00 0x00 0x02 0xc5 0x8f
Dabei ist 0x05 die Geräteadresse. Ändert sich die Geräteadresse, dann ändert sich natürlich auch die Checksumme (Die letzten beiden Bytes)!
Eine Antwort könnte so aussehen:
0x05 0x03 0x04 0x00 0x0f 0xc8 0x3b 0x99 0xe3
Der Zählerstand entspricht 0x000fc83b ≙ 1034299 *10-2m3 = 10342,99 m3.
-
Diagnostics: Return Query Data (FC08, 0x0000):
Hiermit wird die gesendete Anfrage von dem Lesekopf unverändert zurückgeschickt. Diese Funktion soll zum Testen der Verbindung dienen. Beispiel:
0x05 0x08 0x00 0x00 0x12 0x34 0xab 0xcd 0xf3 0xe7
Die Anfrage wird wie erwähnt ohne Änderung zurückgegeben:
0x05 0x08 0x00 0x00 0x12 0x34 0xab 0xcd 0xf3 0xe7
-
Preset Multiple Registers (FC16):
Mit dieser Funktion kann ein Zählerstand voreingestellt werden. Um beispielsweise einen Zählerstand von 10342,99 m3 = 1034299 *10-2m3 ≙ 0x000fc83b einzustellen, wird folgende Anfrage gesendet:
0x05 0x10 0x00 0x00 0x00 0x02 0x04 0x00 0x0f 0xc8 0x3b 0xc0 0x8f
Zur Bestätigung antwortet der Lesekopf in diesem Beispiel wie folgt:
0x05 0x10 0x00 0x00 0x00 0x02 0x40 0x4c
Bei einem nicht unterstützten Funktionscode oder einer ungültigen Registeradresse, antwortet der Lesekopf mit einer Fehlermeldung. Bei einem ungültigen Funktionscode schaut das z.B. so aus:
0x05 0x83 0x01 0xc1 0x31
Bauteil | Bezeichnung / Wert | Gehäuse / Bauform | Benennung | Menge | Preis* |
---|---|---|---|---|---|
Klemmleiste | WAGO 233-504 | 4 / 2.54 mm | XZ1 | 1 | 1,60 € |
Mosfet (P-Channel) | NDS0610 | SOT-23 | QA1 | 1 | 0,12 € |
Zenerdiode | MM3Z12VT1G | SOD-323 | FA1 | 1 | 0,03 € |
Widerstand | 100 kΩ | 0603 | RA1, RA6, RA7 | 3 | 0,09 € (0,03 €/St.) |
Kondensator | 150 nF | 0603 | CA1 | 1 | 0,15 € |
Spannungsregler | LM3480IM3-5.0/NOPB | SOT-23 | TA1 | 1 | 1,18 € |
Kondensator | 1µF | 0603 | CA2 | 1 | 0,02 € |
Schottkydiode | BAT54J | SOD-323F | RA2, RA4 | 2 | 0,12 € (0,06 €/St.) |
Stiftleiste | 1x2 | 2,54 mm | XG1 | 1 | 0,05 € |
Kurzschlussbrücke | - | 2,54 mm | für XG1, XE1 | 2 | 0,04 € (0,02 €/St.) |
Widerstand | 120 Ω | 1206 | RA3 | 1 | 0,04 € |
Kondensator | 1 nF | 0603 | RB1 | 1 | 0,02 € |
Drehcodierschalter | Hexadezimal | 3+3 SMD | SF1, SF2 | 2 | 3,98 € (1,99 €/St.) |
Knopfzellenhalter | KEYSTONE 1069 | 16 mm | UA1 | 1 | 1,74 € |
Knopfzelle | 3V | 16 mm | für UA1 | 1 | 2,04 € |
Mosfet (P-Channel) | IRLML2244TRPBF | SOT-23 | QA2 | 1 | 0,18 € |
Widerstand | 1kΩ | 0603 | RA5 | 1 | 0,03 € |
Stiftleiste | 2x3 | 2,54 mm | XZ2 | 1 | 0,14 € |
485-IC | MAX485CSA+ | SO-8 | TF1 | 1 | 1,55 € |
Kondensator | 100 nF | 0603 | CA3, CA4 | 2 | 0,04 € (0x02 €/St.) |
Stiftleiste | 2x2 | 2,54 mm | XE1 | 1 | 0,09 € |
Widerstand | 1.8 kΩ | 0603 | RA8 | 1 | 0,03 € |
LED | TLMY 1000 | 0603 | PF1 | 1 | 0,20 € |
Transistor (NPN) | BCW32 | SOT-23 | QA3 | 1 | 0,05 € |
Widerstand | 470 kΩ | 0603 | RA9 | 1 | 0,03 € |
Mikrocontroller | ATTINY861A-SU | SOIC-20 | AF1 | 1 | 1,25 € |
Widerstand | 10 kΩ | 0603 | RA10 | 1 | 0,03 € |
Lichtleiter | - | 3,2 mm | für PF1 | 1 | 0,40 € |
Kabelverschraubung | - | M16x1,5 | - | 1 | 0,55 € |
Gegenmutter | - | M16x1,5 | - | 1 | 0,28 € |
Blechschraube | PAN-Head | 2,9x6,5 mm | - | 3 (MOQ: 100) | 1,99 € |
Magnetoresistiver Sensor | SM351LT | SOT-23 | BE1 | 1 | 0,79 €** |
SUMME: ~18,84€ (Ohne Platine und Anschlussleitung)
*: Die oben genannten Preise wurden am 24.02.2021 bei Reichelt ermittelt. Die wirklichen Preise können abweichen.
**: Der Preis für den magnetoresistiven Sensor wurde am 24.02.2021 bei Conrad ermittelt. Der wirkliche Preis kann abweichen.
Nachfolgend ist eine Materialliste bei Reichelt verlinkt (Der magnetoresistive Sensor ist nicht enthalten!).
Bei dem genannten Händler handelt es sich um ein unabhängiges Beispiel. Natürlich können die Materialien bei jedem beliebigen Händler erworben werden.
Reichelt: Lesekopf
-
28.03.2021:
- Erstveröffentlichung
-
02.01.2022:
- Kondensator CA1 wegen zu niedriger Spannungsfestigkeit getauscht
-
16.01.2022:
-
Firmwareaktualisierung auf Version 1.1.0:
- Vorteiler für den internen Oszillator des Mikrocontrollers wird automatisch auf 0 gesetzt, sodass der Mikrocontroller mit 8 MHz arbeitet. Eine manuelle Anpassung in den Fuse-Bits ist nicht mehr notwendig.
- Signal des magnetoresistiven Sensors wird nun auch im Batteriebetrieb erkannt.
-
Firmwareaktualisierung auf Version 1.1.0:
-
15.02.2023:
- Gehäuse mit einer größeren Fase versehen