Code example to regularly report light level and temperature over Sigfox on the QW dev kit
Fork of QW_Temperature_Light_Monitor by
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 }
Generated on Fri Jul 15 2022 13:51:45 by 1.7.2