define(`TITLE', `M-Bus Master, Part 3 (Water)')
define(`DATE', `2013-09-10')
define(`CONTENT', `
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>

(Note the thin grey cable, that'`s the M-Bus cable.)

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>

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.

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.)

')