116 lines
4.8 KiB
HTML
Raw Normal View History

2018-05-08 17:25:41 +02:00
define(`TITLE', `M-Bus Master, Part 3 (Water)')
define(`DATE', `2013-09-10')
define(`CONTENT', `
2018-05-02 16:30:12 +02:00
Now, also the water meter talks to me.
<a href="http://a385e-5.de/wp-content/uploads/2013/09/Wasserzaehler.jpg"><img src="http://a385e-5.de/wp-content/uploads/2013/09/Wasserzaehler-225x300.jpg" alt="Wasserzaehler" width="225" height="300" class="alignnone size-medium wp-image-173" /></a>
2018-05-08 17:25:41 +02:00
(Note the thin grey cable, that'`s the M-Bus cable.)
2018-05-02 16:30:12 +02:00
And, after a small modification of the circuit I can talk to water meter and electric power meter connected in parallel to the master.
<blockquote>
<a href="http://a385e-5.de/wp-content/uploads/2013/09/laser-drucker_005120.jpg"><img src="http://a385e-5.de/wp-content/uploads/2013/09/laser-drucker_005120-209x300.jpg" alt="laser-drucker_005120" width="209" height="300" class="alignnone size-medium wp-image-192" /></a>
2018-05-08 17:25:41 +02:00
IC2 was already added in the last step, since the output of the analog circuit and the requirements of the MCU didn'`t match concerning their logical polarity.
2018-05-02 16:30:12 +02:00
Now, T3 (BS108) and R9 (2k2) have been added to disable the receive path while data is transmitted.
</blockquote>
Responding the <code>REQ_UD2</code> command, the water meter sends this telegram (address 0x30 has been assigned to it first):
<code>
so 10 5b 30 8b 16
success
SO RESP: 68 46 46 68 08 30 72 45 71 43 00 24 23 25 07 02 00 00 00 0C
13 51 84 00 00 8C 10 13 00 00 00 00 0B 3B 00 00 00 0B 26 62 06 00 02
5A CC 00 04 6D 17 16 A9 19 7C 13 00 00 00 00 FC 10 13 00 00 00 00 72
6C 00 00 42 EC 7E BF 1C 35 16
</code>
A closer look, consulting the <a href="http://www.m-bus.com/mbusdoc/md8.php" title="M-Bus documentation" target="_blank">M-Bus documentation</a> reveals the meaning:
[table]Octet(s), Field, Meaning
<code>68 46 46 68</code>, Preamble with length,
<code>08</code>, C field,
<code>30</code>, A field (address),
<code>72</code>, CI field, variable data response
<code>45 71 43 00</code>, Ident. No.,
<code>24 23</code>, Manufacturer , HYD = Hydrometer GmbH
<code>25</code>, Version,
<code>07</code>, Medium, Water
<code>02</code>, Access No.,
<code>00</code>, Status,
<code>00 00</code>, Signature,
<code>0C</code>, DIF, 8 digit BCD
<code>13</code>, VIF, Volume; 10^(3-6)m^3
<code>51 84 00 00</code>, Value, 8.451m^3
<code>8C</code>, DIF, ext; 8 digit BCD
<code>10</code>, DIFE, minimum value
<code>13</code>, VIF, Volume; 10^(3-6)m^3
<code>00 00 00 00</code>, Value, 0
<code>0B</code>, DIF, 6 digit BCD
<code>3B</code>, VIF, Volume flow; 10^(3-6)m^3/h
<code>00 00 00</code>, Value, 0
<code>0B</code>, DIF, 6 digit BCD
<code>26</code>, VIF, Operating time; hours
<code>62 06 00</code>, Value, 662h = 27.6d
<code>02</code>, DIF, 16bit integer
<code>5A</code>, VIF, Flow Temperature; 10^(2-3)°C
<code>CC 00</code>, Value, 20.4°C
<code>04</code>, DIF, 32bit integer
<code>6D</code>, VIF, Time Point; time&amp;date
<code>17 16 A9 19</code>, Value,
<code>7C</code>, DIF, LSB; value during error state; 8 digit BCD
<code>13</code>, VIF, Volume; 10^(3-6)m^3
<code>00 00 00 00</code>, Value, 0
<code>FC</code>, DIF, ext; LSB; value during error state; 8 digit BCD
<code>10</code>, DIFE, tariff 1
<code>13</code>, VIF, Volume; 10^(3-6)m^3
<code>00 00 00 00</code>, Value, 0
<code>72</code>, DIF, LSB; value during error state; 16bit integer
<code>6C</code>, VIF, Time Point; date
<code>00 00</code>, Value, 0
<code>42</code>, DIF, LSB; 16bit integer
<code>EC</code>, VIF, ext; Time Point; date
<code>7E</code>, VIFE, ??
<code>BF 1C</code>, Value,
<code>35</code>, Checksum,
<code>16</code>, Stopbyte,
[/table]
Decoding of the time&amp;date type is done like this:
<pre>
if (t_data)
{
if (t_data_size == 4) // Type F = Compound CP32: Date and Time
{
if ((t_data[0] &amp; 0x80) == 0) // Time valid ?
{
t-&gt;tm_min = t_data[0] &amp; 0x3F;
t-&gt;tm_hour = t_data[1] &amp; 0x1F;
t-&gt;tm_mday = t_data[2] &amp; 0x1F;
t-&gt;tm_mon = (t_data[3] &amp; 0x0F) - 1;
t-&gt;tm_year = ((t_data[2] &amp; 0xE0) &gt;&gt; 5) |
((t_data[3] &amp; 0xF0) &gt;&gt; 1);
t-&gt;tm_isdst = (t_data[1] &amp; 0x80) ? 1 : 0; // day saving time
}
}
else if (t_data_size == 2) // Type G: Compound CP16: Date
{
t-&gt;tm_mday = t_data[0] &amp; 0x1F;
t-&gt;tm_mon = (t_data[1] &amp; 0x0F) - 1;
t-&gt;tm_year = ((t_data[0] &amp; 0xE0) &gt;&gt; 5) |
((t_data[1] &amp; 0xF0) &gt;&gt; 1);
}
}
</pre>
(Found on github in the libmbus repo.)
2018-05-08 17:25:41 +02:00
')