This software example demonstrates the downlink capabilities of the SIGFOX network.
Dependencies: QW_Sensors mbed
Fork of HelloWorld - QW Development kit by
Revision 4:1d707586e24d, committed 2017-03-14
- Comitter:
- quicksand
- Date:
- Tue Mar 14 12:45:21 2017 +0000
- Parent:
- 3:4da15d6e1429
- Commit message:
- This first version of the QW-Downlink program demonstrates the usage of SIGFOX downlinks to receive data from the cloud on the device.
Changed in this revision
main.cpp | Show annotated file Show diff for this revision Revisions of this file |
diff -r 4da15d6e1429 -r 1d707586e24d main.cpp --- a/main.cpp Mon May 02 12:04:13 2016 +0000 +++ b/main.cpp Tue Mar 14 12:45:21 2017 +0000 @@ -1,32 +1,31 @@ #include "mbed.h" #include "math.h" -#include "LinearTempSensor.h" /* The 4 onboard LEDs */ +BusOut leds(PB_6, PA_7, PA_6, PA_5); + +/* DigitalOut LED_0 (PB_6); DigitalOut LED_1 (PA_7); DigitalOut LED_2 (PA_6); DigitalOut LED_3 (PA_5); +*/ /* The 2 user buttons */ InterruptIn SW1(PA_8); InterruptIn SW2(PB_10); -/*Temperature sensor */ -LinearTempSensor sensor(PA_0, 5); - /* Function prototypes */ -void sw1interrupt(); -void sw2interrupt(); +void buttoninterrupt(); void beat(); void sertmout(); bool modem_command_check_ok(char * command); void modem_setup(); -void txData(uint8_t btn); +void downlink(); +void error(); bool ser_timeout = false; - -Ticker heartbeat; +bool go_downlink = false; /* Serial port over USB */ Serial pc(USBTX, USBRX); @@ -34,6 +33,34 @@ /* Serial connection to sigfox modem */ Serial modem(PA_9, PA_10); +void binToString(char *inputData, int dataLength, char *outputData) // Note outputdata must be 2 x inputdata + 1 in size! +{ + + for (int i = 0; i<dataLength; i++) { + sprintf(outputData+2*i,"%02X",*(inputData+i)); + } + outputData[dataLength*2] = 0; // in theory redundant, the last sprintf should have done this but just to be sure... +} + +void error() +{ + pc.printf("Something went wrong, please try again\n\r"); + int i = 0; + // Failure, blink rapidly: + while(i < 25) { + leds = 0b0000; + wait_ms(100); + leds = 0b1111; + wait_ms(100); + i++; + } +} + +/* Button 1 ISR */ +void buttoninterrupt() +{ + go_downlink = true; +} int main() { @@ -41,24 +68,16 @@ /* Setup TD120x */ wait(3); modem_setup(); - /* Test temperature sensor */ - float vOut = sensor.Sense(); - pc.printf("\n\rMCP9700 reading: Vout: %.2f mV", vOut); - - /* Turn off all LED */ - LED_0 = 1; - LED_1 = 1; - LED_2 = 1; - LED_3 = 1; - - /* Blinking LED */ - heartbeat.attach(&beat, 0.5); - + leds = 0b1111; /* Setup button interrupts */ - SW2.fall(&sw2interrupt); - SW1.fall(&sw1interrupt); + SW2.fall(&buttoninterrupt); + SW1.fall(&buttoninterrupt); while(1) { + if(go_downlink) { + downlink(); + go_downlink = false; + } if(pc.readable()) { modem.putc(pc.getc()); } @@ -68,46 +87,130 @@ } } -void beat() -{ - LED_0 = !LED_0; -} - -/* Button 1 ISR */ -void sw1interrupt() +void downlink() { - pc.printf("\n\rButton 1 pressed\n\r"); - LED_1 = 0; - txData(1); -} + leds = 0b0000; + pc.printf("Requesting bidirectional data\n\r"); + if(modem_command_check_ok("AT$SF=0102030405060708090A0B0C,2,1")) { + pc.printf("Done sending request, waiting to start reception...\n\r"); + char * beginString = "+RX BEGIN"; + char * beginStringPtr; + beginStringPtr = beginString; + bool begin_rx = false; + + /* Turn off all LED*/ + leds = 0b1111; + /* Timeout */ + Timeout tmout; + ser_timeout = false; + tmout.attach(&sertmout, 35.0); + /* Animation while waiting for downlink */ + int c; + int animation = 0; + while(!ser_timeout && !begin_rx) { -/* Button 2 ISR */ -void sw2interrupt() -{ - pc.printf("\n\rButton 2 pressed\n\r"); - LED_2 = 0; - txData(2); -} + while (modem.readable() && !ser_timeout && !begin_rx) { + c = modem.getc(); + if ( (char)c == *beginStringPtr ) beginStringPtr++; + else beginStringPtr = beginString; + if ( *beginStringPtr == 0 ) { + begin_rx = true; + pc.printf("Entering reception window\n\r"); + } + } + animation = (animation + 1)%150000; + if(animation == 0) leds = 0b1110; + if(animation == 25000) leds = 0b1101; + if(animation == 50000) leds = 0b1011; + if(animation == 75000) leds = 0b0111; + if(animation == 100000) leds = 0b1011; + if(animation == 125000) leds = 0b1101; + } + /* turn off timeout timer */ + tmout.detach(); + if(ser_timeout) error(); + else { + /* Turn on outer LEDs*/ + leds = 0b0110; + /* Read the data */ + // check if reception window ended + char * readyString = "+RX END"; + char * readyStringPtr; + readyStringPtr = readyString; + bool rx_ready = false; + int c; + char rx_buffer[128]; + int i = 0; + int j = 0; + tmout.attach(&sertmout, 30.0); + ser_timeout = false; + while(modem.readable() && !ser_timeout && !rx_ready) + while (((c = modem.getc()) > 0) && !ser_timeout && !rx_ready) { + rx_buffer[i++] = (char)c; + pc.putc((char)c); + if ( (char)c == *readyStringPtr ) readyStringPtr++; + else readyStringPtr = readyString; + if ( *readyStringPtr == 0 ) { + rx_ready = true; + } + } + rx_buffer[i++] = 0; // EOS + tmout.detach(); + if(ser_timeout) error(); + else { + /* Turn off all LED*/ + leds = 0b1111; + pc.printf("\n\rReception done, received data:\n\r"); + /* removing spaces, new lines, start and end markings */ + for(i = 0, j = 0; i < strlen(rx_buffer); i++) { + rx_buffer[i-j] = rx_buffer[i]; + 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')) + j++; + } + /* do not forget EOS again! */ + rx_buffer[i-j] = 0; + + if(strlen(rx_buffer) != 0) { + /* Print received data without spaces and markers */ + for(j = 0; j < strlen(rx_buffer); j++) pc.putc(rx_buffer[j]); + + char buff[32]; + + /* Extract tap and store to int (in this case you would have been able to just print the received data)*/ + memcpy( buff, &rx_buffer[0], 8 ); + buff[8] = '\0'; + int tap = (int)strtol(buff, NULL, 16); + + /* Extract Client data*/ + memcpy( buff, &rx_buffer[8], 4 ); + buff[4] = '\0'; + int client = (int)strtol(buff, NULL, 16); + + /* Exctract the RSSI */ + memcpy( buff, &rx_buffer[12], 4 ); + buff[4] = '\0'; + int16_t rssi = (int16_t)strtol(buff, NULL, 16); + + pc.printf("\n\rMessage received on tap: %X\n\r", tap); + pc.printf("Client data: %X\n\r", client); + pc.printf("RSSI level: %d\n\r", rssi); + + if(rssi > -90) leds = 0b0000; + else if (rssi > -110) leds = 0b0001; + else if (rssi > -130) leds = 0b0011; + else leds = 0b0111; + } else { + pc.printf("\n\rNo valid downlink data received!\n\r"); + error(); + } + } + } -/* TX data over Sigfox */ -void txData (uint8_t btn) -{ - - float tAvg; - char command[32]; - sensor.Sense(); - tAvg = sensor.GetAverageTemp(); - char temperature[6] =""; - sprintf(temperature, "%3.1f", tAvg); - for(int i = 0; i < 5; i++) - if(temperature[i]==0) temperature[i] = ' '; - sprintf(command, "AT$SF=0142544e%x20%x%x%x%x%x43,2,0\n", btn+48, temperature[0],temperature[1],temperature[2],temperature[3],temperature[4]); - pc.printf("Sending pressed button %d and temperature %s C over Sigfox.\n", btn, temperature); - pc.printf("using modem command: %s", command); - modem_command_check_ok(command); - LED_1 = 1; - LED_2 = 1; + } else { + // Failure, blink rapidly indefinetly: + error(); + } } void modem_setup() @@ -142,8 +245,13 @@ /* Timeout for response of the modem */ Timeout tmout; ser_timeout = false; - /* Buffer for incoming data */ - char responsebuffer[6]; + // check if ok or error is received + char * readyString = "OK"; + char * readyStringPtr; + readyStringPtr = readyString; + char * errorString = "ERROR"; + char * errorStringPtr; + errorStringPtr = errorString; /* Flag to set when we get 'OK' response */ bool ok = false; bool error = false; @@ -151,22 +259,24 @@ modem.printf(command); /* Newline to activate command */ modem.printf("\n"); - /* Wait untill serial feedback, max 3 seconds before timeout */ - tmout.attach(&sertmout, 3.0); - while(!modem.readable()&& ser_timeout == false); - while(!ok && !ser_timeout && !error) { - if(modem.readable()) { - for(int i = 0; i < 5; i++) { - responsebuffer[i] = responsebuffer[i+1]; + /* Wait untill serial feedback, max 10 seconds before timeout */ + tmout.attach(&sertmout, 10.0); + int c; + while(!ser_timeout && !ok && !error) + if(modem.readable()) + while (((c = modem.getc()) > 0) && !ser_timeout && !ok && !error) { + if ( (char)c == *readyStringPtr ) readyStringPtr++; + else readyStringPtr = readyString; + if ( *readyStringPtr == 0 ) { + ok = true; + } + if ( (char)c == *errorStringPtr ) errorStringPtr++; + else errorStringPtr = errorString; + if ( *errorStringPtr == 0 ) { + error = true; + } } - responsebuffer[5] = modem.getc(); - if(responsebuffer[0] == '\r' && responsebuffer[1] == '\n' && responsebuffer[2] == 'O' && responsebuffer[3] == 'K' && responsebuffer[4] == '\r' && responsebuffer[5] == '\n' ) { - ok = true; - } else if(responsebuffer[0] == '\r' && responsebuffer[1] == '\n' && responsebuffer[2] == 'E' && responsebuffer[3] == 'R' && responsebuffer[4] == 'R' && responsebuffer[5] == 'O' ) { - error = true; - } - } - } tmout.detach(); - return ok; + if(ser_timeout) return false; + else return ok; } \ No newline at end of file