Raghav Ganesh
/
AvnetATT_shape_hackathon
This program simply connects to a HTS221 I2C device to read Temperature
Embed:
(wiki syntax)
Show/hide line numbers
sensors.cpp
00001 #include "mbed.h" 00002 #include "sensors.h" 00003 00004 //I2C for pmod sensors: 00005 #define Si1145_PMOD_I2C_ADDR 0xC0 //this is for 7-bit addr 0x60 for the Si7020 00006 #define Si7020_PMOD_I2C_ADDR 0x80 //this is for 7-bit addr 0x4 for the Si7020 00007 00008 #include "hardware.h" 00009 //I2C i2c(PTC11, PTC10); //SDA, SCL 00010 00011 #include "FXOS8700CQ.h" 00012 // Pin names for the motion sensor FRDM-K64F board: 00013 FXOS8700CQ fxos(PTE25, PTE24, FXOS8700CQ_SLAVE_ADDR1); // SDA, SCL, (addr << 1) 00014 // Storage for the data from the sensor 00015 SRAWDATA accel_data; 00016 SRAWDATA magn_data; 00017 //InterruptIn fxos_int1(PTC6); // unused, common with SW2 on FRDM-K64F 00018 InterruptIn fxos_int2(PTC13); // should just be the Data-Ready interrupt 00019 bool fxos_int2_triggered = false; 00020 void trigger_fxos_int2(void) 00021 { 00022 fxos_int2_triggered = true; 00023 //us_ellapsed = t.read_us(); 00024 } 00025 00026 /*------------------------------------------------------------------------------ 00027 * Perform I2C single read. 00028 *------------------------------------------------------------------------------*/ 00029 unsigned char I2C_ReadSingleByte(unsigned char ucDeviceAddress) 00030 { 00031 char rxbuffer [1]; 00032 i2c.read(ucDeviceAddress, rxbuffer, 1 ); 00033 return (unsigned char)rxbuffer[0]; 00034 } //I2C_ReadSingleByte() 00035 00036 /*------------------------------------------------------------------------------ 00037 * Perform I2C single read from address. 00038 *------------------------------------------------------------------------------*/ 00039 unsigned char I2C_ReadSingleByteFromAddr(unsigned char ucDeviceAddress, unsigned char Addr) 00040 { 00041 char txbuffer [1]; 00042 char rxbuffer [1]; 00043 txbuffer[0] = (char)Addr; 00044 i2c.write(ucDeviceAddress, txbuffer, 1 ); 00045 i2c.read(ucDeviceAddress, rxbuffer, 1 ); 00046 return (unsigned char)rxbuffer[0]; 00047 } //I2C_ReadSingleByteFromAddr() 00048 00049 /*------------------------------------------------------------------------------ 00050 * Perform I2C read of more than 1 byte. 00051 *------------------------------------------------------------------------------*/ 00052 int I2C_ReadMultipleBytes(unsigned char ucDeviceAddress, char *ucData, unsigned char ucLength) 00053 { 00054 int status; 00055 status = i2c.read(ucDeviceAddress, ucData, ucLength); 00056 return status; 00057 } //I2C_ReadMultipleBytes() 00058 00059 /*------------------------------------------------------------------------------ 00060 * Perform I2C write of a single byte. 00061 *------------------------------------------------------------------------------*/ 00062 int I2C_WriteSingleByte(unsigned char ucDeviceAddress, unsigned char Data, bool bSendStop) 00063 { 00064 int status; 00065 char txbuffer [1]; 00066 txbuffer[0] = (char)Data; //data 00067 status = i2c.write(ucDeviceAddress, txbuffer, 1, !bSendStop); //true: do not send stop 00068 return status; 00069 } //I2C_WriteSingleByte() 00070 00071 /*------------------------------------------------------------------------------ 00072 * Perform I2C write of 1 byte to an address. 00073 *------------------------------------------------------------------------------*/ 00074 int I2C_WriteSingleByteToAddr(unsigned char ucDeviceAddress, unsigned char Addr, unsigned char Data, bool bSendStop) 00075 { 00076 int status; 00077 char txbuffer [2]; 00078 txbuffer[0] = (char)Addr; //address 00079 txbuffer[1] = (char)Data; //data 00080 //status = i2c.write(ucDeviceAddress, txbuffer, 2, false); //stop at end 00081 status = i2c.write(ucDeviceAddress, txbuffer, 2, !bSendStop); //true: do not send stop 00082 return status; 00083 } //I2C_WriteSingleByteToAddr() 00084 00085 /*------------------------------------------------------------------------------ 00086 * Perform I2C write of more than 1 byte. 00087 *------------------------------------------------------------------------------*/ 00088 int I2C_WriteMultipleBytes(unsigned char ucDeviceAddress, char *ucData, unsigned char ucLength, bool bSendStop) 00089 { 00090 int status; 00091 status = i2c.write(ucDeviceAddress, ucData, ucLength, !bSendStop); //true: do not send stop 00092 return status; 00093 } //I2C_WriteMultipleBytes() 00094 00095 bool bSi7020_present = false; 00096 void Init_Si7020(void) 00097 { 00098 char SN_7020 [8]; 00099 //SN part 1: 00100 I2C_WriteSingleByteToAddr(Si7020_PMOD_I2C_ADDR, 0xFA, 0x0F, false); 00101 I2C_ReadMultipleBytes(Si7020_PMOD_I2C_ADDR, &SN_7020[0], 4); 00102 00103 //SN part 1: 00104 I2C_WriteSingleByteToAddr(Si7020_PMOD_I2C_ADDR, 0xFC, 0xC9, false); 00105 I2C_ReadMultipleBytes(Si7020_PMOD_I2C_ADDR, &SN_7020[4], 4); 00106 00107 char Ver_7020 [2]; 00108 //FW version: 00109 I2C_WriteSingleByteToAddr(Si7020_PMOD_I2C_ADDR, 0x84, 0xB8, false); 00110 I2C_ReadMultipleBytes(Si7020_PMOD_I2C_ADDR, &Ver_7020[0], 2); 00111 00112 if (SN_7020[4] != 0x14) 00113 { 00114 bSi7020_present = false; 00115 printf("Si7020 sensor not found\n"); 00116 } 00117 else 00118 { 00119 bSi7020_present = true; 00120 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]); 00121 printf("Si7020 Version# = 0x%02X\n", Ver_7020[0]); 00122 } //bool bSi7020_present = true 00123 00124 } //Init_Si7020() 00125 00126 void Read_Si7020(void) 00127 { 00128 if (bSi7020_present) 00129 { 00130 char Humidity [2]; 00131 char Temperature [2]; 00132 //Command to measure humidity (temperature also gets measured): 00133 I2C_WriteSingleByte(Si7020_PMOD_I2C_ADDR, 0xF5, false); //no hold, must do dummy read 00134 I2C_ReadMultipleBytes(Si7020_PMOD_I2C_ADDR, &Humidity[0], 1); //dummy read, should get an nack until it is done 00135 wait (0.05); //wait for measurement. Can also keep reading until no NACK is received 00136 //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... 00137 I2C_ReadMultipleBytes(Si7020_PMOD_I2C_ADDR, &Humidity[0], 2); //read humidity 00138 //printf("Read Si7020 Humidity = 0x%02X%02X\n", Humidity[0], Humidity[1]); 00139 int rh_code = (Humidity[0] << 8) + Humidity[1]; 00140 float fRh = (125.0*rh_code/65536.0) - 6.0; //from datasheet 00141 //printf("Si7020 Humidity = %*.*f %%\n", 4, 2, fRh); //double % sign for escape //printf("%*.*f\n", myFieldWidth, myPrecision, myFloatValue); 00142 sprintf(SENSOR_DATA.Humidity_Si7020, "%0.2f", fRh); 00143 00144 //Command to read temperature when humidity is already done: 00145 I2C_WriteSingleByte(Si7020_PMOD_I2C_ADDR, 0xE0, false); 00146 I2C_ReadMultipleBytes(Si7020_PMOD_I2C_ADDR, &Temperature[0], 2); //read temperature 00147 //printf("Read Si7020 Temperature = 0x%02X%02X\n", Temperature[0], Temperature[1]); 00148 int temp_code = (Temperature[0] << 8) + Temperature[1]; 00149 float fTemp = (175.72*temp_code/65536.0) - 46.85; //from datasheet in Celcius 00150 //printf("Si7020 Temperature = %*.*f deg C\n", 4, 2, fTemp); 00151 sprintf(SENSOR_DATA.Temperature_Si7020, "%0.2f", fTemp); 00152 } //bool bSi7020_present = true 00153 00154 } //Read_Si7020() 00155 00156 /*------------------------------------------------------------------------------ 00157 * The following are aliases so that the Si1145 coding examples can be used as-is. 00158 *------------------------------------------------------------------------------*/ 00159 unsigned char ReadFrom_Si1145_Register(unsigned char reg) //returns byte from I2C Register 'reg' 00160 { 00161 unsigned char result = I2C_ReadSingleByteFromAddr(Si1145_PMOD_I2C_ADDR, reg); 00162 return (result); 00163 } //ReadFrom_Si1145_Register() 00164 00165 void WriteTo_Si1145_Register(unsigned char reg, unsigned char value) //writes 'value' into I2C Register reg' 00166 { 00167 I2C_WriteSingleByteToAddr(Si1145_PMOD_I2C_ADDR, reg, value, true); 00168 } //WriteTo_Si1145_Register() 00169 00170 #define REG_PARAM_WR 0x17 00171 #define REG_PARAM_RD 0x2E 00172 #define REG_COMMAND 0x18 00173 #define REG_RESPONSE 0x20 00174 #define REG_HW_KEY 0x07 00175 #define HW_KEY_VAL0 0x17 00176 #define REG_MEAS_RATE_LSB 0x08 00177 #define REG_MEAS_RATE_MSB 0x09 00178 #define REG_PS_LED21 0x0F 00179 #define REG_PS_LED3 0x10 00180 #define MAX_LED_CURRENT 0xF 00181 #define PARAM_CH_LIST 0x01 00182 #define REG_ALS_VIS_DATA0 0x22 00183 #define REG_ALS_VIS_DATA1 0x23 00184 #define REG_ALS_IR_DATA0 0x24 00185 #define REG_ALS_IR_DATA1 0x25 00186 #define REG_PS1_DATA0 0x26 00187 #define REG_PS1_DATA1 0x27 00188 #define REG_PS2_DATA0 0x28 00189 #define REG_PS2_DATA1 0x29 00190 #define REG_PS3_DATA0 0x2A 00191 #define REG_PS3_DATA1 0x2B 00192 #define REG_UVINDEX0 0x2C 00193 #define REG_UVINDEX1 0x2D 00194 int Si1145_ParamSet(unsigned char address, unsigned char value) //writes 'value' into Parameter 'address' 00195 { 00196 char txbuffer [3]; 00197 txbuffer[0] = (char)REG_PARAM_WR; //destination 00198 txbuffer[1] = (char)value; 00199 txbuffer[2] = (char)(0xA0 + (address & 0x1F)); 00200 int retval; 00201 //if((retval = _waitUntilSleep(si114x_handle))!=0) return retval; 00202 retval = I2C_WriteMultipleBytes(Si1145_PMOD_I2C_ADDR, &txbuffer[0], 3, true); 00203 if(retval!=0) return retval; 00204 while(1) 00205 { 00206 retval=ReadFrom_Si1145_Register(REG_PARAM_RD); 00207 if (retval==value) break; 00208 } 00209 return (0); 00210 } //Si1145_ParamSet() 00211 00212 void PsAlsForce(void) //equivalent to WriteTo_Si1145_Register(REG_COMMAND,0x07). This forces PS and ALS measurements 00213 { 00214 WriteTo_Si1145_Register(REG_COMMAND,0x07); 00215 } //PsAlsForce() 00216 00217 bool bSi1145_present = false; 00218 void Init_Si1145(void) 00219 { 00220 unsigned char readbyte; 00221 //Read Si1145 part ID: 00222 readbyte = ReadFrom_Si1145_Register(0x00); 00223 if (readbyte != 0x45) 00224 { 00225 bSi1145_present = false; 00226 printf("Si1145 sensor not found\n"); 00227 } 00228 else 00229 { 00230 bSi1145_present = true; 00231 printf("Si1145 Part ID : 0x%02X\n", readbyte); 00232 //Initialize Si1145 by writing to HW_KEY (I2C Register 0x07 = 0x17) 00233 WriteTo_Si1145_Register(REG_HW_KEY, HW_KEY_VAL0); 00234 00235 // Initialize LED Current 00236 // I2C Register 0x0F = 0xFF 00237 // I2C Register 0x10 = 0x0F 00238 WriteTo_Si1145_Register(REG_PS_LED21,(MAX_LED_CURRENT<<4) + MAX_LED_CURRENT); 00239 WriteTo_Si1145_Register(REG_PS_LED3, MAX_LED_CURRENT); 00240 00241 // Parameter 0x01 = 0x37 00242 //Si1145_ParamSet(PARAM_CH_LIST, ALS_IR_TASK + ALS_VIS_TASK + PS1_TASK + PS2_TASK + PS3_TASK); 00243 //Si1145_ParamSet(0x01, 0x37); //CHLIST is address 0x01 in the parameter RAM. It defines which sensors are enabled (here, some) 00244 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...) 00245 // 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... 00246 PsAlsForce(); // can also be written as WriteTo_Si1145_Register(REG_COMMAND,0x07); 00247 WriteTo_Si1145_Register(REG_COMMAND, 0x0F);//command to put it into auto mode 00248 //Set MES_RATE to 0x1000. I.e. the device will automatically wake up every 16 * 256* 31.25 us = 0.128 seconds to measure 00249 WriteTo_Si1145_Register(REG_MEAS_RATE_LSB, 0x00); 00250 WriteTo_Si1145_Register(REG_MEAS_RATE_MSB, 0x10); 00251 } //bSi1145_present = true 00252 } //Init_Si1145() 00253 00254 void Read_Si1145(void) 00255 { 00256 if (bSi1145_present) 00257 { 00258 // Once the measurements are completed, here is how to reconstruct them 00259 // Note very carefully that 16-bit registers are in the 'Little Endian' byte order 00260 // It may be more efficient to perform block I2C Reads, but this example shows 00261 // individual reads of registers 00262 00263 int PS1 = ReadFrom_Si1145_Register(REG_PS1_DATA0) + 256 * ReadFrom_Si1145_Register(REG_PS1_DATA1); 00264 int PS2 = ReadFrom_Si1145_Register(REG_PS2_DATA0) + 256 * ReadFrom_Si1145_Register(REG_PS2_DATA1); 00265 int PS3 = ReadFrom_Si1145_Register(REG_PS3_DATA0) + 256 * ReadFrom_Si1145_Register(REG_PS3_DATA1); 00266 //printf("PS1_Data = %d\n", PS1); 00267 //printf("PS2_Data = %d\n", PS2); 00268 //printf("PS3_Data = %d\n", PS3); 00269 //OBJECT PRESENT? 00270 if(PS1 < 22000){ 00271 //printf("Object Far\n"); 00272 sprintf(SENSOR_DATA.Proximity, "Object Far"); 00273 } 00274 else if(PS1 < 24000) 00275 { 00276 //printf("Object in Vicinity\n"); 00277 sprintf(SENSOR_DATA.Proximity, "Object in Vicinity"); 00278 } 00279 else if (PS1 < 30000) 00280 { 00281 //printf("Object Near\n"); 00282 sprintf(SENSOR_DATA.Proximity, "Object Near"); 00283 } 00284 else 00285 { 00286 //printf("Object Very Near\n"); 00287 sprintf(SENSOR_DATA.Proximity, "Object Very Near"); 00288 } 00289 00290 //Force ALS read: 00291 //WriteTo_Si1145_Register(REG_COMMAND, 0x06); 00292 //wait (0.1); 00293 int ALS_VIS = ReadFrom_Si1145_Register(REG_ALS_VIS_DATA0) + 256 * ReadFrom_Si1145_Register(REG_ALS_VIS_DATA1); 00294 int ALS_IR = ReadFrom_Si1145_Register(REG_ALS_IR_DATA0) + 256 * ReadFrom_Si1145_Register(REG_ALS_IR_DATA1); 00295 int UV_INDEX = ReadFrom_Si1145_Register(REG_UVINDEX0) + 256 * ReadFrom_Si1145_Register(REG_UVINDEX1); 00296 //printf("ALS_VIS_Data = %d\n", ALS_VIS); 00297 //printf("ALS_IR_Data = %d\n", ALS_IR); 00298 //printf("UV_INDEX_Data = %d\n", UV_INDEX); 00299 00300 //printf("Ambient Light Visible Sensor = %d\n", ALS_VIS); 00301 sprintf(SENSOR_DATA.AmbientLightVis, "%d", ALS_VIS); 00302 //printf("Ambient Light Infrared Sensor = %d\n", ALS_IR); 00303 sprintf(SENSOR_DATA.AmbientLightIr, "%d", ALS_IR); 00304 //float fUV_value = (UV_INDEX -50.0)/10000.0; 00305 float fUV_value = (UV_INDEX)/100.0; //this is the aux reading 00306 //printf("UV_Data = %0.2f\n", fUV_value); 00307 sprintf(SENSOR_DATA.UVindex, "%0.2f", fUV_value); 00308 } //bSi1145_present = true 00309 } //Read_Si1145() 00310 00311 //******************************************************************************************************************************************** 00312 //* Read the FXOS8700CQ - 6-axis combo Sensor Accelerometer and Magnetometer 00313 //******************************************************************************************************************************************** 00314 bool bMotionSensor_present = false; 00315 void init_motion_sensor() 00316 { 00317 int iWhoAmI = fxos.get_whoami(); 00318 00319 printf("FXOS8700CQ WhoAmI = %X\r\n", iWhoAmI); 00320 // Iterrupt for active-low interrupt line from FXOS 00321 // Configured with only one interrupt on INT2 signaling Data-Ready 00322 //fxos_int2.fall(&trigger_fxos_int2); 00323 if (iWhoAmI != 0xC7) 00324 { 00325 bMotionSensor_present = false; 00326 printf("FXOS8700CQ motion sensor not found\n"); 00327 } 00328 else 00329 { 00330 bMotionSensor_present = true; 00331 fxos.enable(); 00332 } 00333 } //init_motion_sensor 00334 00335 void read_motion_sensor() 00336 { 00337 if (bMotionSensor_present) 00338 { 00339 fxos.get_data(&accel_data, &magn_data); 00340 //printf("Roll=%5d, Pitch=%5d, Yaw=%5d;\r\n", magn_data.x, magn_data.y, magn_data.z); 00341 sprintf(SENSOR_DATA.MagnetometerX, "%5d", magn_data.x); 00342 sprintf(SENSOR_DATA.MagnetometerY, "%5d", magn_data.y); 00343 sprintf(SENSOR_DATA.MagnetometerZ, "%5d", magn_data.z); 00344 00345 //Try to normalize (/2048) the values so they will match the eCompass output: 00346 float fAccelScaled_x, fAccelScaled_y, fAccelScaled_z; 00347 fAccelScaled_x = (accel_data.x/2048.0); 00348 fAccelScaled_y = (accel_data.y/2048.0); 00349 fAccelScaled_z = (accel_data.z/2048.0); 00350 //printf("Acc: X=%2.3f Y=%2.3f Z=%2.3f;\r\n", fAccelScaled_x, fAccelScaled_y, fAccelScaled_z); 00351 sprintf(SENSOR_DATA.AccelX, "%2.3f", fAccelScaled_x); 00352 sprintf(SENSOR_DATA.AccelY, "%2.3f", fAccelScaled_y); 00353 sprintf(SENSOR_DATA.AccelZ, "%2.3f", fAccelScaled_z); 00354 } //bMotionSensor_present 00355 } //read_motion_sensor 00356 00357 void sensors_init(void) 00358 { 00359 Init_Si7020(); 00360 Init_Si1145(); 00361 init_motion_sensor(); 00362 } //sensors_init 00363 00364 void read_sensors(void) 00365 { 00366 Read_Si7020(); 00367 Read_Si1145(); 00368 read_motion_sensor(); 00369 } //read_sensors
Generated on Mon Jul 18 2022 21:05:05 by 1.7.2