Llibrary for the WiGo MPL3115A2, I2C Precision Altimeter sensor. This is a temp fork
Dependents: sensor AerCloud_MutliTech_Socket_Modem_Example Freescale_Multi-Sensor_Shield 2lemetry_Sensor_Example ... more
Fork of MPL3115A2 by
MPL3115A2.cpp
00001 #include "MPL3115A2.h" 00002 00003 #define REG_WHO_AM_I 0x0C // return 0xC4 by default 00004 #define REG_STATUS 0x00 00005 #define REG_CTRL_REG_1 0x26 00006 #define REG_CTRL_REG_3 0x28 00007 #define REG_CTRL_REG_4 0x29 00008 #define REG_CTRL_REG_5 0x2A 00009 #define REG_PRESSURE_MSB 0x01 // 3 byte pressure data 00010 #define REG_ALTIMETER_MSB 0x01 // 3 byte altimeter data 00011 #define REG_TEMP_MSB 0x04 // 2 byte temperature data 00012 #define REG_PT_DATA_CFG 0x13 00013 #define REG_P_TGT_MSB 0x16 00014 #define REG_P_WND_MSB 0x19 00015 #define REG_OFF_P 0x2b 00016 #define REG_OFF_T 0x2c 00017 #define REG_OFF_H 0x2d 00018 #define REG_PRES_MIN_MSB 0x1c 00019 #define REG_ALTI_MIN_MSB 0x1c 00020 #define REG_TEMP_MIN_MSB 0x1f 00021 #define REG_PRES_MAX_MSB 0x21 00022 #define REG_ALTI_MAX_MSB 0x21 00023 #define REG_TEMP_MAX_MSB 0x24 00024 #define REG_PRES_DELTA_MSB 0x07 00025 #define REG_ALTI_DELTA_MSB 0x07 00026 #define REG_TEMP_DELTA_MSB 0x0a 00027 00028 00029 #define UINT14_MAX 16383 00030 00031 // Status flag for data ready. 00032 #define PTDR_STATUS 0x03 // Pressure Altitude and Temperature ready 00033 #define PDR_STATUS 0x02 // Pressure and Altitude data ready 00034 #define TDR_STATUS 0x01 // Temperature data ready 00035 00036 00037 void (*MPL3115A2_usr2_fptr)(void); // Pointers to user function called after 00038 void (*MPL3115A2_usr1_fptr)(void); // IRQ assertion. 00039 00040 00041 MPL3115A2::MPL3115A2(PinName sda, PinName scl, int addr, PinName int1, PinName int2) : m_i2c(sda, scl), m_addr(addr), MPL3115A2_Int1(int1), MPL3115A2_Int2(int2) { 00042 unsigned char data[6]; 00043 00044 MPL3115A2_mode = BAROMETRIC_MODE; 00045 MPL3115A2_oversampling = OVERSAMPLE_RATIO_1; 00046 // 00047 MPL3115A2_usr1_fptr = NULL; 00048 MPL3115A2_usr2_fptr = NULL; 00049 MPL3115A2_Int1.fall( NULL); 00050 MPL3115A2_Int2.fall( NULL); 00051 00052 Reset(); 00053 00054 data[0]=REG_PRES_MIN_MSB; 00055 data[1]=0;data[2]=0;data[3]=0;data[4]=0;data[5]=0; 00056 writeRegs( &data[0], 6); 00057 } 00058 00059 void MPL3115A2::Reset( void) 00060 { 00061 unsigned char t; 00062 00063 // soft reset... 00064 readRegs( REG_CTRL_REG_1, &t, 1); 00065 unsigned char data[2] = { REG_CTRL_REG_1, t|0x04}; 00066 writeRegs(data, 2); 00067 wait( 0.1); 00068 00069 } 00070 00071 void MPL3115A2::DataReady( void(*fptr)(void), unsigned char OS) 00072 { 00073 unsigned char dt[5]; 00074 unsigned char data[2]; 00075 00076 // Soft Reset 00077 Reset(); 00078 00079 Standby(); 00080 00081 // Clear all interrupts by reading the output registers. 00082 readRegs( REG_ALTIMETER_MSB, &dt[0], 5); 00083 getStatus(); 00084 // Configure INT active low and pullup 00085 data[0] = REG_CTRL_REG_3; 00086 data[1] = 0x00; 00087 writeRegs(data, 2); 00088 // Enable Interrupt fot data ready 00089 data[0] = REG_CTRL_REG_4; 00090 data[1] = 0x80; 00091 writeRegs(data, 2); 00092 // Configure Interrupt to route to INT2 00093 data[0] = REG_CTRL_REG_5; 00094 data[1] = 0x00; 00095 writeRegs(data, 2); 00096 data[0] = REG_PT_DATA_CFG; 00097 data[1] = 0x07; 00098 writeRegs(data, 2); 00099 00100 // Configure the OverSampling rate, Altimeter/Barometer mode and set the sensor Active 00101 data[0] = REG_CTRL_REG_1; 00102 data[1] = (OS<<3); 00103 // 00104 if (MPL3115A2_mode == BAROMETRIC_MODE) 00105 data[1] &= 0x7F; 00106 else 00107 data[1] |= 0x80; 00108 // 00109 data[1] |= 0x01; 00110 writeRegs(data, 2); 00111 00112 MPL3115A2_usr2_fptr = fptr; 00113 MPL3115A2_Int2.fall( this, &MPL3115A2::DataReady_IRQ); 00114 00115 } 00116 00117 void MPL3115A2::DataReady_IRQ( void) 00118 { 00119 // Clear the IRQ flag 00120 getStatus(); 00121 // Run the user supplied function 00122 MPL3115A2_usr2_fptr(); 00123 } 00124 00125 void MPL3115A2::AltitudeTrigger( void(*fptr)(void), unsigned short level) 00126 { 00127 unsigned char dt[5]; 00128 unsigned char data[2]; 00129 00130 // Soft Reset 00131 Reset(); 00132 00133 // The device is on standby 00134 Standby(); 00135 00136 // Clear all interrupts by reading the output registers. 00137 readRegs( REG_ALTIMETER_MSB, &dt[0], 5); 00138 getStatus(); 00139 00140 // Write Target and Window Values 00141 dt[0] = REG_P_TGT_MSB; 00142 dt[1] = (level>>8); 00143 dt[2] = (level&0xFF); 00144 writeRegs( dt, 3); 00145 00146 // Window values are zero 00147 dt[0] = REG_P_WND_MSB; 00148 dt[1] = 0; 00149 dt[2] = 0; 00150 writeRegs( dt, 3); 00151 00152 // Enable Pressure Threshold interrupt 00153 data[0] = REG_CTRL_REG_4; 00154 data[1] = 0x08; 00155 writeRegs( data, 2); 00156 // Interrupt is routed to INT1 00157 data[0] = REG_CTRL_REG_5; 00158 data[1] = 0x08; 00159 writeRegs( data, 2); 00160 data[0] = REG_PT_DATA_CFG; 00161 data[1] = 0x07; 00162 writeRegs(data, 2); 00163 // Configure the OverSampling rate, Altimeter mode and set the sensor Active 00164 data[0] = REG_CTRL_REG_1; 00165 data[1] = 0x81 | (MPL3115A2_oversampling<<3); 00166 writeRegs(data, 2); 00167 00168 MPL3115A2_usr1_fptr = fptr; 00169 MPL3115A2_Int1.fall( this, &MPL3115A2::AltitudeTrg_IRQ); 00170 00171 } 00172 00173 void MPL3115A2::AltitudeTrg_IRQ( void) 00174 { 00175 // Clear the IRQ flag 00176 getStatus(); 00177 // Run the user supplied function 00178 MPL3115A2_usr1_fptr(); 00179 00180 } 00181 00182 void MPL3115A2::Barometric_Mode( void) 00183 { 00184 unsigned char t; 00185 unsigned char data[2]; 00186 00187 Standby(); 00188 00189 // soft reset... 00190 Reset(); 00191 00192 Standby(); 00193 readRegs( REG_CTRL_REG_1, &t, 1); 00194 00195 // Set the Barometric mode 00196 data[0] = REG_CTRL_REG_1; 00197 data[1] = t&0x7F; 00198 writeRegs(data, 2); 00199 00200 data[0] = REG_PT_DATA_CFG; 00201 data[1] = 0x07; 00202 writeRegs(data, 2); 00203 00204 Oversample_Ratio( MPL3115A2_oversampling); 00205 00206 Active(); 00207 00208 MPL3115A2_mode = BAROMETRIC_MODE; 00209 } 00210 00211 void MPL3115A2::Altimeter_Mode( void) 00212 { 00213 unsigned char t; 00214 unsigned char data[2]; 00215 00216 Standby(); 00217 00218 // soft reset... 00219 Reset(); 00220 00221 Standby(); 00222 readRegs( REG_CTRL_REG_1, &t, 1); 00223 00224 data[0] = REG_CTRL_REG_1; 00225 data[1] = t|0x80; 00226 writeRegs(data, 2); 00227 00228 data[0] = REG_PT_DATA_CFG; 00229 data[1] = 0x07; 00230 writeRegs(data, 2); 00231 00232 Oversample_Ratio( MPL3115A2_oversampling); 00233 00234 Active(); 00235 00236 MPL3115A2_mode = ALTIMETER_MODE; 00237 } 00238 00239 void MPL3115A2::Oversample_Ratio( unsigned int ratio) 00240 { 00241 unsigned char t; 00242 00243 Standby(); 00244 readRegs( REG_CTRL_REG_1, &t, 1); 00245 00246 t = t & 0xE7; 00247 t = t | ( ratio<<3); 00248 00249 unsigned char data[2] = { REG_CTRL_REG_1, t}; 00250 writeRegs(data, 2); 00251 00252 Active(); 00253 00254 MPL3115A2_oversampling = ratio; 00255 } 00256 00257 00258 void MPL3115A2::Active( void) 00259 { 00260 unsigned char t; 00261 00262 // Activate the peripheral 00263 readRegs(REG_CTRL_REG_1, &t, 1); 00264 unsigned char data[2] = {REG_CTRL_REG_1, t|0x01}; 00265 writeRegs(data, 2); 00266 } 00267 00268 void MPL3115A2::Standby( void) 00269 { 00270 unsigned char t; 00271 00272 // Standby 00273 readRegs(REG_CTRL_REG_1, &t, 1); 00274 unsigned char data[2] = {REG_CTRL_REG_1, t&0xFE}; 00275 writeRegs(data, 2); 00276 } 00277 00278 unsigned char MPL3115A2::getDeviceID() { 00279 unsigned char device_id = 0; 00280 readRegs(REG_WHO_AM_I, &device_id, 1); 00281 return device_id; 00282 } 00283 00284 unsigned int MPL3115A2::isDataAvailable( void) 00285 { 00286 unsigned char status; 00287 00288 readRegs( REG_STATUS, &status, 1); 00289 00290 return ((status>>1)); 00291 00292 } 00293 00294 unsigned char MPL3115A2::getStatus( void) 00295 { 00296 unsigned char status; 00297 00298 readRegs( REG_STATUS, &status, 1); 00299 return status; 00300 } 00301 00302 unsigned int MPL3115A2::getAllData( float *f) 00303 { 00304 if ( isDataAvailable() & PTDR_STATUS) { 00305 if ( MPL3115A2_mode == ALTIMETER_MODE) { 00306 f[0] = getAltimeter( REG_ALTIMETER_MSB); 00307 } else { 00308 f[0] = getPressure( REG_PRESSURE_MSB); 00309 } 00310 00311 f[1] = getTemperature( REG_TEMP_MSB); 00312 // 00313 return 1; 00314 } else 00315 return 0; 00316 } 00317 00318 unsigned int MPL3115A2::getAllData( float *f, float *d) 00319 { 00320 if ( isDataAvailable() & PTDR_STATUS) { 00321 if ( MPL3115A2_mode == ALTIMETER_MODE) { 00322 f[0] = getAltimeter(); 00323 d[0] = getAltimeter( REG_ALTI_DELTA_MSB); 00324 } else { 00325 f[0] = getPressure(); 00326 d[0] = getPressure( REG_PRES_DELTA_MSB); 00327 } 00328 00329 f[1] = getTemperature(); 00330 d[1] = getTemperature( REG_TEMP_DELTA_MSB); 00331 // 00332 return 1; 00333 } else 00334 return 0; 00335 } 00336 00337 void MPL3115A2::getAllMaximumData( float *f) 00338 { 00339 if ( MPL3115A2_mode == ALTIMETER_MODE) { 00340 f[0] = getAltimeter( REG_ALTI_MAX_MSB); 00341 } else { 00342 f[0] = getPressure( REG_PRES_MAX_MSB); 00343 } 00344 00345 f[1] = getTemperature( REG_TEMP_MAX_MSB); 00346 } 00347 00348 void MPL3115A2::getAllMinimumData( float *f) 00349 { 00350 if ( MPL3115A2_mode == ALTIMETER_MODE) { 00351 f[0] = getAltimeter( REG_ALTI_MIN_MSB); 00352 } else { 00353 f[0] = getPressure( REG_PRES_MIN_MSB); 00354 } 00355 00356 f[1] = getTemperature( REG_TEMP_MIN_MSB); 00357 } 00358 00359 float MPL3115A2::getAltimeter( void) 00360 { 00361 float a; 00362 00363 a = getAltimeter( REG_ALTIMETER_MSB); 00364 return a; 00365 } 00366 00367 float MPL3115A2::getAltimeter( unsigned char reg) 00368 { 00369 unsigned char dt[3]; 00370 unsigned short altm; 00371 short tmp; 00372 float faltm; 00373 00374 /* 00375 * dt[0] = Bits 12-19 of 20-bit real-time Altitude sample. (b7-b0) 00376 * dt[1] = Bits 4-11 of 20-bit real-time Altitude sample. (b7-b0) 00377 * dt[2] = Bits 0-3 of 20-bit real-time Altitude sample (b7-b4) 00378 */ 00379 readRegs( reg, &dt[0], 3); 00380 altm = (dt[0]<<8) | dt[1]; 00381 // 00382 if ( dt[0] > 0x7F) { 00383 // negative number 00384 tmp = ~altm + 1; 00385 faltm = (float)tmp * -1.0f; 00386 } else { 00387 faltm = (float)altm * 1.0f; 00388 } 00389 // 00390 faltm = faltm+((float)(dt[2]>>4) * 0.0625f); 00391 return faltm; 00392 } 00393 00394 float MPL3115A2::getPressure( void) 00395 { 00396 float a; 00397 00398 a = getPressure( REG_PRESSURE_MSB); 00399 return a; 00400 } 00401 00402 float MPL3115A2::getPressure( unsigned char reg) 00403 { 00404 unsigned char dt[3]; 00405 unsigned int prs; 00406 int tmp; 00407 float fprs; 00408 00409 /* 00410 * dt[0] = Bits 12-19 of 20-bit real-time Pressure sample. (b7-b0) 00411 * dt[1] = Bits 4-11 of 20-bit real-time Pressure sample. (b7-b0) 00412 * dt[2] = Bits 0-3 of 20-bit real-time Pressure sample (b7-b4) 00413 */ 00414 readRegs( reg, &dt[0], 3); 00415 prs = ((dt[0]<<10) | (dt[1]<<2) | (dt[2]>>6)); 00416 // 00417 if ( dt[0] > 0x7f) { 00418 // negative number 00419 if ( dt[0] & 0x80) 00420 prs |= 0xFFFC0000; // set at 1 the bits to complete the word len 00421 else 00422 prs |= 0xFFFE0000; 00423 tmp = ~prs + 1; // make the complemets. At this point all the bits are inverted. 00424 fprs = (float)tmp * -1.0f; // set the signe.. 00425 } else { 00426 fprs = (float)prs * 1.0f; 00427 } 00428 00429 if ( dt[2] & 0x10) // I did some experiment to set the fractional parte. 00430 fprs += 0.25f; // ** Warning: the DS is wrong! ** 00431 if ( dt[2] & 0x20) 00432 fprs += 0.5f; 00433 00434 return fprs; 00435 } 00436 00437 float MPL3115A2::getTemperature( void) 00438 { 00439 float a; 00440 00441 a = getTemperature( REG_TEMP_MSB); 00442 return a; 00443 } 00444 00445 float MPL3115A2::getTemperature( unsigned char reg) 00446 { 00447 unsigned char dt[2]; 00448 unsigned short temp; 00449 float ftemp; 00450 00451 /* 00452 * dt[0] = Bits 4-11 of 16-bit real-time temperature sample. (b7-b0) 00453 * dt[1] = Bits 0-3 of 16-bit real-time temperature sample. (b7-b4) 00454 */ 00455 readRegs( reg, &dt[0], 2); 00456 temp = dt[0]; 00457 // 00458 if ( dt[0] > 0x7F) { 00459 temp = ~temp + 1; 00460 ftemp = (float)temp * -1.0f; 00461 } else { 00462 ftemp = (float)temp * 1.0f; 00463 } 00464 // 00465 ftemp = ftemp+((float)(dt[1]>>4) * 0.0625f); 00466 return ftemp; 00467 00468 } 00469 00470 00471 unsigned int MPL3115A2::getAllDataRaw( unsigned char *dt) 00472 { 00473 // Check for Press/Alti and Temp value ready 00474 if ( isDataAvailable() & PTDR_STATUS) { 00475 if ( MPL3115A2_mode == ALTIMETER_MODE) { 00476 getAltimeterRaw( &dt[0]); // 3 bytes 00477 } else { 00478 getPressureRaw( &dt[0]); // 3 bytes 00479 } 00480 00481 getTemperatureRaw( &dt[3]); // 2 bytes 00482 00483 return 1; 00484 } else { 00485 return 0; 00486 } 00487 } 00488 00489 unsigned int MPL3115A2::getAltimeterRaw( unsigned char *dt) 00490 { 00491 00492 /* 00493 * dt[0] = Bits 12-19 of 20-bit real-time Pressure sample. (b7-b0) 00494 * dt[1] = Bits 4-11 of 20-bit real-time Pressure sample. (b7-b0) 00495 * dt[2] = Bits 0-3 of 20-bit real-time Pressure sample (b7-b4) 00496 */ 00497 00498 // Check for Press/Alti value ready 00499 if ( isDataAvailable() & PDR_STATUS) { 00500 readRegs( REG_ALTIMETER_MSB, &dt[0], 3); 00501 return 1; 00502 } else 00503 return 0; 00504 } 00505 00506 unsigned int MPL3115A2::getPressureRaw( unsigned char *dt) 00507 { 00508 00509 /* 00510 * dt[0] = Bits 12-19 of 20-bit real-time Pressure sample. (b7-b0) 00511 * dt[1] = Bits 4-11 of 20-bit real-time Pressure sample. (b7-b0) 00512 * dt[2] = Bits 0-3 of 20-bit real-time Pressure sample (b7-b4) 00513 */ 00514 00515 // Check for Press/Alti value ready 00516 if ( isDataAvailable() & PDR_STATUS) { 00517 readRegs( REG_PRESSURE_MSB, &dt[0], 3); 00518 return 1; 00519 } else 00520 return 0; 00521 00522 } 00523 00524 unsigned int MPL3115A2::getTemperatureRaw( unsigned char *dt) 00525 { 00526 00527 /* 00528 * dt[0] = Bits 4-11 of 16-bit real-time temperature sample. (b7-b0) 00529 * dt[1] = Bits 0-3 of 16-bit real-time temperature sample. (b7-b4) 00530 */ 00531 00532 // Check for Temp value ready 00533 if ( isDataAvailable() & TDR_STATUS) { 00534 readRegs( REG_TEMP_MSB, &dt[0], 2); 00535 return 1; 00536 } else 00537 return 0; 00538 } 00539 00540 void MPL3115A2::SetPressureOffset( char offset) 00541 { 00542 unsigned char data [2] = {REG_OFF_P, offset}; 00543 00544 Standby(); 00545 writeRegs(data,2); 00546 00547 Active(); 00548 } 00549 00550 void MPL3115A2::SetTemperatureOffset( char offset) 00551 { 00552 unsigned char data [2] = {REG_OFF_T, offset}; 00553 00554 Standby(); 00555 writeRegs(data,2); 00556 00557 Active(); 00558 } 00559 00560 void MPL3115A2::SetAltitudeOffset( char offset) 00561 { 00562 unsigned char data [2] = {REG_OFF_H, offset}; 00563 00564 Standby(); 00565 writeRegs(data,2); 00566 00567 Active(); 00568 } 00569 00570 void MPL3115A2::readRegs(int addr, uint8_t * data, int len) { 00571 char t[1] = {addr}; 00572 m_i2c.write(m_addr, t, 1, true); 00573 m_i2c.read(m_addr, (char *)data, len); 00574 } 00575 00576 void MPL3115A2::writeRegs(uint8_t * data, int len) { 00577 m_i2c.write(m_addr, (char *)data, len); 00578 }
Generated on Tue Jul 12 2022 18:14:51 by 1.7.2