you can use LPS25HB sensor on mbed. i2c

Dependents:   read_Pmod optWingforHAPS_Eigen hexaTest_Eigen

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers LPS.cpp Source File

LPS.cpp

00001 #include "LPS.h"
00002 #include "mbed.h"
00003 
00004 // Defines ///////////////////////////////////////////////////////////
00005 
00006 // The Arduino two-wire interface uses a 7-bit number for the address,
00007 #define SA0_LOW_ADDRESS  0b1011100
00008 #define SA0_HIGH_ADDRESS 0b1011101
00009 
00010 #define TEST_REG_NACK -1
00011 
00012 #define LPS331AP_WHO_ID 0xBB
00013 #define LPS25H_WHO_ID   0xBD
00014 
00015 // Constructors //////////////////////////////////////////////////////
00016 
00017 LPS::LPS(I2C& p_i2c):_i2c(p_i2c)
00018 {
00019     _device = device_auto;
00020   
00021     // Pololu board pulls SA0 high, so default assumption is that it is
00022     // high
00023     address = SA0_HIGH_ADDRESS;
00024 }
00025 
00026 // Public Methods ////////////////////////////////////////////////////
00027 
00028 // sets or detects device type and slave address; returns bool indicating success
00029 bool LPS::init(deviceType device, uint8_t sa0)
00030 {
00031     if (!detectDeviceAndAddress(device, (sa0State)sa0))
00032         return false;
00033     
00034     switch (_device)
00035     {
00036         case device_25H:
00037         translated_regs[-INTERRUPT_CFG] = LPS25H_INTERRUPT_CFG;
00038         translated_regs[-INT_SOURCE]    = LPS25H_INT_SOURCE;
00039         translated_regs[-THS_P_L]       = LPS25H_THS_P_L;
00040         translated_regs[-THS_P_H]       = LPS25H_THS_P_H;
00041         return true;
00042         break;
00043       
00044         case device_331AP:
00045         translated_regs[-INTERRUPT_CFG] = LPS331AP_INTERRUPT_CFG;
00046         translated_regs[-INT_SOURCE]    = LPS331AP_INT_SOURCE;
00047         translated_regs[-THS_P_L]       = LPS331AP_THS_P_L;
00048         translated_regs[-THS_P_H]       = LPS331AP_THS_P_H;
00049         return true;
00050         break;
00051     }
00052     return true;
00053 }
00054 
00055 // turns on sensor and enables continuous output
00056 void LPS::enableDefault(void)
00057 {
00058     if (_device == device_25H)
00059     {
00060         // 0xB0 = 0b10110000
00061         // PD = 1 (active mode);  ODR = 011 (12.5 Hz pressure & temperature output data rate)
00062         writeReg(CTRL_REG1, 0xB0);
00063     }
00064     else if (_device == device_331AP)
00065     {
00066         // 0xE0 = 0b11100000
00067         // PD = 1 (active mode);  ODR = 110 (12.5 Hz pressure & temperature output data rate)
00068         writeReg(CTRL_REG1, 0xE0);
00069     }
00070 }
00071 
00072 // writes register
00073 void LPS::writeReg(char reg, char value)
00074 {
00075     // if dummy register address, look up actual translated address (based on device type)
00076     if (reg < 0)
00077     {
00078         reg = translated_regs[-reg];
00079     }
00080     char command[] = {reg,value};
00081     _i2c.write(address << 1,command,2);
00082 }
00083 
00084 // reads register
00085 int8_t LPS::readReg(char reg)
00086 {
00087     char value;
00088     // if dummy register address, look up actual translated address (based on device type)
00089     if(reg < 0)
00090     {
00091         reg = translated_regs[-reg];
00092     }
00093     _i2c.write(address << 1,&reg,1);
00094     _i2c.read((address << 1)|1,&value,1);
00095   
00096     return value;
00097 }
00098 
00099 // reads pressure in millibars (mbar)/hectopascals (hPa)
00100 float LPS::readPressureMillibars(void)
00101 {
00102     return (float)readPressureRaw() / 4096;
00103 }
00104 
00105 // reads pressure in inches of mercury (inHg)
00106 float LPS::readPressureInchesHg(void)
00107 {
00108     return (float)readPressureRaw() / 138706.5;
00109 }
00110 
00111 // reads pressure and returns raw 24-bit sensor output
00112 int32_t LPS::readPressureRaw(void)
00113 {
00114     // assert MSB to enable register address auto-increment
00115   
00116     char command = PRESS_OUT_XL | (1 << 7);
00117     char p[3];
00118     _i2c.write(address << 1,&command,1);
00119     _i2c.read((address << 1)| 1,p,3);
00120   
00121     // combine int8_ts
00122     return (int32_t)(int8_t)p[2] << 16 | (uint16_t)p[1] << 8 | p[0];
00123 }
00124 
00125 // reads temperature in degrees C
00126 float LPS::readTemperatureC(void)
00127 {
00128     return 42.5 + (float)readTemperatureRaw() / 480;
00129 }
00130 
00131 // reads temperature in degrees F
00132 float LPS::readTemperatureF(void)
00133 {
00134     return 108.5 + (float)readTemperatureRaw() / 480 * 1.8;
00135 }
00136 
00137 // reads temperature and returns raw 16-bit sensor output
00138 int16_t LPS::readTemperatureRaw(void)
00139 {
00140     char command = TEMP_OUT_L | (1 << 7);
00141   
00142     // assert MSB to enable register address auto-increment
00143     char t[2];
00144     _i2c.write(address << 1,&command,1);
00145     _i2c.read((address << 1)| 1,t,2);
00146 
00147     // combine bytes
00148     return (int16_t)(t[1] << 8 | t[0]);
00149 }
00150 
00151 // converts pressure in mbar to altitude in meters, using 1976 US
00152 // Standard Atmosphere model (note that this formula only applies to a
00153 // height of 11 km, or about 36000 ft)
00154 //  If altimeter setting (QNH, barometric pressure adjusted to sea
00155 //  level) is given, this function returns an indicated altitude
00156 //  compensated for actual regional pressure; otherwise, it returns
00157 //  the pressure altitude above the standard pressure level of 1013.25
00158 //  mbar or 29.9213 inHg
00159 float LPS::pressureToAltitudeMeters(double pressure_mbar, double altimeter_setting_mbar)
00160 {
00161     return (1 - pow(pressure_mbar / altimeter_setting_mbar, 0.190263)) * 44330.8;//pressure;
00162 }
00163 
00164 // converts pressure in inHg to altitude in feet; see notes above
00165 float LPS::pressureToAltitudeFeet(double pressure_inHg, double altimeter_setting_inHg)
00166 {
00167     return (1 - pow(pressure_inHg / altimeter_setting_inHg, 0.190263)) * 145442;//pressure;
00168 }
00169 
00170 // Private Methods ///////////////////////////////////////////////////
00171 
00172 bool LPS::detectDeviceAndAddress(deviceType device, sa0State sa0)
00173 {
00174     if (sa0 == sa0_auto || sa0 == sa0_high)
00175     {
00176         address = SA0_HIGH_ADDRESS;
00177         if (detectDevice(device)) return true;
00178     }
00179     if (sa0 == sa0_auto || sa0 == sa0_low)
00180     {
00181         address = SA0_LOW_ADDRESS;
00182         if (detectDevice(device)) return true;
00183     }
00184 
00185     return false;
00186 }
00187 
00188 bool LPS::detectDevice(deviceType device)
00189 {
00190     uint8_t id = testWhoAmI(address);
00191   
00192     if ((device == device_auto || device == device_25H) && id == (uint8_t)LPS25H_WHO_ID)
00193     {
00194         _device = device_25H;
00195         return true;
00196     }
00197     if ((device == device_auto || device == device_331AP) && id == (uint8_t)LPS331AP_WHO_ID)
00198     {
00199         _device = device_331AP;
00200         return true;
00201     }
00202 
00203     return false;
00204 }
00205 
00206 int LPS::testWhoAmI(uint8_t address)
00207 {
00208     char command = WHO_AM_I;
00209     char status = 0;
00210     _i2c.write(address << 1,&command,1);
00211     _i2c.read((address << 1)| 1,&status,1);
00212     return status;
00213 }