define(`TITLE', `M-Bus Master, Part 3 (Water)') define(`DATE', `2013-09-10') define(`CONTENT', ` Now, also the water meter talks to me. Wasserzaehler (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.
laser-drucker_005120 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.
Responding the 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.) ')