Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: FXOS8700CQ MODSERIAL mbed
Fork of Avnet_ATT_Cellular_IOT by
sensors.cpp
00001 /* =================================================================== 00002 Copyright © 2016, AVNET Inc. 00003 00004 Licensed under the Apache License, Version 2.0 (the "License"); 00005 you may not use this file except in compliance with the License. 00006 You may obtain a copy of the License at 00007 00008 http://www.apache.org/licenses/LICENSE-2.0 00009 00010 Unless required by applicable law or agreed to in writing, 00011 software distributed under the License is distributed on an 00012 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 00013 either express or implied. See the License for the specific 00014 language governing permissions and limitations under the License. 00015 00016 ======================================================================== */ 00017 00018 #include "mbed.h" 00019 #include "sensors.h" 00020 #include "hardware.h" 00021 #include "config_me.h" 00022 #include "FXOS8700CQ.h" 00023 #include "HTS221.h" 00024 #include "xadow_gps.h" 00025 #include <string> 00026 00027 //I2C for pmod sensors: 00028 #define Si1145_PMOD_I2C_ADDR 0xC0 //this is for 7-bit addr 0x60 for the Si7020 00029 #define Si7020_PMOD_I2C_ADDR 0x80 //this is for 7-bit addr 0x4 for the Si7020 00030 00031 // Storage for the data from the motion sensor 00032 SRAWDATA accel_data; 00033 SRAWDATA magn_data; 00034 //InterruptIn fxos_int1(PTC6); // unused, common with SW2 on FRDM-K64F 00035 InterruptIn fxos_int2(PTC13); // should just be the Data-Ready interrupt 00036 bool fxos_int2_triggered = false; 00037 void trigger_fxos_int2(void) 00038 { 00039 fxos_int2_triggered = true; 00040 00041 } 00042 00043 /*------------------------------------------------------------------------------ 00044 * Perform I2C single read. 00045 *------------------------------------------------------------------------------*/ 00046 unsigned char I2C_ReadSingleByte(unsigned char ucDeviceAddress) 00047 { 00048 char rxbuffer [1]; 00049 i2c.read(ucDeviceAddress, rxbuffer, 1 ); 00050 return (unsigned char)rxbuffer[0]; 00051 } //I2C_ReadSingleByte() 00052 00053 /*------------------------------------------------------------------------------ 00054 * Perform I2C single read from address. 00055 *------------------------------------------------------------------------------*/ 00056 unsigned char I2C_ReadSingleByteFromAddr(unsigned char ucDeviceAddress, unsigned char Addr) 00057 { 00058 char txbuffer [1]; 00059 char rxbuffer [1]; 00060 txbuffer[0] = (char)Addr; 00061 i2c.write(ucDeviceAddress, txbuffer, 1 ); 00062 i2c.read(ucDeviceAddress, rxbuffer, 1 ); 00063 return (unsigned char)rxbuffer[0]; 00064 } //I2C_ReadSingleByteFromAddr() 00065 00066 /*------------------------------------------------------------------------------ 00067 * Perform I2C read of more than 1 byte. 00068 *------------------------------------------------------------------------------*/ 00069 int I2C_ReadMultipleBytes(unsigned char ucDeviceAddress, char *ucData, unsigned char ucLength) 00070 { 00071 int status; 00072 status = i2c.read(ucDeviceAddress, ucData, ucLength); 00073 return status; 00074 } //I2C_ReadMultipleBytes() 00075 00076 /*------------------------------------------------------------------------------ 00077 * Perform I2C write of a single byte. 00078 *------------------------------------------------------------------------------*/ 00079 int I2C_WriteSingleByte(unsigned char ucDeviceAddress, unsigned char Data, bool bSendStop) 00080 { 00081 int status; 00082 char txbuffer [1]; 00083 txbuffer[0] = (char)Data; //data 00084 status = i2c.write(ucDeviceAddress, txbuffer, 1, !bSendStop); //true: do not send stop 00085 return status; 00086 } //I2C_WriteSingleByte() 00087 00088 /*------------------------------------------------------------------------------ 00089 * Perform I2C write of 1 byte to an address. 00090 *------------------------------------------------------------------------------*/ 00091 int I2C_WriteSingleByteToAddr(unsigned char ucDeviceAddress, unsigned char Addr, unsigned char Data, bool bSendStop) 00092 { 00093 int status; 00094 char txbuffer [2]; 00095 txbuffer[0] = (char)Addr; //address 00096 txbuffer[1] = (char)Data; //data 00097 //status = i2c.write(ucDeviceAddress, txbuffer, 2, false); //stop at end 00098 status = i2c.write(ucDeviceAddress, txbuffer, 2, !bSendStop); //true: do not send stop 00099 return status; 00100 } //I2C_WriteSingleByteToAddr() 00101 00102 /*------------------------------------------------------------------------------ 00103 * Perform I2C write of more than 1 byte. 00104 *------------------------------------------------------------------------------*/ 00105 int I2C_WriteMultipleBytes(unsigned char ucDeviceAddress, char *ucData, unsigned char ucLength, bool bSendStop) 00106 { 00107 int status; 00108 status = i2c.write(ucDeviceAddress, ucData, ucLength, !bSendStop); //true: do not send stop 00109 return status; 00110 } //I2C_WriteMultipleBytes() 00111 00112 bool bSi7020_present = false; 00113 void Init_Si7020(void) 00114 { 00115 char SN_7020 [8]; 00116 //SN part 1: 00117 I2C_WriteSingleByteToAddr(Si7020_PMOD_I2C_ADDR, 0xFA, 0x0F, false); 00118 I2C_ReadMultipleBytes(Si7020_PMOD_I2C_ADDR, &SN_7020[0], 4); 00119 00120 //SN part 1: 00121 I2C_WriteSingleByteToAddr(Si7020_PMOD_I2C_ADDR, 0xFC, 0xC9, false); 00122 I2C_ReadMultipleBytes(Si7020_PMOD_I2C_ADDR, &SN_7020[4], 4); 00123 00124 char Ver_7020 [2]; 00125 //FW version: 00126 I2C_WriteSingleByteToAddr(Si7020_PMOD_I2C_ADDR, 0x84, 0xB8, false); 00127 I2C_ReadMultipleBytes(Si7020_PMOD_I2C_ADDR, &Ver_7020[0], 2); 00128 00129 if (SN_7020[4] != 0x14) 00130 { 00131 bSi7020_present = false; 00132 PRINTF("Si7020 sensor not found\r\n"); 00133 } 00134 else 00135 { 00136 bSi7020_present = true; 00137 PRINTF("Si7020 SN = 0x%02X%02X%02X%02X%02X%02X%02X%02X\n", SN_7020[0], SN_7020[1], SN_7020[2], SN_7020[3], SN_7020[4], SN_7020[5], SN_7020[6], SN_7020[7]); 00138 PRINTF("Si7020 Version# = 0x%02X\n", Ver_7020[0]); 00139 } //bool bSi7020_present = true 00140 00141 } //Init_Si7020() 00142 00143 void Read_Si7020(void) 00144 { 00145 if (bSi7020_present) 00146 { 00147 char Humidity [2]; 00148 char Temperature [2]; 00149 //Command to measure humidity (temperature also gets measured): 00150 I2C_WriteSingleByte(Si7020_PMOD_I2C_ADDR, 0xF5, false); //no hold, must do dummy read 00151 I2C_ReadMultipleBytes(Si7020_PMOD_I2C_ADDR, &Humidity[0], 1); //dummy read, should get an nack until it is done 00152 wait (0.05); //wait for measurement. Can also keep reading until no NACK is received 00153 //I2C_WriteSingleByte(Si7020_PMOD_I2C_ADDR, 0xE5, false); //Hold mod, the device does a clock stretch on the read until it is done (crashes the I2C bus... 00154 I2C_ReadMultipleBytes(Si7020_PMOD_I2C_ADDR, &Humidity[0], 2); //read humidity 00155 //PRINTF("Read Si7020 Humidity = 0x%02X%02X\n", Humidity[0], Humidity[1]); 00156 int rh_code = (Humidity[0] << 8) + Humidity[1]; 00157 float fRh = (125.0*rh_code/65536.0) - 6.0; //from datasheet 00158 //PRINTF("Si7020 Humidity = %*.*f %%\n", 4, 2, fRh); //double % sign for escape //PRINTF("%*.*f\n", myFieldWidth, myPrecision, myFloatValue); 00159 sprintf(SENSOR_DATA.Humidity_Si7020, "%0.2f", fRh); 00160 00161 //Command to read temperature when humidity is already done: 00162 I2C_WriteSingleByte(Si7020_PMOD_I2C_ADDR, 0xE0, false); 00163 I2C_ReadMultipleBytes(Si7020_PMOD_I2C_ADDR, &Temperature[0], 2); //read temperature 00164 //PRINTF("Read Si7020 Temperature = 0x%02X%02X\n", Temperature[0], Temperature[1]); 00165 int temp_code = (Temperature[0] << 8) + Temperature[1]; 00166 float fTemp = (175.72*temp_code/65536.0) - 46.85; //from datasheet in Celcius 00167 //PRINTF("Si7020 Temperature = %*.*f deg C\n", 4, 2, fTemp); 00168 sprintf(SENSOR_DATA.Temperature_Si7020, "%0.2f", fTemp); 00169 } //bool bSi7020_present = true 00170 00171 } //Read_Si7020() 00172 00173 /*------------------------------------------------------------------------------ 00174 * The following are aliases so that the Si1145 coding examples can be used as-is. 00175 *------------------------------------------------------------------------------*/ 00176 unsigned char ReadFrom_Si1145_Register(unsigned char reg) //returns byte from I2C Register 'reg' 00177 { 00178 unsigned char result = I2C_ReadSingleByteFromAddr(Si1145_PMOD_I2C_ADDR, reg); 00179 return (result); 00180 } //ReadFrom_Si1145_Register() 00181 00182 void WriteTo_Si1145_Register(unsigned char reg, unsigned char value) //writes 'value' into I2C Register reg' 00183 { 00184 I2C_WriteSingleByteToAddr(Si1145_PMOD_I2C_ADDR, reg, value, true); 00185 } //WriteTo_Si1145_Register() 00186 00187 #define REG_PARAM_WR 0x17 00188 #define REG_PARAM_RD 0x2E 00189 #define REG_COMMAND 0x18 00190 #define REG_RESPONSE 0x20 00191 #define REG_HW_KEY 0x07 00192 #define HW_KEY_VAL0 0x17 00193 #define REG_MEAS_RATE_LSB 0x08 00194 #define REG_MEAS_RATE_MSB 0x09 00195 #define REG_PS_LED21 0x0F 00196 #define REG_PS_LED3 0x10 00197 #define MAX_LED_CURRENT 0xF 00198 #define PARAM_CH_LIST 0x01 00199 #define REG_ALS_VIS_DATA0 0x22 00200 #define REG_ALS_VIS_DATA1 0x23 00201 #define REG_ALS_IR_DATA0 0x24 00202 #define REG_ALS_IR_DATA1 0x25 00203 #define REG_PS1_DATA0 0x26 00204 #define REG_PS1_DATA1 0x27 00205 #define REG_PS2_DATA0 0x28 00206 #define REG_PS2_DATA1 0x29 00207 #define REG_PS3_DATA0 0x2A 00208 #define REG_PS3_DATA1 0x2B 00209 #define REG_UVINDEX0 0x2C 00210 #define REG_UVINDEX1 0x2D 00211 int Si1145_ParamSet(unsigned char address, unsigned char value) //writes 'value' into Parameter 'address' 00212 { 00213 char txbuffer [3]; 00214 txbuffer[0] = (char)REG_PARAM_WR; //destination 00215 txbuffer[1] = (char)value; 00216 txbuffer[2] = (char)(0xA0 + (address & 0x1F)); 00217 int retval; 00218 //if((retval = _waitUntilSleep(si114x_handle))!=0) return retval; 00219 retval = I2C_WriteMultipleBytes(Si1145_PMOD_I2C_ADDR, &txbuffer[0], 3, true); 00220 if(retval!=0) return retval; 00221 while(1) 00222 { 00223 retval=ReadFrom_Si1145_Register(REG_PARAM_RD); 00224 if (retval==value) break; 00225 } 00226 return (0); 00227 } //Si1145_ParamSet() 00228 00229 void PsAlsForce(void) //equivalent to WriteTo_Si1145_Register(REG_COMMAND,0x07). This forces PS and ALS measurements 00230 { 00231 WriteTo_Si1145_Register(REG_COMMAND,0x07); 00232 } //PsAlsForce() 00233 00234 bool bSi1145_present = false; 00235 void Init_Si1145(void) 00236 { 00237 unsigned char readbyte; 00238 //Read Si1145 part ID: 00239 readbyte = ReadFrom_Si1145_Register(0x00); 00240 if (readbyte != 0x45) 00241 { 00242 bSi1145_present = false; 00243 PRINTF("Si1145 sensor not found\r\n"); 00244 } 00245 else 00246 { 00247 bSi1145_present = true; 00248 PRINTF("Si1145 Part ID : 0x%02X\n", readbyte); 00249 //Initialize Si1145 by writing to HW_KEY (I2C Register 0x07 = 0x17) 00250 WriteTo_Si1145_Register(REG_HW_KEY, HW_KEY_VAL0); 00251 00252 // Initialize LED Current 00253 // I2C Register 0x0F = 0xFF 00254 // I2C Register 0x10 = 0x0F 00255 WriteTo_Si1145_Register(REG_PS_LED21,(MAX_LED_CURRENT<<4) + MAX_LED_CURRENT); 00256 WriteTo_Si1145_Register(REG_PS_LED3, MAX_LED_CURRENT); 00257 00258 // Parameter 0x01 = 0x37 00259 //Si1145_ParamSet(PARAM_CH_LIST, ALS_IR_TASK + ALS_VIS_TASK + PS1_TASK + PS2_TASK + PS3_TASK); 00260 //Si1145_ParamSet(0x01, 0x37); //CHLIST is address 0x01 in the parameter RAM. It defines which sensors are enabled (here, some) 00261 Si1145_ParamSet(0x01, 0x7F); //CHLIST is address 0x01 in the parameter RAM. It defines which sensors are enabled (here, all but UV. One can only use AUX or UV but here we use AUX because UV does not work...) 00262 // I2C Register 0x18 = 0x0x07 //This is PSALS_FORCE to the Command register => Force a single PS (proximity sensor) and ALS (ambient light sensor) reading - The factory code has this as 0x05 which only does PS... 00263 PsAlsForce(); // can also be written as WriteTo_Si1145_Register(REG_COMMAND,0x07); 00264 WriteTo_Si1145_Register(REG_COMMAND, 0x0F);//command to put it into auto mode 00265 //Set MES_RATE to 0x1000. I.e. the device will automatically wake up every 16 * 256* 31.25 us = 0.128 seconds to measure 00266 WriteTo_Si1145_Register(REG_MEAS_RATE_LSB, 0x00); 00267 WriteTo_Si1145_Register(REG_MEAS_RATE_MSB, 0x10); 00268 } //bSi1145_present = true 00269 } //Init_Si1145() 00270 00271 void Read_Si1145(void) 00272 { 00273 if (bSi1145_present) 00274 { 00275 // Once the measurements are completed, here is how to reconstruct them 00276 // Note very carefully that 16-bit registers are in the 'Little Endian' byte order 00277 // It may be more efficient to perform block I2C Reads, but this example shows 00278 // individual reads of registers 00279 00280 int PS1 = ReadFrom_Si1145_Register(REG_PS1_DATA0) + 256 * ReadFrom_Si1145_Register(REG_PS1_DATA1); 00281 int PS2 = ReadFrom_Si1145_Register(REG_PS2_DATA0) + 256 * ReadFrom_Si1145_Register(REG_PS2_DATA1); 00282 int PS3 = ReadFrom_Si1145_Register(REG_PS3_DATA0) + 256 * ReadFrom_Si1145_Register(REG_PS3_DATA1); 00283 //PRINTF("PS1_Data = %d\n", PS1); 00284 //PRINTF("PS2_Data = %d\n", PS2); 00285 //PRINTF("PS3_Data = %d\n", PS3); 00286 //OBJECT PRESENT? 00287 #if (0) 00288 if(PS1 < 22000){ 00289 //PRINTF("Object Far\n"); 00290 sprintf(SENSOR_DATA.Proximity, "Object Far\0"); 00291 } 00292 else if(PS1 < 24000) 00293 { 00294 //PRINTF("Object in Vicinity\n"); 00295 sprintf(SENSOR_DATA.Proximity, "Object in Vicinity\0"); 00296 } 00297 else if (PS1 < 30000) 00298 { 00299 //PRINTF("Object Near\n"); 00300 sprintf(SENSOR_DATA.Proximity, "Object Near\0"); 00301 } 00302 else 00303 { 00304 //PRINTF("Object Very Near\n"); 00305 sprintf(SENSOR_DATA.Proximity, "Object Very Near\0"); 00306 } 00307 #else 00308 sprintf(SENSOR_DATA.Proximity, "%d\0", PS1); 00309 #endif 00310 00311 //Force ALS read: 00312 //WriteTo_Si1145_Register(REG_COMMAND, 0x06); 00313 //wait (0.1); 00314 int ALS_VIS = ReadFrom_Si1145_Register(REG_ALS_VIS_DATA0) + 256 * ReadFrom_Si1145_Register(REG_ALS_VIS_DATA1); 00315 int ALS_IR = ReadFrom_Si1145_Register(REG_ALS_IR_DATA0) + 256 * ReadFrom_Si1145_Register(REG_ALS_IR_DATA1); 00316 int UV_INDEX = ReadFrom_Si1145_Register(REG_UVINDEX0) + 256 * ReadFrom_Si1145_Register(REG_UVINDEX1); 00317 //PRINTF("ALS_VIS_Data = %d\n", ALS_VIS); 00318 //PRINTF("ALS_IR_Data = %d\n", ALS_IR); 00319 //PRINTF("UV_INDEX_Data = %d\n", UV_INDEX); 00320 00321 //PRINTF("Ambient Light Visible Sensor = %d\n", ALS_VIS); 00322 sprintf(SENSOR_DATA.AmbientLightVis, "%d", ALS_VIS); 00323 //PRINTF("Ambient Light Infrared Sensor = %d\n", ALS_IR); 00324 sprintf(SENSOR_DATA.AmbientLightIr, "%d", ALS_IR); 00325 //float fUV_value = (UV_INDEX -50.0)/10000.0; 00326 float fUV_value = (UV_INDEX)/100.0; //this is the aux reading 00327 //PRINTF("UV_Data = %0.2f\n", fUV_value); 00328 sprintf(SENSOR_DATA.UVindex, "%0.2f", fUV_value); 00329 } //bSi1145_present = true 00330 } //Read_Si1145() 00331 00332 //******************************************************************************************************************************************** 00333 //* Read the FXOS8700CQ - 6-axis combo Sensor Accelerometer and Magnetometer 00334 //******************************************************************************************************************************************** 00335 bool bMotionSensor_present = false; 00336 void Init_motion_sensor() 00337 { 00338 // Note: this class is instantiated here because if it is statically declared, the cellular shield init kills the I2C bus... 00339 // Class instantiation with pin names for the motion sensor on the FRDM-K64F board: 00340 FXOS8700CQ fxos(PTE25, PTE24, FXOS8700CQ_SLAVE_ADDR1); // SDA, SCL, (addr << 1) 00341 int iWhoAmI = fxos.get_whoami(); 00342 00343 PRINTF("FXOS8700CQ WhoAmI = %X\r\n", iWhoAmI); 00344 // Iterrupt for active-low interrupt line from FXOS 00345 // Configured with only one interrupt on INT2 signaling Data-Ready 00346 //fxos_int2.fall(&trigger_fxos_int2); 00347 if (iWhoAmI != 0xC7) 00348 { 00349 bMotionSensor_present = false; 00350 PRINTF("FXOS8700CQ motion sensor not found\r\n"); 00351 } 00352 else 00353 { 00354 bMotionSensor_present = true; 00355 fxos.enable(); 00356 } 00357 } //Init_motion_sensor() 00358 00359 void Read_motion_sensor() 00360 { 00361 // Note: this class is instantiated here because if it is statically declared, the cellular shield init kills the I2C bus... 00362 // Class instantiation with pin names for the motion sensor on the FRDM-K64F board: 00363 FXOS8700CQ fxos(PTE25, PTE24, FXOS8700CQ_SLAVE_ADDR1); // SDA, SCL, (addr << 1) 00364 if (bMotionSensor_present) 00365 { 00366 fxos.enable(); 00367 fxos.get_data(&accel_data, &magn_data); 00368 //PRINTF("Roll=%5d, Pitch=%5d, Yaw=%5d;\r\n", magn_data.x, magn_data.y, magn_data.z); 00369 sprintf(SENSOR_DATA.MagnetometerX, "%5d", magn_data.x); 00370 sprintf(SENSOR_DATA.MagnetometerY, "%5d", magn_data.y); 00371 sprintf(SENSOR_DATA.MagnetometerZ, "%5d", magn_data.z); 00372 00373 //Try to normalize (/2048) the values so they will match the eCompass output: 00374 float fAccelScaled_x, fAccelScaled_y, fAccelScaled_z; 00375 fAccelScaled_x = (accel_data.x/2048.0); 00376 fAccelScaled_y = (accel_data.y/2048.0); 00377 fAccelScaled_z = (accel_data.z/2048.0); 00378 //PRINTF("Acc: X=%2.3f Y=%2.3f Z=%2.3f;\r\n", fAccelScaled_x, fAccelScaled_y, fAccelScaled_z); 00379 sprintf(SENSOR_DATA.AccelX, "%2.3f", fAccelScaled_x); 00380 sprintf(SENSOR_DATA.AccelY, "%2.3f", fAccelScaled_y); 00381 sprintf(SENSOR_DATA.AccelZ, "%2.3f", fAccelScaled_z); 00382 } //bMotionSensor_present 00383 } //Read_motion_sensor() 00384 00385 00386 //******************************************************************************************************************************************** 00387 //* Read the HTS221 temperature & humidity sensor on the Cellular Shield 00388 //******************************************************************************************************************************************** 00389 // These are to be built on the fly 00390 string my_temp; 00391 string my_humidity; 00392 HTS221 hts221; 00393 00394 #define CTOF(x) ((x)*1.8+32) 00395 bool bHTS221_present = false; 00396 void Init_HTS221() 00397 { 00398 int i; 00399 void hts221_init(void); 00400 i = hts221.begin(); 00401 if (i) 00402 { 00403 bHTS221_present = true; 00404 PRINTF(BLU "HTS221 Detected (0x%02X)\n\r",i); 00405 PRINTF(" Temp is: %0.2f F \n\r",CTOF(hts221.readTemperature())); 00406 PRINTF(" Humid is: %02d %%\n\r",hts221.readHumidity()); 00407 } 00408 else 00409 { 00410 bHTS221_present = false; 00411 PRINTF(RED "HTS221 NOT DETECTED!\n\r"); 00412 } 00413 } //Init_HTS221() 00414 00415 void Read_HTS221() 00416 { 00417 if (bHTS221_present) 00418 { 00419 sprintf(SENSOR_DATA.Temperature, "%0.2f", CTOF(hts221.readTemperature())); 00420 sprintf(SENSOR_DATA.Humidity, "%02d", hts221.readHumidity()); 00421 } //bHTS221_present 00422 } //Read_HTS221() 00423 00424 bool bGPS_present = false; 00425 void Init_GPS(void) 00426 { 00427 char scan_id[GPS_SCAN_SIZE+2]; //The first two bytes are the response length (0x00, 0x04) 00428 I2C_WriteSingleByte(GPS_DEVICE_ADDR, GPS_SCAN_ID, true); //no hold, must do read 00429 00430 unsigned char i; 00431 for(i=0;i<(GPS_SCAN_SIZE+2);i++) 00432 { 00433 scan_id[i] = I2C_ReadSingleByte(GPS_DEVICE_ADDR); 00434 } 00435 00436 if(scan_id[5] != GPS_DEVICE_ID) 00437 { 00438 bGPS_present = false; 00439 PRINTF("Xadow GPS not found\n"); 00440 } 00441 else 00442 { 00443 bGPS_present = true; 00444 PRINTF("Xadow GPS Scan ID response = 0x%02X%02X (length), 0x%02X%02X%02X%02X\r\n", scan_id[0], scan_id[1], scan_id[2], scan_id[3], scan_id[4], scan_id[5]); 00445 char status = gps_get_status(); 00446 if ((status != 'A') && (iSensorsToReport == TEMP_HUMIDITY_ACCELEROMETER_GPS)) 00447 { //we must wait for GPS to initialize 00448 PRINTF("Waiting for GPS to become ready... "); 00449 while (status != 'A') 00450 { 00451 wait (5.0); 00452 status = gps_get_status(); 00453 unsigned char num_satellites = gps_get_sate_in_veiw(); 00454 PRINTF("%c%d", status, num_satellites); 00455 } 00456 PRINTF("\r\n"); 00457 } //we must wait for GPS to initialize 00458 PRINTF("gps_check_online is %d\r\n", gps_check_online()); 00459 unsigned char *data; 00460 data = gps_get_utc_date_time(); 00461 PRINTF("gps_get_utc_date_time : %d-%d-%d,%d:%d:%d\r\n", data[0], data[1], data[2], data[3], data[4], data[5]); 00462 PRINTF("gps_get_status : %c ('A' = Valid, 'V' = Invalid)\r\n", gps_get_status()); 00463 PRINTF("gps_get_latitude : %c:%f\r\n", gps_get_ns(), gps_get_latitude()); 00464 PRINTF("gps_get_longitude : %c:%f\r\n", gps_get_ew(), gps_get_longitude()); 00465 PRINTF("gps_get_altitude : %f meters\r\n", gps_get_altitude()); 00466 PRINTF("gps_get_speed : %f knots\r\n", gps_get_speed()); 00467 PRINTF("gps_get_course : %f degrees\r\n", gps_get_course()); 00468 PRINTF("gps_get_position_fix : %c\r\n", gps_get_position_fix()); 00469 PRINTF("gps_get_sate_in_view : %d satellites\r\n", gps_get_sate_in_veiw()); 00470 PRINTF("gps_get_sate_used : %d\r\n", gps_get_sate_used()); 00471 PRINTF("gps_get_mode : %c ('A' = Automatic, 'M' = Manual)\r\n", gps_get_mode()); 00472 PRINTF("gps_get_mode2 : %c ('1' = no fix, '1' = 2D fix, '3' = 3D fix)\r\n", gps_get_mode2()); 00473 } //bool bGPS_present = true 00474 } //Init_GPS() 00475 00476 void Read_GPS() 00477 { 00478 unsigned char gps_satellites = 0; //default 00479 int lat_sign; 00480 int long_sign; 00481 if (bGPS_present) 00482 { 00483 if ((gps_get_status() == 'A') && (gps_get_mode2() != '1')) 00484 { 00485 gps_satellites = gps_get_sate_in_veiw(); //show the number of satellites 00486 } 00487 if (gps_get_ns() == 'S') 00488 { 00489 lat_sign = -1; //negative number 00490 } 00491 else 00492 { 00493 lat_sign = 1; 00494 } 00495 if (gps_get_ew() == 'W') 00496 { 00497 long_sign = -1; //negative number 00498 } 00499 else 00500 { 00501 long_sign = 1; 00502 } 00503 #if (0) 00504 PRINTF("gps_satellites : %d\r\n", gps_satellites); 00505 PRINTF("gps_get_latitude : %f\r\n", (lat_sign * gps_get_latitude())); 00506 PRINTF("gps_get_longitude : %f\r\n", (long_sign * gps_get_longitude())); 00507 PRINTF("gps_get_altitude : %f meters\r\n", gps_get_altitude()); 00508 PRINTF("gps_get_speed : %f knots\r\n", gps_get_speed()); 00509 PRINTF("gps_get_course : %f degrees\r\n", gps_get_course()); 00510 #endif 00511 sprintf(SENSOR_DATA.GPS_Satellites, "%d", gps_satellites); 00512 sprintf(SENSOR_DATA.GPS_Latitude, "%f", (lat_sign * gps_get_latitude())); 00513 sprintf(SENSOR_DATA.GPS_Longitude, "%f", (long_sign * gps_get_longitude())); 00514 sprintf(SENSOR_DATA.GPS_Altitude, "%f", gps_get_altitude()); 00515 sprintf(SENSOR_DATA.GPS_Speed, "%f", gps_get_speed()); 00516 sprintf(SENSOR_DATA.GPS_Course, "%f", gps_get_course()); 00517 } //bGPS_present 00518 } //Read_GPS() 00519 00520 #ifdef USE_VIRTUAL_SENSORS 00521 bool bUsbConnected = false; 00522 volatile uint8_t usb_uart_rx_buff[256]; 00523 //volatile uint8_t usb_uart_tx_buff[256]; 00524 volatile unsigned char usb_uart_rx_buff_putptr = 0; 00525 volatile unsigned char usb_uart_rx_buff_getptr = 0; 00526 //volatile unsigned char usb_uart_tx_buff_putptr = 0; 00527 //volatile unsigned char usb_uart_tx_buff_getptr = 0; 00528 char usbhost_rx_string[256]; 00529 unsigned char usbhost_rxstring_index; 00530 char usbhost_tx_string[256]; 00531 00532 00533 float f_sensor1_value = 12.3; 00534 float f_sensor2_value = 45.6; 00535 float f_sensor3_value = 78.9; 00536 float f_sensor4_value = 78.9; 00537 float f_sensor5_value = 78.9; 00538 float f_sensor6_value = 78.9; 00539 float f_sensor7_value = 78.9; 00540 float f_sensor8_value = 78.9; 00541 char usb_sensor_string[110]; 00542 00543 00544 //******************************************************************************************************************************************** 00545 //* Parse the input sensor data from the USB host 00546 //******************************************************************************************************************************************** 00547 int parse_usbhost_message() 00548 { 00549 //PRINTF("String = %s\n", usbhost_rx_string); //test 00550 uint8_t length; 00551 uint8_t x ; 00552 //It seems that sscanf needs 11 characters to store a 7-character number. There must be some formatting and termination values... 00553 char Record[8][11]; //There are 8 sensors with up to 7 characters each 00554 char StringRecord[110]; //There are is a sensor "string" with up to 100 characters in it 00555 00556 // Data format is: "S1:1234,S2:5678,S3:1234,S4:5678,S5:1234,S6:5678,S7:5678,S8:5678,S9:abcde...\n" 00557 int args_assigned = sscanf(usbhost_rx_string, "%[^','],%[^','],%[^','],%[^','],%[^','],%[^','],%[^','],%[^','],%[^\n]", Record[0], Record[1], Record[2], Record[3], Record[4], Record[5], Record[6], Record[7], StringRecord); 00558 00559 //StringRecord[109] = '\0'; 00560 //PRINTF("Last = %s\n", StringRecord); //test 00561 00562 if (args_assigned == 9) 00563 { //sscanf was able to assign all 9 values 00564 for (x=0; x < 8; x++) // loop through the 8 sensors 00565 { 00566 // Strip the "Sx:" label characters from the field value 00567 length = strlen(Record[x]); // max of 7 characters but could be less 00568 strncpy(Record[x], Record[x] + 3, length); 00569 Record[x][length] = '\0'; // null termination character manually added 00570 } 00571 length = strlen(StringRecord); 00572 strncpy(StringRecord, StringRecord + 3, length); 00573 StringRecord[length] = '\0'; // null termination character manually added 00574 00575 if ((usbhost_rx_string[0] == 'S') && (usbhost_rx_string[1] == '1')) //The message starts with "S1" 00576 { 00577 f_sensor1_value = atof(Record[0]); 00578 f_sensor2_value = atof(Record[1]); 00579 f_sensor3_value = atof(Record[2]); 00580 f_sensor4_value = atof(Record[3]); 00581 f_sensor5_value = atof(Record[4]); 00582 f_sensor6_value = atof(Record[5]); 00583 f_sensor7_value = atof(Record[6]); 00584 f_sensor8_value = atof(Record[7]); 00585 sprintf(usb_sensor_string,StringRecord); 00586 //PRINTF("Received = %s, %s, %s, %s, %s, %s, %s, %s, %s\n", Record[0], Record[1], Record[2], Record[3], Record[4], Record[5], Record[6], Record[7], usb_sensor_string); //test 00587 sprintf(SENSOR_DATA.Virtual_Sensor1, "%s", Record[0]); 00588 sprintf(SENSOR_DATA.Virtual_Sensor2, "%s", Record[1]); 00589 sprintf(SENSOR_DATA.Virtual_Sensor3, "%s", Record[2]); 00590 sprintf(SENSOR_DATA.Virtual_Sensor4, "%s", Record[3]); 00591 sprintf(SENSOR_DATA.Virtual_Sensor5, "%s", Record[4]); 00592 sprintf(SENSOR_DATA.Virtual_Sensor6, "%s", Record[5]); 00593 sprintf(SENSOR_DATA.Virtual_Sensor7, "%s", Record[6]); 00594 sprintf(SENSOR_DATA.Virtual_Sensor8, "%s", Record[7]); 00595 } 00596 } //sscanf was able to assign all values 00597 return args_assigned; 00598 } //parse_usbhost_message() 00599 00600 //******************************************************************************************************************************************** 00601 //* Process any received message from the USB host 00602 //******************************************************************************************************************************************** 00603 void process_usb_rx(unsigned char ucNewRxByte) 00604 { 00605 if (ucNewRxByte == '?') 00606 { //just pinging 00607 usbhost_rxstring_index = 0; 00608 return; 00609 } //just pinging 00610 usbhost_rx_string[usbhost_rxstring_index++] = ucNewRxByte; 00611 if (ucNewRxByte == '\n') 00612 { //end of message 00613 usbhost_rx_string[usbhost_rxstring_index] = 0; //null terminate string 00614 usbhost_rxstring_index = 0; 00615 parse_usbhost_message(); 00616 } //end of message 00617 } //process_usb_rx() 00618 00619 void ProcessUsbInterface(void) 00620 { 00621 //Process the USB host UART receive commands: 00622 if (usb_uart_rx_buff_getptr != usb_uart_rx_buff_putptr) 00623 { 00624 bUsbConnected = true; 00625 while (usb_uart_rx_buff_getptr != usb_uart_rx_buff_putptr) 00626 { 00627 unsigned char ucByteFromHost = usb_uart_rx_buff[usb_uart_rx_buff_getptr++]; //Copy latest received byte 00628 process_usb_rx(ucByteFromHost); 00629 } //while (usb_uart_rx_buff_getptr != usb_uart_rx_buff_putptr) 00630 } // if there are USB UART bytes to receive 00631 //USB host UART transmit: 00632 //while (usb_uart_tx_buff_getptr != usb_uart_tx_buff_putptr) 00633 //{ 00634 //pc.putc(usb_uart_tx_buff[usb_uart_tx_buff_getptr++]); 00635 //} 00636 } //ProcessUsbInterface() 00637 00638 // This function is called when a character goes into the RX buffer. 00639 void UsbUartRxCallback(MODSERIAL_IRQ_INFO *info) 00640 { 00641 // Get the pointer to our MODSERIAL object that invoked this callback. 00642 MODSERIAL *pc = info->serial; 00643 while (pc->readable()) 00644 { 00645 usb_uart_rx_buff[usb_uart_rx_buff_putptr++] = pc->getcNb(); 00646 } 00647 } 00648 #endif 00649 00650 void sensors_init(void) 00651 { 00652 #ifdef USE_VIRTUAL_SENSORS 00653 pc.attach(&UsbUartRxCallback, MODSERIAL::RxIrq); 00654 #endif 00655 Init_HTS221(); 00656 Init_Si7020(); 00657 Init_Si1145(); 00658 Init_motion_sensor(); 00659 Init_GPS(); 00660 } //sensors_init 00661 00662 void read_sensors(void) 00663 { 00664 Read_HTS221(); 00665 Read_Si7020(); 00666 Read_Si1145(); 00667 Read_motion_sensor(); 00668 Read_GPS(); 00669 } //read_sensors
Generated on Tue Jul 12 2022 17:36:30 by
1.7.2
