define(`TITLE', `M-Bus Master, Part 3 (Water)')
define(`DATE', `2013-09-10')
define(`CONTENT', `
Now, also the water meter talks to me.
(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.
Responding theIC2 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.
REQ_UD2
command, the water meter sends this telegram (address 0x30 has been assigned to it first):
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
A closer look, consulting the M-Bus documentation reveals the meaning:
[table]Octet(s), Field, Meaning
68 46 46 68
, Preamble with length,
08
, C field,
30
, A field (address),
72
, CI field, variable data response
45 71 43 00
, Ident. No.,
24 23
, Manufacturer , HYD = Hydrometer GmbH
25
, Version,
07
, Medium, Water
02
, Access No.,
00
, Status,
00 00
, Signature,
0C
, DIF, 8 digit BCD
13
, VIF, Volume; 10^(3-6)m^3
51 84 00 00
, Value, 8.451m^3
8C
, DIF, ext; 8 digit BCD
10
, DIFE, minimum value
13
, VIF, Volume; 10^(3-6)m^3
00 00 00 00
, Value, 0
0B
, DIF, 6 digit BCD
3B
, VIF, Volume flow; 10^(3-6)m^3/h
00 00 00
, Value, 0
0B
, DIF, 6 digit BCD
26
, VIF, Operating time; hours
62 06 00
, Value, 662h = 27.6d
02
, DIF, 16bit integer
5A
, VIF, Flow Temperature; 10^(2-3)°C
CC 00
, Value, 20.4°C
04
, DIF, 32bit integer
6D
, VIF, Time Point; time&date
17 16 A9 19
, Value,
7C
, DIF, LSB; value during error state; 8 digit BCD
13
, VIF, Volume; 10^(3-6)m^3
00 00 00 00
, Value, 0
FC
, DIF, ext; LSB; value during error state; 8 digit BCD
10
, DIFE, tariff 1
13
, VIF, Volume; 10^(3-6)m^3
00 00 00 00
, Value, 0
72
, DIF, LSB; value during error state; 16bit integer
6C
, VIF, Time Point; date
00 00
, Value, 0
42
, DIF, LSB; 16bit integer
EC
, VIF, ext; Time Point; date
7E
, VIFE, ??
BF 1C
, Value,
35
, Checksum,
16
, Stopbyte,
[/table]
Decoding of the time&date type is done like this:
if (t_data) { if (t_data_size == 4) // Type F = Compound CP32: Date and Time { if ((t_data[0] & 0x80) == 0) // Time valid ? { t->tm_min = t_data[0] & 0x3F; t->tm_hour = t_data[1] & 0x1F; t->tm_mday = t_data[2] & 0x1F; t->tm_mon = (t_data[3] & 0x0F) - 1; t->tm_year = ((t_data[2] & 0xE0) >> 5) | ((t_data[3] & 0xF0) >> 1); t->tm_isdst = (t_data[1] & 0x80) ? 1 : 0; // day saving time } } else if (t_data_size == 2) // Type G: Compound CP16: Date { t->tm_mday = t_data[0] & 0x1F; t->tm_mon = (t_data[1] & 0x0F) - 1; t->tm_year = ((t_data[0] & 0xE0) >> 5) | ((t_data[1] & 0xF0) >> 1); } }(Found on github in the libmbus repo.) ')