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.
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
