Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: NetServices FatFileSystem csv_parser mbed MQTTClient RF12B DNSResolver SDFileSystem
main.cpp
00001 /** IoT Gateway main code 00002 * 00003 * @author Andrew Lindsay 00004 * 00005 * @section LICENSE 00006 * 00007 * Copyright (c) 2012 Andrew Lindsay (andrew [at] thiseldo [dot] co [dot] uk) 00008 * 00009 * Permission is hereby granted, free of charge, to any person obtaining a copy 00010 * of this software and associated documentation files (the "Software"), to deal 00011 * in the Software without restriction, including without limitation the rights 00012 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 00013 * copies of the Software, and to permit persons to whom the Software is 00014 * furnished to do so, subject to the following conditions: 00015 00016 * The above copyright notice and this permission notice shall be included in 00017 * all copies or substantial portions of the Software. 00018 * 00019 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00020 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00021 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00022 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00023 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00024 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 00025 * THE SOFTWARE. 00026 * 00027 * @section DESCRIPTION 00028 * 00029 * Code is to be classed as beta. There is a lot of debug code still includes 00030 * to dump heap sizes and other values. It is still a work in progress and 00031 * should be treated as such. 00032 * 00033 * Further documentation available from 00034 * http://blog.thiseldo.co.uk/wp-filez/IoTGateway.pdf 00035 * 00036 * Sample configuration file IOTSETUP.TXT 00037 * 00038 * @code 00039 * ip.mode=fixed 00040 * ip.address=192.168.1.99 00041 * ip.netmask=255.255.255.0 00042 * ip.gateway=192.168.1.1 00043 * ip.dns=192.168.1.1 00044 * rfm12b.band=868 00045 * rfm12b.id=30 00046 * rfm12b.group=212 00047 * time.host=0.uk.pool.ntp.org 00048 * time.timezone=GMT 00049 * time.dst=yes 00050 * pachube.key=***your Pachube api key*** 00051 * pachube.apiurl=http://api.pachube.com/v2/feeds/%d.csv?_method=PUT 00052 * emoncms.key=***your emonCms api key*** 00053 * emoncms.apiurl=http://your.host.com/emoncms/api/post?apikey=%s&json= 00054 * sense.key=***your Sen.se api key*** 00055 * sense.apiurl=http://api.sen.se/events/?sense_key=%s 00056 * mqtt.host= 00057 * mqtt.port=1883 00058 * mqtt.username= 00059 * mqtt.password= 00060 * @endcode 00061 * 00062 * Some values are not yet used 00063 * 00064 */ 00065 00066 #include "iotgateway.h" 00067 #include "mbed.h" 00068 #include <ctype.h> 00069 #include "SDFileSystem.h" 00070 #include "EthernetNetIf.h" 00071 #include "NTPClient.h" 00072 #include "dnsresolve.h" 00073 #include "RF12B.h" 00074 #include "IoTRouting.h" 00075 00076 using std::string; 00077 00078 #undef DEBUG 00079 00080 #define VERSION_INFO "IoT Gateway Basic - Version 0.8" 00081 00082 DigitalOut heartbeatLED(LED1, "heartbeatLED"); 00083 DigitalOut led2(LED2, "led2"); 00084 DigitalOut led3(LED3, "led3"); 00085 //DigitalOut led4(LED4, "led4"); 00086 DigitalOut linkLED(p30, "linkLED"); 00087 DigitalOut statusLED(p25, "statusLED"); 00088 00089 // Put as much as we can into RAM bank AHBSRAM0 which is reserved for USB that we are not using 00090 00091 // Setup which filesystem to use, Local or uSD card, both use same name 00092 //__attribute((section("AHBSRAM0"))) LocalFileSystem fs("iotfs"); 00093 __attribute((section("AHBSRAM0"))) SDFileSystem sd(p5, p6, p7, p8, "iotfs"); 00094 00095 __attribute((section("AHBSRAM0"))) EthernetNetIf *eth; 00096 __attribute((section("AHBSRAM0"))) NTPClient ntp; 00097 __attribute((section("AHBSRAM0"))) Ethernet ethernet; 00098 __attribute((section("AHBSRAM0"))) DNSResolver resolver; 00099 00100 // Configuration values loaded from file iotsetup.dat 00101 __attribute((section("AHBSRAM0"))) IpAddr ipAddress(0, 0, 0, 0); 00102 __attribute((section("AHBSRAM0"))) IpAddr netMask(255, 255, 255, 0); 00103 __attribute((section("AHBSRAM0"))) IpAddr gwAddress(0, 0, 0, 0); 00104 __attribute((section("AHBSRAM0"))) IpAddr dnsAddress(0, 0, 0, 0); 00105 __attribute((section("AHBSRAM0"))) bool useDHCP = false; 00106 00107 // Static buffers 00108 __attribute((section("AHBSRAM0"))) static char lineBuf[MAX_LINE_LENGTH]; 00109 __attribute((section("AHBSRAM0"))) static OutputPachube outPachube; 00110 __attribute((section("AHBSRAM0"))) static OutputEmonCms outEmonCms; 00111 __attribute((section("AHBSRAM0"))) static OutputSenSe outSenSe; 00112 __attribute((section("AHBSRAM0"))) static IoTRouting rtr; 00113 00114 // Pachube config 00115 __attribute((section("AHBSRAM0"))) char pachubeApiUrl[API_URL_LENGTH]; 00116 __attribute((section("AHBSRAM0"))) char pachubeApiKey[API_KEY_LENGTH]; 00117 __attribute((section("AHBSRAM0"))) char pachubeDataBuffer[DATABUF_SIZE]; 00118 00119 // MQTT config 00120 __attribute((section("AHBSRAM0"))) IpAddr mqttHostAddress( 0, 0, 0, 0); 00121 __attribute((section("AHBSRAM0"))) short mqttPort; 00122 __attribute((section("AHBSRAM0"))) char mqttUsername[MAX_LINE_LENGTH]; 00123 __attribute((section("AHBSRAM0"))) char mqttPassword[MAX_LINE_LENGTH]; 00124 __attribute((section("AHBSRAM0"))) bool useMQTT = false; 00125 00126 //char mqttHostName[65]; 00127 00128 // Open energy Monitor emonCMS config 00129 __attribute((section("AHBSRAM0"))) char emonCmsApiUrl[API_URL_LENGTH]; 00130 __attribute((section("AHBSRAM0"))) char emonCmsApiKey[API_KEY_LENGTH]; 00131 __attribute((section("AHBSRAM0"))) char emonCmsDataBuffer[DATABUF_SIZE]; 00132 00133 // Open energy Monitor Sen.Se config 00134 __attribute((section("AHBSRAM0"))) char senSeApiUrl[API_URL_LENGTH]; 00135 __attribute((section("AHBSRAM0"))) char senSeApiKey[API_KEY_LENGTH]; 00136 __attribute((section("AHBSRAM0"))) char senSeDataBuffer[DATABUF_SIZE]; 00137 00138 // Time server config 00139 __attribute((section("AHBSRAM0"))) char ntpHost[MAX_LINE_LENGTH] = "0.uk.pool.ntp.org"; 00140 00141 // RFM12B config 00142 __attribute((section("AHBSRAM0"))) static string rfm12bBands[4] = {"xxx", "433", "868", "915" }; 00143 __attribute((section("AHBSRAM0"))) static uint8_t rfm12bId; 00144 __attribute((section("AHBSRAM0"))) static uint8_t rfm12bBand; 00145 __attribute((section("AHBSRAM0"))) static uint8_t rfm12bGroup; 00146 00147 #define iotConfigFile "/iotfs/IOTSETUP.TXT" 00148 00149 __attribute((section("AHBSRAM0"))) RF12B rfm12b(p11, p12, p13, p14, p18); 00150 __attribute((section("AHBSRAM0"))) Serial pc(USBTX, USBRX); // tx, rx 00151 00152 // Utility functions 00153 00154 /** convert string to IP address 00155 * 00156 * @param ipAddrInt IP address as single 32bit integer 00157 * @param value The IP address as a string 00158 */ 00159 void setIpAddress( int *ipAddrInt, char *value ) { 00160 sscanf(value, "%d.%d.%d.%d", &ipAddrInt[0],&ipAddrInt[1],&ipAddrInt[2],&ipAddrInt[3]); 00161 } 00162 00163 /** Get the value from a name=value pair 00164 * 00165 * @param buf The name/value pair character buffer 00166 * @returns pointer to value 00167 */ 00168 char *getConfigValue( char *buf ) { 00169 char *ptr = strchr(buf, '='); 00170 if ( ptr == NULL ) 00171 return NULL; 00172 ptr++; 00173 return ptr; 00174 } 00175 00176 /** Copy zero or CR/LF terminated string to new zero terminated string 00177 * Used when reading config values from files to remove CR/LF endings 00178 * 00179 * @param to Char pointer to destination 00180 * @param from Char pointer to source 00181 */ 00182 void strcpynull(char *to, char *from ) { 00183 while ( *from != '\n' && *from != '\r' && *from != '\0' ) { 00184 *to++ = *from++; 00185 } 00186 *to = '\0'; 00187 } 00188 00189 /** Trim a string in buffer, remove leading and trailing spaces 00190 * 00191 */ 00192 char *trim(char *str) { 00193 size_t len = 0; 00194 char *frontp = str - 1; 00195 char *endp = NULL; 00196 00197 if ( str == NULL ) 00198 return NULL; 00199 00200 if ( str[0] == '\0' ) 00201 return str; 00202 00203 len = strlen(str); 00204 endp = str + len; 00205 00206 /* Move the front and back pointers to address 00207 * the first non-whitespace characters from 00208 * each end. 00209 */ 00210 while ( isspace(*(++frontp)) ); 00211 while ( isspace(*(--endp)) && endp != frontp ); 00212 00213 // while( *(++frontp) == ' ' ); 00214 // while( (*(--endp) == ' ') && endp != frontp ); 00215 00216 if ( str + len - 1 != endp ) 00217 *(endp + 1) = '\0'; 00218 else if ( frontp != str && endp == frontp ) 00219 *str = '\0'; 00220 00221 /* Shift the string so that it starts at str so 00222 * that if it's dynamically allocated, we can 00223 * still free it on the returned pointer. Note 00224 * the reuse of endp to mean the front of the 00225 * string buffer now. 00226 */ 00227 endp = str; 00228 if ( frontp != str ) { 00229 while ( *frontp ) *endp++ = *frontp++; 00230 *endp = '\0'; 00231 } 00232 00233 00234 return str; 00235 } 00236 00237 /** Read IoT gateway configuration file 00238 * File is of format name=value 00239 * 00240 */ 00241 bool readConfig() { 00242 00243 FILE *fp = fopen(iotConfigFile, "r"); 00244 if (fp == NULL) { 00245 printf("Could not open file %s for read\n", iotConfigFile); 00246 return false; 00247 } 00248 // read file 00249 while (!feof( fp )) { 00250 fgets(lineBuf,MAX_LINE_LENGTH,fp); 00251 // printf("[%s] ",lineBuf); 00252 trim( lineBuf ); 00253 // printf("[%s]\n", lineBuf); 00254 00255 // Need to read each entry and update config 00256 char *nameStr; 00257 char *valueStr; 00258 nameStr = lineBuf; 00259 valueStr = strchr( lineBuf, '=' ); 00260 if ( valueStr != NULL ) { 00261 *valueStr++ = '\0'; 00262 int tmpAddress[4] = {0,0,0,0}; 00263 if ( strcmp( nameStr, "ip.address" ) == 0 ) { 00264 setIpAddress( &tmpAddress[0], valueStr ); 00265 ipAddress = IpAddr( tmpAddress[0],tmpAddress[1],tmpAddress[2],tmpAddress[3]); 00266 00267 } else if ( strcmp( nameStr, "ip.netmask" ) == 0 ) { 00268 setIpAddress( &tmpAddress[0], valueStr ); 00269 netMask = IpAddr( tmpAddress[0],tmpAddress[1],tmpAddress[2],tmpAddress[3]); 00270 00271 } else if ( strcmp( nameStr, "ip.gateway" ) == 0 ) { 00272 setIpAddress( &tmpAddress[0], valueStr ); 00273 gwAddress = IpAddr( tmpAddress[0],tmpAddress[1],tmpAddress[2],tmpAddress[3]); 00274 00275 } else if ( strcmp( nameStr, "ip.dns" ) == 0 ) { 00276 setIpAddress( &tmpAddress[0], valueStr ); 00277 dnsAddress = IpAddr( tmpAddress[0],tmpAddress[1],tmpAddress[2],tmpAddress[3]); 00278 00279 } else if ( strcmp( nameStr, "ip.mode" ) == 0 ) { 00280 useDHCP = (strncmp( valueStr, "dhcp", 4) == 0 ? true : false); 00281 00282 } else if ( strcmp( nameStr, "time.host" ) == 0 ) { 00283 strcpynull(ntpHost, valueStr ); 00284 00285 } else if ( strcmp( nameStr, "pachube.apiurl" ) == 0 ) { 00286 strcpynull(pachubeApiUrl, valueStr ); 00287 00288 } else if ( strcmp( nameStr, "pachube.key" ) == 0 ) { 00289 strcpynull(pachubeApiKey, valueStr ); 00290 00291 } else if ( strcmp( nameStr, "emoncms.apiurl" ) == 0 ) { 00292 strcpynull(emonCmsApiUrl, valueStr ); 00293 00294 } else if ( strcmp( nameStr, "emoncms.key" ) == 0 ) { 00295 strcpynull(emonCmsApiKey, valueStr ); 00296 00297 } else if ( strcmp( nameStr, "sense.apiurl" ) == 0 ) { 00298 strcpynull(senSeApiUrl, valueStr ); 00299 00300 } else if ( strcmp( nameStr, "sense.key" ) == 0 ) { 00301 strcpynull(senSeApiKey, valueStr ); 00302 } else if ( strcmp( nameStr, "mqtt.host" ) == 0 ) { 00303 setIpAddress( &tmpAddress[0], valueStr ); 00304 mqttHostAddress = IpAddr( tmpAddress[0],tmpAddress[1],tmpAddress[2],tmpAddress[3]); 00305 00306 } else if ( strcmp( nameStr, "mqtt.port" ) == 0 ) { 00307 mqttPort = atoi( valueStr ); 00308 00309 } else if ( strcmp( nameStr, "mqtt.username" ) == 0 ) { 00310 strcpynull(mqttUsername, valueStr ); 00311 00312 } else if ( strcmp( nameStr, "mqtt.password" ) == 0 ) { 00313 strcpynull(mqttPassword, valueStr ); 00314 00315 } else if ( strcmp( nameStr, "rfm12b.band" ) == 0 ) { 00316 if ( strncmp( valueStr, "433", 3 ) == 0 ) 00317 rfm12bBand = RF12_433MHZ; 00318 else if ( strncmp( valueStr, "868", 3 ) == 0 ) 00319 rfm12bBand = RF12_868MHZ; 00320 else if ( strncmp( valueStr, "915", 3 ) == 0 ) 00321 rfm12bBand = RF12_915MHZ; 00322 00323 } else if ( strcmp( nameStr, "rfm12b.id" ) == 0 ) { 00324 rfm12bId = atoi( valueStr ); 00325 } else if ( strcmp( nameStr, "rfm12b.group" ) == 0 ) { 00326 rfm12bGroup = atoi( valueStr ); 00327 } 00328 } 00329 } 00330 fclose(fp); 00331 00332 return true; 00333 } 00334 00335 /** Write the current config to file 00336 */ 00337 bool writeConfig() { 00338 00339 // Doesnt work? 00340 // Rename original file 00341 // if( rename ( iotConfigFile.c_str(), iotConfigFileBak.c_str() ) != 0 ) { 00342 // printf("Could not rename file %s\n", iotConfigFile); 00343 // return false; 00344 // } 00345 00346 FILE *fp = fopen(iotConfigFile, "w"); 00347 if (fp == NULL) { 00348 printf("Could not open file %s for write\n", iotConfigFile); 00349 return false; 00350 } 00351 00352 time_t ctTime; 00353 ctTime = time(NULL); 00354 00355 fprintf(fp, "# iotsetup created (UTC) %s\n", ctime(&ctTime)); 00356 fprintf(fp, "ip.mode=%s\n", (useDHCP ? "dhcp" : "fixed") ); 00357 // Add msg to say net config being ignored 00358 if ( useDHCP ) 00359 fprintf(fp, "# Following ip.* parameters not used in DHCP mode\n"); 00360 00361 fprintf(fp, "ip.address=%hhu.%hhu.%hhu.%hhu\n", ipAddress[0], ipAddress[1],ipAddress[2],ipAddress[3]); 00362 fprintf(fp, "ip.netmask=%hhu.%hhu.%hhu.%hhu\n",netMask[0], netMask[1], netMask[2], netMask[3]); 00363 fprintf(fp, "ip.gateway=%hhu.%hhu.%hhu.%hhu\n",gwAddress[0],gwAddress[1],gwAddress[2],gwAddress[3]); 00364 fprintf(fp, "ip.dns=%hhu.%hhu.%hhu.%hhu\n",dnsAddress[0],dnsAddress[1],dnsAddress[2],dnsAddress[3]); 00365 00366 fprintf(fp, "rfm12b.band=%s\n",rfm12bBands[rfm12bBand].c_str()); 00367 fprintf(fp, "rfm12b.id=%d\n",rfm12bId); 00368 fprintf(fp, "rfm12b.group=%d\n",rfm12bGroup); 00369 00370 fprintf(fp, "time.timezone=GMT\n"); 00371 fprintf(fp, "time.dst=yes\n"); 00372 00373 fprintf(fp, "pachube.key=%s\n", pachubeApiKey ); 00374 00375 fprintf(fp, "mqtt.host=%hhu.%hhu.%hhu.%hhu\n",mqttHostAddress[0],mqttHostAddress[1],mqttHostAddress[2],mqttHostAddress[3]); 00376 fprintf(fp, "mqtt.port=%d\n",mqttPort); 00377 fprintf(fp, "mqtt.username=%s\n", mqttUsername ); 00378 fprintf(fp, "mqtt.password=%s\n", mqttPassword ); 00379 00380 fclose(fp); 00381 00382 return true; 00383 } 00384 00385 00386 // These external symbols are maintained by the linker to indicate the 00387 // location of various regions in the device's memory. They will be used by 00388 // DisplayRAMBanks() to dump the size of each RAM bank to stdout. 00389 extern unsigned int Image$$RW_IRAM1$$Base; 00390 extern unsigned int Image$$RW_IRAM1$$ZI$$Limit; 00391 extern unsigned int Image$$RW_IRAM2$$Base; 00392 extern unsigned int Image$$RW_IRAM2$$ZI$$Limit; 00393 extern unsigned int Image$$RW_IRAM3$$Base; 00394 extern unsigned int Image$$RW_IRAM3$$ZI$$Limit; 00395 00396 //#ifdef DEBUG 00397 // Displays the size of static allocations for each RAM bank as indicated by 00398 // ARM linker to stdout. 00399 static void DisplayRAMBanks(void) { 00400 printf("Static RAM bank allocations\r\n"); 00401 printf(" Main RAM = %u\r\n", (unsigned int)&Image$$RW_IRAM1$$ZI$$Limit - 00402 (unsigned int)&Image$$RW_IRAM1$$Base); 00403 printf(" RAM0 = %u\r\n", (unsigned int)&Image$$RW_IRAM2$$ZI$$Limit - 00404 (unsigned int)&Image$$RW_IRAM2$$Base); 00405 printf(" RAM1 = %u\r\n", (unsigned int)&Image$$RW_IRAM3$$ZI$$Limit - 00406 (unsigned int)&Image$$RW_IRAM3$$Base); 00407 } 00408 //#endif 00409 00410 /** Main function, where all the magic starts 00411 */ 00412 int main() { 00413 linkLED = 1; 00414 statusLED = 0; 00415 pc.baud(115200); 00416 00417 printf(VERSION_INFO); 00418 printf("\n"); 00419 DisplayRAMBanks(); 00420 #ifdef DEBUG 00421 00422 printf("Setting up...\n"); 00423 printf("\nHEAP STATS\n"); 00424 __heapstats((__heapprt)fprintf,stderr); 00425 #endif 00426 00427 if ( !readConfig() ) { 00428 error("Setup failed"); 00429 } 00430 00431 if (useDHCP) { 00432 printf("Using DHCP\n"); 00433 eth = new EthernetNetIf( "IoTGateway" ); 00434 } else { 00435 // printf("Using Fixed addressing\n"); 00436 eth = new EthernetNetIf( ipAddress, netMask, gwAddress, dnsAddress ); 00437 } 00438 EthernetErr ethErr = eth->setup(); 00439 if (ethErr) { 00440 printf("Error %d in setup.\n", ethErr); 00441 return -1; 00442 } 00443 00444 linkLED = !ethernet.link(); 00445 00446 if (useDHCP) { 00447 // We are using dhcp so get IP Address 00448 ipAddress = eth->getIp(); 00449 } 00450 00451 // Get Current time 00452 Host server(IpAddr(), 123, ntpHost); // "0.uk.pool.ntp.org"); 00453 ntp.setTime(server); 00454 00455 time_t ctTime = time(NULL); 00456 printf("\nTime is now (UTC): %s\n", ctime(&ctTime)); 00457 00458 // If Pachube API Key defined, set up output module 00459 if ( strlen(pachubeApiKey) > 0 ) { 00460 outPachube = OutputPachube( pachubeDataBuffer, pachubeApiUrl, pachubeApiKey ); 00461 // outPachube.setApiKey( pachubeApiKey ); 00462 // printf("MAIN: outPachube = %ld\n",(int)&outPachube); 00463 rtr.addOutput( (OutputDef*)&outPachube , OUTPUT_TYPE_PACHUBE); 00464 } 00465 00466 // If emonCms API Key defined, set up output module 00467 if ( strlen(emonCmsApiKey) > 0 ) { 00468 outEmonCms = OutputEmonCms( emonCmsDataBuffer, emonCmsApiUrl, emonCmsApiKey ); 00469 rtr.addOutput( (OutputDef*)&outEmonCms , OUTPUT_TYPE_EMONCMS); 00470 } 00471 00472 // If Sen.se API Key defined, set up output module 00473 if ( strlen(senSeApiKey) > 0 ) { 00474 outSenSe = OutputSenSe( senSeDataBuffer, senSeApiUrl, senSeApiKey ); 00475 rtr.addOutput( (OutputDef*)&outSenSe , OUTPUT_TYPE_SENSE); 00476 } 00477 00478 //mqttHostAddress = IpAddr(192,168,1,77); 00479 OutputMqtt outMqtt = OutputMqtt(); 00480 // mqttHostAddress = resolver.resolveName("api.pachube.com"); 00481 // Only use MQTT is we have a host IP address 00482 if ( mqttHostAddress[0] > 0 && mqttHostAddress[3] > 0 ) { 00483 outMqtt.initConnection( &mqttHostAddress, mqttPort, mqttUsername, mqttPassword ); 00484 //( &serverIpAddr ); 00485 useMQTT = outMqtt.init(); 00486 00487 if ( useMQTT ) 00488 rtr.addOutput( (OutputDef*)&outMqtt , OUTPUT_TYPE_MQTT); 00489 } 00490 00491 rtr.initRouting(); 00492 #ifdef DEBUG 00493 printf("Setup OK\n"); 00494 00495 printf( "Setting RFM12B ID %d, Band %d Group %d\n",rfm12bId, rfm12bBand, rfm12bGroup); 00496 #endif 00497 00498 rfm12b.init(rfm12bId, rfm12bBand, rfm12bGroup ); //id = 2, band 866, group 5 00499 00500 // printf("Listening...\n"); 00501 00502 Timer tm; 00503 tm.start(); 00504 #ifdef DEBUG 00505 printf("\nHEAP STATS\n"); 00506 __heapstats((__heapprt)fprintf,stderr); 00507 #endif 00508 00509 short dataLen = 0; 00510 uint8_t *rf12Buf; 00511 00512 // Start receiving data 00513 rfm12b.rf12_recvStart(); 00514 while (true) { 00515 Net::poll(); 00516 00517 // This is RFM12B specific 00518 if ( rfm12b.available() > 0 ) { 00519 statusLED = 1; 00520 rf12Buf = rfm12b.get_data(); 00521 dataLen = rfm12b.length(); 00522 00523 if ( rtr.routePayload( rf12Buf, dataLen + 3 ) ) { 00524 // Successfully dealt with a packet 00525 00526 // Do something different if routed 00527 00528 } 00529 00530 // For now, acknowledge everything 00531 00532 // Send an ack if required 00533 if ((rf12Buf[1] & ~RF12_HDR_MASK) == RF12_HDR_ACK // && 00534 //(config.nodeId & 0x20) == 0 00535 ) { 00536 #ifdef DEBUG 00537 printf("RFM12B -> ack\n"); 00538 #endif 00539 byte addr = rf12Buf[1] & RF12_HDR_MASK; 00540 rfm12b.rf12_sendStart(RF12_HDR_CTL | RF12_HDR_DST | addr, 0, 1); 00541 } 00542 00543 statusLED = 0; 00544 } 00545 00546 if (tm.read()>.5) { 00547 heartbeatLED=!heartbeatLED; //Show that we are alive 00548 tm.start(); 00549 } 00550 00551 // If using mqtt then send heartbeat 00552 if (useMQTT) { 00553 outMqtt.send(); // Used for heartbeat/keepalive packet 00554 } 00555 00556 linkLED = !ethernet.link(); 00557 00558 } 00559 00560 } 00561 00562 // The End!
Generated on Tue Jul 12 2022 22:07:04 by
1.7.2