Bowen Feng / Mbed 2 deprecated Hiking_Pal

Dependencies:   FXOS8700CQ MODSERIAL mbed

Fork of Avnet_ATT_Cellular_IOT by Avnet

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers sensors.cpp Source File

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