Lieven Hollevoet
/
QW_Temperature_Light_Monitor
Code example to regularly report light level and temperature over Sigfox on the QW dev kit
Embed:
(wiki syntax)
Show/hide line numbers
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 00052 /* Function prototypes */ 00053 void sw1interrupt(); 00054 void sw2interrupt(); 00055 void sertmout(); 00056 bool read_acc(int& x, int& y, int& z); 00057 bool modem_command_check_ok(char * command); 00058 void modem_setup(); 00059 void txData(); 00060 void dataScheduledTX(); 00061 void senseTemperature(); 00062 00063 bool ser_timeout = false; 00064 bool handleIRQ1 = false; 00065 00066 /* Serial port over USB */ 00067 Serial pc(USBTX, USBRX); 00068 00069 /* Serial connection to sigfox modem */ 00070 Serial modem(PA_9, PA_10); 00071 00072 int main() 00073 { 00074 /* Storage for VCNL4010 readout */ 00075 unsigned char ID=0, Current=0; 00076 //unsigned int ProxiValue=0, AmbiValue=0; 00077 00078 /* Variables that will store analog temperature sensor reading */ 00079 //float Tav, To; 00080 00081 /* Setup TD120x */ 00082 wait(3); 00083 modem_setup(); 00084 00085 /* Turn off all LED */ 00086 LED_0 = 1; 00087 LED_1 = 1; 00088 LED_2 = 1; 00089 LED_3 = 1; 00090 00091 /* Setup button interrupts */ 00092 SW2.fall(&sw2interrupt); 00093 SW1.fall(&sw1interrupt); 00094 00095 /* Read VCNL40x0 product ID revision register */ 00096 VCNL4010.ReadID (&ID); 00097 pc.printf("\nVCNL4010 Product ID Revision Register: %d", ID); 00098 00099 VCNL4010.SetCurrent (20); // Set current to 200mA 00100 VCNL4010.ReadCurrent (&Current); // Read back IR LED current 00101 pc.printf("\nVCNL4010 IR LED Current: %d\n\n", Current); 00102 00103 // Sense temperature for the first time 00104 senseTemperature(); 00105 00106 wait_ms(3000); // wait 3s (only for display) 00107 00108 tTX.attach(&dataScheduledTX, TX_INTERVAL*60); // Attach the timer for TX 00109 tSense.attach(&senseTemperature, MEASURE_INTERVAL); // Attach the timer for sensing the temperature 00110 00111 while(1) 00112 { 00113 /* 00114 // VCNL4010 reading 00115 VCNL4010.ReadProxiOnDemand (&ProxiValue); // read prox value on demand 00116 VCNL4010.ReadAmbiOnDemand (&AmbiValue); // read ambi value on demand 00117 // MCP9700 reading 00118 Tav = sensor.GetAverageTemp(); 00119 To = sensor.GetLatestTemp(); 00120 00121 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); 00122 wait_ms(5000); 00123 */ 00124 00125 if (handleIRQ1) { 00126 txData(); 00127 handleIRQ1 = false; 00128 } 00129 } 00130 } 00131 00132 void modem_setup() 00133 { 00134 /* Reset to factory defaults */ 00135 if(modem_command_check_ok("AT&F")) 00136 { 00137 pc.printf("Factory reset succesfull\r\n"); 00138 } 00139 else 00140 { 00141 pc.printf("Factory reset TD120x failed\r\n"); 00142 } 00143 /* Disable local echo */ 00144 modem.printf("ATE0\n"); 00145 if(modem_command_check_ok("ATE0")) 00146 { 00147 pc.printf("Local echo disabled\r\n"); 00148 } 00149 /* Write to mem */ 00150 if(modem_command_check_ok("AT&W")) 00151 { 00152 pc.printf("Settings saved!\r\n"); 00153 } 00154 } 00155 00156 bool modem_command_check_ok(char * command) 00157 { 00158 /* first clear serial data buffers */ 00159 while(modem.readable()) modem.getc(); 00160 /* Timeout for response of the modem */ 00161 Timeout tmout; 00162 ser_timeout = false; 00163 /* Buffer for incoming data */ 00164 char responsebuffer[6]; 00165 /* Flag to set when we get 'OK' response */ 00166 bool ok = false; 00167 bool error = false; 00168 /* Print command to TD120x */ 00169 modem.printf(command); 00170 /* Newline to activate command */ 00171 modem.printf("\n"); 00172 /* Wait untill serial feedback, max 3 seconds before timeout */ 00173 tmout.attach(&sertmout, 3.0); 00174 while(!modem.readable()&& ser_timeout == false); 00175 while(!ok && !ser_timeout && !error) 00176 { 00177 if(modem.readable()) 00178 { 00179 for(int i = 0; i < 5; i++) 00180 { 00181 responsebuffer[i] = responsebuffer[i+1]; 00182 } 00183 responsebuffer[5] = modem.getc(); 00184 if(responsebuffer[0] == '\r' && responsebuffer[1] == '\n' && responsebuffer[2] == 'O' && responsebuffer[3] == 'K' && responsebuffer[4] == '\r' && responsebuffer[5] == '\n' ) 00185 { 00186 ok = true; 00187 } 00188 else if(responsebuffer[0] == '\r' && responsebuffer[1] == '\n' && responsebuffer[2] == 'E' && responsebuffer[3] == 'R' && responsebuffer[4] == 'R' && responsebuffer[5] == 'O' ) 00189 { 00190 error = true; 00191 } 00192 } 00193 } 00194 tmout.detach(); 00195 return ok; 00196 } 00197 00198 /* Button 1 ISR */ 00199 void sw1interrupt() 00200 { 00201 pc.printf("\n\rButton 1 pressed\n\r"); 00202 LED_1 = 0; 00203 handleIRQ1 = true; 00204 } 00205 00206 /* Button 2 ISR */ 00207 void sw2interrupt() 00208 { 00209 pc.printf("\n\rButton 2 pressed\n\r"); 00210 } 00211 00212 void dataScheduledTX() 00213 { 00214 pc.printf("\n\rScheduled Sigfox TX triggered\n\r"); 00215 LED_1 = 0; 00216 handleIRQ1 = true; 00217 } 00218 00219 /* ISR for serial timeout */ 00220 void sertmout() 00221 { 00222 ser_timeout = true; 00223 } 00224 00225 /* TX data over Sigfox */ 00226 void txData (){ 00227 00228 unsigned int ambiValue = 0; 00229 int8_t tAvgByte = 0; 00230 uint16_t ambiValueShort; 00231 float tAvg; 00232 char command[32]; 00233 00234 VCNL4010.ReadAmbiOnDemand (&ambiValue); // read ambi value on demand 00235 tAvg = sensor.GetAverageTemp(); 00236 tAvgByte = (int8_t)tAvg; 00237 ambiValueShort = (uint16_t)ambiValue; 00238 00239 sprintf(command, "AT$SF=%04X%02X,2,0\n", ambiValueShort, tAvgByte); 00240 00241 pc.printf("Sending ambient light level %i cts and temperature %i degrees C over Sigfox\n", ambiValueShort, tAvgByte); 00242 pc.printf("using modem command: %s", command); 00243 modem_command_check_ok(command); 00244 LED_1 = 1; 00245 } 00246 00247 void senseTemperature() { 00248 float vOut = sensor.Sense(); 00249 //pc.printf("\n\rMCP9700 reading: Vout: %.2f mV", vOut); 00250 }
Generated on Thu Jul 21 2022 14:58:16 by 1.7.2