Code example to regularly report light level and temperature over Sigfox on the QW dev kit
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.
Diff: main.cpp
- Revision:
- 0:9a93fff79b27
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp Tue Mar 08 09:46:45 2016 +0000
@@ -0,0 +1,250 @@
+/* This program is an example application that measures the temperature and the light level
+ * and transmits the sensor readings over the Sigfox network.
+ * A transmission is scheduled every 15 minutes, and the user can force a transmission
+ * by pressing the user button one.
+ *
+ * The data format of the Sigfox payload is:
+ * First two bytes of the payload: light level as unsigned 16-bit value.
+ * Third byte of the payload: temperature as signed 8-bit value
+ *
+ * Open a serial console to the board to get a debug trace.
+ *
+ * Note: this is a very basic example that has no energy usage optimization. The controller is not put in sleep mode
+ * in between readings/Sigfox transmissions in order to keep the code flow linear and short.
+ *
+ * In the current configuration, the temperature sensor is read once per second and a Sigfox transmission is scheduled every 15 minutes.
+ * Adapt the defines TX_INTERVAL and MEASURE_INTERVAL to change these settings.
+ */
+
+#include "mbed.h"
+#include "math.h"
+#include "LinearTempSensor.h"
+#include "VCNL4010.h"
+
+#define SER_BUFFER_SIZE 32
+
+// Interval in minutes for scheduled Tx
+#define TX_INTERVAL 15
+
+// Temperature measure interval in seconds
+#define MEASURE_INTERVAL 1
+
+/* The 4 onboard LEDs */
+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);
+
+/* Proximity and ambient light sensor*/
+VCNL40x0 VCNL4010(PB_9, PB_8, VCNL40x0_ADDRESS); // SDA, SCL pin and I2C address
+
+/*Temperature sensor */
+LinearTempSensor sensor(PA_0, 40);
+
+/* Ticker for scheduled transmissions */
+Ticker tTX;
+Ticker tSense;
+
+/* Function prototypes */
+void sw1interrupt();
+void sw2interrupt();
+void sertmout();
+bool read_acc(int& x, int& y, int& z);
+bool modem_command_check_ok(char * command);
+void modem_setup();
+void txData();
+void dataScheduledTX();
+void senseTemperature();
+
+bool ser_timeout = false;
+bool handleIRQ1 = false;
+
+/* Serial port over USB */
+Serial pc(USBTX, USBRX);
+
+/* Serial connection to sigfox modem */
+Serial modem(PA_9, PA_10);
+
+int main()
+{
+ /* Storage for VCNL4010 readout */
+ unsigned char ID=0, Current=0;
+ //unsigned int ProxiValue=0, AmbiValue=0;
+
+ /* Variables that will store analog temperature sensor reading */
+ //float Tav, To;
+
+ /* Setup TD120x */
+ wait(3);
+ modem_setup();
+
+ /* Turn off all LED */
+ LED_0 = 1;
+ LED_1 = 1;
+ LED_2 = 1;
+ LED_3 = 1;
+
+ /* Setup button interrupts */
+ SW2.fall(&sw2interrupt);
+ SW1.fall(&sw1interrupt);
+
+ /* Read VCNL40x0 product ID revision register */
+ VCNL4010.ReadID (&ID);
+ pc.printf("\nVCNL4010 Product ID Revision Register: %d", ID);
+
+ VCNL4010.SetCurrent (20); // Set current to 200mA
+ VCNL4010.ReadCurrent (&Current); // Read back IR LED current
+ pc.printf("\nVCNL4010 IR LED Current: %d\n\n", Current);
+
+ // Sense temperature for the first time
+ senseTemperature();
+
+ wait_ms(3000); // wait 3s (only for display)
+
+ tTX.attach(&dataScheduledTX, TX_INTERVAL*60); // Attach the timer for TX
+ tSense.attach(&senseTemperature, MEASURE_INTERVAL); // Attach the timer for sensing the temperature
+
+ while(1)
+ {
+ /*
+ // VCNL4010 reading
+ VCNL4010.ReadProxiOnDemand (&ProxiValue); // read prox value on demand
+ VCNL4010.ReadAmbiOnDemand (&AmbiValue); // read ambi value on demand
+ // MCP9700 reading
+ Tav = sensor.GetAverageTemp();
+ To = sensor.GetLatestTemp();
+
+ 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);
+ wait_ms(5000);
+ */
+
+ if (handleIRQ1) {
+ txData();
+ handleIRQ1 = false;
+ }
+ }
+}
+
+void modem_setup()
+{
+ /* Reset to factory defaults */
+ if(modem_command_check_ok("AT&F"))
+ {
+ pc.printf("Factory reset succesfull\r\n");
+ }
+ else
+ {
+ pc.printf("Factory reset TD120x failed\r\n");
+ }
+ /* Disable local echo */
+ modem.printf("ATE0\n");
+ if(modem_command_check_ok("ATE0"))
+ {
+ pc.printf("Local echo disabled\r\n");
+ }
+ /* Write to mem */
+ if(modem_command_check_ok("AT&W"))
+ {
+ pc.printf("Settings saved!\r\n");
+ }
+}
+
+bool modem_command_check_ok(char * command)
+{
+ /* first clear serial data buffers */
+ while(modem.readable()) modem.getc();
+ /* Timeout for response of the modem */
+ Timeout tmout;
+ ser_timeout = false;
+ /* Buffer for incoming data */
+ char responsebuffer[6];
+ /* Flag to set when we get 'OK' response */
+ bool ok = false;
+ bool error = false;
+ /* Print command to TD120x */
+ 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];
+ }
+ 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;
+}
+
+/* Button 1 ISR */
+void sw1interrupt()
+{
+ pc.printf("\n\rButton 1 pressed\n\r");
+ LED_1 = 0;
+ handleIRQ1 = true;
+}
+
+/* Button 2 ISR */
+void sw2interrupt()
+{
+ pc.printf("\n\rButton 2 pressed\n\r");
+}
+
+void dataScheduledTX()
+{
+ pc.printf("\n\rScheduled Sigfox TX triggered\n\r");
+ LED_1 = 0;
+ handleIRQ1 = true;
+}
+
+/* ISR for serial timeout */
+void sertmout()
+{
+ ser_timeout = true;
+}
+
+/* TX data over Sigfox */
+void txData (){
+
+ unsigned int ambiValue = 0;
+ int8_t tAvgByte = 0;
+ uint16_t ambiValueShort;
+ float tAvg;
+ char command[32];
+
+ VCNL4010.ReadAmbiOnDemand (&ambiValue); // read ambi value on demand
+ tAvg = sensor.GetAverageTemp();
+ tAvgByte = (int8_t)tAvg;
+ ambiValueShort = (uint16_t)ambiValue;
+
+ sprintf(command, "AT$SF=%04X%02X,2,0\n", ambiValueShort, tAvgByte);
+
+ pc.printf("Sending ambient light level %i cts and temperature %i degrees C over Sigfox\n", ambiValueShort, tAvgByte);
+ pc.printf("using modem command: %s", command);
+ modem_command_check_ok(command);
+ LED_1 = 1;
+}
+
+void senseTemperature() {
+ float vOut = sensor.Sense();
+ //pc.printf("\n\rMCP9700 reading: Vout: %.2f mV", vOut);
+}
Lieven Hollevoet