define(`TITLE', `Revisiting the MeterBus master') define(`DATE', `2015-06-05') define(`CONTENT', ` I was already talking about the network attached MeterBus master here and here early. By now, a cronjob on my MacMini in the basement was querying the device every minute to collect measurement results from the attached meters (water, gas, electricity, out door temperature). Now, I changed and improved the software slightly: First, I enabled the watchdog timer, since it occasionally happened that the device became unresponsive. In this case now the watchdog timer is triggered to reset the beast. Second, I modified the upstream communication. Now the master publishes the results of configured meters using the MQTT protocol. Doing this, I ran into another problem with the MQTT library from http://knolleary.net/arduino-client-for-mqtt/. I had to increase the maximum packet size to 1024 bytes since some of the meters sent about 250 bytes, which I represent in a hex string in the MQTT payload. But as soon as the packet was higher the 256 bytes, only the first 256 bytes had been sent to the broker. Tracking this down to the `write` method in the MQTT library I found a `uint8_t` which a `uint16_t` should be: [code language="cpp"] boolean PubSubClient::write(uint8_t header, uint8_t* buf, uint16_t length) { uint8_t lenBuf[4]; uint8_t llen = 0; uint8_t digit; uint8_t pos = 0; uint8_t rc; uint8_t len = length; [/code] Using `uint16_t` for the variable `len` immediately fixed this problem. Aha, and enabling the watchdog on the Teensy was also not that easy. Finally, I came to this solution: [code language="cpp"] extern "C" { void startup_early_hook( ) __attribute__ ((weak)); void startup_early_hook() { // enable watchdog WDOG_UNLOCK = WDOG_UNLOCK_SEQ1; WDOG_UNLOCK = WDOG_UNLOCK_SEQ2; // one minute WDOG_TOVALL = 0xea60; WDOG_TOVALH = 0; WDOG_PRESC = 0; WDOG_STCTRLH = WDOG_STCTRLH_WDOGEN | WDOG_STCTRLH_ALLOWUPDATE | WDOG_STCTRLH_STOPEN | WDOG_STCTRLH_WAITEN; } } // extern "C" [/code] It this require the enable the watchdog in the `startup_early_hook` since the Cortex accepts it only the first 256 clock cycles. Next, the `extern "C"` is important, otherwise the link does not find the overwrite of the function, since it is compile with a C++ file. The clock for the watchdog is taken from the LPO of the CPU, which is running at 1kHz. Thus, a timeout value of 0xea60 equals 60000 let to a watchdog timeout of one minute. Reading the K20 reference manual, which I found on the Teensy homepage, was really helpful here. Today, all the measurements from a couple of meters find their way via MQTT and a small serverside script into the MongoDB for further analysis. [code language="javascript"] { "data":{ "telegram":"68 38 38 68 08 51 72 10 01 00 13 2E 19 24 02 9C 00 00 00 8C 10 04 12 06 00 00 8C 11 04 12 06 00 00 02 FD C9 FF 01 E2 00 02 FD DB FF 01 00 00 02 AC FF 01 00 00 82 40 AC FF 01 00 00 09 16 ", "uptime":52815 }, "metadata":{ "device":"MeterbusHub", "token":5, "name":"dryer" } } { "data":{ "telegram":"68 61 61 68 08 21 72 00 00 00 00 00 00 01 00 AA 00 00 00 01 24 03 01 25 0A 01 26 10 02 27 01 00 05 67 28 14 B3 3D 05 67 D2 45 E3 BA 05 67 9F B5 A7 41 05 67 79 13 E0 41 0F D0 27 00 00 AA 08 00 00 05 00 00 00 00 00 00 00 01 00 00 00 A2 C3 7F 3F A5 BA 7F 3F 85 A7 7F 3F E7 F9 7F 3F CD CC CC 3D E8 03 00 00 8B 16 ", "uptime":52822 }, "metadata":{ "device":"MeterbusHub", "token":1, "name":"thermom." } } { "data":{ "telegram":"68 38 38 68 08 52 72 99 51 00 13 2E 19 21 02 86 00 00 00 8C 10 04 06 09 00 00 8C 11 04 00 09 00 00 02 FD C9 FF 01 E3 00 02 FD DB FF 01 00 00 02 AC FF 01 00 00 82 40 AC FF 01 00 00 B3 16 ", "uptime":52840 }, "metadata":{ "device":"MeterbusHub", "token":6, "name":"laundry" } } { "data":{ "telegram":"68 92 92 68 08 50 72 81 14 01 11 2E 19 16 02 A2 00 00 00 8C 10 04 82 62 85 00 8C 11 04 82 62 85 00 8C 20 04 00 00 00 00 8C 21 04 00 00 00 00 02 FD C9 FF 01 DD 00 02 FD DB FF 01 08 00 02 AC FF 01 0F 00 82 40 AC FF 01 00 00 02 FD C9 FF 02 E2 00 02 FD DB FF 02 0C 00 02 AC FF 02 16 00 82 40 AC FF 02 F7 FF 02 FD C9 FF 03 E9 00 02 FD DB FF 03 09 00 02 AC FF 03 11 00 82 40 AC FF 03 FA FF 02 FF 68 00 00 02 AC FF 00 36 00 82 40 AC FF 00 F1 FF 01 FF 13 00 D2 16 ", "uptime":52867 }, "metadata":{ "device":"MeterbusHub", "token":4, "name":"electricity" } } { "data":{ "telegram":"68 46 46 68 08 30 72 45 71 43 00 24 23 25 07 4B 00 00 00 0C 13 83 50 43 00 8C 10 13 00 00 00 00 0B 3B 00 00 00 0B 26 69 58 01 02 5A B6 00 04 6D 30 0D E5 16 4C 13 96 41 33 00 CC 10 13 00 00 00 00 42 6C DF 1C 42 EC 7E FF 1C 01 16 ", "uptime":53047 }, "metadata":{ "device":"MeterbusHub", "token":2, "name":"water" } } { "data":{ "telegram":"68 56 56 68 08 40 72 43 60 52 00 77 04 14 03 56 10 00 00 0C 78 76 03 01 10 0D 7C 08 44 49 20 2E 74 73 75 63 0A 30 30 30 30 30 30 30 30 30 30 04 6D 23 0D E5 16 02 7C 09 65 6D 69 74 20 2E 74 61 62 A9 09 04 13 F5 A9 04 00 04 93 7F 4E 01 00 00 44 13 FC A5 04 00 0F 01 00 1F 1C 16 ", "uptime":53049 }, "metadata":{ "device":"MeterbusHub", "token":3, "name":"gas" } } [/code] Sources for the firmware are here: NetMeterBusMaster2 ')