mbed based IoT Gateway More details http://blog.thiseldo.co.uk/wp-filez/IoTGateway.pdf

Dependencies:   NetServices FatFileSystem csv_parser mbed MQTTClient RF12B DNSResolver SDFileSystem

Committer:
SomeRandomBloke
Date:
Tue May 01 21:43:40 2012 +0000
Revision:
4:d460406ac780
Parent:
3:f19f9c62c00b
Child:
5:0dbc27a7af55
Added output module for Sen.Se and emonCMS

Who changed what in which revision?

UserRevisionLine numberNew contents of line
SomeRandomBloke 0:a29a0225f203 1 /** IoT Gateway main code
SomeRandomBloke 0:a29a0225f203 2 *
SomeRandomBloke 0:a29a0225f203 3 * @author Andrew Lindsay
SomeRandomBloke 0:a29a0225f203 4 *
SomeRandomBloke 0:a29a0225f203 5 * @section LICENSE
SomeRandomBloke 0:a29a0225f203 6 *
SomeRandomBloke 0:a29a0225f203 7 * Copyright (c) 2012 Andrew Lindsay (andrew [at] thiseldo [dot] co [dot] uk)
SomeRandomBloke 0:a29a0225f203 8 *
SomeRandomBloke 0:a29a0225f203 9 * Permission is hereby granted, free of charge, to any person obtaining a copy
SomeRandomBloke 0:a29a0225f203 10 * of this software and associated documentation files (the "Software"), to deal
SomeRandomBloke 0:a29a0225f203 11 * in the Software without restriction, including without limitation the rights
SomeRandomBloke 0:a29a0225f203 12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
SomeRandomBloke 0:a29a0225f203 13 * copies of the Software, and to permit persons to whom the Software is
SomeRandomBloke 0:a29a0225f203 14 * furnished to do so, subject to the following conditions:
SomeRandomBloke 0:a29a0225f203 15
SomeRandomBloke 0:a29a0225f203 16 * The above copyright notice and this permission notice shall be included in
SomeRandomBloke 0:a29a0225f203 17 * all copies or substantial portions of the Software.
SomeRandomBloke 0:a29a0225f203 18 *
SomeRandomBloke 0:a29a0225f203 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
SomeRandomBloke 0:a29a0225f203 20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
SomeRandomBloke 0:a29a0225f203 21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
SomeRandomBloke 0:a29a0225f203 22 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
SomeRandomBloke 0:a29a0225f203 23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
SomeRandomBloke 0:a29a0225f203 24 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
SomeRandomBloke 0:a29a0225f203 25 * THE SOFTWARE.
SomeRandomBloke 0:a29a0225f203 26 *
SomeRandomBloke 0:a29a0225f203 27 * @section DESCRIPTION
SomeRandomBloke 0:a29a0225f203 28 *
SomeRandomBloke 0:a29a0225f203 29 * Code is to be classed as beta. There is a lot of debug code still includes
SomeRandomBloke 0:a29a0225f203 30 * to dump heap sizes and other values. It is still a work in progress and
SomeRandomBloke 0:a29a0225f203 31 * should be treated as such.
SomeRandomBloke 3:f19f9c62c00b 32 *
SomeRandomBloke 3:f19f9c62c00b 33 * Further documentation available from
SomeRandomBloke 2:27714c8c9c0a 34 * http://blog.thiseldo.co.uk/wp-filez/IoTGateway.pdf
SomeRandomBloke 0:a29a0225f203 35 *
SomeRandomBloke 0:a29a0225f203 36 * Sample configuration file IOTSETUP.TXT
SomeRandomBloke 0:a29a0225f203 37 *
SomeRandomBloke 0:a29a0225f203 38 * @code
SomeRandomBloke 0:a29a0225f203 39 * ip.mode=fixed
SomeRandomBloke 0:a29a0225f203 40 * ip.address=192.168.1.99
SomeRandomBloke 0:a29a0225f203 41 * ip.netmask=255.255.255.0
SomeRandomBloke 0:a29a0225f203 42 * ip.gateway=192.168.1.1
SomeRandomBloke 0:a29a0225f203 43 * ip.dns=192.168.1.1
SomeRandomBloke 0:a29a0225f203 44 * rfm12b.band=868
SomeRandomBloke 0:a29a0225f203 45 * rfm12b.id=30
SomeRandomBloke 0:a29a0225f203 46 * rfm12b.group=212
SomeRandomBloke 3:f19f9c62c00b 47 * time.host=0.uk.pool.ntp.org
SomeRandomBloke 0:a29a0225f203 48 * time.timezone=GMT
SomeRandomBloke 0:a29a0225f203 49 * time.dst=yes
SomeRandomBloke 4:d460406ac780 50 * pachube.key=***your Pachube api key***
SomeRandomBloke 4:d460406ac780 51 * pachube.apiurl=http://api.pachube.com/v2/feeds/%d.csv?_method=PUT
SomeRandomBloke 4:d460406ac780 52 * emoncms.key=***your emonCms api key***
SomeRandomBloke 4:d460406ac780 53 * emoncms.apiurl=http://your.host.com/emoncms/api/post?apikey=%s&json=
SomeRandomBloke 4:d460406ac780 54 * sense.key=***your Sen.se api key***
SomeRandomBloke 4:d460406ac780 55 * sense.apiurl=http://api.sen.se/events/?sense_key=%s
SomeRandomBloke 0:a29a0225f203 56 * mqtt.host=
SomeRandomBloke 2:27714c8c9c0a 57 * mqtt.port=1883
SomeRandomBloke 2:27714c8c9c0a 58 * mqtt.username=
SomeRandomBloke 2:27714c8c9c0a 59 * mqtt.password=
SomeRandomBloke 0:a29a0225f203 60 * @endcode
SomeRandomBloke 0:a29a0225f203 61 *
SomeRandomBloke 0:a29a0225f203 62 * Some values are not yet used
SomeRandomBloke 0:a29a0225f203 63 *
SomeRandomBloke 0:a29a0225f203 64 */
SomeRandomBloke 0:a29a0225f203 65
SomeRandomBloke 0:a29a0225f203 66
SomeRandomBloke 0:a29a0225f203 67 #include "mbed.h"
SomeRandomBloke 3:f19f9c62c00b 68 #include <ctype.h>
SomeRandomBloke 0:a29a0225f203 69 #include "SDFileSystem.h"
SomeRandomBloke 0:a29a0225f203 70 #include "EthernetNetIf.h"
SomeRandomBloke 0:a29a0225f203 71 #include "NTPClient.h"
SomeRandomBloke 2:27714c8c9c0a 72 #include "dnsresolve.h"
SomeRandomBloke 0:a29a0225f203 73 #include "RF12B.h"
SomeRandomBloke 0:a29a0225f203 74 #include "IoTRouting.h"
SomeRandomBloke 0:a29a0225f203 75
SomeRandomBloke 0:a29a0225f203 76 using std::string;
SomeRandomBloke 0:a29a0225f203 77
SomeRandomBloke 4:d460406ac780 78 #define VERSION_INFO "IoT Gateway Basic - Version 0.7-BETA "
SomeRandomBloke 0:a29a0225f203 79
SomeRandomBloke 0:a29a0225f203 80 DigitalOut heartbeatLED(LED1, "heartbeatLED");
SomeRandomBloke 0:a29a0225f203 81 DigitalOut led2(LED2, "led2");
SomeRandomBloke 0:a29a0225f203 82 DigitalOut led3(LED3, "led3");
SomeRandomBloke 0:a29a0225f203 83 //DigitalOut led4(LED4, "led4");
SomeRandomBloke 0:a29a0225f203 84 DigitalOut linkLED(p30, "linkLED");
SomeRandomBloke 0:a29a0225f203 85 DigitalOut statusLED(p25, "statusLED");
SomeRandomBloke 0:a29a0225f203 86
SomeRandomBloke 2:27714c8c9c0a 87 // Put as much as we can into RAM bank AHBSRAM0 which is reserved for USB that we are not using
SomeRandomBloke 2:27714c8c9c0a 88
SomeRandomBloke 2:27714c8c9c0a 89 // Setup which filesystem to use, Local or uSD card, both use same name
SomeRandomBloke 0:a29a0225f203 90 __attribute((section("AHBSRAM0"))) LocalFileSystem fs("iotfs");
SomeRandomBloke 0:a29a0225f203 91 //__attribute((section("AHBSRAM0"))) SDFileSystem sd(p5, p6, p7, p8, "iotfs");
SomeRandomBloke 0:a29a0225f203 92
SomeRandomBloke 0:a29a0225f203 93 __attribute((section("AHBSRAM0"))) EthernetNetIf *eth;
SomeRandomBloke 0:a29a0225f203 94 __attribute((section("AHBSRAM0"))) NTPClient ntp;
SomeRandomBloke 0:a29a0225f203 95 __attribute((section("AHBSRAM0"))) Ethernet ethernet;
SomeRandomBloke 2:27714c8c9c0a 96 __attribute((section("AHBSRAM0"))) DNSResolver resolver;
SomeRandomBloke 0:a29a0225f203 97
SomeRandomBloke 0:a29a0225f203 98 // Configuration values loaded from file iotsetup.dat
SomeRandomBloke 0:a29a0225f203 99 __attribute((section("AHBSRAM0"))) IpAddr ipAddress(0, 0, 0, 0);
SomeRandomBloke 0:a29a0225f203 100 __attribute((section("AHBSRAM0"))) IpAddr netMask(255, 255, 255, 0);
SomeRandomBloke 0:a29a0225f203 101 __attribute((section("AHBSRAM0"))) IpAddr gwAddress(0, 0, 0, 0);
SomeRandomBloke 0:a29a0225f203 102 __attribute((section("AHBSRAM0"))) IpAddr dnsAddress(0, 0, 0, 0);
SomeRandomBloke 0:a29a0225f203 103 __attribute((section("AHBSRAM0"))) bool useDHCP = false;
SomeRandomBloke 0:a29a0225f203 104
SomeRandomBloke 0:a29a0225f203 105 // Static buffers
SomeRandomBloke 0:a29a0225f203 106 #define MAX_LINE_LENGTH 128
SomeRandomBloke 2:27714c8c9c0a 107 __attribute((section("AHBSRAM0"))) static char lineBuf[MAX_LINE_LENGTH];
SomeRandomBloke 2:27714c8c9c0a 108 __attribute((section("AHBSRAM0"))) static OutputPachube outPachube;
SomeRandomBloke 4:d460406ac780 109 __attribute((section("AHBSRAM0"))) static OutputEmonCms outEmonCms;
SomeRandomBloke 4:d460406ac780 110 __attribute((section("AHBSRAM0"))) static OutputSenSe outSenSe;
SomeRandomBloke 2:27714c8c9c0a 111 __attribute((section("AHBSRAM0"))) static IoTRouting rtr;
SomeRandomBloke 0:a29a0225f203 112
SomeRandomBloke 0:a29a0225f203 113 // Pachube config
SomeRandomBloke 4:d460406ac780 114 __attribute((section("AHBSRAM0"))) char pachubeApiUrl[128];
SomeRandomBloke 3:f19f9c62c00b 115 __attribute((section("AHBSRAM0"))) char pachubeApiKey[65];
SomeRandomBloke 4:d460406ac780 116 __attribute((section("AHBSRAM0"))) char pachubeDataBuffer[200];
SomeRandomBloke 0:a29a0225f203 117
SomeRandomBloke 0:a29a0225f203 118 // MQTT config
SomeRandomBloke 3:f19f9c62c00b 119 __attribute((section("AHBSRAM0"))) IpAddr mqttHostAddress( 0, 0, 0, 0);
SomeRandomBloke 2:27714c8c9c0a 120 __attribute((section("AHBSRAM0"))) short mqttPort;
SomeRandomBloke 3:f19f9c62c00b 121 __attribute((section("AHBSRAM0"))) char mqttUsername[MAX_LINE_LENGTH];
SomeRandomBloke 3:f19f9c62c00b 122 __attribute((section("AHBSRAM0"))) char mqttPassword[MAX_LINE_LENGTH];
SomeRandomBloke 2:27714c8c9c0a 123 __attribute((section("AHBSRAM0"))) bool useMQTT = false;
SomeRandomBloke 2:27714c8c9c0a 124
SomeRandomBloke 0:a29a0225f203 125 //char mqttHostName[65];
SomeRandomBloke 0:a29a0225f203 126
SomeRandomBloke 4:d460406ac780 127 // Open energy Monitor emonCMS config
SomeRandomBloke 4:d460406ac780 128 __attribute((section("AHBSRAM0"))) char emonCmsApiUrl[128];
SomeRandomBloke 4:d460406ac780 129 __attribute((section("AHBSRAM0"))) char emonCmsApiKey[65];
SomeRandomBloke 4:d460406ac780 130 __attribute((section("AHBSRAM0"))) char emonCmsDataBuffer[200];
SomeRandomBloke 4:d460406ac780 131
SomeRandomBloke 4:d460406ac780 132 // Open energy Monitor Sen.Se config
SomeRandomBloke 4:d460406ac780 133 __attribute((section("AHBSRAM0"))) char senSeApiUrl[128];
SomeRandomBloke 4:d460406ac780 134 __attribute((section("AHBSRAM0"))) char senSeApiKey[65];
SomeRandomBloke 4:d460406ac780 135 __attribute((section("AHBSRAM0"))) char senSeDataBuffer[200];
SomeRandomBloke 4:d460406ac780 136
SomeRandomBloke 3:f19f9c62c00b 137 // Time server config
SomeRandomBloke 3:f19f9c62c00b 138 __attribute((section("AHBSRAM0"))) char ntpHost[MAX_LINE_LENGTH] = "0.uk.pool.ntp.org";
SomeRandomBloke 3:f19f9c62c00b 139
SomeRandomBloke 0:a29a0225f203 140 // RFM12B config
SomeRandomBloke 0:a29a0225f203 141 __attribute((section("AHBSRAM0"))) static string rfm12bBands[4] = {"xxx", "433", "868", "915" };
SomeRandomBloke 2:27714c8c9c0a 142 __attribute((section("AHBSRAM0"))) static uint8_t rfm12bId;
SomeRandomBloke 2:27714c8c9c0a 143 __attribute((section("AHBSRAM0"))) static uint8_t rfm12bBand;
SomeRandomBloke 2:27714c8c9c0a 144 __attribute((section("AHBSRAM0"))) static uint8_t rfm12bGroup;
SomeRandomBloke 0:a29a0225f203 145
SomeRandomBloke 0:a29a0225f203 146 #define iotConfigFile "/iotfs/IOTSETUP.TXT"
SomeRandomBloke 2:27714c8c9c0a 147
SomeRandomBloke 0:a29a0225f203 148 __attribute((section("AHBSRAM0"))) RF12B rfm12b(p11, p12, p13, p14, p18);
SomeRandomBloke 0:a29a0225f203 149 __attribute((section("AHBSRAM0"))) Serial pc(USBTX, USBRX); // tx, rx
SomeRandomBloke 0:a29a0225f203 150
SomeRandomBloke 0:a29a0225f203 151 // Utility functions
SomeRandomBloke 0:a29a0225f203 152
SomeRandomBloke 0:a29a0225f203 153 /** convert string to IP address
SomeRandomBloke 0:a29a0225f203 154 *
SomeRandomBloke 0:a29a0225f203 155 * @param ipAddrInt IP address as single 32bit integer
SomeRandomBloke 0:a29a0225f203 156 * @param value The IP address as a string
SomeRandomBloke 0:a29a0225f203 157 */
SomeRandomBloke 0:a29a0225f203 158 void setIpAddress( int *ipAddrInt, char *value ) {
SomeRandomBloke 0:a29a0225f203 159 sscanf(value, "%d.%d.%d.%d", &ipAddrInt[0],&ipAddrInt[1],&ipAddrInt[2],&ipAddrInt[3]);
SomeRandomBloke 0:a29a0225f203 160 }
SomeRandomBloke 0:a29a0225f203 161
SomeRandomBloke 0:a29a0225f203 162 /** Get the value from a name=value pair
SomeRandomBloke 0:a29a0225f203 163 *
SomeRandomBloke 0:a29a0225f203 164 * @param buf The name/value pair character buffer
SomeRandomBloke 0:a29a0225f203 165 * @returns pointer to value
SomeRandomBloke 0:a29a0225f203 166 */
SomeRandomBloke 0:a29a0225f203 167 char *getConfigValue( char *buf ) {
SomeRandomBloke 0:a29a0225f203 168 char *ptr = strchr(buf, '=');
SomeRandomBloke 0:a29a0225f203 169 if ( ptr == NULL )
SomeRandomBloke 0:a29a0225f203 170 return NULL;
SomeRandomBloke 0:a29a0225f203 171 ptr++;
SomeRandomBloke 0:a29a0225f203 172 return ptr;
SomeRandomBloke 0:a29a0225f203 173 }
SomeRandomBloke 0:a29a0225f203 174
SomeRandomBloke 0:a29a0225f203 175 /** Copy zero or CR/LF terminated string to new zero terminated string
SomeRandomBloke 0:a29a0225f203 176 * Used when reading config values from files to remove CR/LF endings
SomeRandomBloke 0:a29a0225f203 177 *
SomeRandomBloke 0:a29a0225f203 178 * @param to Char pointer to destination
SomeRandomBloke 0:a29a0225f203 179 * @param from Char pointer to source
SomeRandomBloke 0:a29a0225f203 180 */
SomeRandomBloke 0:a29a0225f203 181 void strcpynull(char *to, char *from ) {
SomeRandomBloke 0:a29a0225f203 182 while ( *from != '\n' && *from != '\r' && *from != '\0' ) {
SomeRandomBloke 0:a29a0225f203 183 *to++ = *from++;
SomeRandomBloke 0:a29a0225f203 184 }
SomeRandomBloke 0:a29a0225f203 185 *to = '\0';
SomeRandomBloke 0:a29a0225f203 186 }
SomeRandomBloke 0:a29a0225f203 187
SomeRandomBloke 3:f19f9c62c00b 188 /** Trim a string in buffer, remove leading and trailing spaces
SomeRandomBloke 3:f19f9c62c00b 189 *
SomeRandomBloke 3:f19f9c62c00b 190 */
SomeRandomBloke 3:f19f9c62c00b 191 char *trim(char *str) {
SomeRandomBloke 3:f19f9c62c00b 192 size_t len = 0;
SomeRandomBloke 3:f19f9c62c00b 193 char *frontp = str - 1;
SomeRandomBloke 3:f19f9c62c00b 194 char *endp = NULL;
SomeRandomBloke 3:f19f9c62c00b 195
SomeRandomBloke 3:f19f9c62c00b 196 if ( str == NULL )
SomeRandomBloke 3:f19f9c62c00b 197 return NULL;
SomeRandomBloke 3:f19f9c62c00b 198
SomeRandomBloke 3:f19f9c62c00b 199 if ( str[0] == '\0' )
SomeRandomBloke 3:f19f9c62c00b 200 return str;
SomeRandomBloke 3:f19f9c62c00b 201
SomeRandomBloke 3:f19f9c62c00b 202 len = strlen(str);
SomeRandomBloke 3:f19f9c62c00b 203 endp = str + len;
SomeRandomBloke 3:f19f9c62c00b 204
SomeRandomBloke 3:f19f9c62c00b 205 /* Move the front and back pointers to address
SomeRandomBloke 3:f19f9c62c00b 206 * the first non-whitespace characters from
SomeRandomBloke 3:f19f9c62c00b 207 * each end.
SomeRandomBloke 3:f19f9c62c00b 208 */
SomeRandomBloke 3:f19f9c62c00b 209 while ( isspace(*(++frontp)) );
SomeRandomBloke 3:f19f9c62c00b 210 while ( isspace(*(--endp)) && endp != frontp );
SomeRandomBloke 3:f19f9c62c00b 211
SomeRandomBloke 3:f19f9c62c00b 212 // while( *(++frontp) == ' ' );
SomeRandomBloke 3:f19f9c62c00b 213 // while( (*(--endp) == ' ') && endp != frontp );
SomeRandomBloke 3:f19f9c62c00b 214
SomeRandomBloke 3:f19f9c62c00b 215 if ( str + len - 1 != endp )
SomeRandomBloke 3:f19f9c62c00b 216 *(endp + 1) = '\0';
SomeRandomBloke 3:f19f9c62c00b 217 else if ( frontp != str && endp == frontp )
SomeRandomBloke 3:f19f9c62c00b 218 *str = '\0';
SomeRandomBloke 3:f19f9c62c00b 219
SomeRandomBloke 3:f19f9c62c00b 220 /* Shift the string so that it starts at str so
SomeRandomBloke 3:f19f9c62c00b 221 * that if it's dynamically allocated, we can
SomeRandomBloke 3:f19f9c62c00b 222 * still free it on the returned pointer. Note
SomeRandomBloke 3:f19f9c62c00b 223 * the reuse of endp to mean the front of the
SomeRandomBloke 3:f19f9c62c00b 224 * string buffer now.
SomeRandomBloke 3:f19f9c62c00b 225 */
SomeRandomBloke 3:f19f9c62c00b 226 endp = str;
SomeRandomBloke 3:f19f9c62c00b 227 if ( frontp != str ) {
SomeRandomBloke 3:f19f9c62c00b 228 while ( *frontp ) *endp++ = *frontp++;
SomeRandomBloke 3:f19f9c62c00b 229 *endp = '\0';
SomeRandomBloke 3:f19f9c62c00b 230 }
SomeRandomBloke 3:f19f9c62c00b 231
SomeRandomBloke 3:f19f9c62c00b 232
SomeRandomBloke 3:f19f9c62c00b 233 return str;
SomeRandomBloke 3:f19f9c62c00b 234 }
SomeRandomBloke 0:a29a0225f203 235
SomeRandomBloke 0:a29a0225f203 236 /** Read IoT gateway configuration file
SomeRandomBloke 0:a29a0225f203 237 * File is of format name=value
SomeRandomBloke 0:a29a0225f203 238 *
SomeRandomBloke 0:a29a0225f203 239 */
SomeRandomBloke 0:a29a0225f203 240 bool readConfig() {
SomeRandomBloke 0:a29a0225f203 241
SomeRandomBloke 0:a29a0225f203 242 FILE *fp = fopen(iotConfigFile, "r");
SomeRandomBloke 0:a29a0225f203 243 if (fp == NULL) {
SomeRandomBloke 0:a29a0225f203 244 printf("Could not open file %s for read\n", iotConfigFile);
SomeRandomBloke 0:a29a0225f203 245 return false;
SomeRandomBloke 0:a29a0225f203 246 }
SomeRandomBloke 0:a29a0225f203 247 // read file
SomeRandomBloke 0:a29a0225f203 248 while (!feof( fp )) {
SomeRandomBloke 0:a29a0225f203 249 fgets(lineBuf,MAX_LINE_LENGTH,fp);
SomeRandomBloke 4:d460406ac780 250 // printf("[%s] ",lineBuf);
SomeRandomBloke 3:f19f9c62c00b 251 trim( lineBuf );
SomeRandomBloke 4:d460406ac780 252 // printf("[%s]\n", lineBuf);
SomeRandomBloke 3:f19f9c62c00b 253
SomeRandomBloke 0:a29a0225f203 254 // Need to read each entry and update config
SomeRandomBloke 0:a29a0225f203 255 char *nameStr;
SomeRandomBloke 0:a29a0225f203 256 char *valueStr;
SomeRandomBloke 0:a29a0225f203 257 nameStr = lineBuf;
SomeRandomBloke 0:a29a0225f203 258 valueStr = strchr( lineBuf, '=' );
SomeRandomBloke 0:a29a0225f203 259 if ( valueStr != NULL ) {
SomeRandomBloke 0:a29a0225f203 260 *valueStr++ = '\0';
SomeRandomBloke 0:a29a0225f203 261 int tmpAddress[4] = {0,0,0,0};
SomeRandomBloke 0:a29a0225f203 262 if ( strcmp( nameStr, "ip.address" ) == 0 ) {
SomeRandomBloke 0:a29a0225f203 263 setIpAddress( &tmpAddress[0], valueStr );
SomeRandomBloke 0:a29a0225f203 264 ipAddress = IpAddr( tmpAddress[0],tmpAddress[1],tmpAddress[2],tmpAddress[3]);
SomeRandomBloke 3:f19f9c62c00b 265
SomeRandomBloke 2:27714c8c9c0a 266 } else if ( strcmp( nameStr, "ip.netmask" ) == 0 ) {
SomeRandomBloke 0:a29a0225f203 267 setIpAddress( &tmpAddress[0], valueStr );
SomeRandomBloke 0:a29a0225f203 268 netMask = IpAddr( tmpAddress[0],tmpAddress[1],tmpAddress[2],tmpAddress[3]);
SomeRandomBloke 3:f19f9c62c00b 269
SomeRandomBloke 2:27714c8c9c0a 270 } else if ( strcmp( nameStr, "ip.gateway" ) == 0 ) {
SomeRandomBloke 0:a29a0225f203 271 setIpAddress( &tmpAddress[0], valueStr );
SomeRandomBloke 0:a29a0225f203 272 gwAddress = IpAddr( tmpAddress[0],tmpAddress[1],tmpAddress[2],tmpAddress[3]);
SomeRandomBloke 3:f19f9c62c00b 273
SomeRandomBloke 2:27714c8c9c0a 274 } else if ( strcmp( nameStr, "ip.dns" ) == 0 ) {
SomeRandomBloke 0:a29a0225f203 275 setIpAddress( &tmpAddress[0], valueStr );
SomeRandomBloke 0:a29a0225f203 276 dnsAddress = IpAddr( tmpAddress[0],tmpAddress[1],tmpAddress[2],tmpAddress[3]);
SomeRandomBloke 2:27714c8c9c0a 277
SomeRandomBloke 2:27714c8c9c0a 278 } else if ( strcmp( nameStr, "ip.mode" ) == 0 ) {
SomeRandomBloke 2:27714c8c9c0a 279 useDHCP = (strncmp( valueStr, "dhcp", 4) == 0 ? true : false);
SomeRandomBloke 3:f19f9c62c00b 280
SomeRandomBloke 3:f19f9c62c00b 281 } else if ( strcmp( nameStr, "time.host" ) == 0 ) {
SomeRandomBloke 3:f19f9c62c00b 282 strcpynull(ntpHost, valueStr );
SomeRandomBloke 3:f19f9c62c00b 283
SomeRandomBloke 4:d460406ac780 284 } else if ( strcmp( nameStr, "pachube.apiurl" ) == 0 ) {
SomeRandomBloke 4:d460406ac780 285 strcpynull(pachubeApiUrl, valueStr );
SomeRandomBloke 4:d460406ac780 286
SomeRandomBloke 0:a29a0225f203 287 } else if ( strcmp( nameStr, "pachube.key" ) == 0 ) {
SomeRandomBloke 0:a29a0225f203 288 strcpynull(pachubeApiKey, valueStr );
SomeRandomBloke 3:f19f9c62c00b 289
SomeRandomBloke 4:d460406ac780 290 } else if ( strcmp( nameStr, "emoncms.apiurl" ) == 0 ) {
SomeRandomBloke 4:d460406ac780 291 strcpynull(emonCmsApiUrl, valueStr );
SomeRandomBloke 4:d460406ac780 292
SomeRandomBloke 4:d460406ac780 293 } else if ( strcmp( nameStr, "emoncms.key" ) == 0 ) {
SomeRandomBloke 4:d460406ac780 294 strcpynull(emonCmsApiKey, valueStr );
SomeRandomBloke 4:d460406ac780 295
SomeRandomBloke 4:d460406ac780 296 } else if ( strcmp( nameStr, "sense.apiurl" ) == 0 ) {
SomeRandomBloke 4:d460406ac780 297 strcpynull(senSeApiUrl, valueStr );
SomeRandomBloke 4:d460406ac780 298
SomeRandomBloke 4:d460406ac780 299 } else if ( strcmp( nameStr, "sense.key" ) == 0 ) {
SomeRandomBloke 4:d460406ac780 300 strcpynull(senSeApiKey, valueStr );
SomeRandomBloke 2:27714c8c9c0a 301 } else if ( strcmp( nameStr, "mqtt.host" ) == 0 ) {
SomeRandomBloke 2:27714c8c9c0a 302 setIpAddress( &tmpAddress[0], valueStr );
SomeRandomBloke 2:27714c8c9c0a 303 mqttHostAddress = IpAddr( tmpAddress[0],tmpAddress[1],tmpAddress[2],tmpAddress[3]);
SomeRandomBloke 2:27714c8c9c0a 304
SomeRandomBloke 2:27714c8c9c0a 305 } else if ( strcmp( nameStr, "mqtt.port" ) == 0 ) {
SomeRandomBloke 2:27714c8c9c0a 306 mqttPort = atoi( valueStr );
SomeRandomBloke 2:27714c8c9c0a 307
SomeRandomBloke 2:27714c8c9c0a 308 } else if ( strcmp( nameStr, "mqtt.username" ) == 0 ) {
SomeRandomBloke 2:27714c8c9c0a 309 strcpynull(mqttUsername, valueStr );
SomeRandomBloke 3:f19f9c62c00b 310
SomeRandomBloke 2:27714c8c9c0a 311 } else if ( strcmp( nameStr, "mqtt.password" ) == 0 ) {
SomeRandomBloke 2:27714c8c9c0a 312 strcpynull(mqttPassword, valueStr );
SomeRandomBloke 3:f19f9c62c00b 313
SomeRandomBloke 0:a29a0225f203 314 } else if ( strcmp( nameStr, "rfm12b.band" ) == 0 ) {
SomeRandomBloke 0:a29a0225f203 315 if ( strncmp( valueStr, "433", 3 ) == 0 )
SomeRandomBloke 0:a29a0225f203 316 rfm12bBand = RF12_433MHZ;
SomeRandomBloke 0:a29a0225f203 317 else if ( strncmp( valueStr, "868", 3 ) == 0 )
SomeRandomBloke 0:a29a0225f203 318 rfm12bBand = RF12_868MHZ;
SomeRandomBloke 0:a29a0225f203 319 else if ( strncmp( valueStr, "915", 3 ) == 0 )
SomeRandomBloke 0:a29a0225f203 320 rfm12bBand = RF12_915MHZ;
SomeRandomBloke 3:f19f9c62c00b 321
SomeRandomBloke 0:a29a0225f203 322 } else if ( strcmp( nameStr, "rfm12b.id" ) == 0 ) {
SomeRandomBloke 0:a29a0225f203 323 rfm12bId = atoi( valueStr );
SomeRandomBloke 0:a29a0225f203 324 } else if ( strcmp( nameStr, "rfm12b.group" ) == 0 ) {
SomeRandomBloke 0:a29a0225f203 325 rfm12bGroup = atoi( valueStr );
SomeRandomBloke 0:a29a0225f203 326 }
SomeRandomBloke 0:a29a0225f203 327 }
SomeRandomBloke 0:a29a0225f203 328 }
SomeRandomBloke 0:a29a0225f203 329 fclose(fp);
SomeRandomBloke 0:a29a0225f203 330
SomeRandomBloke 0:a29a0225f203 331 return true;
SomeRandomBloke 0:a29a0225f203 332 }
SomeRandomBloke 0:a29a0225f203 333
SomeRandomBloke 0:a29a0225f203 334 /** Write the current config to file
SomeRandomBloke 0:a29a0225f203 335 */
SomeRandomBloke 0:a29a0225f203 336 bool writeConfig() {
SomeRandomBloke 0:a29a0225f203 337
SomeRandomBloke 0:a29a0225f203 338 // Doesnt work?
SomeRandomBloke 0:a29a0225f203 339 // Rename original file
SomeRandomBloke 0:a29a0225f203 340 // if( rename ( iotConfigFile.c_str(), iotConfigFileBak.c_str() ) != 0 ) {
SomeRandomBloke 0:a29a0225f203 341 // printf("Could not rename file %s\n", iotConfigFile);
SomeRandomBloke 0:a29a0225f203 342 // return false;
SomeRandomBloke 0:a29a0225f203 343 // }
SomeRandomBloke 0:a29a0225f203 344
SomeRandomBloke 0:a29a0225f203 345 FILE *fp = fopen(iotConfigFile, "w");
SomeRandomBloke 0:a29a0225f203 346 if (fp == NULL) {
SomeRandomBloke 0:a29a0225f203 347 printf("Could not open file %s for write\n", iotConfigFile);
SomeRandomBloke 0:a29a0225f203 348 return false;
SomeRandomBloke 0:a29a0225f203 349 }
SomeRandomBloke 0:a29a0225f203 350
SomeRandomBloke 0:a29a0225f203 351 time_t ctTime;
SomeRandomBloke 0:a29a0225f203 352 ctTime = time(NULL);
SomeRandomBloke 0:a29a0225f203 353
SomeRandomBloke 0:a29a0225f203 354 fprintf(fp, "# iotsetup created (UTC) %s\n", ctime(&ctTime));
SomeRandomBloke 0:a29a0225f203 355 fprintf(fp, "ip.mode=%s\n", (useDHCP ? "dhcp" : "fixed") );
SomeRandomBloke 0:a29a0225f203 356 // Add msg to say net config being ignored
SomeRandomBloke 0:a29a0225f203 357 if ( useDHCP )
SomeRandomBloke 0:a29a0225f203 358 fprintf(fp, "# Following ip.* parameters not used in DHCP mode\n");
SomeRandomBloke 0:a29a0225f203 359
SomeRandomBloke 0:a29a0225f203 360 fprintf(fp, "ip.address=%hhu.%hhu.%hhu.%hhu\n", ipAddress[0], ipAddress[1],ipAddress[2],ipAddress[3]);
SomeRandomBloke 0:a29a0225f203 361 fprintf(fp, "ip.netmask=%hhu.%hhu.%hhu.%hhu\n",netMask[0], netMask[1], netMask[2], netMask[3]);
SomeRandomBloke 0:a29a0225f203 362 fprintf(fp, "ip.gateway=%hhu.%hhu.%hhu.%hhu\n",gwAddress[0],gwAddress[1],gwAddress[2],gwAddress[3]);
SomeRandomBloke 0:a29a0225f203 363 fprintf(fp, "ip.dns=%hhu.%hhu.%hhu.%hhu\n",dnsAddress[0],dnsAddress[1],dnsAddress[2],dnsAddress[3]);
SomeRandomBloke 0:a29a0225f203 364
SomeRandomBloke 0:a29a0225f203 365 fprintf(fp, "rfm12b.band=%s\n",rfm12bBands[rfm12bBand].c_str());
SomeRandomBloke 0:a29a0225f203 366 fprintf(fp, "rfm12b.id=%d\n",rfm12bId);
SomeRandomBloke 0:a29a0225f203 367 fprintf(fp, "rfm12b.group=%d\n",rfm12bGroup);
SomeRandomBloke 0:a29a0225f203 368
SomeRandomBloke 0:a29a0225f203 369 fprintf(fp, "time.timezone=GMT\n");
SomeRandomBloke 0:a29a0225f203 370 fprintf(fp, "time.dst=yes\n");
SomeRandomBloke 2:27714c8c9c0a 371
SomeRandomBloke 2:27714c8c9c0a 372 fprintf(fp, "pachube.key=%s\n", pachubeApiKey );
SomeRandomBloke 2:27714c8c9c0a 373
SomeRandomBloke 2:27714c8c9c0a 374 fprintf(fp, "mqtt.host=%hhu.%hhu.%hhu.%hhu\n",mqttHostAddress[0],mqttHostAddress[1],mqttHostAddress[2],mqttHostAddress[3]);
SomeRandomBloke 2:27714c8c9c0a 375 fprintf(fp, "mqtt.port=%d\n",mqttPort);
SomeRandomBloke 2:27714c8c9c0a 376 fprintf(fp, "mqtt.username=%s\n", mqttUsername );
SomeRandomBloke 2:27714c8c9c0a 377 fprintf(fp, "mqtt.password=%s\n", mqttPassword );
SomeRandomBloke 2:27714c8c9c0a 378
SomeRandomBloke 0:a29a0225f203 379 fclose(fp);
SomeRandomBloke 0:a29a0225f203 380
SomeRandomBloke 0:a29a0225f203 381 return true;
SomeRandomBloke 0:a29a0225f203 382 }
SomeRandomBloke 0:a29a0225f203 383
SomeRandomBloke 0:a29a0225f203 384
SomeRandomBloke 0:a29a0225f203 385 // These external symbols are maintained by the linker to indicate the
SomeRandomBloke 0:a29a0225f203 386 // location of various regions in the device's memory. They will be used by
SomeRandomBloke 0:a29a0225f203 387 // DisplayRAMBanks() to dump the size of each RAM bank to stdout.
SomeRandomBloke 0:a29a0225f203 388 extern unsigned int Image$$RW_IRAM1$$Base;
SomeRandomBloke 0:a29a0225f203 389 extern unsigned int Image$$RW_IRAM1$$ZI$$Limit;
SomeRandomBloke 0:a29a0225f203 390 extern unsigned int Image$$RW_IRAM2$$Base;
SomeRandomBloke 0:a29a0225f203 391 extern unsigned int Image$$RW_IRAM2$$ZI$$Limit;
SomeRandomBloke 0:a29a0225f203 392 extern unsigned int Image$$RW_IRAM3$$Base;
SomeRandomBloke 0:a29a0225f203 393 extern unsigned int Image$$RW_IRAM3$$ZI$$Limit;
SomeRandomBloke 0:a29a0225f203 394
SomeRandomBloke 0:a29a0225f203 395 // Displays the size of static allocations for each RAM bank as indicated by
SomeRandomBloke 0:a29a0225f203 396 // ARM linker to stdout.
SomeRandomBloke 0:a29a0225f203 397 static void DisplayRAMBanks(void) {
SomeRandomBloke 0:a29a0225f203 398 printf("Static RAM bank allocations\r\n");
SomeRandomBloke 0:a29a0225f203 399 printf(" Main RAM = %u\r\n", (unsigned int)&Image$$RW_IRAM1$$ZI$$Limit -
SomeRandomBloke 0:a29a0225f203 400 (unsigned int)&Image$$RW_IRAM1$$Base);
SomeRandomBloke 0:a29a0225f203 401 printf(" RAM0 = %u\r\n", (unsigned int)&Image$$RW_IRAM2$$ZI$$Limit -
SomeRandomBloke 0:a29a0225f203 402 (unsigned int)&Image$$RW_IRAM2$$Base);
SomeRandomBloke 0:a29a0225f203 403 printf(" RAM1 = %u\r\n", (unsigned int)&Image$$RW_IRAM3$$ZI$$Limit -
SomeRandomBloke 0:a29a0225f203 404 (unsigned int)&Image$$RW_IRAM3$$Base);
SomeRandomBloke 0:a29a0225f203 405 }
SomeRandomBloke 0:a29a0225f203 406
SomeRandomBloke 0:a29a0225f203 407 /** Main function, where all the magic starts
SomeRandomBloke 0:a29a0225f203 408 */
SomeRandomBloke 0:a29a0225f203 409 int main() {
SomeRandomBloke 0:a29a0225f203 410 linkLED = 1;
SomeRandomBloke 0:a29a0225f203 411 statusLED = 0;
SomeRandomBloke 0:a29a0225f203 412 pc.baud(115200);
SomeRandomBloke 0:a29a0225f203 413
SomeRandomBloke 0:a29a0225f203 414 printf(VERSION_INFO);
SomeRandomBloke 0:a29a0225f203 415 printf("\n");
SomeRandomBloke 0:a29a0225f203 416
SomeRandomBloke 0:a29a0225f203 417 DisplayRAMBanks();
SomeRandomBloke 0:a29a0225f203 418
SomeRandomBloke 0:a29a0225f203 419 printf("Setting up...\n");
SomeRandomBloke 0:a29a0225f203 420 printf("\nHEAP STATS\n");
SomeRandomBloke 0:a29a0225f203 421 __heapstats((__heapprt)fprintf,stderr);
SomeRandomBloke 0:a29a0225f203 422
SomeRandomBloke 0:a29a0225f203 423 if ( !readConfig() ) {
SomeRandomBloke 0:a29a0225f203 424 error("Setup failed");
SomeRandomBloke 0:a29a0225f203 425 }
SomeRandomBloke 0:a29a0225f203 426
SomeRandomBloke 0:a29a0225f203 427 if (useDHCP) {
SomeRandomBloke 0:a29a0225f203 428 printf("Using DHCP\n");
SomeRandomBloke 0:a29a0225f203 429 eth = new EthernetNetIf( "IoTGateway" );
SomeRandomBloke 0:a29a0225f203 430 } else {
SomeRandomBloke 0:a29a0225f203 431 // printf("Using Fixed addressing\n");
SomeRandomBloke 0:a29a0225f203 432 eth = new EthernetNetIf( ipAddress, netMask, gwAddress, dnsAddress );
SomeRandomBloke 0:a29a0225f203 433 }
SomeRandomBloke 0:a29a0225f203 434 EthernetErr ethErr = eth->setup();
SomeRandomBloke 0:a29a0225f203 435 if (ethErr) {
SomeRandomBloke 0:a29a0225f203 436 printf("Error %d in setup.\n", ethErr);
SomeRandomBloke 0:a29a0225f203 437 return -1;
SomeRandomBloke 0:a29a0225f203 438 }
SomeRandomBloke 0:a29a0225f203 439
SomeRandomBloke 0:a29a0225f203 440 linkLED = !ethernet.link();
SomeRandomBloke 0:a29a0225f203 441
SomeRandomBloke 0:a29a0225f203 442 if (useDHCP) {
SomeRandomBloke 0:a29a0225f203 443 // We are using dhcp so get IP Address
SomeRandomBloke 0:a29a0225f203 444 ipAddress = eth->getIp();
SomeRandomBloke 0:a29a0225f203 445 }
SomeRandomBloke 0:a29a0225f203 446
SomeRandomBloke 0:a29a0225f203 447 // Get Current time
SomeRandomBloke 3:f19f9c62c00b 448 Host server(IpAddr(), 123, ntpHost); // "0.uk.pool.ntp.org");
SomeRandomBloke 0:a29a0225f203 449 ntp.setTime(server);
SomeRandomBloke 0:a29a0225f203 450
SomeRandomBloke 0:a29a0225f203 451 time_t ctTime = time(NULL);
SomeRandomBloke 0:a29a0225f203 452 printf("\nTime is now (UTC): %s\n", ctime(&ctTime));
SomeRandomBloke 0:a29a0225f203 453
SomeRandomBloke 4:d460406ac780 454 // If Pachube API Key defined, set up output module
SomeRandomBloke 3:f19f9c62c00b 455 if ( strlen(pachubeApiKey) > 0 ) {
SomeRandomBloke 4:d460406ac780 456 outPachube = OutputPachube( pachubeDataBuffer, pachubeApiUrl, pachubeApiKey );
SomeRandomBloke 4:d460406ac780 457 // outPachube.setApiKey( pachubeApiKey );
SomeRandomBloke 3:f19f9c62c00b 458 // printf("MAIN: outPachube = %ld\n",(int)&outPachube);
SomeRandomBloke 3:f19f9c62c00b 459 rtr.addOutput( (OutputDef*)&outPachube , OUTPUT_TYPE_PACHUBE);
SomeRandomBloke 3:f19f9c62c00b 460 }
SomeRandomBloke 0:a29a0225f203 461
SomeRandomBloke 4:d460406ac780 462 // If emonCms API Key defined, set up output module
SomeRandomBloke 4:d460406ac780 463 if ( strlen(emonCmsApiKey) > 0 ) {
SomeRandomBloke 4:d460406ac780 464 outEmonCms = OutputEmonCms( emonCmsDataBuffer, emonCmsApiUrl, emonCmsApiKey );
SomeRandomBloke 4:d460406ac780 465 rtr.addOutput( (OutputDef*)&outEmonCms , OUTPUT_TYPE_EMONCMS);
SomeRandomBloke 4:d460406ac780 466 }
SomeRandomBloke 4:d460406ac780 467
SomeRandomBloke 4:d460406ac780 468 // If Sen.se API Key defined, set up output module
SomeRandomBloke 4:d460406ac780 469 if ( strlen(senSeApiKey) > 0 ) {
SomeRandomBloke 4:d460406ac780 470 outSenSe = OutputSenSe( senSeDataBuffer, senSeApiUrl, senSeApiKey );
SomeRandomBloke 4:d460406ac780 471 rtr.addOutput( (OutputDef*)&outSenSe , OUTPUT_TYPE_SENSE);
SomeRandomBloke 4:d460406ac780 472 }
SomeRandomBloke 4:d460406ac780 473
SomeRandomBloke 2:27714c8c9c0a 474 //mqttHostAddress = IpAddr(192,168,1,77);
SomeRandomBloke 2:27714c8c9c0a 475 OutputMqtt outMqtt = OutputMqtt();
SomeRandomBloke 2:27714c8c9c0a 476 // mqttHostAddress = resolver.resolveName("api.pachube.com");
SomeRandomBloke 2:27714c8c9c0a 477 // Only use MQTT is we have a host IP address
SomeRandomBloke 3:f19f9c62c00b 478 if ( mqttHostAddress[0] > 0 && mqttHostAddress[3] > 0 ) {
SomeRandomBloke 2:27714c8c9c0a 479 outMqtt.initConnection( &mqttHostAddress, mqttPort, mqttUsername, mqttPassword );
SomeRandomBloke 2:27714c8c9c0a 480 //( &serverIpAddr );
SomeRandomBloke 2:27714c8c9c0a 481 useMQTT = outMqtt.init();
SomeRandomBloke 0:a29a0225f203 482
SomeRandomBloke 3:f19f9c62c00b 483 if ( useMQTT )
SomeRandomBloke 2:27714c8c9c0a 484 rtr.addOutput( (OutputDef*)&outMqtt , OUTPUT_TYPE_MQTT);
SomeRandomBloke 2:27714c8c9c0a 485 }
SomeRandomBloke 3:f19f9c62c00b 486
SomeRandomBloke 0:a29a0225f203 487 rtr.initRouting();
SomeRandomBloke 0:a29a0225f203 488
SomeRandomBloke 0:a29a0225f203 489 printf("Setup OK\n");
SomeRandomBloke 0:a29a0225f203 490
SomeRandomBloke 0:a29a0225f203 491 printf( "Setting RFM12B ID %d, Band %d Group %d\n",rfm12bId, rfm12bBand, rfm12bGroup);
SomeRandomBloke 0:a29a0225f203 492 rfm12b.init(rfm12bId, rfm12bBand, rfm12bGroup ); //id = 2, band 866, group 5
SomeRandomBloke 0:a29a0225f203 493
SomeRandomBloke 0:a29a0225f203 494 printf("Listening...\n");
SomeRandomBloke 0:a29a0225f203 495
SomeRandomBloke 0:a29a0225f203 496 Timer tm;
SomeRandomBloke 0:a29a0225f203 497 tm.start();
SomeRandomBloke 0:a29a0225f203 498
SomeRandomBloke 0:a29a0225f203 499 printf("\nHEAP STATS\n");
SomeRandomBloke 0:a29a0225f203 500 __heapstats((__heapprt)fprintf,stderr);
SomeRandomBloke 0:a29a0225f203 501
SomeRandomBloke 0:a29a0225f203 502 short dataLen = 0;
SomeRandomBloke 0:a29a0225f203 503 uint8_t *rf12Buf;
SomeRandomBloke 0:a29a0225f203 504
SomeRandomBloke 0:a29a0225f203 505 // Start receiving data
SomeRandomBloke 0:a29a0225f203 506 rfm12b.rf12_recvStart();
SomeRandomBloke 0:a29a0225f203 507 while (true) {
SomeRandomBloke 0:a29a0225f203 508 Net::poll();
SomeRandomBloke 0:a29a0225f203 509
SomeRandomBloke 0:a29a0225f203 510 // This is RFM12B specific
SomeRandomBloke 0:a29a0225f203 511 if ( rfm12b.available() > 0 ) {
SomeRandomBloke 0:a29a0225f203 512 statusLED = 1;
SomeRandomBloke 0:a29a0225f203 513 rf12Buf = rfm12b.get_data();
SomeRandomBloke 0:a29a0225f203 514 dataLen = rfm12b.length();
SomeRandomBloke 0:a29a0225f203 515
SomeRandomBloke 0:a29a0225f203 516 if ( rtr.routePayload( rf12Buf, dataLen + 3 ) ) {
SomeRandomBloke 0:a29a0225f203 517 // Successfully dealt with a packet
SomeRandomBloke 0:a29a0225f203 518
SomeRandomBloke 0:a29a0225f203 519 // Do something different if routed
SomeRandomBloke 0:a29a0225f203 520
SomeRandomBloke 0:a29a0225f203 521 }
SomeRandomBloke 0:a29a0225f203 522
SomeRandomBloke 0:a29a0225f203 523 // For now, acknowledge everything
SomeRandomBloke 0:a29a0225f203 524
SomeRandomBloke 0:a29a0225f203 525 // Send an ack if required
SomeRandomBloke 0:a29a0225f203 526 if ((rf12Buf[1] & ~RF12_HDR_MASK) == RF12_HDR_ACK // &&
SomeRandomBloke 0:a29a0225f203 527 //(config.nodeId & 0x20) == 0
SomeRandomBloke 0:a29a0225f203 528 ) {
SomeRandomBloke 0:a29a0225f203 529
SomeRandomBloke 0:a29a0225f203 530 printf("RFM12B -> ack\n");
SomeRandomBloke 0:a29a0225f203 531
SomeRandomBloke 0:a29a0225f203 532 byte addr = rf12Buf[1] & RF12_HDR_MASK;
SomeRandomBloke 0:a29a0225f203 533 rfm12b.rf12_sendStart(RF12_HDR_CTL | RF12_HDR_DST | addr, 0, 1);
SomeRandomBloke 0:a29a0225f203 534 }
SomeRandomBloke 0:a29a0225f203 535
SomeRandomBloke 0:a29a0225f203 536 statusLED = 0;
SomeRandomBloke 0:a29a0225f203 537 }
SomeRandomBloke 0:a29a0225f203 538
SomeRandomBloke 0:a29a0225f203 539 if (tm.read()>.5) {
SomeRandomBloke 0:a29a0225f203 540 heartbeatLED=!heartbeatLED; //Show that we are alive
SomeRandomBloke 0:a29a0225f203 541 tm.start();
SomeRandomBloke 0:a29a0225f203 542 }
SomeRandomBloke 0:a29a0225f203 543
SomeRandomBloke 2:27714c8c9c0a 544 // If using mqtt then send heartbeat
SomeRandomBloke 3:f19f9c62c00b 545 if (useMQTT) {
SomeRandomBloke 2:27714c8c9c0a 546 outMqtt.send(); // Used for heartbeat/keepalive packet
SomeRandomBloke 2:27714c8c9c0a 547 }
SomeRandomBloke 3:f19f9c62c00b 548
SomeRandomBloke 0:a29a0225f203 549 linkLED = !ethernet.link();
SomeRandomBloke 0:a29a0225f203 550
SomeRandomBloke 0:a29a0225f203 551 }
SomeRandomBloke 0:a29a0225f203 552
SomeRandomBloke 0:a29a0225f203 553 }
SomeRandomBloke 0:a29a0225f203 554
SomeRandomBloke 0:a29a0225f203 555 // The End!