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

Dependencies:   QW_Sensors mbed

Fork of QW-Downlink by Quicksand

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