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

Dependencies:   QW_Sensors mbed

Fork of QW_Temperature_Light_Monitor by Lieven Hollevoet

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 byte temperature reading.

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

Committer:
quicksand
Date:
Mon May 02 12:03:27 2016 +0000
Revision:
2:33e92af45279
Parent:
0:9a93fff79b27
Added a header byte (0x02) that indicates this example. Added blinking LED to show the device is alive.

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;
quicksand 2:33e92af45279 51 Ticker heartbeat;
LievenHollevoet 0:9a93fff79b27 52
LievenHollevoet 0:9a93fff79b27 53 /* Function prototypes */
LievenHollevoet 0:9a93fff79b27 54 void sw1interrupt();
LievenHollevoet 0:9a93fff79b27 55 void sw2interrupt();
LievenHollevoet 0:9a93fff79b27 56 void sertmout();
LievenHollevoet 0:9a93fff79b27 57 bool read_acc(int& x, int& y, int& z);
LievenHollevoet 0:9a93fff79b27 58 bool modem_command_check_ok(char * command);
LievenHollevoet 0:9a93fff79b27 59 void modem_setup();
LievenHollevoet 0:9a93fff79b27 60 void txData();
LievenHollevoet 0:9a93fff79b27 61 void dataScheduledTX();
LievenHollevoet 0:9a93fff79b27 62 void senseTemperature();
LievenHollevoet 0:9a93fff79b27 63
LievenHollevoet 0:9a93fff79b27 64 bool ser_timeout = false;
LievenHollevoet 0:9a93fff79b27 65 bool handleIRQ1 = false;
LievenHollevoet 0:9a93fff79b27 66
LievenHollevoet 0:9a93fff79b27 67 /* Serial port over USB */
LievenHollevoet 0:9a93fff79b27 68 Serial pc(USBTX, USBRX);
LievenHollevoet 0:9a93fff79b27 69
LievenHollevoet 0:9a93fff79b27 70 /* Serial connection to sigfox modem */
LievenHollevoet 0:9a93fff79b27 71 Serial modem(PA_9, PA_10);
LievenHollevoet 0:9a93fff79b27 72
quicksand 2:33e92af45279 73 void beat()
quicksand 2:33e92af45279 74 {
quicksand 2:33e92af45279 75 LED_3 = !LED_3;
quicksand 2:33e92af45279 76 }
quicksand 2:33e92af45279 77
LievenHollevoet 0:9a93fff79b27 78 int main()
LievenHollevoet 0:9a93fff79b27 79 {
quicksand 2:33e92af45279 80 /* Blinking LED */
quicksand 2:33e92af45279 81 heartbeat.attach(&beat, 0.5);
LievenHollevoet 0:9a93fff79b27 82 /* Storage for VCNL4010 readout */
LievenHollevoet 0:9a93fff79b27 83 unsigned char ID=0, Current=0;
LievenHollevoet 0:9a93fff79b27 84 //unsigned int ProxiValue=0, AmbiValue=0;
LievenHollevoet 0:9a93fff79b27 85
LievenHollevoet 0:9a93fff79b27 86 /* Variables that will store analog temperature sensor reading */
LievenHollevoet 0:9a93fff79b27 87 //float Tav, To;
LievenHollevoet 0:9a93fff79b27 88
LievenHollevoet 0:9a93fff79b27 89 /* Setup TD120x */
LievenHollevoet 0:9a93fff79b27 90 wait(3);
LievenHollevoet 0:9a93fff79b27 91 modem_setup();
LievenHollevoet 0:9a93fff79b27 92
LievenHollevoet 0:9a93fff79b27 93 /* Turn off all LED */
LievenHollevoet 0:9a93fff79b27 94 LED_0 = 1;
LievenHollevoet 0:9a93fff79b27 95 LED_1 = 1;
LievenHollevoet 0:9a93fff79b27 96 LED_2 = 1;
LievenHollevoet 0:9a93fff79b27 97 LED_3 = 1;
LievenHollevoet 0:9a93fff79b27 98
LievenHollevoet 0:9a93fff79b27 99 /* Setup button interrupts */
LievenHollevoet 0:9a93fff79b27 100 SW2.fall(&sw2interrupt);
LievenHollevoet 0:9a93fff79b27 101 SW1.fall(&sw1interrupt);
LievenHollevoet 0:9a93fff79b27 102
LievenHollevoet 0:9a93fff79b27 103 /* Read VCNL40x0 product ID revision register */
LievenHollevoet 0:9a93fff79b27 104 VCNL4010.ReadID (&ID);
LievenHollevoet 0:9a93fff79b27 105 pc.printf("\nVCNL4010 Product ID Revision Register: %d", ID);
LievenHollevoet 0:9a93fff79b27 106
LievenHollevoet 0:9a93fff79b27 107 VCNL4010.SetCurrent (20); // Set current to 200mA
LievenHollevoet 0:9a93fff79b27 108 VCNL4010.ReadCurrent (&Current); // Read back IR LED current
LievenHollevoet 0:9a93fff79b27 109 pc.printf("\nVCNL4010 IR LED Current: %d\n\n", Current);
LievenHollevoet 0:9a93fff79b27 110
LievenHollevoet 0:9a93fff79b27 111 // Sense temperature for the first time
LievenHollevoet 0:9a93fff79b27 112 senseTemperature();
LievenHollevoet 0:9a93fff79b27 113
LievenHollevoet 0:9a93fff79b27 114 wait_ms(3000); // wait 3s (only for display)
LievenHollevoet 0:9a93fff79b27 115
LievenHollevoet 0:9a93fff79b27 116 tTX.attach(&dataScheduledTX, TX_INTERVAL*60); // Attach the timer for TX
LievenHollevoet 0:9a93fff79b27 117 tSense.attach(&senseTemperature, MEASURE_INTERVAL); // Attach the timer for sensing the temperature
LievenHollevoet 0:9a93fff79b27 118
LievenHollevoet 0:9a93fff79b27 119 while(1)
LievenHollevoet 0:9a93fff79b27 120 {
LievenHollevoet 0:9a93fff79b27 121 /*
LievenHollevoet 0:9a93fff79b27 122 // VCNL4010 reading
LievenHollevoet 0:9a93fff79b27 123 VCNL4010.ReadProxiOnDemand (&ProxiValue); // read prox value on demand
LievenHollevoet 0:9a93fff79b27 124 VCNL4010.ReadAmbiOnDemand (&AmbiValue); // read ambi value on demand
LievenHollevoet 0:9a93fff79b27 125 // MCP9700 reading
LievenHollevoet 0:9a93fff79b27 126 Tav = sensor.GetAverageTemp();
LievenHollevoet 0:9a93fff79b27 127 To = sensor.GetLatestTemp();
LievenHollevoet 0:9a93fff79b27 128
LievenHollevoet 0:9a93fff79b27 129 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 130 wait_ms(5000);
LievenHollevoet 0:9a93fff79b27 131 */
LievenHollevoet 0:9a93fff79b27 132
LievenHollevoet 0:9a93fff79b27 133 if (handleIRQ1) {
LievenHollevoet 0:9a93fff79b27 134 txData();
LievenHollevoet 0:9a93fff79b27 135 handleIRQ1 = false;
LievenHollevoet 0:9a93fff79b27 136 }
LievenHollevoet 0:9a93fff79b27 137 }
LievenHollevoet 0:9a93fff79b27 138 }
LievenHollevoet 0:9a93fff79b27 139
LievenHollevoet 0:9a93fff79b27 140 void modem_setup()
LievenHollevoet 0:9a93fff79b27 141 {
LievenHollevoet 0:9a93fff79b27 142 /* Reset to factory defaults */
LievenHollevoet 0:9a93fff79b27 143 if(modem_command_check_ok("AT&F"))
LievenHollevoet 0:9a93fff79b27 144 {
LievenHollevoet 0:9a93fff79b27 145 pc.printf("Factory reset succesfull\r\n");
LievenHollevoet 0:9a93fff79b27 146 }
LievenHollevoet 0:9a93fff79b27 147 else
LievenHollevoet 0:9a93fff79b27 148 {
LievenHollevoet 0:9a93fff79b27 149 pc.printf("Factory reset TD120x failed\r\n");
LievenHollevoet 0:9a93fff79b27 150 }
LievenHollevoet 0:9a93fff79b27 151 /* Disable local echo */
LievenHollevoet 0:9a93fff79b27 152 modem.printf("ATE0\n");
LievenHollevoet 0:9a93fff79b27 153 if(modem_command_check_ok("ATE0"))
LievenHollevoet 0:9a93fff79b27 154 {
LievenHollevoet 0:9a93fff79b27 155 pc.printf("Local echo disabled\r\n");
LievenHollevoet 0:9a93fff79b27 156 }
LievenHollevoet 0:9a93fff79b27 157 /* Write to mem */
LievenHollevoet 0:9a93fff79b27 158 if(modem_command_check_ok("AT&W"))
LievenHollevoet 0:9a93fff79b27 159 {
LievenHollevoet 0:9a93fff79b27 160 pc.printf("Settings saved!\r\n");
LievenHollevoet 0:9a93fff79b27 161 }
LievenHollevoet 0:9a93fff79b27 162 }
LievenHollevoet 0:9a93fff79b27 163
LievenHollevoet 0:9a93fff79b27 164 bool modem_command_check_ok(char * command)
LievenHollevoet 0:9a93fff79b27 165 {
LievenHollevoet 0:9a93fff79b27 166 /* first clear serial data buffers */
LievenHollevoet 0:9a93fff79b27 167 while(modem.readable()) modem.getc();
LievenHollevoet 0:9a93fff79b27 168 /* Timeout for response of the modem */
LievenHollevoet 0:9a93fff79b27 169 Timeout tmout;
LievenHollevoet 0:9a93fff79b27 170 ser_timeout = false;
LievenHollevoet 0:9a93fff79b27 171 /* Buffer for incoming data */
LievenHollevoet 0:9a93fff79b27 172 char responsebuffer[6];
LievenHollevoet 0:9a93fff79b27 173 /* Flag to set when we get 'OK' response */
LievenHollevoet 0:9a93fff79b27 174 bool ok = false;
LievenHollevoet 0:9a93fff79b27 175 bool error = false;
LievenHollevoet 0:9a93fff79b27 176 /* Print command to TD120x */
LievenHollevoet 0:9a93fff79b27 177 modem.printf(command);
LievenHollevoet 0:9a93fff79b27 178 /* Newline to activate command */
LievenHollevoet 0:9a93fff79b27 179 modem.printf("\n");
LievenHollevoet 0:9a93fff79b27 180 /* Wait untill serial feedback, max 3 seconds before timeout */
LievenHollevoet 0:9a93fff79b27 181 tmout.attach(&sertmout, 3.0);
LievenHollevoet 0:9a93fff79b27 182 while(!modem.readable()&& ser_timeout == false);
LievenHollevoet 0:9a93fff79b27 183 while(!ok && !ser_timeout && !error)
LievenHollevoet 0:9a93fff79b27 184 {
LievenHollevoet 0:9a93fff79b27 185 if(modem.readable())
LievenHollevoet 0:9a93fff79b27 186 {
LievenHollevoet 0:9a93fff79b27 187 for(int i = 0; i < 5; i++)
LievenHollevoet 0:9a93fff79b27 188 {
LievenHollevoet 0:9a93fff79b27 189 responsebuffer[i] = responsebuffer[i+1];
LievenHollevoet 0:9a93fff79b27 190 }
LievenHollevoet 0:9a93fff79b27 191 responsebuffer[5] = modem.getc();
LievenHollevoet 0:9a93fff79b27 192 if(responsebuffer[0] == '\r' && responsebuffer[1] == '\n' && responsebuffer[2] == 'O' && responsebuffer[3] == 'K' && responsebuffer[4] == '\r' && responsebuffer[5] == '\n' )
LievenHollevoet 0:9a93fff79b27 193 {
LievenHollevoet 0:9a93fff79b27 194 ok = true;
LievenHollevoet 0:9a93fff79b27 195 }
LievenHollevoet 0:9a93fff79b27 196 else if(responsebuffer[0] == '\r' && responsebuffer[1] == '\n' && responsebuffer[2] == 'E' && responsebuffer[3] == 'R' && responsebuffer[4] == 'R' && responsebuffer[5] == 'O' )
LievenHollevoet 0:9a93fff79b27 197 {
LievenHollevoet 0:9a93fff79b27 198 error = true;
LievenHollevoet 0:9a93fff79b27 199 }
LievenHollevoet 0:9a93fff79b27 200 }
LievenHollevoet 0:9a93fff79b27 201 }
LievenHollevoet 0:9a93fff79b27 202 tmout.detach();
LievenHollevoet 0:9a93fff79b27 203 return ok;
LievenHollevoet 0:9a93fff79b27 204 }
LievenHollevoet 0:9a93fff79b27 205
LievenHollevoet 0:9a93fff79b27 206 /* Button 1 ISR */
LievenHollevoet 0:9a93fff79b27 207 void sw1interrupt()
LievenHollevoet 0:9a93fff79b27 208 {
LievenHollevoet 0:9a93fff79b27 209 pc.printf("\n\rButton 1 pressed\n\r");
LievenHollevoet 0:9a93fff79b27 210 LED_1 = 0;
LievenHollevoet 0:9a93fff79b27 211 handleIRQ1 = true;
LievenHollevoet 0:9a93fff79b27 212 }
LievenHollevoet 0:9a93fff79b27 213
LievenHollevoet 0:9a93fff79b27 214 /* Button 2 ISR */
LievenHollevoet 0:9a93fff79b27 215 void sw2interrupt()
LievenHollevoet 0:9a93fff79b27 216 {
LievenHollevoet 0:9a93fff79b27 217 pc.printf("\n\rButton 2 pressed\n\r");
quicksand 2:33e92af45279 218 LED_1 = 0;
quicksand 2:33e92af45279 219 handleIRQ1 = true;
LievenHollevoet 0:9a93fff79b27 220 }
LievenHollevoet 0:9a93fff79b27 221
LievenHollevoet 0:9a93fff79b27 222 void dataScheduledTX()
LievenHollevoet 0:9a93fff79b27 223 {
LievenHollevoet 0:9a93fff79b27 224 pc.printf("\n\rScheduled Sigfox TX triggered\n\r");
LievenHollevoet 0:9a93fff79b27 225 LED_1 = 0;
LievenHollevoet 0:9a93fff79b27 226 handleIRQ1 = true;
LievenHollevoet 0:9a93fff79b27 227 }
LievenHollevoet 0:9a93fff79b27 228
LievenHollevoet 0:9a93fff79b27 229 /* ISR for serial timeout */
LievenHollevoet 0:9a93fff79b27 230 void sertmout()
LievenHollevoet 0:9a93fff79b27 231 {
LievenHollevoet 0:9a93fff79b27 232 ser_timeout = true;
LievenHollevoet 0:9a93fff79b27 233 }
LievenHollevoet 0:9a93fff79b27 234
LievenHollevoet 0:9a93fff79b27 235 /* TX data over Sigfox */
LievenHollevoet 0:9a93fff79b27 236 void txData (){
LievenHollevoet 0:9a93fff79b27 237
LievenHollevoet 0:9a93fff79b27 238 unsigned int ambiValue = 0;
LievenHollevoet 0:9a93fff79b27 239 int8_t tAvgByte = 0;
LievenHollevoet 0:9a93fff79b27 240 uint16_t ambiValueShort;
LievenHollevoet 0:9a93fff79b27 241 float tAvg;
LievenHollevoet 0:9a93fff79b27 242 char command[32];
LievenHollevoet 0:9a93fff79b27 243
LievenHollevoet 0:9a93fff79b27 244 VCNL4010.ReadAmbiOnDemand (&ambiValue); // read ambi value on demand
quicksand 2:33e92af45279 245 sensor.Sense();
LievenHollevoet 0:9a93fff79b27 246 tAvg = sensor.GetAverageTemp();
LievenHollevoet 0:9a93fff79b27 247 tAvgByte = (int8_t)tAvg;
LievenHollevoet 0:9a93fff79b27 248 ambiValueShort = (uint16_t)ambiValue;
LievenHollevoet 0:9a93fff79b27 249
quicksand 2:33e92af45279 250 sprintf(command, "AT$SF=02%04X%02X,2,0\n", ambiValueShort, tAvgByte);
LievenHollevoet 0:9a93fff79b27 251
LievenHollevoet 0:9a93fff79b27 252 pc.printf("Sending ambient light level %i cts and temperature %i degrees C over Sigfox\n", ambiValueShort, tAvgByte);
LievenHollevoet 0:9a93fff79b27 253 pc.printf("using modem command: %s", command);
LievenHollevoet 0:9a93fff79b27 254 modem_command_check_ok(command);
LievenHollevoet 0:9a93fff79b27 255 LED_1 = 1;
LievenHollevoet 0:9a93fff79b27 256 }
LievenHollevoet 0:9a93fff79b27 257
LievenHollevoet 0:9a93fff79b27 258 void senseTemperature() {
LievenHollevoet 0:9a93fff79b27 259 float vOut = sensor.Sense();
LievenHollevoet 0:9a93fff79b27 260 //pc.printf("\n\rMCP9700 reading: Vout: %.2f mV", vOut);
LievenHollevoet 0:9a93fff79b27 261 }