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. IMG_3167 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] IMG_3168 Sources for the firmware are here: NetMeterBusMaster2 ')