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

Revision:
4:1d707586e24d
Parent:
3:4da15d6e1429
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