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

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers MPL3115A2.cpp Source File

MPL3115A2.cpp

00001 #include "MPL3115A2.h"
00002 #include "mbed.h"
00003 
00004 #include "stdarg.h" // For debugOut use of the ... parameter and va_list
00005 
00006 MPL3115A2::MPL3115A2(I2C *i2c, Serial *pc) : _i2c(i2c), _debug(pc)
00007 {
00008 }
00009 
00010 // By default I set the sensor to altimeter mode. I inserted a 1ms pause 
00011 // between each call to allow logic capture if needed. This give a small
00012 // gap between captures on the bus to make working with the data easier.
00013 void MPL3115A2::init()
00014 {
00015     setModeStandby();
00016     wait_ms(1);
00017     setModeAltimeter();
00018     wait_ms(1);
00019     setOversampleRate(7);
00020     wait_ms(1);
00021     enableEventFlags();
00022     wait_ms(1);
00023     setModeActive();
00024     wait_ms(1);
00025 }
00026 
00027 // This method wait for a specified amount of time for one of the data
00028 // ready flags to be set. You need to pass in the correct data ready
00029 // mask for this to work. See page 22 of the datasheet.
00030 int MPL3115A2::dataReady(const char mask)
00031 {
00032     int attempts = 0;
00033  
00034     while ((i2cRead(STATUS) & mask) == 0)
00035     {
00036         attempts++;
00037         
00038         if(attempts > MAX_DATA_READY_ATTEMPTS) 
00039             return 0; // Failed
00040             
00041         wait_ms(1);
00042     }
00043     
00044     return 1; // Success
00045 }
00046 
00047 Altitude* MPL3115A2::readAltitude(Altitude* a)
00048 {
00049     // Force the sensor to take a new reading.
00050     toggleOneShot();
00051     
00052     // Wait for the data to be ready.
00053     if (!pressureDataReady())
00054     {
00055         debugOut("MPL3115A2::readAltitude: Sensor failed to generate an altitude reading in a reasonable time.\r\n");
00056         
00057         // We leave the altitude object as is if we encounter an error.
00058         return a;
00059     }
00060         
00061     // Get the new data from the sensor.
00062     _i2c->start();                              // Start
00063     if (_i2c->write(MPL3115A2_ADDRESS) != 1)    // A write to device
00064         debugOut("MPL3115A2::readAltitude: Sensor failed to respond to write request at address 0x%X\r\n", MPL3115A2_ADDRESS);
00065     
00066     if (_i2c->write(OUT_P_MSB) != 1)            // Register to read
00067         debugOut("MPL3115A2::readAltitude: Sensor at address 0x%X did not acknowledge register 0x%X\r\n", MPL3115A2_ADDRESS, OUT_P_MSB);
00068     
00069     // Write the data directly into our Altitude object. This object
00070     // takes care of converting the compressed data from the sensor, and
00071     // provides functions to get the data in various units. And it also
00072     // has a print function to output the data as a string.
00073     _i2c->read(MPL3115A2_ADDRESS, (*a), Altitude::size);
00074     a->setAltitude();
00075 
00076     return a;
00077 }
00078 
00079 // See readAltitude for comments about this function.
00080 Pressure* MPL3115A2::readPressure(Pressure* p)
00081 {
00082     toggleOneShot();
00083     
00084     if (!pressureDataReady())
00085     {
00086         debugOut("MPL3115A2::readPressure: Sensor failed to generate a pressure reading in a reasonable time.\r\n");
00087         return p;
00088     }
00089 
00090     _i2c->start(); 
00091     if (_i2c->write(MPL3115A2_ADDRESS) != 1)
00092         debugOut("MPL3115A2::readPressure: Sensor failed to respond to write request at address 0x%X\r\n", MPL3115A2_ADDRESS);
00093     
00094     if (_i2c->write(OUT_P_MSB) != 1) 
00095         debugOut("MPL3115A2::readPressure: Sensor at address 0x%X did not acknowledge register 0x%X\r\n", MPL3115A2_ADDRESS, OUT_P_MSB);
00096     
00097     _i2c->read(MPL3115A2_ADDRESS, (*p), Pressure::size);
00098     p->setPressure();
00099 
00100     return p;
00101 }
00102 
00103 // See readAltitude for comments about this function.
00104 Temperature* MPL3115A2::readTemperature(Temperature* t)
00105 {
00106     toggleOneShot();
00107 
00108     if (!temperatureDataReady())
00109     {
00110         debugOut("MPL3115A2::readTemperature: Sensor failed to generate a temperature reading in a reasonable time.\r\n");
00111         return t;
00112     }
00113 
00114     _i2c->start();  
00115     if (_i2c->write(MPL3115A2_ADDRESS) != 1)
00116         debugOut("MPL3115A2::readTemperature: Sensor failed to respond to write request at address 0x%X\r\n", MPL3115A2_ADDRESS);
00117     
00118     if (_i2c->write(OUT_T_MSB) != 1)        
00119         debugOut("MPL3115A2::readTemperature: Sensor at address 0x%X did not acknowledge register 0x%X\r\n", MPL3115A2_ADDRESS, OUT_P_MSB);
00120     
00121     _i2c->read(MPL3115A2_ADDRESS, (*t), Temperature::size);
00122     t->setTemperature();
00123     
00124     return t;
00125 }
00126 
00127 void MPL3115A2::setModeAltimeter()
00128 {
00129     setRegisterBit(CTRL_REG1, 0x80);    // Set ALT bit
00130 }
00131 
00132 void MPL3115A2::setModeBarometer()
00133 {
00134     clearRegisterBit(CTRL_REG1, 0x80);  // Clear ALT bit
00135 }
00136 
00137 void MPL3115A2::setModeStandby()
00138 {
00139     clearRegisterBit(CTRL_REG1, 0x01);  // Clear SBYB bit for Standby mode
00140 }
00141 void MPL3115A2::setModeActive()
00142 {
00143     setRegisterBit(CTRL_REG1, 0x01);    // Set SBYB bit for Active mode
00144 }
00145 
00146 void MPL3115A2::setOversampleRate(char sampleRate)
00147 {
00148     if(sampleRate > 7) 
00149         sampleRate = 7;                 // OS cannot be larger than 0b.0111
00150     
00151     sampleRate <<= 3;                   // Align it for the CTRL_REG1 register
00152   
00153     char temp = i2cRead(CTRL_REG1);     // Read current settings
00154     temp &= 0xC7;                       // Clear out old OS bits
00155     temp |= sampleRate;                 // Mask in new OS bits
00156     i2cWrite(CTRL_REG1, temp);
00157 }
00158 
00159 void MPL3115A2::enableEventFlags()
00160 {
00161     i2cWrite(PT_DATA_CFG, 0x07); // Enable all three pressure and temp event flags 
00162 }
00163 
00164 void MPL3115A2::toggleOneShot(void)
00165 {
00166     clearRegisterBit(CTRL_REG1, 0x02);  // Clear OST bit
00167     setRegisterBit(CTRL_REG1, 0x02);    // Set the OST bit.
00168 }
00169 
00170 void MPL3115A2::clearRegisterBit(const char regAddr, const char bitMask)
00171 {
00172     char temp = i2cRead(regAddr);   // Read the current register value
00173     temp &= ~bitMask;               // Clear the bit from the value
00174     i2cWrite(regAddr, temp);        // Write register value back
00175 }
00176 
00177 void MPL3115A2::setRegisterBit(const char regAddr, const char bitMask)
00178 {
00179     char temp = i2cRead(regAddr);   // Read the current register value
00180     temp |= bitMask;                // Set the bit in the value
00181     i2cWrite(regAddr, temp);        // Write register value back
00182 }
00183 
00184 char MPL3115A2::i2cRead(char regAddr)
00185 {
00186     _i2c->start();                              // Start
00187     if (_i2c->write(MPL3115A2_ADDRESS)!=1)      // A write to device
00188         debugOut("MPL3115A2::i2cRead: Sensor failed to respond to write request at address 0x%X\r\n", MPL3115A2_ADDRESS);
00189     
00190     if (_i2c->write(regAddr)!=1)                // Register to read
00191         debugOut("MPL3115A2::i2cRead: Sensor at address 0x%X did not acknowledge register 0x%X\r\n", MPL3115A2_ADDRESS, regAddr);
00192     
00193     _i2c->start();                  
00194     if (_i2c->write(MPL3115A2_ADDRESS|0x01)!=1) // Read from device
00195         debugOut("MPL3115A2::i2cRead: Sensor failed to respond to read request at address 0x%X\r\n", MPL3115A2_ADDRESS);
00196 
00197     char result = _i2c->read(READ_NAK);         // Read the data
00198     _i2c->stop();
00199     
00200     return result;  
00201 }
00202 
00203 void MPL3115A2::i2cWrite(char regAddr, char value)
00204 {
00205     char cmd[2];
00206     cmd[0] = regAddr;
00207     cmd[1] = value;
00208     if (_i2c->write(MPL3115A2_ADDRESS, cmd, 2) != 0)
00209         debugOut("MPL3115A2::i2cWrite: Failed writing value (%d, 0x%X) to register 0x%X\r\n", value, regAddr);    
00210 }
00211 
00212 void MPL3115A2::debugOut(const char * format, ...)
00213 {
00214     if (_debug == NULL)
00215         return;
00216         
00217     va_list arg;
00218     _debug->printf(format, arg);
00219 }