Library to wrapper most of the functions on the MPL3115A2 pressure and temperature sensor.

Dependents:   WeatherBalloon4180 WeatherBalloon4180 mbed_rifletool Smart_Watch_4180_Final_Design ... more

MPL3115A2 Precision Altimeter

This class wraps the functions of the MPL3115A2 sensor into a usable class that exposes most functions to your project. Functions that are not exposed can easily be added using the existing functions in this library. Specifically, I did not add any functions to handle FIFO logging or the use of either of the pin interrupts. This should not be too difficult to add if you need those features.

The motivation here was to get a set of support classes together that supported the chip and could be expanded on. With this library you can extract all relevant data from the sensor.

Be sure to download the DATASHEET and the App Note AN4519.

This library was created using the mbed NXP LPC11U24. Pins p27 and p28 were used for the I2C functions. Be sure to install 1K pull-up resistors on both lines. Also, if you're not using the SparkFun breakout board, be sure to use the right caps on the power pin. If you don't, the jitter can cause problems.

This library was inspired by the similar library available for the Arduino written by Nathan Seidle at SparkFun. I copied some of the number crunching routines and tried to follow his style of coding for the library. That way users of Arduinos could step into this library a little easier.

Below is some sample code that outputs the sensor data to a serial debug terminal window. If you have a logic analyzer, like the Saleae Logic, then you might not need the debug terminal window. If you still need the serial driver for your mbed, you can get it here.

Sample Code

#include "mbed.h"
#include "MPL3115A2.h"

I2C i2c(p28, p27);       // sda, scl

// Comment out all of the references to 'pc' on this page if you don't have the 
// serial debug driver for your mbed board installed on your computer. If you do,
// I personally like to use Putty as the terminal window to capture debug messages.
Serial pc(USBTX, USBRX); // tx, rx

// Again, remove the '&pc' parameter is you're not debugging.
MPL3115A2 sensor(&i2c, &pc);

DigitalOut myled(LED1);     // Sanity check to make sure the program is working.
DigitalOut powerPin(p21);   // <-- I powered the sensor from a pin. You don't have to.

int main() {
    
    powerPin = 1;
    wait_ms(300);

    pc.printf("** MPL3115A2 SENSOR **\r\n");

    sensor.init();

    pc.printf("Who Am I: 0x%X\r\n", sensor.whoAmI());

    Altitude a;
    Temperature t;
    Pressure p;
    
    // Offsets for Dacula, GA
    sensor.setOffsetAltitude(83);
    sensor.setOffsetTemperature(20);
    sensor.setOffsetPressure(-32);
    
    while(1) 
    {
        sensor.readAltitude(&a);
        sensor.readTemperature(&t);
        
        sensor.setModeStandby();
        sensor.setModeBarometer();
        sensor.setModeActive();
        sensor.readPressure(&p);
        
        pc.printf("Altitude: %sft, Temp: %sºF, Pressure: %sPa\r\n", a.print(), t.print(), p.print());
        pc.printf("OFF_H: 0x%X, OFF_T: 0x%X, OFF_P: 0x%X\r\n", sensor.offsetAltitude(), sensor.offsetTemperature(), sensor.offsetPressure());
    
        myled = 1;
        wait(5);
        myled = 0;
        wait(5);

        sensor.setModeStandby();
        sensor.setModeAltimeter();
        sensor.setModeActive();
    }
}
Committer:
sophtware
Date:
Wed Apr 02 12:59:44 2014 +0000
Revision:
3:7c7c1ea6fc33
Updated documentation.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
sophtware 0:beb43bc3d6d4 1 #include "MPL3115A2.h"
sophtware 0:beb43bc3d6d4 2 #include "mbed.h"
sophtware 0:beb43bc3d6d4 3
sophtware 0:beb43bc3d6d4 4 #include "stdarg.h" // For debugOut use of the ... parameter and va_list
sophtware 0:beb43bc3d6d4 5
sophtware 0:beb43bc3d6d4 6 MPL3115A2::MPL3115A2(I2C *i2c, Serial *pc) : _i2c(i2c), _debug(pc)
sophtware 0:beb43bc3d6d4 7 {
sophtware 0:beb43bc3d6d4 8 }
sophtware 0:beb43bc3d6d4 9
sophtware 0:beb43bc3d6d4 10 // By default I set the sensor to altimeter mode. I inserted a 1ms pause
sophtware 0:beb43bc3d6d4 11 // between each call to allow logic capture if needed. This give a small
sophtware 0:beb43bc3d6d4 12 // gap between captures on the bus to make working with the data easier.
sophtware 0:beb43bc3d6d4 13 void MPL3115A2::init()
sophtware 0:beb43bc3d6d4 14 {
sophtware 0:beb43bc3d6d4 15 setModeStandby();
sophtware 0:beb43bc3d6d4 16 wait_ms(1);
sophtware 0:beb43bc3d6d4 17 setModeAltimeter();
sophtware 0:beb43bc3d6d4 18 wait_ms(1);
sophtware 0:beb43bc3d6d4 19 setOversampleRate(7);
sophtware 0:beb43bc3d6d4 20 wait_ms(1);
sophtware 0:beb43bc3d6d4 21 enableEventFlags();
sophtware 0:beb43bc3d6d4 22 wait_ms(1);
sophtware 0:beb43bc3d6d4 23 setModeActive();
sophtware 0:beb43bc3d6d4 24 wait_ms(1);
sophtware 0:beb43bc3d6d4 25 }
sophtware 0:beb43bc3d6d4 26
sophtware 0:beb43bc3d6d4 27 // This method wait for a specified amount of time for one of the data
sophtware 0:beb43bc3d6d4 28 // ready flags to be set. You need to pass in the correct data ready
sophtware 0:beb43bc3d6d4 29 // mask for this to work. See page 22 of the datasheet.
sophtware 0:beb43bc3d6d4 30 int MPL3115A2::dataReady(const char mask)
sophtware 0:beb43bc3d6d4 31 {
sophtware 0:beb43bc3d6d4 32 int attempts = 0;
sophtware 0:beb43bc3d6d4 33
sophtware 0:beb43bc3d6d4 34 while ((i2cRead(STATUS) & mask) == 0)
sophtware 0:beb43bc3d6d4 35 {
sophtware 0:beb43bc3d6d4 36 attempts++;
sophtware 0:beb43bc3d6d4 37
sophtware 0:beb43bc3d6d4 38 if(attempts > MAX_DATA_READY_ATTEMPTS)
sophtware 0:beb43bc3d6d4 39 return 0; // Failed
sophtware 0:beb43bc3d6d4 40
sophtware 0:beb43bc3d6d4 41 wait_ms(1);
sophtware 0:beb43bc3d6d4 42 }
sophtware 0:beb43bc3d6d4 43
sophtware 0:beb43bc3d6d4 44 return 1; // Success
sophtware 0:beb43bc3d6d4 45 }
sophtware 0:beb43bc3d6d4 46
sophtware 0:beb43bc3d6d4 47 Altitude* MPL3115A2::readAltitude(Altitude* a)
sophtware 0:beb43bc3d6d4 48 {
sophtware 0:beb43bc3d6d4 49 // Force the sensor to take a new reading.
sophtware 0:beb43bc3d6d4 50 toggleOneShot();
sophtware 0:beb43bc3d6d4 51
sophtware 0:beb43bc3d6d4 52 // Wait for the data to be ready.
sophtware 0:beb43bc3d6d4 53 if (!pressureDataReady())
sophtware 0:beb43bc3d6d4 54 {
sophtware 0:beb43bc3d6d4 55 debugOut("MPL3115A2::readAltitude: Sensor failed to generate an altitude reading in a reasonable time.\r\n");
sophtware 0:beb43bc3d6d4 56
sophtware 0:beb43bc3d6d4 57 // We leave the altitude object as is if we encounter an error.
sophtware 0:beb43bc3d6d4 58 return a;
sophtware 0:beb43bc3d6d4 59 }
sophtware 0:beb43bc3d6d4 60
sophtware 0:beb43bc3d6d4 61 // Get the new data from the sensor.
sophtware 0:beb43bc3d6d4 62 _i2c->start(); // Start
sophtware 0:beb43bc3d6d4 63 if (_i2c->write(MPL3115A2_ADDRESS) != 1) // A write to device
sophtware 0:beb43bc3d6d4 64 debugOut("MPL3115A2::readAltitude: Sensor failed to respond to write request at address 0x%X\r\n", MPL3115A2_ADDRESS);
sophtware 0:beb43bc3d6d4 65
sophtware 0:beb43bc3d6d4 66 if (_i2c->write(OUT_P_MSB) != 1) // Register to read
sophtware 0:beb43bc3d6d4 67 debugOut("MPL3115A2::readAltitude: Sensor at address 0x%X did not acknowledge register 0x%X\r\n", MPL3115A2_ADDRESS, OUT_P_MSB);
sophtware 0:beb43bc3d6d4 68
sophtware 0:beb43bc3d6d4 69 // Write the data directly into our Altitude object. This object
sophtware 0:beb43bc3d6d4 70 // takes care of converting the compressed data from the sensor, and
sophtware 0:beb43bc3d6d4 71 // provides functions to get the data in various units. And it also
sophtware 0:beb43bc3d6d4 72 // has a print function to output the data as a string.
sophtware 0:beb43bc3d6d4 73 _i2c->read(MPL3115A2_ADDRESS, (*a), Altitude::size);
sophtware 0:beb43bc3d6d4 74 a->setAltitude();
sophtware 0:beb43bc3d6d4 75
sophtware 0:beb43bc3d6d4 76 return a;
sophtware 0:beb43bc3d6d4 77 }
sophtware 0:beb43bc3d6d4 78
sophtware 0:beb43bc3d6d4 79 // See readAltitude for comments about this function.
sophtware 0:beb43bc3d6d4 80 Pressure* MPL3115A2::readPressure(Pressure* p)
sophtware 0:beb43bc3d6d4 81 {
sophtware 0:beb43bc3d6d4 82 toggleOneShot();
sophtware 0:beb43bc3d6d4 83
sophtware 0:beb43bc3d6d4 84 if (!pressureDataReady())
sophtware 0:beb43bc3d6d4 85 {
sophtware 0:beb43bc3d6d4 86 debugOut("MPL3115A2::readPressure: Sensor failed to generate a pressure reading in a reasonable time.\r\n");
sophtware 0:beb43bc3d6d4 87 return p;
sophtware 0:beb43bc3d6d4 88 }
sophtware 0:beb43bc3d6d4 89
sophtware 0:beb43bc3d6d4 90 _i2c->start();
sophtware 0:beb43bc3d6d4 91 if (_i2c->write(MPL3115A2_ADDRESS) != 1)
sophtware 0:beb43bc3d6d4 92 debugOut("MPL3115A2::readPressure: Sensor failed to respond to write request at address 0x%X\r\n", MPL3115A2_ADDRESS);
sophtware 0:beb43bc3d6d4 93
sophtware 0:beb43bc3d6d4 94 if (_i2c->write(OUT_P_MSB) != 1)
sophtware 0:beb43bc3d6d4 95 debugOut("MPL3115A2::readPressure: Sensor at address 0x%X did not acknowledge register 0x%X\r\n", MPL3115A2_ADDRESS, OUT_P_MSB);
sophtware 0:beb43bc3d6d4 96
sophtware 0:beb43bc3d6d4 97 _i2c->read(MPL3115A2_ADDRESS, (*p), Pressure::size);
sophtware 0:beb43bc3d6d4 98 p->setPressure();
sophtware 0:beb43bc3d6d4 99
sophtware 0:beb43bc3d6d4 100 return p;
sophtware 0:beb43bc3d6d4 101 }
sophtware 0:beb43bc3d6d4 102
sophtware 0:beb43bc3d6d4 103 // See readAltitude for comments about this function.
sophtware 0:beb43bc3d6d4 104 Temperature* MPL3115A2::readTemperature(Temperature* t)
sophtware 0:beb43bc3d6d4 105 {
sophtware 0:beb43bc3d6d4 106 toggleOneShot();
sophtware 0:beb43bc3d6d4 107
sophtware 0:beb43bc3d6d4 108 if (!temperatureDataReady())
sophtware 0:beb43bc3d6d4 109 {
sophtware 0:beb43bc3d6d4 110 debugOut("MPL3115A2::readTemperature: Sensor failed to generate a temperature reading in a reasonable time.\r\n");
sophtware 0:beb43bc3d6d4 111 return t;
sophtware 0:beb43bc3d6d4 112 }
sophtware 0:beb43bc3d6d4 113
sophtware 0:beb43bc3d6d4 114 _i2c->start();
sophtware 0:beb43bc3d6d4 115 if (_i2c->write(MPL3115A2_ADDRESS) != 1)
sophtware 0:beb43bc3d6d4 116 debugOut("MPL3115A2::readTemperature: Sensor failed to respond to write request at address 0x%X\r\n", MPL3115A2_ADDRESS);
sophtware 0:beb43bc3d6d4 117
sophtware 0:beb43bc3d6d4 118 if (_i2c->write(OUT_T_MSB) != 1)
sophtware 0:beb43bc3d6d4 119 debugOut("MPL3115A2::readTemperature: Sensor at address 0x%X did not acknowledge register 0x%X\r\n", MPL3115A2_ADDRESS, OUT_P_MSB);
sophtware 0:beb43bc3d6d4 120
sophtware 0:beb43bc3d6d4 121 _i2c->read(MPL3115A2_ADDRESS, (*t), Temperature::size);
sophtware 0:beb43bc3d6d4 122 t->setTemperature();
sophtware 0:beb43bc3d6d4 123
sophtware 0:beb43bc3d6d4 124 return t;
sophtware 0:beb43bc3d6d4 125 }
sophtware 0:beb43bc3d6d4 126
sophtware 0:beb43bc3d6d4 127 void MPL3115A2::setModeAltimeter()
sophtware 0:beb43bc3d6d4 128 {
sophtware 0:beb43bc3d6d4 129 setRegisterBit(CTRL_REG1, 0x80); // Set ALT bit
sophtware 0:beb43bc3d6d4 130 }
sophtware 0:beb43bc3d6d4 131
sophtware 0:beb43bc3d6d4 132 void MPL3115A2::setModeBarometer()
sophtware 0:beb43bc3d6d4 133 {
sophtware 0:beb43bc3d6d4 134 clearRegisterBit(CTRL_REG1, 0x80); // Clear ALT bit
sophtware 0:beb43bc3d6d4 135 }
sophtware 0:beb43bc3d6d4 136
sophtware 0:beb43bc3d6d4 137 void MPL3115A2::setModeStandby()
sophtware 0:beb43bc3d6d4 138 {
sophtware 0:beb43bc3d6d4 139 clearRegisterBit(CTRL_REG1, 0x01); // Clear SBYB bit for Standby mode
sophtware 0:beb43bc3d6d4 140 }
sophtware 0:beb43bc3d6d4 141 void MPL3115A2::setModeActive()
sophtware 0:beb43bc3d6d4 142 {
sophtware 0:beb43bc3d6d4 143 setRegisterBit(CTRL_REG1, 0x01); // Set SBYB bit for Active mode
sophtware 0:beb43bc3d6d4 144 }
sophtware 0:beb43bc3d6d4 145
sophtware 0:beb43bc3d6d4 146 void MPL3115A2::setOversampleRate(char sampleRate)
sophtware 0:beb43bc3d6d4 147 {
sophtware 0:beb43bc3d6d4 148 if(sampleRate > 7)
sophtware 0:beb43bc3d6d4 149 sampleRate = 7; // OS cannot be larger than 0b.0111
sophtware 0:beb43bc3d6d4 150
sophtware 0:beb43bc3d6d4 151 sampleRate <<= 3; // Align it for the CTRL_REG1 register
sophtware 0:beb43bc3d6d4 152
sophtware 0:beb43bc3d6d4 153 char temp = i2cRead(CTRL_REG1); // Read current settings
sophtware 0:beb43bc3d6d4 154 temp &= 0xC7; // Clear out old OS bits
sophtware 0:beb43bc3d6d4 155 temp |= sampleRate; // Mask in new OS bits
sophtware 0:beb43bc3d6d4 156 i2cWrite(CTRL_REG1, temp);
sophtware 0:beb43bc3d6d4 157 }
sophtware 0:beb43bc3d6d4 158
sophtware 0:beb43bc3d6d4 159 void MPL3115A2::enableEventFlags()
sophtware 0:beb43bc3d6d4 160 {
sophtware 0:beb43bc3d6d4 161 i2cWrite(PT_DATA_CFG, 0x07); // Enable all three pressure and temp event flags
sophtware 0:beb43bc3d6d4 162 }
sophtware 0:beb43bc3d6d4 163
sophtware 0:beb43bc3d6d4 164 void MPL3115A2::toggleOneShot(void)
sophtware 0:beb43bc3d6d4 165 {
sophtware 0:beb43bc3d6d4 166 clearRegisterBit(CTRL_REG1, 0x02); // Clear OST bit
sophtware 0:beb43bc3d6d4 167 setRegisterBit(CTRL_REG1, 0x02); // Set the OST bit.
sophtware 0:beb43bc3d6d4 168 }
sophtware 0:beb43bc3d6d4 169
sophtware 0:beb43bc3d6d4 170 void MPL3115A2::clearRegisterBit(const char regAddr, const char bitMask)
sophtware 0:beb43bc3d6d4 171 {
sophtware 0:beb43bc3d6d4 172 char temp = i2cRead(regAddr); // Read the current register value
sophtware 0:beb43bc3d6d4 173 temp &= ~bitMask; // Clear the bit from the value
sophtware 0:beb43bc3d6d4 174 i2cWrite(regAddr, temp); // Write register value back
sophtware 0:beb43bc3d6d4 175 }
sophtware 0:beb43bc3d6d4 176
sophtware 0:beb43bc3d6d4 177 void MPL3115A2::setRegisterBit(const char regAddr, const char bitMask)
sophtware 0:beb43bc3d6d4 178 {
sophtware 0:beb43bc3d6d4 179 char temp = i2cRead(regAddr); // Read the current register value
sophtware 0:beb43bc3d6d4 180 temp |= bitMask; // Set the bit in the value
sophtware 0:beb43bc3d6d4 181 i2cWrite(regAddr, temp); // Write register value back
sophtware 0:beb43bc3d6d4 182 }
sophtware 0:beb43bc3d6d4 183
sophtware 0:beb43bc3d6d4 184 char MPL3115A2::i2cRead(char regAddr)
sophtware 0:beb43bc3d6d4 185 {
sophtware 0:beb43bc3d6d4 186 _i2c->start(); // Start
sophtware 0:beb43bc3d6d4 187 if (_i2c->write(MPL3115A2_ADDRESS)!=1) // A write to device
sophtware 0:beb43bc3d6d4 188 debugOut("MPL3115A2::i2cRead: Sensor failed to respond to write request at address 0x%X\r\n", MPL3115A2_ADDRESS);
sophtware 0:beb43bc3d6d4 189
sophtware 0:beb43bc3d6d4 190 if (_i2c->write(regAddr)!=1) // Register to read
sophtware 0:beb43bc3d6d4 191 debugOut("MPL3115A2::i2cRead: Sensor at address 0x%X did not acknowledge register 0x%X\r\n", MPL3115A2_ADDRESS, regAddr);
sophtware 0:beb43bc3d6d4 192
sophtware 0:beb43bc3d6d4 193 _i2c->start();
sophtware 0:beb43bc3d6d4 194 if (_i2c->write(MPL3115A2_ADDRESS|0x01)!=1) // Read from device
sophtware 0:beb43bc3d6d4 195 debugOut("MPL3115A2::i2cRead: Sensor failed to respond to read request at address 0x%X\r\n", MPL3115A2_ADDRESS);
sophtware 0:beb43bc3d6d4 196
sophtware 0:beb43bc3d6d4 197 char result = _i2c->read(READ_NAK); // Read the data
sophtware 0:beb43bc3d6d4 198 _i2c->stop();
sophtware 0:beb43bc3d6d4 199
sophtware 0:beb43bc3d6d4 200 return result;
sophtware 0:beb43bc3d6d4 201 }
sophtware 0:beb43bc3d6d4 202
sophtware 0:beb43bc3d6d4 203 void MPL3115A2::i2cWrite(char regAddr, char value)
sophtware 0:beb43bc3d6d4 204 {
sophtware 0:beb43bc3d6d4 205 char cmd[2];
sophtware 0:beb43bc3d6d4 206 cmd[0] = regAddr;
sophtware 0:beb43bc3d6d4 207 cmd[1] = value;
sophtware 0:beb43bc3d6d4 208 if (_i2c->write(MPL3115A2_ADDRESS, cmd, 2) != 0)
sophtware 0:beb43bc3d6d4 209 debugOut("MPL3115A2::i2cWrite: Failed writing value (%d, 0x%X) to register 0x%X\r\n", value, regAddr);
sophtware 0:beb43bc3d6d4 210 }
sophtware 0:beb43bc3d6d4 211
sophtware 0:beb43bc3d6d4 212 void MPL3115A2::debugOut(const char * format, ...)
sophtware 0:beb43bc3d6d4 213 {
sophtware 0:beb43bc3d6d4 214 if (_debug == NULL)
sophtware 0:beb43bc3d6d4 215 return;
sophtware 0:beb43bc3d6d4 216
sophtware 0:beb43bc3d6d4 217 va_list arg;
sophtware 0:beb43bc3d6d4 218 _debug->printf(format, arg);
sophtware 0:beb43bc3d6d4 219 }