This is a BMP180 Library. Using "Timeout", so you do not need to use "wait".
BMP180.hpp
- Committer:
- Gaku0606
- Date:
- 2018-07-20
- Revision:
- 0:6953e7630b84
File content as of revision 0:6953e7630b84:
/** * @file BMP180.hpp * @brief This is a Library for BMP180 * @author Matsumoto Gaku * @date 2018/07/10 */ #pragma once #include "mbed.h" #define BMP180_AC1_H 0xAA #define BMP180_AC1_L 0xAB #define BMP180_AC2_H 0xAC #define BMP180_AC2_L 0xAD #define BMP180_AC3_H 0xAE #define BMP180_AC3_L 0xAF #define BMP180_AC4_H 0xB0 #define BMP180_AC4_L 0xB1 #define BMP180_AC5_H 0xB2 #define BMP180_AC5_L 0xB3 #define BMP180_AC6_H 0xB4 #define BMP180_AC6_L 0xB5 #define BMP180_B1_H 0xB6 #define BMP180_B1_L 0xB7 #define BMP180_B2_H 0xB8 #define BMP180_B2_L 0xB9 #define BMP180_MB_H 0xBA #define BMP180_MB_L 0xBB #define BMP180_MC_H 0xBC #define BMP180_MC_L 0xBD #define BMP180_MD_H 0xBE #define BMP180_MD_L 0xBF #define BMP180_SLAVEADDR 0b11101110 //#define BMP180_SLAVEADDR_READ 0xEF #define BMP180_OUT_MSB 0xF6 #define BMP180_OUT_LSB 0xF7 #define BMP180_OUT_XLSB 0xF8 #define BMP180_CTRL_MEAS 0xF4 #define BMP180_SOFT_REAST 0xE0 #define BMP180_ID 0xD0 /** * @brief BMP180 class */ class BMP180 { public: /** * @enum Enum * hardware accuracy modes * 測定モードの選択 */ enum MODE { ULTRA_LOW_POWER = 0x34, STANDARD = 0x74, HIGH_RESOLUTION = 0xB4, ULTRA_HIGH_RESOLUTION = 0xF4 }; /** * @brief BMP180 library's constructor * @param Pointer of User I2C */ BMP180(I2C &i2c) : _i2c(i2c){ ctrl_meas = ULTRA_HIGH_RESOLUTION; convertion_time = 25500; oss = 3; char coeff[22]; readReg(BMP180_SLAVEADDR, BMP180_AC1_H, coeff, 22); AC1 = ((uint16_t)coeff[0] << 8) | (uint16_t)coeff[1]; AC2 = ((uint16_t)coeff[2] << 8) | (uint16_t)coeff[3]; AC3 = ((uint16_t)coeff[4] << 8) | (uint16_t)coeff[5]; AC4 = ((uint16_t)coeff[6] << 8) | (uint16_t)coeff[7]; AC5 = ((uint16_t)coeff[8] << 8) | (uint16_t)coeff[9]; AC6 = ((uint16_t)coeff[10] << 8) | (uint16_t)coeff[11]; B1 = ((uint16_t)coeff[12] << 8) | (uint16_t)coeff[13]; B2 = ((uint16_t)coeff[14] << 8) | (uint16_t)coeff[15]; MB = ((uint16_t)coeff[16] << 8) | (uint16_t)coeff[17]; MC = ((uint16_t)coeff[18] << 8) | (uint16_t)coeff[19]; MD = ((uint16_t)coeff[20] << 8) | (uint16_t)coeff[21]; callFlag_press = 0; callFlag_temp = 0; pressure = 0.0f; temperature = 0.0f; }; /** * @brief Set hardware accurary modes * @param mode : ULTRA_HIGH_RESOLUTION etc. * @return connection status. if senser's ID could not read, return false. * @sa MODE */ bool begin(MODE mode) { switch (mode) { case BMP180::ULTRA_LOW_POWER: ctrl_meas = 0x34; oss = 0; convertion_time = 4500; break; case BMP180::STANDARD: ctrl_meas = 0x74; oss = 1; convertion_time = 7500; break; case BMP180::HIGH_RESOLUTION: ctrl_meas = 0xB4; oss = 2; convertion_time = 13500; break; case BMP180::ULTRA_HIGH_RESOLUTION: ctrl_meas = 0xF4; oss = 3; convertion_time = 25500; break; default: break; } //センサーチェック char result = readReg(BMP180_SLAVEADDR, BMP180_ID); if (result == 0x55) { return true; } else { return false; } } /** * @brief start measuring * @detail you have to read data after you excute this. */ void measure() { startTemperature(); } /** * @brief get pressure and temperature data * @param *press float variable pointer for pressure data * @param *temp float variable pointer for temperature data */ void readPressTemp(float *press, float *temp) { *press = pressure; *temp = temperature; } private: void startTemperature() { //測定開始 writeReg(BMP180_SLAVEADDR, BMP180_CTRL_MEAS, 0x2E); if (callFlag_temp) { callFlag_temp = 0; tempTimer.detach(); } //測定終了後にデータを取得する callFlag_temp = 1; tempTimer.attach_us(this, &BMP180::readTemperature, 4500); } void startPressure() { writeReg(BMP180_SLAVEADDR, BMP180_CTRL_MEAS, ctrl_meas); if (callFlag_press) { callFlag_press = 0; pressTimer.detach(); } callFlag_press = 1; pressTimer.attach_us(this, &BMP180::readPressure, convertion_time); } void readTemperature() { callFlag_temp = 0; char buff[2]; readReg(BMP180_SLAVEADDR, BMP180_OUT_MSB, buff,2); UT = (uint16_t)buff[0] << 8 | (uint16_t)buff[1]; startPressure(); } void readPressure() { char buff[3]; readReg(BMP180_SLAVEADDR, BMP180_OUT_MSB, buff, 3); UP = ((uint32_t)buff[0] << 16) | ((uint32_t)buff[1] << 8) | (uint32_t)buff[2]; UP = UP >> (8 - oss); //値更新 update pressure and tempsrature temperature = CaluculateTrueTemperature(); pressure = CaluculateTruePressure(); } //生の温度データを校正係数で補正する //raw temp data change to accurate data float CaluculateTrueTemperature() { X1 = ((UT - AC6) * AC5) >> 15; X2 = ((long)MC << 11) / (X1 + MD); B5 = X1 + X2; T = (B5 + 8) >> 4; return T * 0.1f; } //生の気圧データを校正係数で補正する //raw press data change to accurate data float CaluculateTruePressure() { B6 = B5 - 4000; X1 = (B2*((B6*B6) >> 12)) >> 11; X2 = AC2 * B6 >> 11; X3 = X1 + X2; B3 = (((AC1 * 4 + X3) << oss) + 2) >> 2; X1 = AC3 * B6 >> 13; X2 = (B1 * (B6*B6 > 12)) >> 16; X3 = ((X1 + X2) + 2) >> 2; B4 = AC4 * (unsigned long)(X3 + 32768) >> 15; B7 = ((unsigned long)UP - B3) * (50000 >> oss); if (B7 < 0x80000000) { P = (B7 << 1) / B4; } else { P = (B7 / B4) << 1; } X1 = (P >> 8) * (P >> 8); X1 = (X1 * 3038) >> 16; X2 = (-7357 * P) >> 16; P += (X1 + X2 + 3791) >> 4; return P * 0.01f;//to hPa } public: float pressure; float temperature; private: I2C _i2c; Timeout tempTimer; Timeout pressTimer; int callFlag_temp; int callFlag_press; //気圧取得時にctrl_measレジスタに設定する値 char ctrl_meas; //over sampling int oss; //変換にかかる時間[us] int convertion_time; short AC1; short AC2; short AC3; unsigned short AC4; unsigned short AC5; unsigned short AC6; short B1; short B2; short MB; short MC; short MD; //ビット演算ができるようにintでなくlong long UT; long UP; long X1; long X2; long B5; long T; long X3; long B3; unsigned long B4; long B6; unsigned long B7; long P; inline void writeReg(char addr, char data) { _i2c.write(addr, &data, 1, false); } inline void writeReg(char addr, char reg, char data) { char temp[2] = { reg, data }; _i2c.write(addr, temp, 2, false); } inline char readReg(char addr, char reg) { char buff[1]; writeReg(addr, reg); _i2c.read(addr | 1, buff, 1, true); return buff[0]; } inline void readReg(char addr, char start_reg, char* buff, char num) { writeReg(addr, start_reg); _i2c.read(addr | 1, buff, num, true); } };