M-BUS – Wasserzähler

Von einem Freund habe ich einen M-Bus (Meter-Bus) Wasserzähler und einen Wärmemengenzähler bekommen. Der M-BUS ist ein Feldbus der über eine Zweidrahtleitung über sehr lange Strecken genutzt werden kann. Ein M-BUS Master fragt dabei alle Slaves im Strang oder Stern ab. Die Slaves werden teilweise vom M-Bus-Master mit Spannung versorgt. Mehr Details im Wiki.

Techem Wärmemengenzähler Techem Wasserzähler

Der M-Bus-Master sollte in meinem Fall aus dem Raspberry und einem Pegelwandler bestehen. Pegelwandler gibt es fertig von verschiedenen Herstellen (Relay, Wachendorff). Diese sind aber, je nachdem für wieviele Slaves sie ausgelegt sind, relativ teuer.

Mein erster Ansatz war daher der Selbstbau eines Pegelwandlers inkl. RS232-Schnittstelle zum Anschluss an den Raspberry Pi. Im Netz gibt es verschiedene Beschreibungen einer einfachen Schaltung und einige wenige Forumseinträge die sich mit dem Selbstbau eines Pegelwandlers bzw. generell mit M-Bus beschäftigen. Leider habe ich in keinem Forum eine Diskussion gefunden die bis zu einem funktionierenden System verfolgt wurde. Egal, ich habe es trotzdem mal versucht…

 

Selbstbau Pegelwandler

Auf der Platine ist der Pegelwandler inkl. einer RSA232 Schnittstelle die aus einem MAX3232 besteht. Die +/-15 Volt für den Pegelwandler habe ich mittels DCDC-Wandler IH0515S der Fa. XP Power erzeugt. Dieses Bauteil kann man z.B. bei Farnell beziehen. Dann das Ganze auf Lochraster zusammen gelötet und mit dem Raspi und dem Wärmemengenzähler verbunden.

IMG_7707 IMG_7708

max3232Lochrasterplan

Damit der Raspberry das M-Bus Protokoll versteht bzw. auch den Pegelwandler korrekt anspricht, habe ich die Bibliotheken von rSCADA genutzt. Die Quellen liessen sich problemlos auf dem Raspberry kompilieren. Im Ergebnis wurden verschiedene Binaries erzeugt um mit Slaves im Bus zu kommunizieren.

Meine ersten Versuche waren jedoch nicht von Erfolg gekrönt. Es wurde kein M-Bus-Gerät gefunden. Bei der Fehlersuche habe ich zuerst die serielle Schnittstelle separat getestet und mit Minicom über den Raspberry mit einem anderen Linux-Rechner kommuniziert. Das hat funktioniert. Die weitere Fehlersuche z.B. am M-Bus-Ausgang sind allerdings am fehlenden Oszilloskop gescheitert, da das Multimeter mich nicht wirklich weiter brachte.

Etwas niedergeschlagen habe ich dann nach drei Tagen erfolgloser Fehlersuche nochmal nach fertigen Pegelwandlern gesucht und ein relativ preiswertes Gerät gefunden und kurzerhand gekauft. Damit fiel die Fehlerquelle “Pegelwandler” schon mal weg.

 

Versuch mit gekauftem Pegelwandler

Der neue Pegelwandler benötigt zum Anschluss an den Raspberry Pi auch eine RS232 Schnittstelle. Um mir diesmal das Löten zu ersparen, hab ich erstmal den kompletten Versuchsaufbau auf einem Breadboard gesteckt. Der Pegelwandler läuft mit einer Spannung von 12-24 V DC weshalb ich den DCDC-Wandler aus dem ersten Versich auch nicht benötige.

IMG_7739

Die Binaries von rSCADA unterscheiden zwischen TCP- und seriell angeschlossenen M-Bus-Pegelwandlern. Da meiner seriell angeschlossen ist, benutze ich “mbus-serial-scan” um nach angeschlossenen Slaves im Bus zu suchen.
Als Argumente übergebe ich “-d” für den Debugmodus, “-b 2400” um 2400 Baud zu nutzen und “/dev/ttyAMA0” als serielle Schnittstelle des Pi.

Zu meiner Überraschung wurde direkt ein Slave (der Wasserzähler) erkannt. Sehr schön…

pi@raspberry2 ~/libmbus-0.8.0/bin $ ./mbus-serial-scan -d -b 2400 /dev/ttyAMA0
Scanning primary addresses:
0 [2014-12-13 13:59:21] SEND (005): 10 40 00 40 16
[2014-12-13 13:59:21] RECV (001): E5

Found a M-Bus device at address 0
1 [2014-12-13 13:59:22] SEND (005): 10 40 01 41 16
2 [2014-12-13 13:59:22] SEND (005): 10 40 02 42 16
3 [2014-12-13 13:59:22] SEND (005): 10 40 03 43 16
4 [2014-12-13 13:59:22] SEND (005): 10 40 04 44 16
5 [2014-12-13 13:59:23] SEND (005): 10 40 05 45 16
6 [2014-12-13 13:59:23] SEND (005): 10 40 06 46 16
7 [2014-12-13 13:59:23] SEND (005): 10 40 07 47 16
...

Hat man alle angeschlossenen M-Bus-Geräte per Scan identifiziert, können mit einem weiteren Programm die Daten des Gerätes ausgelesen werden. Auch hier gibt es wieder das Argument “-d” für den Debugmodus, “-b” zur Einstellung der Baudrate, das Device der seriellen Schnittstelle und die vom Scan ermittelte Device-Nummer. Im Fall meines Wasserzählers ist das die “0”. Die Daten der Slaves werden in einer einfachen XML-Struktur zurück geliefert.

./mbus-serial-request-data -d -b 2400 /dev/ttyAMA0 0
[2014-12-13 14:06:46] SEND (005): 10 5B 00 5B 16
[2014-12-13 14:06:47] RECV (084): 68 4E 4E 68 08 00 72 12 37 16 46 68 50 49 07 B6 00 00 00 0C 14 53 42 00 00 8C 10 12 35 53 42 00 0B 3B 00 00 00 8C 20 14 53 42 00 00 8C 30 14 00 00 00 00 04 6D 21 0F CD 1C 4C 14 02 00 00 00 42 6C BF 1C 42 EC 7E DF 1C 0A 92 2A 00 10 0A 92 2B 00 10 3E 16
mbus_frame_print: Dumping M-Bus frame [type 4, 84 bytes]: 68 4E 4E 68 08 00 72 12 37 16 46 68 50 49 07 B6 00 00 00 0C 14 53 42 00 00 8C 10 12 35 53 42 00 0B 3B 00 00 00 8C 20 14 53 42 00 00 8C 30 14 00 00 00 00 04 6D 21 0F CD 1C 4C 14 02 00 00 00 42 6C BF 1C 42 EC 7E DF 1C 0A 92 2A 00 10 0A 92 2B 00 10 3E 16



46163712
TCH
73

Water
182
00
0000



Instantaneous value
Volume (1e-2  m^3)
4253
2014-12-13T14:06:47



Instantaneous value
Volume (1e-4  m^3)
425335
2014-12-13T14:06:47

...

Da es auf Anhieb funktioniert hat, habe ich die serielle Schnittstelle auf Lochraster gebannt und der Pegelwandler wird mittels kleinem 12V-Netzteil betrieben. Dann Raspberry Pi, Pegelwandler und Platine im Netzwerkschrank verstauen…

MAX3232

 

Software

Den Stand des Wasserzählers protokolliere ich nun einmal täglich um 23:59 Uhr. Das wird per Cronjob und einem kleinen PHP-Script erledigt. Warum PHP? Weil ich zu ungeduldig war und das schnell umsetzen wollte und schon das ein oder andere ähnliche PHP-Script fertig hatte.

Das Script ruft das Binary wie oben erklärt per shell_exec auf. Ab dem XML-Teil parse ich die Ausgabe und extrahiere die relevanten Informationen die dann in eine MySQL-Tabelle geschrieben werden.

[cc lang=”php”]
‘));
$xmloutput = new SimpleXMLElement($xmloutput);
$zaehlerID=$xmloutput->SlaveInformation->Id;
$zaehlerStand=$xmloutput->DataRecord[1]->Value/10000;

$mysqlhost=””;
$mysqluser=””;
$mysqlpwd=””;
$connection=mysql_connect($mysqlhost,$mysqluser,$mysqlpwd) or die (“Verbindungsversuch fehlgeschlagen”);
$mysqldb=””;
mysql_select_db($mysqldb,$connection) or die(“Konnte die Datenbank nicht waehlen.”);
$sql = “INSERT INTO wasserzaehler (timestamp,zaehlerid,zaehlerstand) VALUES (CURRENT_TIMESTAMP,$zaehlerID,$zaehlerStand)”;
$query = mysql_query($sql) or die(“Anfrage 1 nicht erfolgreich”);
?>;
[/cc]

Da ich auf meiner Webseite aber nicht nur den absoluten Wasserverbrauch darstellen möchte sondern auch den Tagesverbrauch, kommt folgendes SQL zum Einsatz. Hier werden die Einträge aus zwei aufeinanderfolgenden Zeilen subtrahiert um die Differenz zum Vortag zu bestimmen.

SELECT 
    CASE DATE_FORMAT(wz1.timestamp,'%w')
	WHEN 0 THEN 'Sonntag'
	WHEN 1 THEN 'Montag'
	WHEN 2 THEN 'Dienstag'
	WHEN 3 THEN 'Mittwoch'
	WHEN 4 THEN 'Donnerstag'
	WHEN 5 THEN 'Freitag'
	WHEN 6 THEN 'Samstag'
    ELSE 'fehler' END,
	wz1.zaehlerstand - IFNULL(wz2.zaehlerstand, 0) AS verbrauch
    FROM wasserzaehler wz1
    LEFT JOIN wasserzaehler wz2
    ON wz2.timestamp = (
	SELECT MAX(timestamp)
	FROM wasserzaehler wz3
	WHERE wz3.timestamp < wz1.timestamp
   )
ORDER BY wz1.timestamp

Das Ergbnis sieht dann wie folgt aus. Ich war etwas erschreckt wieviel Wasser man an machen Tagen verbraucht!

wasserzaehler_screenshot

 

Selbstgebauter Pegelwandler

Da ich ja nun weiß das es generell funktioniert und der Fehler meiner ersten Lösung definitiv im selbstgebauten Pegelwandler liegt, werde ich den Versuch mit dem Selbstbau demnächst nochmal angehen.

 

Sobald der Wärmemengenzähler in den Wasserlauf des Kachelofens eingebaut ist, werde ich nochmal einen kurzen Beitrag schreiben. Das Prinzip des Auslesens ist ja analog zum Wasserzähler aber vielleicht gibt es in den zurückgelieferten Daten unterschiede.

 

Viel Spaß mit dem M-Bus!

Chris

21 Gedanken zu „M-BUS – Wasserzähler

  • Pingback: Vorlauf- und Rücklauf vom Kachelofen mittels 1-wire Temperatursensoren | bubuxblog

  • 28. August 2015 um 12:28 Uhr
    Permalink

    Hallo Chris,

    das klingt eigentlich genau, nach dem was ich suche – abgesehen davon, dass ich vermeiden wollte nochmal 100 EUR für so einen fertigen Pegelwandler auszugeben.

    Mir ist jetzt nicht ganz klar, ob Du den Fehler in Deiner DIY-Lösung inzwischen gefunden hast und es jetzt auch ohne das teure Zusatzgerät funktioniert bzw. funktionieren würde.
    (Quote: “Da ich ja nun weiß das es generell funktioniert und der Fehler meiner ersten Lösung definitiv im selbstgebauten Pegelwandler liegt, werde ich den Versuch mit dem Selbstbau demnächst nochmal angehen.”)

    Solltest Du eine funktionierende DIY-Lösung haben, wäre ich sehr daran interessiert.

    Habe gerade noch den Link in Deinem Artikel zu http://www.m-bus.de/pw1.html entdeckt. Ist es denn diese Schaltung die Du nachgebaut hast?

    Was Deinen Schaltplan angeht: “1” und “2” sind die beiden Adern des M-Bus Anschluß, oder? Ist es da egal wie ich meinen Sensor anschließe? Laut Datenblatt des Herstellers geht “grün” an GND und “Weiss” an einen “NPN” Eingang in einer SPS.

    VG
    Markus

    Antwort
    • 30. August 2015 um 09:21 Uhr
      Permalink

      Hallo Markus,

      wie das oft so ist wenn man eine funktionierende Lösung hat, bin ich noch nicht dazu gekommen nach dem Problem mit der DIY-Platine zu schauen. Vielleicht diesen Winter…
      Ja, im Prinzip ist es diese Schaltung. Die gibt es mit kleinen Variationen auf verschiedenen Seiten im Internet.
      Ich habe noch die Stromversorgung für den M-Bus und den Maxim Pegelwandler für den Anschluss an den Raspberry Pi mit verbaut.

      Beim Anschluss der Geräte an den M-Bus wäre mir nicht bekannt, das man auf eine Polung achten müsste (zumindest nicht bei dem gekauften Pegelwandler).
      Bei meiner Platine könnte ich das nochmal testen!

      Gruß
      Chris

      Antwort
      • 19. Juni 2017 um 15:29 Uhr
        Permalink

        Hallo Chris

        auf der suche nach einer Möglichkeit meinen M-Bus E-Zähler auszulesen bin ich auf deine Seite gestoßen.
        Bei dem bestellen der benötigten Teile, um deine Schaltung zu realisieren, bin ich vermutlich auf dein Fehler gestoßen warum deine Lochrasterplatine nicht funktioniert.
        Vorausgesetzt du bist noch auf der suche…
        Schau dir mal dein DC/DC Wandler an laut deinem Schaltbild wird dein Bus nur mit 15V betrieben. Da am Ausgang 0V mit GND zusammen geführt und nur die -15V beschaltet hast. Jetzt könntest du ja versuchen die -15V mit GND zusammen zu führen und den +15V auf den Bus zu geben (0V bleibt frei) jetzt sollte dein Bus mit 30V arbeiten was gerade so in der Spec. liegt (Logisch Null = 24V; Logisch High=36V)

        Wenn ich alles zusammen habe kann ich es selber testen aber vielleicht hast die die Platine noch nicht begraben und kannst es versuchen.

        Grüße Martin

        Antwort
        • 20. Juni 2017 um 17:14 Uhr
          Permalink

          Hallo Martin,

          danke für den Tip. die Platine liegt noch auf meinem Werktisch und ich werde es mal testen. Im Keller ist es schön kühl 🙂

          Gruß
          Chris

          Antwort
        • 2. August 2017 um 21:41 Uhr
          Permalink

          Hallo Martin & Chris,

          habt ihr die Schaltung zwischenzeitlich aufgebaut und getestet?
          Ich hab bei mir den Volkszähler am laufen und würde neben DMLS, S0 und W1therm auch gerne M-Bus Zähler anbinden, der Preis für kommerzielle M-Bus Master schreckt mich allerdings ab. Sollte die Schaltung funktionieren, wäre das eine geniale Alternative zu den kommerziellen Produkten.

          Schöne Grüße
          Michael

          Antwort
          • 11. August 2017 um 14:52 Uhr
            Permalink

            Hallo Michael,
            ich bin leider noch nicht dazu gekommen und da ich eine funktionierende Variante habe, ist mein Antrieb auch leider nicht so groß. Die Platine liegt aber noch hier.
            Widme mich gerade meinem Holzbackofen-Projekt. Da bleibt nicht so viel Zeit für anderes.

            Gruß
            Chris

          • 30. März 2018 um 23:54 Uhr
            Permalink

            Schau dir mal die Schaltung hier an: https://github.com/rscada/libmbus/blob/master/hardware/MBus_USB.pdf . Ich hatte diese mal nachgebaut, allerdings ohne Step-Up-Spannungswandler und und ohne FTDI-Teil. Den Spannungswandler habe ich ersetzt durch einen Printrtrafo mit 2x12V + B80-Diodenbrücke und 220uF/50V Elko; den FTDI durch ein fertiges Kabel TTL-232R-3V3 (mit bereits integriertem FTDI).

            Zum Zähler-Auslesen unter Windows kannst du den auf win portierten libmbus benutzen: https://github.com/xaelsouth/libmbus-winport/tree/master/msvc/libmbus/Release

            Wenn du COM-Port > 9 benutzen musst, dann in der Commandline \\.\\COM99 eingeben.

  • 3. Oktober 2016 um 22:04 Uhr
    Permalink

    Hallo Chris

    Bei mir läuft unter Windows mein Energiezähler (gleicher Pegelwandler wie du hast). Ich möchte jetzt das ganze auf dem Raspberry PI2 laufen lassen. Ich habe jedoch meine Probleme bei der Installation von libmbus. Kannst du mir schrittweise erklären, wie ich den Installieren muss? Ich habe es noch nicht so mit Linux.

    Antwort
  • 26. Juli 2017 um 12:57 Uhr
    Permalink

    Hallo,

    danke für deinen hilfreichen Beitrag!

    Ich hätte aber eine Frage, wie würde es aussehen, wenn man versucht die Ausgabe in Python zu verwerten?

    Habe dazu mal versucht:
    !/usr/bin/python

    from xml.dom import minidom
    from pdb import set_trace as bkp
    import subprocess

    bashCommand = “mbus-serial-request-data -d -b 2400 /dev/serial0 10”
    process = subprocess.Popen(bashCommand.split(), stdout=subprocess.PIPE)
    output, error = process.communicate()

    Ich erhalte eine Antwort versuche ich das nun aber in xml zu parsen klappts nicht… auch sieht die Ausgabe anders aus.

    Wenn ich den Befehl direkt in der BASH ausführe wird eine XML Formatierung zusätzlich ausgegeben…bei indirekten Aufruf von Python aus leider nicht…

    Vieleicht hast du eine Idee…

    Danke!

    Antwort
    • 29. Juli 2017 um 17:46 Uhr
      Permalink

      Hallo Daniela,

      das XML sieht etwas “zerhackt” aus aber grundsätzlich kommt die MBUS-Antwort zurück.
      Schick doch auch mal den Rest des Scripts wo Du die XML-Ausgabe parst.

      Gruß
      Chris

      Antwort
  • 31. Juli 2017 um 10:16 Uhr
    Permalink

    Mein Script sieht derzeit so aus:

    `#!/usr/bin/python

    from xml.dom import minidom
    from pdb import set_trace as bkp
    import subprocess

    bashCommand = “mbus-serial-request-data -d -b 2400 /dev/serial0 10”
    process = subprocess.Popen(bashCommand.split(), stdout=subprocess.PIPE)
    output, error = process.communicate()

    #mbusdata = minidom.parseString(output)

    Ich erhalte allterdings eine Fehlermeldung:

    Traceback (most recent call last): File “test.py”, line 13, in mbusdata = minidom.parseString(output) File “/usr/lib/python2.7/xml/dom/minidom.py”, line 1928, in parseString return expatbuilder.parseString(string) File “/usr/lib/python2.7/xml/dom/expatbuilder.py”, line 940, in parseString return builder.parseString(string) File “/usr/lib/python2.7/xml/dom/expatbuilder.py”, line 223, in parseString parser.Parse(string, True) xml.parsers.expat.ExpatError: syntax error: line 1, column 0

    Wobei ich vermute dass es sich dabei um keine ordnungsgemäße Antwort handelt (XML) Format handelt …

    Antwort
    • 11. August 2017 um 15:42 Uhr
      Permalink

      Hallo Daniela,

      ich denke Deine Vermutung ist richtig. In “output” nicht nur XML, sondern auch noch Text und ein HEX-Frame. Das müsstest Du zuerst beschneiden indem Du den Start des XMLs raus suchst. Im PHP z.B. so:
      $xmloutput=substr($output,strpos($output,’‘));

      Das ist in meinem Beispielcode im Artikel durch das WYSIWYG verloren gegangen. Habe das korrigiert.

      Gruß
      Chris

      Antwort
  • 8. August 2017 um 13:43 Uhr
    Permalink

    Hallo Chris,

    ich bekomme bei dem Aufbau leider keine Antwort des Pegelwandlers. Anstelle des Max3232 verwende ich den KY-051 Voltage Translator. Wie sind denn die Einstellungen deiner seriellen Schnittstelle?

    Gruß
    Martin

    Antwort
    • 11. August 2017 um 14:54 Uhr
      Permalink

      Hi Martin,

      Du meinst bei der Selbstbau-Platine?
      Das weiß ich leider nicht mehr. Gefühlt habe ich alles 10x durchprobiert.

      Gruß
      Chris

      Antwort
    • 30. März 2018 um 23:58 Uhr
      Permalink

      Die meisten Zähler werden mit 2400 baud mit 8E1 (parity even!) ausgelesen.

      Antwort
  • 19. September 2018 um 19:15 Uhr
    Permalink

    Hi an Alle!
    Ich habe die Schaltung
    http://m-bus.de/pw1.html
    schon mehrfach aufgebaut. Es funktioniert. Bei einer Änderung von R10 Widerstand lassen sich sogar mehr als 20 M-Bus Zähler auslesen. Selbst habe ich mit 22 Zählern ausprobiert. Man muss halt für gute Kühlung bei Transistor T5 achten. Die Schaltung hat aber keine galvanische Trennung, was zu Problemen bei langen Busleitungen führen kann – Überspannungen die zum Beispiel bei Gewitter entstehen. Eine Supresor-Diode von 50-60 Volt am Ausgang wäre nicht schlecht.
    Einen teuren Server würde ich da aber nicht anschließen.
    Die Versorgung Spannung kann auch +/- 12 Volt betragen.

    Antwort
  • 11. August 2021 um 08:04 Uhr
    Permalink

    Jetzt mal abseits der inhaltlichen Diskussion:
    Können wir mal kurz festhalten, dass ich begeistert bin von der professionellen Gestaltung Deiner Lochrasterplatine und wie unverschämt gut Du die Komponenten verlötet hast? 🙂

    Antwort
    • 14. August 2021 um 10:18 Uhr
      Permalink

      Hallo Christian,

      danke danke! Ich bin da etwas pedantisch 😉 und habe es auch vor längerer Zeit mal in der Ausbildung gelernt.
      Also immer schön den Draht vorher strecken und auf glänzende konkave Lötstellen achten.

      Gruß
      Chris

      Antwort

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert