Code example to regularly report light level and temperature over Sigfox on the QW dev kit

Dependencies:   QW_Sensors mbed

This is a code example that demonstrates sending the light level sensor and temperature sensor output over Sigfox at regular time intervals.

The payload that is sent over the network consists of 3 bytes:

  • two bytes light level reading
  • one bye temperature reading.

Use this code example as a start to connect your own device over Sigfox with the Quicksand QW development kit.

Committer:
LievenHollevoet
Date:
Tue Mar 08 09:48:32 2016 +0000
Revision:
1:b2c941af91c6
Parent:
0:9a93fff79b27
Updated repo of QW sensors to local copy.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
LievenHollevoet 0:9a93fff79b27 1 /* This program is an example application that measures the temperature and the light level
LievenHollevoet 0:9a93fff79b27 2 * and transmits the sensor readings over the Sigfox network.
LievenHollevoet 0:9a93fff79b27 3 * A transmission is scheduled every 15 minutes, and the user can force a transmission
LievenHollevoet 0:9a93fff79b27 4 * by pressing the user button one.
LievenHollevoet 0:9a93fff79b27 5 *
LievenHollevoet 0:9a93fff79b27 6 * The data format of the Sigfox payload is:
LievenHollevoet 0:9a93fff79b27 7 * First two bytes of the payload: light level as unsigned 16-bit value.
LievenHollevoet 0:9a93fff79b27 8 * Third byte of the payload: temperature as signed 8-bit value
LievenHollevoet 0:9a93fff79b27 9 *
LievenHollevoet 0:9a93fff79b27 10 * Open a serial console to the board to get a debug trace.
LievenHollevoet 0:9a93fff79b27 11 *
LievenHollevoet 0:9a93fff79b27 12 * Note: this is a very basic example that has no energy usage optimization. The controller is not put in sleep mode
LievenHollevoet 0:9a93fff79b27 13 * in between readings/Sigfox transmissions in order to keep the code flow linear and short.
LievenHollevoet 0:9a93fff79b27 14 *
LievenHollevoet 0:9a93fff79b27 15 * In the current configuration, the temperature sensor is read once per second and a Sigfox transmission is scheduled every 15 minutes.
LievenHollevoet 0:9a93fff79b27 16 * Adapt the defines TX_INTERVAL and MEASURE_INTERVAL to change these settings.
LievenHollevoet 0:9a93fff79b27 17 */
LievenHollevoet 0:9a93fff79b27 18
LievenHollevoet 0:9a93fff79b27 19 #include "mbed.h"
LievenHollevoet 0:9a93fff79b27 20 #include "math.h"
LievenHollevoet 0:9a93fff79b27 21 #include "LinearTempSensor.h"
LievenHollevoet 0:9a93fff79b27 22 #include "VCNL4010.h"
LievenHollevoet 0:9a93fff79b27 23
LievenHollevoet 0:9a93fff79b27 24 #define SER_BUFFER_SIZE 32
LievenHollevoet 0:9a93fff79b27 25
LievenHollevoet 0:9a93fff79b27 26 // Interval in minutes for scheduled Tx
LievenHollevoet 0:9a93fff79b27 27 #define TX_INTERVAL 15
LievenHollevoet 0:9a93fff79b27 28
LievenHollevoet 0:9a93fff79b27 29 // Temperature measure interval in seconds
LievenHollevoet 0:9a93fff79b27 30 #define MEASURE_INTERVAL 1
LievenHollevoet 0:9a93fff79b27 31
LievenHollevoet 0:9a93fff79b27 32 /* The 4 onboard LEDs */
LievenHollevoet 0:9a93fff79b27 33 DigitalOut LED_0 (PB_6);
LievenHollevoet 0:9a93fff79b27 34 DigitalOut LED_1 (PA_7);
LievenHollevoet 0:9a93fff79b27 35 DigitalOut LED_2 (PA_6);
LievenHollevoet 0:9a93fff79b27 36 DigitalOut LED_3 (PA_5);
LievenHollevoet 0:9a93fff79b27 37
LievenHollevoet 0:9a93fff79b27 38 /* The 2 user buttons */
LievenHollevoet 0:9a93fff79b27 39 InterruptIn SW1(PA_8);
LievenHollevoet 0:9a93fff79b27 40 InterruptIn SW2(PB_10);
LievenHollevoet 0:9a93fff79b27 41
LievenHollevoet 0:9a93fff79b27 42 /* Proximity and ambient light sensor*/
LievenHollevoet 0:9a93fff79b27 43 VCNL40x0 VCNL4010(PB_9, PB_8, VCNL40x0_ADDRESS); // SDA, SCL pin and I2C address
LievenHollevoet 0:9a93fff79b27 44
LievenHollevoet 0:9a93fff79b27 45 /*Temperature sensor */
LievenHollevoet 0:9a93fff79b27 46 LinearTempSensor sensor(PA_0, 40);
LievenHollevoet 0:9a93fff79b27 47
LievenHollevoet 0:9a93fff79b27 48 /* Ticker for scheduled transmissions */
LievenHollevoet 0:9a93fff79b27 49 Ticker tTX;
LievenHollevoet 0:9a93fff79b27 50 Ticker tSense;
LievenHollevoet 0:9a93fff79b27 51
LievenHollevoet 0:9a93fff79b27 52 /* Function prototypes */
LievenHollevoet 0:9a93fff79b27 53 void sw1interrupt();
LievenHollevoet 0:9a93fff79b27 54 void sw2interrupt();
LievenHollevoet 0:9a93fff79b27 55 void sertmout();
LievenHollevoet 0:9a93fff79b27 56 bool read_acc(int& x, int& y, int& z);
LievenHollevoet 0:9a93fff79b27 57 bool modem_command_check_ok(char * command);
LievenHollevoet 0:9a93fff79b27 58 void modem_setup();
LievenHollevoet 0:9a93fff79b27 59 void txData();
LievenHollevoet 0:9a93fff79b27 60 void dataScheduledTX();
LievenHollevoet 0:9a93fff79b27 61 void senseTemperature();
LievenHollevoet 0:9a93fff79b27 62
LievenHollevoet 0:9a93fff79b27 63 bool ser_timeout = false;
LievenHollevoet 0:9a93fff79b27 64 bool handleIRQ1 = false;
LievenHollevoet 0:9a93fff79b27 65
LievenHollevoet 0:9a93fff79b27 66 /* Serial port over USB */
LievenHollevoet 0:9a93fff79b27 67 Serial pc(USBTX, USBRX);
LievenHollevoet 0:9a93fff79b27 68
LievenHollevoet 0:9a93fff79b27 69 /* Serial connection to sigfox modem */
LievenHollevoet 0:9a93fff79b27 70 Serial modem(PA_9, PA_10);
LievenHollevoet 0:9a93fff79b27 71
LievenHollevoet 0:9a93fff79b27 72 int main()
LievenHollevoet 0:9a93fff79b27 73 {
LievenHollevoet 0:9a93fff79b27 74 /* Storage for VCNL4010 readout */
LievenHollevoet 0:9a93fff79b27 75 unsigned char ID=0, Current=0;
LievenHollevoet 0:9a93fff79b27 76 //unsigned int ProxiValue=0, AmbiValue=0;
LievenHollevoet 0:9a93fff79b27 77
LievenHollevoet 0:9a93fff79b27 78 /* Variables that will store analog temperature sensor reading */
LievenHollevoet 0:9a93fff79b27 79 //float Tav, To;
LievenHollevoet 0:9a93fff79b27 80
LievenHollevoet 0:9a93fff79b27 81 /* Setup TD120x */
LievenHollevoet 0:9a93fff79b27 82 wait(3);
LievenHollevoet 0:9a93fff79b27 83 modem_setup();
LievenHollevoet 0:9a93fff79b27 84
LievenHollevoet 0:9a93fff79b27 85 /* Turn off all LED */
LievenHollevoet 0:9a93fff79b27 86 LED_0 = 1;
LievenHollevoet 0:9a93fff79b27 87 LED_1 = 1;
LievenHollevoet 0:9a93fff79b27 88 LED_2 = 1;
LievenHollevoet 0:9a93fff79b27 89 LED_3 = 1;
LievenHollevoet 0:9a93fff79b27 90
LievenHollevoet 0:9a93fff79b27 91 /* Setup button interrupts */
LievenHollevoet 0:9a93fff79b27 92 SW2.fall(&sw2interrupt);
LievenHollevoet 0:9a93fff79b27 93 SW1.fall(&sw1interrupt);
LievenHollevoet 0:9a93fff79b27 94
LievenHollevoet 0:9a93fff79b27 95 /* Read VCNL40x0 product ID revision register */
LievenHollevoet 0:9a93fff79b27 96 VCNL4010.ReadID (&ID);
LievenHollevoet 0:9a93fff79b27 97 pc.printf("\nVCNL4010 Product ID Revision Register: %d", ID);
LievenHollevoet 0:9a93fff79b27 98
LievenHollevoet 0:9a93fff79b27 99 VCNL4010.SetCurrent (20); // Set current to 200mA
LievenHollevoet 0:9a93fff79b27 100 VCNL4010.ReadCurrent (&Current); // Read back IR LED current
LievenHollevoet 0:9a93fff79b27 101 pc.printf("\nVCNL4010 IR LED Current: %d\n\n", Current);
LievenHollevoet 0:9a93fff79b27 102
LievenHollevoet 0:9a93fff79b27 103 // Sense temperature for the first time
LievenHollevoet 0:9a93fff79b27 104 senseTemperature();
LievenHollevoet 0:9a93fff79b27 105
LievenHollevoet 0:9a93fff79b27 106 wait_ms(3000); // wait 3s (only for display)
LievenHollevoet 0:9a93fff79b27 107
LievenHollevoet 0:9a93fff79b27 108 tTX.attach(&dataScheduledTX, TX_INTERVAL*60); // Attach the timer for TX
LievenHollevoet 0:9a93fff79b27 109 tSense.attach(&senseTemperature, MEASURE_INTERVAL); // Attach the timer for sensing the temperature
LievenHollevoet 0:9a93fff79b27 110
LievenHollevoet 0:9a93fff79b27 111 while(1)
LievenHollevoet 0:9a93fff79b27 112 {
LievenHollevoet 0:9a93fff79b27 113 /*
LievenHollevoet 0:9a93fff79b27 114 // VCNL4010 reading
LievenHollevoet 0:9a93fff79b27 115 VCNL4010.ReadProxiOnDemand (&ProxiValue); // read prox value on demand
LievenHollevoet 0:9a93fff79b27 116 VCNL4010.ReadAmbiOnDemand (&AmbiValue); // read ambi value on demand
LievenHollevoet 0:9a93fff79b27 117 // MCP9700 reading
LievenHollevoet 0:9a93fff79b27 118 Tav = sensor.GetAverageTemp();
LievenHollevoet 0:9a93fff79b27 119 To = sensor.GetLatestTemp();
LievenHollevoet 0:9a93fff79b27 120
LievenHollevoet 0:9a93fff79b27 121 pc.printf("\n\rVCNL4010 report: Proximity: %5.0i cts, Ambient light: %5.0i cts, Illuminance: %7.2f lx\n\rMCP9700 report: Average Temp: %.2f %cC, Latest Temp: %.2f %cC", ProxiValue, AmbiValue, AmbiValue/4.0, Tav, 176, To, 176);
LievenHollevoet 0:9a93fff79b27 122 wait_ms(5000);
LievenHollevoet 0:9a93fff79b27 123 */
LievenHollevoet 0:9a93fff79b27 124
LievenHollevoet 0:9a93fff79b27 125 if (handleIRQ1) {
LievenHollevoet 0:9a93fff79b27 126 txData();
LievenHollevoet 0:9a93fff79b27 127 handleIRQ1 = false;
LievenHollevoet 0:9a93fff79b27 128 }
LievenHollevoet 0:9a93fff79b27 129 }
LievenHollevoet 0:9a93fff79b27 130 }
LievenHollevoet 0:9a93fff79b27 131
LievenHollevoet 0:9a93fff79b27 132 void modem_setup()
LievenHollevoet 0:9a93fff79b27 133 {
LievenHollevoet 0:9a93fff79b27 134 /* Reset to factory defaults */
LievenHollevoet 0:9a93fff79b27 135 if(modem_command_check_ok("AT&F"))
LievenHollevoet 0:9a93fff79b27 136 {
LievenHollevoet 0:9a93fff79b27 137 pc.printf("Factory reset succesfull\r\n");
LievenHollevoet 0:9a93fff79b27 138 }
LievenHollevoet 0:9a93fff79b27 139 else
LievenHollevoet 0:9a93fff79b27 140 {
LievenHollevoet 0:9a93fff79b27 141 pc.printf("Factory reset TD120x failed\r\n");
LievenHollevoet 0:9a93fff79b27 142 }
LievenHollevoet 0:9a93fff79b27 143 /* Disable local echo */
LievenHollevoet 0:9a93fff79b27 144 modem.printf("ATE0\n");
LievenHollevoet 0:9a93fff79b27 145 if(modem_command_check_ok("ATE0"))
LievenHollevoet 0:9a93fff79b27 146 {
LievenHollevoet 0:9a93fff79b27 147 pc.printf("Local echo disabled\r\n");
LievenHollevoet 0:9a93fff79b27 148 }
LievenHollevoet 0:9a93fff79b27 149 /* Write to mem */
LievenHollevoet 0:9a93fff79b27 150 if(modem_command_check_ok("AT&W"))
LievenHollevoet 0:9a93fff79b27 151 {
LievenHollevoet 0:9a93fff79b27 152 pc.printf("Settings saved!\r\n");
LievenHollevoet 0:9a93fff79b27 153 }
LievenHollevoet 0:9a93fff79b27 154 }
LievenHollevoet 0:9a93fff79b27 155
LievenHollevoet 0:9a93fff79b27 156 bool modem_command_check_ok(char * command)
LievenHollevoet 0:9a93fff79b27 157 {
LievenHollevoet 0:9a93fff79b27 158 /* first clear serial data buffers */
LievenHollevoet 0:9a93fff79b27 159 while(modem.readable()) modem.getc();
LievenHollevoet 0:9a93fff79b27 160 /* Timeout for response of the modem */
LievenHollevoet 0:9a93fff79b27 161 Timeout tmout;
LievenHollevoet 0:9a93fff79b27 162 ser_timeout = false;
LievenHollevoet 0:9a93fff79b27 163 /* Buffer for incoming data */
LievenHollevoet 0:9a93fff79b27 164 char responsebuffer[6];
LievenHollevoet 0:9a93fff79b27 165 /* Flag to set when we get 'OK' response */
LievenHollevoet 0:9a93fff79b27 166 bool ok = false;
LievenHollevoet 0:9a93fff79b27 167 bool error = false;
LievenHollevoet 0:9a93fff79b27 168 /* Print command to TD120x */
LievenHollevoet 0:9a93fff79b27 169 modem.printf(command);
LievenHollevoet 0:9a93fff79b27 170 /* Newline to activate command */
LievenHollevoet 0:9a93fff79b27 171 modem.printf("\n");
LievenHollevoet 0:9a93fff79b27 172 /* Wait untill serial feedback, max 3 seconds before timeout */
LievenHollevoet 0:9a93fff79b27 173 tmout.attach(&sertmout, 3.0);
LievenHollevoet 0:9a93fff79b27 174 while(!modem.readable()&& ser_timeout == false);
LievenHollevoet 0:9a93fff79b27 175 while(!ok && !ser_timeout && !error)
LievenHollevoet 0:9a93fff79b27 176 {
LievenHollevoet 0:9a93fff79b27 177 if(modem.readable())
LievenHollevoet 0:9a93fff79b27 178 {
LievenHollevoet 0:9a93fff79b27 179 for(int i = 0; i < 5; i++)
LievenHollevoet 0:9a93fff79b27 180 {
LievenHollevoet 0:9a93fff79b27 181 responsebuffer[i] = responsebuffer[i+1];
LievenHollevoet 0:9a93fff79b27 182 }
LievenHollevoet 0:9a93fff79b27 183 responsebuffer[5] = modem.getc();
LievenHollevoet 0:9a93fff79b27 184 if(responsebuffer[0] == '\r' && responsebuffer[1] == '\n' && responsebuffer[2] == 'O' && responsebuffer[3] == 'K' && responsebuffer[4] == '\r' && responsebuffer[5] == '\n' )
LievenHollevoet 0:9a93fff79b27 185 {
LievenHollevoet 0:9a93fff79b27 186 ok = true;
LievenHollevoet 0:9a93fff79b27 187 }
LievenHollevoet 0:9a93fff79b27 188 else if(responsebuffer[0] == '\r' && responsebuffer[1] == '\n' && responsebuffer[2] == 'E' && responsebuffer[3] == 'R' && responsebuffer[4] == 'R' && responsebuffer[5] == 'O' )
LievenHollevoet 0:9a93fff79b27 189 {
LievenHollevoet 0:9a93fff79b27 190 error = true;
LievenHollevoet 0:9a93fff79b27 191 }
LievenHollevoet 0:9a93fff79b27 192 }
LievenHollevoet 0:9a93fff79b27 193 }
LievenHollevoet 0:9a93fff79b27 194 tmout.detach();
LievenHollevoet 0:9a93fff79b27 195 return ok;
LievenHollevoet 0:9a93fff79b27 196 }
LievenHollevoet 0:9a93fff79b27 197
LievenHollevoet 0:9a93fff79b27 198 /* Button 1 ISR */
LievenHollevoet 0:9a93fff79b27 199 void sw1interrupt()
LievenHollevoet 0:9a93fff79b27 200 {
LievenHollevoet 0:9a93fff79b27 201 pc.printf("\n\rButton 1 pressed\n\r");
LievenHollevoet 0:9a93fff79b27 202 LED_1 = 0;
LievenHollevoet 0:9a93fff79b27 203 handleIRQ1 = true;
LievenHollevoet 0:9a93fff79b27 204 }
LievenHollevoet 0:9a93fff79b27 205
LievenHollevoet 0:9a93fff79b27 206 /* Button 2 ISR */
LievenHollevoet 0:9a93fff79b27 207 void sw2interrupt()
LievenHollevoet 0:9a93fff79b27 208 {
LievenHollevoet 0:9a93fff79b27 209 pc.printf("\n\rButton 2 pressed\n\r");
LievenHollevoet 0:9a93fff79b27 210 }
LievenHollevoet 0:9a93fff79b27 211
LievenHollevoet 0:9a93fff79b27 212 void dataScheduledTX()
LievenHollevoet 0:9a93fff79b27 213 {
LievenHollevoet 0:9a93fff79b27 214 pc.printf("\n\rScheduled Sigfox TX triggered\n\r");
LievenHollevoet 0:9a93fff79b27 215 LED_1 = 0;
LievenHollevoet 0:9a93fff79b27 216 handleIRQ1 = true;
LievenHollevoet 0:9a93fff79b27 217 }
LievenHollevoet 0:9a93fff79b27 218
LievenHollevoet 0:9a93fff79b27 219 /* ISR for serial timeout */
LievenHollevoet 0:9a93fff79b27 220 void sertmout()
LievenHollevoet 0:9a93fff79b27 221 {
LievenHollevoet 0:9a93fff79b27 222 ser_timeout = true;
LievenHollevoet 0:9a93fff79b27 223 }
LievenHollevoet 0:9a93fff79b27 224
LievenHollevoet 0:9a93fff79b27 225 /* TX data over Sigfox */
LievenHollevoet 0:9a93fff79b27 226 void txData (){
LievenHollevoet 0:9a93fff79b27 227
LievenHollevoet 0:9a93fff79b27 228 unsigned int ambiValue = 0;
LievenHollevoet 0:9a93fff79b27 229 int8_t tAvgByte = 0;
LievenHollevoet 0:9a93fff79b27 230 uint16_t ambiValueShort;
LievenHollevoet 0:9a93fff79b27 231 float tAvg;
LievenHollevoet 0:9a93fff79b27 232 char command[32];
LievenHollevoet 0:9a93fff79b27 233
LievenHollevoet 0:9a93fff79b27 234 VCNL4010.ReadAmbiOnDemand (&ambiValue); // read ambi value on demand
LievenHollevoet 0:9a93fff79b27 235 tAvg = sensor.GetAverageTemp();
LievenHollevoet 0:9a93fff79b27 236 tAvgByte = (int8_t)tAvg;
LievenHollevoet 0:9a93fff79b27 237 ambiValueShort = (uint16_t)ambiValue;
LievenHollevoet 0:9a93fff79b27 238
LievenHollevoet 0:9a93fff79b27 239 sprintf(command, "AT$SF=%04X%02X,2,0\n", ambiValueShort, tAvgByte);
LievenHollevoet 0:9a93fff79b27 240
LievenHollevoet 0:9a93fff79b27 241 pc.printf("Sending ambient light level %i cts and temperature %i degrees C over Sigfox\n", ambiValueShort, tAvgByte);
LievenHollevoet 0:9a93fff79b27 242 pc.printf("using modem command: %s", command);
LievenHollevoet 0:9a93fff79b27 243 modem_command_check_ok(command);
LievenHollevoet 0:9a93fff79b27 244 LED_1 = 1;
LievenHollevoet 0:9a93fff79b27 245 }
LievenHollevoet 0:9a93fff79b27 246
LievenHollevoet 0:9a93fff79b27 247 void senseTemperature() {
LievenHollevoet 0:9a93fff79b27 248 float vOut = sensor.Sense();
LievenHollevoet 0:9a93fff79b27 249 //pc.printf("\n\rMCP9700 reading: Vout: %.2f mV", vOut);
LievenHollevoet 0:9a93fff79b27 250 }