This software example demonstrates the downlink capabilities of the SIGFOX network.
Fork of QW-Downlink by
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 }
Generated on Wed Jul 13 2022 10:41:24 by 1.7.2