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

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /* This program is an example application that measures the temperature and the light level
00002  * and transmits the sensor readings over the Sigfox network.
00003  * A transmission is scheduled every 15 minutes, and the user can force a transmission 
00004  * by pressing the user button one.
00005  * 
00006  * The data format of the Sigfox payload is:
00007  * First two bytes of the payload: light level as unsigned 16-bit value.
00008  * Third byte of the payload: temperature as signed 8-bit value
00009  * 
00010  * Open a serial console to the board to get a debug trace.
00011  *
00012  * Note: this is a very basic example that has no energy usage optimization. The controller is not put in sleep mode
00013  * in between readings/Sigfox transmissions in order to keep the code flow linear and short.
00014  *
00015  * In the current configuration, the temperature sensor is read once per second and a Sigfox transmission is scheduled every 15 minutes. 
00016  * Adapt the defines TX_INTERVAL and MEASURE_INTERVAL to change these settings.
00017  */
00018 
00019 #include "mbed.h"
00020 #include "math.h"
00021 #include "LinearTempSensor.h"
00022 #include "VCNL4010.h"
00023 
00024 #define SER_BUFFER_SIZE 32
00025 
00026 // Interval in minutes for scheduled Tx
00027 #define TX_INTERVAL 15
00028 
00029 // Temperature measure interval in seconds
00030 #define MEASURE_INTERVAL 1
00031 
00032 /* The 4 onboard LEDs */
00033 DigitalOut LED_0 (PB_6);
00034 DigitalOut LED_1 (PA_7);
00035 DigitalOut LED_2 (PA_6);
00036 DigitalOut LED_3 (PA_5);
00037 
00038 /* The 2 user buttons */
00039 InterruptIn SW1(PA_8);
00040 InterruptIn SW2(PB_10);
00041 
00042 /* Proximity and ambient light sensor*/
00043 VCNL40x0 VCNL4010(PB_9, PB_8, VCNL40x0_ADDRESS);      // SDA, SCL pin and I2C address
00044 
00045 /*Temperature sensor */
00046 LinearTempSensor sensor(PA_0, 40);
00047 
00048 /* Ticker for scheduled transmissions */
00049 Ticker tTX;
00050 Ticker tSense;
00051 Ticker heartbeat;
00052 
00053 /* Function prototypes */
00054 void sw1interrupt();
00055 void sw2interrupt();
00056 void sertmout();
00057 bool read_acc(int& x, int& y, int& z);
00058 bool modem_command_check_ok(char * command);
00059 void modem_setup();
00060 void txData();
00061 void dataScheduledTX();
00062 void senseTemperature();
00063 
00064 bool ser_timeout = false;
00065 bool handleIRQ1 = false;
00066 
00067 /* Serial port over USB */
00068 Serial pc(USBTX, USBRX);
00069 
00070 /* Serial connection to sigfox modem */
00071 Serial modem(PA_9, PA_10);
00072 
00073 void beat()
00074 {
00075     LED_3 = !LED_3;
00076 }
00077 
00078 int main()
00079 {
00080     /* Blinking LED */
00081     heartbeat.attach(&beat, 0.5);
00082     /* Storage for VCNL4010 readout */
00083     unsigned char ID=0, Current=0;
00084     //unsigned int  ProxiValue=0, AmbiValue=0;
00085 
00086     /* Variables that will store analog temperature sensor reading */
00087     //float Tav, To;
00088     
00089     /* Setup TD120x */
00090     wait(3);
00091     modem_setup();
00092 
00093     /* Turn off all LED */
00094     LED_0 = 1;
00095     LED_1 = 1;
00096     LED_2 = 1;
00097     LED_3 = 1;
00098 
00099     /* Setup button interrupts */
00100     SW2.fall(&sw2interrupt);
00101     SW1.fall(&sw1interrupt);
00102 
00103     /* Read VCNL40x0 product ID revision register */
00104     VCNL4010.ReadID (&ID);
00105     pc.printf("\nVCNL4010 Product ID Revision Register: %d", ID);
00106 
00107     VCNL4010.SetCurrent (20);                        // Set current to 200mA
00108     VCNL4010.ReadCurrent (&Current);                 // Read back IR LED current
00109     pc.printf("\nVCNL4010 IR LED Current: %d\n\n", Current);
00110 
00111     // Sense temperature for the first time
00112     senseTemperature();
00113     
00114     wait_ms(3000);                                   // wait 3s (only for display)
00115 
00116     tTX.attach(&dataScheduledTX, TX_INTERVAL*60);               // Attach the timer for TX
00117     tSense.attach(&senseTemperature, MEASURE_INTERVAL);           // Attach the timer for sensing the temperature
00118     
00119     while(1) 
00120     {
00121         /*
00122         // VCNL4010 reading 
00123         VCNL4010.ReadProxiOnDemand (&ProxiValue);    // read prox value on demand
00124         VCNL4010.ReadAmbiOnDemand (&AmbiValue);      // read ambi value on demand
00125         // MCP9700 reading 
00126         Tav  = sensor.GetAverageTemp();
00127         To   = sensor.GetLatestTemp();
00128 
00129         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);
00130         wait_ms(5000);
00131         */
00132         
00133         if (handleIRQ1) {
00134             txData();
00135             handleIRQ1 = false;
00136         }
00137     }
00138 }
00139 
00140 void modem_setup()
00141 {
00142     /* Reset to factory defaults */
00143     if(modem_command_check_ok("AT&F")) 
00144     {
00145         pc.printf("Factory reset succesfull\r\n");
00146     }
00147     else 
00148     {
00149         pc.printf("Factory reset TD120x failed\r\n");
00150     }
00151     /* Disable local echo */
00152     modem.printf("ATE0\n");
00153     if(modem_command_check_ok("ATE0")) 
00154     {
00155         pc.printf("Local echo disabled\r\n");
00156     }
00157     /* Write to mem */
00158     if(modem_command_check_ok("AT&W")) 
00159     {
00160         pc.printf("Settings saved!\r\n");
00161     }
00162 }
00163 
00164 bool modem_command_check_ok(char * command)
00165 {
00166     /* first clear serial data buffers */
00167     while(modem.readable()) modem.getc();
00168     /* Timeout for response of the modem */
00169     Timeout tmout;
00170     ser_timeout = false;
00171     /* Buffer for incoming data */
00172     char responsebuffer[6];
00173     /* Flag to set when we get 'OK' response */
00174     bool ok = false;
00175     bool error = false;
00176     /* Print command to TD120x */
00177     modem.printf(command);
00178     /* Newline to activate command */
00179     modem.printf("\n");
00180     /* Wait untill serial feedback, max 3 seconds before timeout */
00181     tmout.attach(&sertmout, 3.0);
00182     while(!modem.readable()&& ser_timeout == false);
00183     while(!ok && !ser_timeout && !error) 
00184     {
00185         if(modem.readable()) 
00186         {
00187             for(int i = 0; i < 5; i++)
00188             {
00189                 responsebuffer[i] = responsebuffer[i+1];
00190             }
00191             responsebuffer[5] = modem.getc();
00192             if(responsebuffer[0] == '\r' && responsebuffer[1] == '\n' && responsebuffer[2] == 'O' && responsebuffer[3] == 'K' && responsebuffer[4] == '\r' && responsebuffer[5] == '\n' ) 
00193             {
00194                 ok = true;
00195             }
00196             else if(responsebuffer[0] == '\r' && responsebuffer[1] == '\n' && responsebuffer[2] == 'E' && responsebuffer[3] == 'R' && responsebuffer[4] == 'R' && responsebuffer[5] == 'O' ) 
00197             {
00198                 error = true;
00199             }
00200         }
00201     }
00202     tmout.detach();
00203     return ok;
00204 }
00205 
00206 /* Button 1 ISR */
00207 void sw1interrupt()
00208 {
00209     pc.printf("\n\rButton 1 pressed\n\r");
00210     LED_1 = 0;
00211     handleIRQ1 = true;
00212 }
00213 
00214 /* Button 2 ISR */
00215 void sw2interrupt()
00216 {
00217     pc.printf("\n\rButton 2 pressed\n\r");
00218     LED_1 = 0;
00219     handleIRQ1 = true;
00220 }
00221 
00222 void dataScheduledTX()
00223 {
00224     pc.printf("\n\rScheduled Sigfox TX triggered\n\r");
00225     LED_1 = 0;
00226     handleIRQ1 = true;
00227 }
00228 
00229 /* ISR for serial timeout */
00230 void sertmout()
00231 {
00232     ser_timeout = true;
00233 }
00234 
00235 /* TX data over Sigfox */
00236 void txData (){
00237 
00238     unsigned int ambiValue = 0;
00239     int8_t   tAvgByte = 0;
00240     uint16_t ambiValueShort;
00241     float    tAvg;
00242     char     command[32];
00243     
00244     VCNL4010.ReadAmbiOnDemand (&ambiValue);      // read ambi value on demand
00245     sensor.Sense();
00246     tAvg = sensor.GetAverageTemp();
00247     tAvgByte = (int8_t)tAvg;
00248     ambiValueShort = (uint16_t)ambiValue;
00249 
00250     sprintf(command, "AT$SF=02%04X%02X,2,0\n", ambiValueShort, tAvgByte);
00251     
00252     pc.printf("Sending ambient light level %i cts and temperature %i degrees C over Sigfox\n", ambiValueShort, tAvgByte);
00253     pc.printf("using modem command: %s", command);
00254     modem_command_check_ok(command);
00255     LED_1 = 1;
00256 }
00257 
00258 void senseTemperature() {
00259     float vOut = sensor.Sense();
00260     //pc.printf("\n\rMCP9700 reading:  Vout: %.2f mV", vOut);
00261 }