Llibrary for the WiGo MPL3115A2, I2C Precision Altimeter sensor.
Dependents: KL25Z_Batt_Test WIGO_MPL3115A2 Multi-Sensor SPACEmk2 ... more
30/05/2013 Added and tested the data acquisition using Interrupt. Added code for Altimeter trigger Interrupt but not yet tested.
Very basic library. Under development. Need to add in order: 1. IRQ configuration. 2. FIFO mode configuration.
Diff: MPL3115A2.cpp
- Revision:
- 0:cfecfabc5e23
- Child:
- 2:a2fcfb7ff611
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MPL3115A2.cpp Thu May 23 06:42:15 2013 +0000 @@ -0,0 +1,239 @@ +#include "MPL3115A2.h" + +#define REG_WHO_AM_I 0x0C // 0xC4 by default +#define REG_STATUS 0x00 +#define REG_CTRL_REG_1 0x26 +#define REG_PRESSURE_MSB 0x01 // 3 byte pressure data +#define REG_ALTIMETER_MSB 0x01 // 3 byte altimeter data +#define REG_TEMP_MSB 0x04 // 2 byte temperature data +#define REG_PT_DATA_CFG 0x13 + +#define UINT14_MAX 16383 + +MPL3115A2::MPL3115A2(PinName sda, PinName scl, int addr) : m_i2c(sda, scl), m_addr(addr) { + MPL3115A2_mode = BAROMETRIC_MODE; + MPL3115A2_oversampling = OVERSAMPLE_RATIO_1; +} + +void MPL3115A2::Barometric_Mode( void) +{ + unsigned char t; + + Standby(); + readRegs( REG_CTRL_REG_1, &t, 1); + + // soft reset... + unsigned char data[2] = { REG_CTRL_REG_1, t|0x04}; + writeRegs(data, 2); + wait( 0.2); + + Standby(); + readRegs( REG_CTRL_REG_1, &t, 1); + + data[0] = REG_CTRL_REG_1; + data[1] = t&0x7F; + writeRegs(data, 2); + + data[0] = REG_PT_DATA_CFG; + data[1] = 0x07; + writeRegs(data, 2); + + Oversample_Ratio( MPL3115A2_oversampling); + + Active(); + + MPL3115A2_mode = BAROMETRIC_MODE; +} + +void MPL3115A2::Altimeter_Mode( void) +{ + unsigned char t; + + Standby(); + readRegs( REG_CTRL_REG_1, &t, 1); + + // soft reset... + unsigned char data[2] = { REG_CTRL_REG_1, t|0x04}; + writeRegs(data, 2); + wait( 0.2); + + Standby(); + readRegs( REG_CTRL_REG_1, &t, 1); + + data[0] = REG_CTRL_REG_1; + data[1] = t|0x80; + writeRegs(data, 2); + + data[0] = REG_PT_DATA_CFG; + data[1] = 0x07; + writeRegs(data, 2); + + Oversample_Ratio( MPL3115A2_oversampling); + + Active(); + + MPL3115A2_mode = ALTIMETER_MODE; +} + +void MPL3115A2::Oversample_Ratio( unsigned int ratio) +{ + unsigned char t; + + Standby(); + readRegs( REG_CTRL_REG_1, &t, 1); + + t = t & 0xE7; + t = t | ( ratio<<3); + + unsigned char data[2] = { REG_CTRL_REG_1, t}; + writeRegs(data, 2); + + Active(); + + MPL3115A2_oversampling = ratio; +} + + +void MPL3115A2::Active( void) +{ + unsigned char t; + + // Activate the peripheral + readRegs(REG_CTRL_REG_1, &t, 1); + unsigned char data[2] = {REG_CTRL_REG_1, t|0x01}; + writeRegs(data, 2); +} + +void MPL3115A2::Standby( void) +{ + unsigned char t; + + // Standby + readRegs(REG_CTRL_REG_1, &t, 1); + unsigned char data[2] = {REG_CTRL_REG_1, t&0xFE}; + writeRegs(data, 2); +} + +unsigned char MPL3115A2::getDeviceID() { + unsigned char device_id = 0; + readRegs(REG_WHO_AM_I, &device_id, 1); + return device_id; +} + +unsigned int MPL3115A2::isDataAvailable( void) +{ + unsigned char status; + + readRegs( REG_STATUS, &status, 1); + + if ( status & 0x08) { + return 1; + } else { + return 0; + } + +} + +unsigned char MPL3115A2::getStatus( void) +{ + unsigned char status; + + readRegs( REG_STATUS, &status, 1); + return status; +} + +void MPL3115A2::getAllData( float *f) +{ + if ( MPL3115A2_mode == ALTIMETER_MODE) { + f[0] = getAltimeter(); + } else { + f[0] = getPressure(); + } + + f[1] = getTemperature(); +} + +float MPL3115A2::getAltimeter( void) +{ + unsigned char dt[3]; + unsigned short altm; + float faltm; + + /* + * dt[0] = Bits 12-19 of 20-bit real-time Pressure sample. (b7-b0) + * dt[1] = Bits 4-11 of 20-bit real-time Pressure sample. (b7-b0) + * dt[2] = Bits 0-3 of 20-bit real-time Pressure sample (b7-b4) + */ + readRegs( REG_ALTIMETER_MSB, &dt[0], 3); + altm = (dt[0]<<8) | dt[1]; + // + if ( dt[0] > 0x7F) { + altm = ~altm + 1; + faltm = (float)altm * -1.0f; + } else { + faltm = (float)altm * 1.0f; + } + // + faltm = faltm+((float)(dt[2]>>4) * 0.0625f); + return faltm; +} + +float MPL3115A2::getPressure( void) +{ + unsigned char dt[3]; + unsigned int prs; + float fprs; + + /* + * dt[0] = Bits 12-19 of 20-bit real-time Pressure sample. (b7-b0) + * dt[1] = Bits 4-11 of 20-bit real-time Pressure sample. (b7-b0) + * dt[2] = Bits 0-3 of 20-bit real-time Pressure sample (b7-b4) + */ + readRegs( REG_PRESSURE_MSB, &dt[0], 3); + prs = (dt[0]<<10) | (dt[1]<<2) | (dt[2]>>6); + // + fprs = (float)prs * 1.0f; + + if ( dt[2] & 0x20) + fprs += 0.25f; + if ( dt[2] & 0x10) + fprs += 0.5f; + + return fprs; +} + + +float MPL3115A2::getTemperature( void) +{ + unsigned char dt[2]; + unsigned short temp; + float ftemp; + + /* + * dt[0] = Bits 4-11 of 16-bit real-time temperature sample. (b7-b0) + * dt[1] = Bits 0-3 of 16-bit real-time temperature sample. (b7-b4) + */ + readRegs( REG_TEMP_MSB, &dt[0], 2); + temp = dt[0]; + // + if ( dt[0] > 0x7F) { + temp = ~temp + 1; + ftemp = (float)temp * -1.0f; + } else { + ftemp = (float)temp * 1.0f; + } + // + ftemp = ftemp+((float)(dt[1]>>4) * 0.0625f); + return ftemp; + +} + +void MPL3115A2::readRegs(int addr, uint8_t * data, int len) { + char t[1] = {addr}; + m_i2c.write(m_addr, t, 1, true); + m_i2c.read(m_addr, (char *)data, len); +} + +void MPL3115A2::writeRegs(uint8_t * data, int len) { + m_i2c.write(m_addr, (char *)data, len); +}