This software example demonstrates the downlink capabilities of the SIGFOX network.

Dependencies:   QW_Sensors mbed

Fork of HelloWorld - QW Development kit by Quicksand micro-electronics

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h"
00002 #include "math.h"
00003 
00004 /* The 4 onboard LEDs */
00005 BusOut leds(PB_6, PA_7, PA_6, PA_5);
00006 
00007 /*
00008 DigitalOut LED_0 (PB_6);
00009 DigitalOut LED_1 (PA_7);
00010 DigitalOut LED_2 (PA_6);
00011 DigitalOut LED_3 (PA_5);
00012 */
00013 
00014 /* The 2 user buttons */
00015 InterruptIn SW1(PA_8);
00016 InterruptIn SW2(PB_10);
00017 
00018 /* Function prototypes */
00019 void buttoninterrupt();
00020 void beat();
00021 void sertmout();
00022 bool modem_command_check_ok(char * command);
00023 void modem_setup();
00024 void downlink();
00025 void error();
00026 
00027 bool ser_timeout = false;
00028 bool go_downlink = false;
00029 
00030 /* Serial port over USB */
00031 Serial pc(USBTX, USBRX);
00032 
00033 /* Serial connection to sigfox modem */
00034 Serial modem(PA_9, PA_10);
00035 
00036 void binToString(char *inputData, int dataLength, char *outputData)   // Note outputdata must be 2 x inputdata + 1 in size!
00037 {
00038 
00039     for (int i = 0; i<dataLength; i++) {
00040         sprintf(outputData+2*i,"%02X",*(inputData+i));
00041     }
00042     outputData[dataLength*2] = 0; // in theory redundant, the last sprintf should have done this but just to be sure...
00043 }
00044 
00045 void error()
00046 {
00047     pc.printf("Something went wrong, please try again\n\r");
00048     int i = 0;
00049     // Failure, blink rapidly:
00050     while(i < 25) {
00051         leds = 0b0000;
00052         wait_ms(100);
00053         leds = 0b1111;
00054         wait_ms(100);
00055         i++;
00056     }
00057 }
00058 
00059 /* Button 1 ISR */
00060 void buttoninterrupt()
00061 {
00062     go_downlink = true;
00063 }
00064 
00065 int main()
00066 {
00067 
00068     /* Setup TD120x */
00069     wait(3);
00070     modem_setup();
00071     leds = 0b1111;
00072     /* Setup button interrupts */
00073     SW2.fall(&buttoninterrupt);
00074     SW1.fall(&buttoninterrupt);
00075 
00076     while(1) {
00077         if(go_downlink) {
00078             downlink();
00079             go_downlink = false;
00080         }
00081         if(pc.readable()) {
00082             modem.putc(pc.getc());
00083         }
00084         if(modem.readable()) {
00085             pc.putc(modem.getc());
00086         }
00087     }
00088 }
00089 
00090 void downlink()
00091 {
00092     leds = 0b0000;
00093     pc.printf("Requesting bidirectional data\n\r");
00094     if(modem_command_check_ok("AT$SF=0102030405060708090A0B0C,2,1")) {
00095         pc.printf("Done sending request, waiting to start reception...\n\r");
00096         char * beginString = "+RX BEGIN";
00097         char * beginStringPtr;
00098         beginStringPtr = beginString;
00099         bool begin_rx = false;
00100 
00101         /* Turn off all LED*/
00102         leds = 0b1111;
00103         /* Timeout */
00104         Timeout tmout;
00105         ser_timeout = false;
00106         tmout.attach(&sertmout, 35.0);
00107         /* Animation while waiting for downlink */
00108         int c;
00109         int animation = 0;
00110         while(!ser_timeout && !begin_rx) {
00111 
00112             while (modem.readable() && !ser_timeout && !begin_rx) {
00113                 c = modem.getc();
00114                 if ( (char)c == *beginStringPtr ) beginStringPtr++;
00115                 else beginStringPtr = beginString;
00116                 if ( *beginStringPtr == 0 ) {
00117                     begin_rx = true;
00118                     pc.printf("Entering reception window\n\r");
00119                 }
00120             }
00121             animation = (animation + 1)%150000;
00122             if(animation == 0)      leds = 0b1110;
00123             if(animation == 25000)  leds = 0b1101;
00124             if(animation == 50000)  leds = 0b1011;
00125             if(animation == 75000)  leds = 0b0111;
00126             if(animation == 100000) leds = 0b1011;
00127             if(animation == 125000) leds = 0b1101;
00128         }
00129         /* turn off timeout timer */
00130         tmout.detach();
00131         if(ser_timeout) error();
00132         else {
00133             /* Turn on outer LEDs*/
00134             leds = 0b0110;
00135             /* Read the data */
00136             // check if reception window ended
00137             char * readyString = "+RX END";
00138             char * readyStringPtr;
00139             readyStringPtr = readyString;
00140             bool rx_ready = false;
00141             int c;
00142             char rx_buffer[128];
00143             int i = 0;
00144             int j = 0;
00145             tmout.attach(&sertmout, 30.0);
00146             ser_timeout = false;
00147             while(modem.readable() && !ser_timeout && !rx_ready)
00148                 while (((c = modem.getc()) > 0) && !ser_timeout && !rx_ready) {
00149                     rx_buffer[i++] = (char)c;
00150                     pc.putc((char)c);
00151                     if ( (char)c == *readyStringPtr ) readyStringPtr++;
00152                     else readyStringPtr = readyString;
00153                     if ( *readyStringPtr == 0 ) {
00154                         rx_ready = true;
00155                     }
00156                 }
00157             rx_buffer[i++] = 0; // EOS
00158             tmout.detach();
00159             if(ser_timeout) error();
00160             else {
00161                 /* Turn off all LED*/
00162                 leds = 0b1111;
00163                 pc.printf("\n\rReception done, received data:\n\r");
00164                 /* removing spaces, new lines, start and end markings */
00165                 for(i = 0, j = 0; i < strlen(rx_buffer); i++) {
00166                     rx_buffer[i-j] = rx_buffer[i];
00167                     if(rx_buffer[i] == ' ' || rx_buffer[i] == '\n' || rx_buffer[i] == '\r' || rx_buffer[i] == '+' || rx_buffer[i] == '=' || (rx_buffer[i] > 'A' && rx_buffer[i] < 'Z'))
00168                         j++;
00169                 }
00170                 /* do not forget EOS again! */
00171                 rx_buffer[i-j] = 0;
00172 
00173                 if(strlen(rx_buffer) != 0) {
00174                     /* Print received data without spaces and markers */
00175                     for(j = 0; j < strlen(rx_buffer); j++) pc.putc(rx_buffer[j]);
00176 
00177                     char buff[32];
00178 
00179                     /* Extract tap and store to int (in this case you would have been able to just print the received data)*/
00180                     memcpy( buff, &rx_buffer[0], 8 );
00181                     buff[8] = '\0';
00182                     int tap = (int)strtol(buff, NULL, 16);
00183 
00184                     /* Extract Client data*/
00185                     memcpy( buff, &rx_buffer[8], 4 );
00186                     buff[4] = '\0';
00187                     int client = (int)strtol(buff, NULL, 16);
00188 
00189                     /* Exctract the RSSI */
00190                     memcpy( buff, &rx_buffer[12], 4 );
00191                     buff[4] = '\0';
00192                     int16_t rssi = (int16_t)strtol(buff, NULL, 16);
00193 
00194                     pc.printf("\n\rMessage received on tap: %X\n\r", tap);
00195                     pc.printf("Client data: %X\n\r", client);
00196                     pc.printf("RSSI level: %d\n\r", rssi);
00197 
00198                     if(rssi > -90) leds = 0b0000;
00199                     else if (rssi > -110) leds = 0b0001;
00200                     else if (rssi > -130) leds = 0b0011;
00201                     else leds = 0b0111;
00202                 } else {
00203                     pc.printf("\n\rNo valid downlink data received!\n\r");
00204                     error();
00205                 }
00206             }
00207         }
00208 
00209 
00210     } else {
00211         // Failure, blink rapidly indefinetly:
00212         error();
00213     }
00214 }
00215 
00216 void modem_setup()
00217 {
00218     /* Reset to factory defaults */
00219     if(modem_command_check_ok("AT&F")) {
00220         pc.printf("Factory reset succesfull\r\n");
00221     } else {
00222         pc.printf("Factory reset TD120x failed\r\n");
00223     }
00224     /* Disable local echo */
00225     modem.printf("ATE0\n");
00226     if(modem_command_check_ok("ATE0")) {
00227         pc.printf("Local echo disabled\r\n");
00228     }
00229     /* Write to mem */
00230     if(modem_command_check_ok("AT&W")) {
00231         pc.printf("Settings saved!\r\n");
00232     }
00233 }
00234 
00235 /* ISR for serial timeout */
00236 void sertmout()
00237 {
00238     ser_timeout = true;
00239 }
00240 
00241 bool modem_command_check_ok(char * command)
00242 {
00243     /* first clear serial data buffers */
00244     while(modem.readable()) modem.getc();
00245     /* Timeout for response of the modem */
00246     Timeout tmout;
00247     ser_timeout = false;
00248     // check if ok or error is received
00249     char * readyString = "OK";
00250     char * readyStringPtr;
00251     readyStringPtr = readyString;
00252     char * errorString = "ERROR";
00253     char * errorStringPtr;
00254     errorStringPtr = errorString;
00255     /* Flag to set when we get 'OK' response */
00256     bool ok = false;
00257     bool error = false;
00258     /* Print command to TD120x */
00259     modem.printf(command);
00260     /* Newline to activate command */
00261     modem.printf("\n");
00262     /* Wait untill serial feedback, max 10 seconds before timeout */
00263     tmout.attach(&sertmout, 10.0);
00264     int c;
00265     while(!ser_timeout && !ok && !error)
00266         if(modem.readable())
00267             while (((c = modem.getc()) > 0) && !ser_timeout  && !ok && !error) {
00268                 if ( (char)c == *readyStringPtr ) readyStringPtr++;
00269                 else readyStringPtr = readyString;
00270                 if ( *readyStringPtr == 0 ) {
00271                     ok = true;
00272                 }
00273                 if ( (char)c == *errorStringPtr ) errorStringPtr++;
00274                 else errorStringPtr = errorString;
00275                 if ( *errorStringPtr == 0 ) {
00276                     error = true;
00277                 }
00278             }
00279     tmout.detach();
00280     if(ser_timeout) return false;
00281     else return ok;
00282 }