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

Committer:
quicksand
Date:
Tue Mar 14 12:45:21 2017 +0000
Revision:
4:1d707586e24d
Parent:
3:4da15d6e1429
This first version of the QW-Downlink program demonstrates the usage of SIGFOX downlinks to receive data from the cloud on the device.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
quicksand 0:49858c4c3500 1 #include "mbed.h"
quicksand 1:897a1b3f0955 2 #include "math.h"
quicksand 0:49858c4c3500 3
quicksand 1:897a1b3f0955 4 /* The 4 onboard LEDs */
quicksand 4:1d707586e24d 5 BusOut leds(PB_6, PA_7, PA_6, PA_5);
quicksand 4:1d707586e24d 6
quicksand 4:1d707586e24d 7 /*
quicksand 0:49858c4c3500 8 DigitalOut LED_0 (PB_6);
quicksand 0:49858c4c3500 9 DigitalOut LED_1 (PA_7);
quicksand 0:49858c4c3500 10 DigitalOut LED_2 (PA_6);
quicksand 0:49858c4c3500 11 DigitalOut LED_3 (PA_5);
quicksand 4:1d707586e24d 12 */
quicksand 0:49858c4c3500 13
quicksand 1:897a1b3f0955 14 /* The 2 user buttons */
quicksand 1:897a1b3f0955 15 InterruptIn SW1(PA_8);
quicksand 1:897a1b3f0955 16 InterruptIn SW2(PB_10);
quicksand 1:897a1b3f0955 17
quicksand 1:897a1b3f0955 18 /* Function prototypes */
quicksand 4:1d707586e24d 19 void buttoninterrupt();
quicksand 1:897a1b3f0955 20 void beat();
quicksand 1:897a1b3f0955 21 void sertmout();
quicksand 1:897a1b3f0955 22 bool modem_command_check_ok(char * command);
quicksand 1:897a1b3f0955 23 void modem_setup();
quicksand 4:1d707586e24d 24 void downlink();
quicksand 4:1d707586e24d 25 void error();
quicksand 0:49858c4c3500 26
quicksand 1:897a1b3f0955 27 bool ser_timeout = false;
quicksand 4:1d707586e24d 28 bool go_downlink = false;
quicksand 1:897a1b3f0955 29
quicksand 1:897a1b3f0955 30 /* Serial port over USB */
quicksand 0:49858c4c3500 31 Serial pc(USBTX, USBRX);
quicksand 1:897a1b3f0955 32
quicksand 1:897a1b3f0955 33 /* Serial connection to sigfox modem */
quicksand 0:49858c4c3500 34 Serial modem(PA_9, PA_10);
quicksand 0:49858c4c3500 35
quicksand 4:1d707586e24d 36 void binToString(char *inputData, int dataLength, char *outputData) // Note outputdata must be 2 x inputdata + 1 in size!
quicksand 4:1d707586e24d 37 {
quicksand 4:1d707586e24d 38
quicksand 4:1d707586e24d 39 for (int i = 0; i<dataLength; i++) {
quicksand 4:1d707586e24d 40 sprintf(outputData+2*i,"%02X",*(inputData+i));
quicksand 4:1d707586e24d 41 }
quicksand 4:1d707586e24d 42 outputData[dataLength*2] = 0; // in theory redundant, the last sprintf should have done this but just to be sure...
quicksand 4:1d707586e24d 43 }
quicksand 4:1d707586e24d 44
quicksand 4:1d707586e24d 45 void error()
quicksand 4:1d707586e24d 46 {
quicksand 4:1d707586e24d 47 pc.printf("Something went wrong, please try again\n\r");
quicksand 4:1d707586e24d 48 int i = 0;
quicksand 4:1d707586e24d 49 // Failure, blink rapidly:
quicksand 4:1d707586e24d 50 while(i < 25) {
quicksand 4:1d707586e24d 51 leds = 0b0000;
quicksand 4:1d707586e24d 52 wait_ms(100);
quicksand 4:1d707586e24d 53 leds = 0b1111;
quicksand 4:1d707586e24d 54 wait_ms(100);
quicksand 4:1d707586e24d 55 i++;
quicksand 4:1d707586e24d 56 }
quicksand 4:1d707586e24d 57 }
quicksand 4:1d707586e24d 58
quicksand 4:1d707586e24d 59 /* Button 1 ISR */
quicksand 4:1d707586e24d 60 void buttoninterrupt()
quicksand 4:1d707586e24d 61 {
quicksand 4:1d707586e24d 62 go_downlink = true;
quicksand 4:1d707586e24d 63 }
quicksand 1:897a1b3f0955 64
quicksand 1:897a1b3f0955 65 int main()
quicksand 1:897a1b3f0955 66 {
quicksand 0:49858c4c3500 67
quicksand 1:897a1b3f0955 68 /* Setup TD120x */
quicksand 1:897a1b3f0955 69 wait(3);
quicksand 1:897a1b3f0955 70 modem_setup();
quicksand 4:1d707586e24d 71 leds = 0b1111;
quicksand 1:897a1b3f0955 72 /* Setup button interrupts */
quicksand 4:1d707586e24d 73 SW2.fall(&buttoninterrupt);
quicksand 4:1d707586e24d 74 SW1.fall(&buttoninterrupt);
quicksand 1:897a1b3f0955 75
quicksand 1:897a1b3f0955 76 while(1) {
quicksand 4:1d707586e24d 77 if(go_downlink) {
quicksand 4:1d707586e24d 78 downlink();
quicksand 4:1d707586e24d 79 go_downlink = false;
quicksand 4:1d707586e24d 80 }
quicksand 0:49858c4c3500 81 if(pc.readable()) {
quicksand 0:49858c4c3500 82 modem.putc(pc.getc());
quicksand 0:49858c4c3500 83 }
quicksand 0:49858c4c3500 84 if(modem.readable()) {
quicksand 1:897a1b3f0955 85 pc.putc(modem.getc());
quicksand 0:49858c4c3500 86 }
quicksand 0:49858c4c3500 87 }
quicksand 0:49858c4c3500 88 }
quicksand 1:897a1b3f0955 89
quicksand 4:1d707586e24d 90 void downlink()
quicksand 1:897a1b3f0955 91 {
quicksand 4:1d707586e24d 92 leds = 0b0000;
quicksand 4:1d707586e24d 93 pc.printf("Requesting bidirectional data\n\r");
quicksand 4:1d707586e24d 94 if(modem_command_check_ok("AT$SF=0102030405060708090A0B0C,2,1")) {
quicksand 4:1d707586e24d 95 pc.printf("Done sending request, waiting to start reception...\n\r");
quicksand 4:1d707586e24d 96 char * beginString = "+RX BEGIN";
quicksand 4:1d707586e24d 97 char * beginStringPtr;
quicksand 4:1d707586e24d 98 beginStringPtr = beginString;
quicksand 4:1d707586e24d 99 bool begin_rx = false;
quicksand 4:1d707586e24d 100
quicksand 4:1d707586e24d 101 /* Turn off all LED*/
quicksand 4:1d707586e24d 102 leds = 0b1111;
quicksand 4:1d707586e24d 103 /* Timeout */
quicksand 4:1d707586e24d 104 Timeout tmout;
quicksand 4:1d707586e24d 105 ser_timeout = false;
quicksand 4:1d707586e24d 106 tmout.attach(&sertmout, 35.0);
quicksand 4:1d707586e24d 107 /* Animation while waiting for downlink */
quicksand 4:1d707586e24d 108 int c;
quicksand 4:1d707586e24d 109 int animation = 0;
quicksand 4:1d707586e24d 110 while(!ser_timeout && !begin_rx) {
quicksand 1:897a1b3f0955 111
quicksand 4:1d707586e24d 112 while (modem.readable() && !ser_timeout && !begin_rx) {
quicksand 4:1d707586e24d 113 c = modem.getc();
quicksand 4:1d707586e24d 114 if ( (char)c == *beginStringPtr ) beginStringPtr++;
quicksand 4:1d707586e24d 115 else beginStringPtr = beginString;
quicksand 4:1d707586e24d 116 if ( *beginStringPtr == 0 ) {
quicksand 4:1d707586e24d 117 begin_rx = true;
quicksand 4:1d707586e24d 118 pc.printf("Entering reception window\n\r");
quicksand 4:1d707586e24d 119 }
quicksand 4:1d707586e24d 120 }
quicksand 4:1d707586e24d 121 animation = (animation + 1)%150000;
quicksand 4:1d707586e24d 122 if(animation == 0) leds = 0b1110;
quicksand 4:1d707586e24d 123 if(animation == 25000) leds = 0b1101;
quicksand 4:1d707586e24d 124 if(animation == 50000) leds = 0b1011;
quicksand 4:1d707586e24d 125 if(animation == 75000) leds = 0b0111;
quicksand 4:1d707586e24d 126 if(animation == 100000) leds = 0b1011;
quicksand 4:1d707586e24d 127 if(animation == 125000) leds = 0b1101;
quicksand 4:1d707586e24d 128 }
quicksand 4:1d707586e24d 129 /* turn off timeout timer */
quicksand 4:1d707586e24d 130 tmout.detach();
quicksand 4:1d707586e24d 131 if(ser_timeout) error();
quicksand 4:1d707586e24d 132 else {
quicksand 4:1d707586e24d 133 /* Turn on outer LEDs*/
quicksand 4:1d707586e24d 134 leds = 0b0110;
quicksand 4:1d707586e24d 135 /* Read the data */
quicksand 4:1d707586e24d 136 // check if reception window ended
quicksand 4:1d707586e24d 137 char * readyString = "+RX END";
quicksand 4:1d707586e24d 138 char * readyStringPtr;
quicksand 4:1d707586e24d 139 readyStringPtr = readyString;
quicksand 4:1d707586e24d 140 bool rx_ready = false;
quicksand 4:1d707586e24d 141 int c;
quicksand 4:1d707586e24d 142 char rx_buffer[128];
quicksand 4:1d707586e24d 143 int i = 0;
quicksand 4:1d707586e24d 144 int j = 0;
quicksand 4:1d707586e24d 145 tmout.attach(&sertmout, 30.0);
quicksand 4:1d707586e24d 146 ser_timeout = false;
quicksand 4:1d707586e24d 147 while(modem.readable() && !ser_timeout && !rx_ready)
quicksand 4:1d707586e24d 148 while (((c = modem.getc()) > 0) && !ser_timeout && !rx_ready) {
quicksand 4:1d707586e24d 149 rx_buffer[i++] = (char)c;
quicksand 4:1d707586e24d 150 pc.putc((char)c);
quicksand 4:1d707586e24d 151 if ( (char)c == *readyStringPtr ) readyStringPtr++;
quicksand 4:1d707586e24d 152 else readyStringPtr = readyString;
quicksand 4:1d707586e24d 153 if ( *readyStringPtr == 0 ) {
quicksand 4:1d707586e24d 154 rx_ready = true;
quicksand 4:1d707586e24d 155 }
quicksand 4:1d707586e24d 156 }
quicksand 4:1d707586e24d 157 rx_buffer[i++] = 0; // EOS
quicksand 4:1d707586e24d 158 tmout.detach();
quicksand 4:1d707586e24d 159 if(ser_timeout) error();
quicksand 4:1d707586e24d 160 else {
quicksand 4:1d707586e24d 161 /* Turn off all LED*/
quicksand 4:1d707586e24d 162 leds = 0b1111;
quicksand 4:1d707586e24d 163 pc.printf("\n\rReception done, received data:\n\r");
quicksand 4:1d707586e24d 164 /* removing spaces, new lines, start and end markings */
quicksand 4:1d707586e24d 165 for(i = 0, j = 0; i < strlen(rx_buffer); i++) {
quicksand 4:1d707586e24d 166 rx_buffer[i-j] = rx_buffer[i];
quicksand 4:1d707586e24d 167 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'))
quicksand 4:1d707586e24d 168 j++;
quicksand 4:1d707586e24d 169 }
quicksand 4:1d707586e24d 170 /* do not forget EOS again! */
quicksand 4:1d707586e24d 171 rx_buffer[i-j] = 0;
quicksand 4:1d707586e24d 172
quicksand 4:1d707586e24d 173 if(strlen(rx_buffer) != 0) {
quicksand 4:1d707586e24d 174 /* Print received data without spaces and markers */
quicksand 4:1d707586e24d 175 for(j = 0; j < strlen(rx_buffer); j++) pc.putc(rx_buffer[j]);
quicksand 4:1d707586e24d 176
quicksand 4:1d707586e24d 177 char buff[32];
quicksand 4:1d707586e24d 178
quicksand 4:1d707586e24d 179 /* Extract tap and store to int (in this case you would have been able to just print the received data)*/
quicksand 4:1d707586e24d 180 memcpy( buff, &rx_buffer[0], 8 );
quicksand 4:1d707586e24d 181 buff[8] = '\0';
quicksand 4:1d707586e24d 182 int tap = (int)strtol(buff, NULL, 16);
quicksand 4:1d707586e24d 183
quicksand 4:1d707586e24d 184 /* Extract Client data*/
quicksand 4:1d707586e24d 185 memcpy( buff, &rx_buffer[8], 4 );
quicksand 4:1d707586e24d 186 buff[4] = '\0';
quicksand 4:1d707586e24d 187 int client = (int)strtol(buff, NULL, 16);
quicksand 4:1d707586e24d 188
quicksand 4:1d707586e24d 189 /* Exctract the RSSI */
quicksand 4:1d707586e24d 190 memcpy( buff, &rx_buffer[12], 4 );
quicksand 4:1d707586e24d 191 buff[4] = '\0';
quicksand 4:1d707586e24d 192 int16_t rssi = (int16_t)strtol(buff, NULL, 16);
quicksand 4:1d707586e24d 193
quicksand 4:1d707586e24d 194 pc.printf("\n\rMessage received on tap: %X\n\r", tap);
quicksand 4:1d707586e24d 195 pc.printf("Client data: %X\n\r", client);
quicksand 4:1d707586e24d 196 pc.printf("RSSI level: %d\n\r", rssi);
quicksand 4:1d707586e24d 197
quicksand 4:1d707586e24d 198 if(rssi > -90) leds = 0b0000;
quicksand 4:1d707586e24d 199 else if (rssi > -110) leds = 0b0001;
quicksand 4:1d707586e24d 200 else if (rssi > -130) leds = 0b0011;
quicksand 4:1d707586e24d 201 else leds = 0b0111;
quicksand 4:1d707586e24d 202 } else {
quicksand 4:1d707586e24d 203 pc.printf("\n\rNo valid downlink data received!\n\r");
quicksand 4:1d707586e24d 204 error();
quicksand 4:1d707586e24d 205 }
quicksand 4:1d707586e24d 206 }
quicksand 4:1d707586e24d 207 }
quicksand 1:897a1b3f0955 208
quicksand 1:897a1b3f0955 209
quicksand 4:1d707586e24d 210 } else {
quicksand 4:1d707586e24d 211 // Failure, blink rapidly indefinetly:
quicksand 4:1d707586e24d 212 error();
quicksand 4:1d707586e24d 213 }
quicksand 1:897a1b3f0955 214 }
quicksand 1:897a1b3f0955 215
quicksand 1:897a1b3f0955 216 void modem_setup()
quicksand 1:897a1b3f0955 217 {
quicksand 1:897a1b3f0955 218 /* Reset to factory defaults */
quicksand 1:897a1b3f0955 219 if(modem_command_check_ok("AT&F")) {
quicksand 1:897a1b3f0955 220 pc.printf("Factory reset succesfull\r\n");
quicksand 1:897a1b3f0955 221 } else {
quicksand 1:897a1b3f0955 222 pc.printf("Factory reset TD120x failed\r\n");
quicksand 1:897a1b3f0955 223 }
quicksand 1:897a1b3f0955 224 /* Disable local echo */
quicksand 1:897a1b3f0955 225 modem.printf("ATE0\n");
quicksand 1:897a1b3f0955 226 if(modem_command_check_ok("ATE0")) {
quicksand 1:897a1b3f0955 227 pc.printf("Local echo disabled\r\n");
quicksand 1:897a1b3f0955 228 }
quicksand 1:897a1b3f0955 229 /* Write to mem */
quicksand 1:897a1b3f0955 230 if(modem_command_check_ok("AT&W")) {
quicksand 1:897a1b3f0955 231 pc.printf("Settings saved!\r\n");
quicksand 1:897a1b3f0955 232 }
quicksand 1:897a1b3f0955 233 }
quicksand 1:897a1b3f0955 234
quicksand 1:897a1b3f0955 235 /* ISR for serial timeout */
quicksand 1:897a1b3f0955 236 void sertmout()
quicksand 1:897a1b3f0955 237 {
quicksand 1:897a1b3f0955 238 ser_timeout = true;
quicksand 1:897a1b3f0955 239 }
quicksand 1:897a1b3f0955 240
quicksand 1:897a1b3f0955 241 bool modem_command_check_ok(char * command)
quicksand 1:897a1b3f0955 242 {
quicksand 1:897a1b3f0955 243 /* first clear serial data buffers */
quicksand 1:897a1b3f0955 244 while(modem.readable()) modem.getc();
quicksand 1:897a1b3f0955 245 /* Timeout for response of the modem */
quicksand 1:897a1b3f0955 246 Timeout tmout;
quicksand 1:897a1b3f0955 247 ser_timeout = false;
quicksand 4:1d707586e24d 248 // check if ok or error is received
quicksand 4:1d707586e24d 249 char * readyString = "OK";
quicksand 4:1d707586e24d 250 char * readyStringPtr;
quicksand 4:1d707586e24d 251 readyStringPtr = readyString;
quicksand 4:1d707586e24d 252 char * errorString = "ERROR";
quicksand 4:1d707586e24d 253 char * errorStringPtr;
quicksand 4:1d707586e24d 254 errorStringPtr = errorString;
quicksand 1:897a1b3f0955 255 /* Flag to set when we get 'OK' response */
quicksand 1:897a1b3f0955 256 bool ok = false;
quicksand 1:897a1b3f0955 257 bool error = false;
quicksand 1:897a1b3f0955 258 /* Print command to TD120x */
quicksand 1:897a1b3f0955 259 modem.printf(command);
quicksand 1:897a1b3f0955 260 /* Newline to activate command */
quicksand 1:897a1b3f0955 261 modem.printf("\n");
quicksand 4:1d707586e24d 262 /* Wait untill serial feedback, max 10 seconds before timeout */
quicksand 4:1d707586e24d 263 tmout.attach(&sertmout, 10.0);
quicksand 4:1d707586e24d 264 int c;
quicksand 4:1d707586e24d 265 while(!ser_timeout && !ok && !error)
quicksand 4:1d707586e24d 266 if(modem.readable())
quicksand 4:1d707586e24d 267 while (((c = modem.getc()) > 0) && !ser_timeout && !ok && !error) {
quicksand 4:1d707586e24d 268 if ( (char)c == *readyStringPtr ) readyStringPtr++;
quicksand 4:1d707586e24d 269 else readyStringPtr = readyString;
quicksand 4:1d707586e24d 270 if ( *readyStringPtr == 0 ) {
quicksand 4:1d707586e24d 271 ok = true;
quicksand 4:1d707586e24d 272 }
quicksand 4:1d707586e24d 273 if ( (char)c == *errorStringPtr ) errorStringPtr++;
quicksand 4:1d707586e24d 274 else errorStringPtr = errorString;
quicksand 4:1d707586e24d 275 if ( *errorStringPtr == 0 ) {
quicksand 4:1d707586e24d 276 error = true;
quicksand 4:1d707586e24d 277 }
quicksand 1:897a1b3f0955 278 }
quicksand 1:897a1b3f0955 279 tmout.detach();
quicksand 4:1d707586e24d 280 if(ser_timeout) return false;
quicksand 4:1d707586e24d 281 else return ok;
quicksand 1:897a1b3f0955 282 }