First Commit

This commit is contained in:
Nigreon 2020-07-08 23:46:02 +02:00
commit d9897cb710
110 changed files with 21617 additions and 0 deletions

10
lib/BMP180MI/README.md Normal file
View file

@ -0,0 +1,10 @@
Yet Another Arduino BMP085 / BMP180 Digital Pressure Sensor Library
home: https://bitbucket.org/christandlg/bmp180mi
sensor: https://www.bosch-sensortec.com/bst/products/all_products/bmp180
Features:
- Supports I2C via the Wire library
- Supports other I2C libraries via inheritance
- Never blocks or delays (except for convenience functions)

View file

@ -0,0 +1,86 @@
// BMP180_I2C.ino
//
// shows how to use the BMP180MI library with the sensor connected using I2C.
//
// Copyright (c) 2018 Gregor Christandl
//
// connect the BMP180 to the Arduino like this:
// Arduino - BMC180
// 5V ------ VCC
// GND ----- GND
// SDA ----- SDA
// SCL ----- SCL
#include <Arduino.h>
#include <Wire.h>
#include <BMP180MI.h>
#define I2C_ADDRESS 0x77
//create an BMP180 object using the I2C interface
BMP180I2C bmp180(I2C_ADDRESS);
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
//wait for serial connection to open (only necessary on some boards)
while (!Serial);
Wire.begin();
//begin() initializes the interface, checks the sensor ID and reads the calibration parameters.
if (!bmp180.begin())
{
Serial.println("begin() failed. check your BMP180 Interface and I2C Address.");
while (1);
}
//reset sensor to default parameters.
bmp180.resetToDefaults();
//enable ultra high resolution mode for pressure measurements
bmp180.setSamplingMode(BMP180MI::MODE_UHR);
}
void loop() {
// put your main code here, to run repeatedly:
delay(1000);
//start a temperature measurement
if (!bmp180.measureTemperature())
{
Serial.println("could not start temperature measurement, is a measurement already running?");
return;
}
//wait for the measurement to finish. proceed as soon as hasValue() returned true.
do
{
delay(100);
} while (!bmp180.hasValue());
Serial.print("Temperature: ");
Serial.print(bmp180.getTemperature());
Serial.println(" degC");
//start a pressure measurement. pressure measurements depend on temperature measurement, you should only start a pressure
//measurement immediately after a temperature measurement.
if (!bmp180.measurePressure())
{
Serial.println("could not start perssure measurement, is a measurement already running?");
return;
}
//wait for the measurement to finish. proceed as soon as hasValue() returned true.
do
{
delay(100);
} while (!bmp180.hasValue());
Serial.print("Pressure: ");
Serial.print(bmp180.getPressure());
Serial.println(" Pa");
}

View file

@ -0,0 +1,175 @@
// BMP180_otherInterfaces.ino
//
// shows how to use the BMP180MI library with interfaces other than the native I2C or SPI interfaces.
//
// Copyright (c) 2018 Gregor Christandl
//
// connect the bmp180 to the Arduino like this:
// Arduino - bmp180
// 5V ------ VCC
// GND ----- GND
// SDA ----- SDA
// SCL ----- SCL
#include <Arduino.h>
#include <Wire.h>
#include <BMP180MI.h>
#define I2C_ADDRESS 0x77
//class derived from BMP180MI that implements communication using a library other than the native I2C library.
class BMP180Wire1 : public BMP180MI
{
public:
//constructor of the derived class.
//@param address i2c address of the sensor.
BMP180Wire1(uint8_t i2c_address) :
address_(i2c_address) //initialize the BMP180Wire1 classes private member address_ to the i2c address provided
{
//nothing else to do here...
}
private:
//this function must be implemented by derived classes. it is used to initialize the interface. first time communication
//test are not necessary - these checks are done by the BMP180MI class
//@return true on success, false otherwise.
bool beginInterface()
{
Wire1.begin();
return true;
}
//this function must be implemented by derived classes. this function is responsible for reading data from the sensor.
//@param reg register to read.
//@return read data (1 byte).
uint8_t readRegister(uint8_t reg)
{
#if defined(ARDUINO_SAM_DUE)
//workaround for Arduino Due. The Due seems not to send a repeated start with the code above, so this
//undocumented feature of Wire::requestFrom() is used. can be used on other Arduinos too (tested on Mega2560)
//see this thread for more info: https://forum.arduino.cc/index.php?topic=385377.0
Wire1.requestFrom(address_, 1, reg, 1, true);
#else
Wire1.beginTransmission(address_);
Wire1.write(reg);
Wire1.endTransmission(false);
Wire1.requestFrom(address_, static_cast<uint8_t>(1));
#endif
return Wire1.read();
}
//this function can be implemented by derived classes. implementing this function is optional.
//@param reg register to read.
//@param length number of registers to read (max: 4)
//@return read data. LSB = last register read.
uint32_t readRegisterBurst(uint8_t reg, uint8_t length)
{
if (length > 4)
return 0L;
uint32_t data = 0L;
#if defined(ARDUINO_SAM_DUE)
//workaround for Arduino Due. The Due seems not to send a repeated start with the code below, so this
//undocumented feature of Wire::requestFrom() is used. can be used on other Arduinos too (tested on Mega2560)
//see this thread for more info: https://forum.arduino.cc/index.php?topic=385377.0
Wire1.requestFrom(address_, length, data, length, true);
#else
Wire1.beginTransmission(address_);
Wire1.write(reg);
Wire1.endTransmission(false);
Wire1.requestFrom(address_, static_cast<uint8_t>(length));
for (uint8_t i = 0; i < length; i++)
{
data <<= 8;
data |= Wire1.read();
}
#endif
return data;
}
//this function must be implemented by derived classes. this function is responsible for sending data to the sensor.
//@param reg register to write to.
//@param data data to write to register.
void writeRegister(uint8_t reg, uint8_t data)
{
Wire1.beginTransmission(address_);
Wire1.write(reg);
Wire1.write(data);
Wire1.endTransmission();
}
uint8_t address_; //i2c address of sensor
};
//create an bmp180 object using the I2C interface, I2C address 0x77 and IRQ pin number 2
BMP180Wire1 bmp180(I2C_ADDRESS);
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
//wait for serial connection to open (only necessary on some boards)
while (!Serial);
//begin() initializes the interface, checks the sensor ID and reads the calibration parameters.
if (!bmp180.begin())
{
Serial.println("begin() failed. check your BMP180 Interface and I2C Address.");
while (1);
}
//reset sensor to default parameters.
bmp180.resetToDefaults();
//enable ultra high resolution mode for pressure measurements
bmp180.setSamplingMode(BMP180MI::MODE_UHR);
//...
}
void loop() {
// put your main code here, to run repeatedly:
delay(1000);
//start a temperature measurement
if (!bmp180.measureTemperature())
{
Serial.println("could not start temperature measurement, is a measurement already running?");
return;
}
//wait for the measurement to finish. proceed as soon as hasValue() returned true.
do
{
delay(100);
} while (!bmp180.hasValue());
Serial.print("Temperature: ");
Serial.print(bmp180.getTemperature());
Serial.println("degC");
//start a pressure measurement. pressure measurements depend on temperature measurement, you should only start a pressure
//measurement immediately after a temperature measurement.
if (!bmp180.measurePressure())
{
Serial.println("could not start perssure measurement, is a measurement already running?");
return;
}
//wait for the measurement to finish. proceed as soon as hasValue() returned true.
do
{
delay(100);
} while (!bmp180.hasValue());
Serial.print("Pressure: ");
Serial.print(bmp180.getPressure());
Serial.println("Pa");
}

25
lib/BMP180MI/keywords.txt Normal file
View file

@ -0,0 +1,25 @@
#######################################
# Syntax Coloring Map For ExampleLibrary
#######################################
#######################################
# Datatypes (KEYWORD1)
#######################################
BMP180MI KEYWORD1
BMP180I2C KEYWORD1
#######################################
# Methods and Functions (KEYWORD2)
#######################################
begin KEYWORD2
#######################################
# Instances (KEYWORD2)
#######################################
#######################################
# Constants (LITERAL1)
#######################################

View file

@ -0,0 +1,10 @@
name=BMP180MI
version=0.1.0
author=Gregor Christandl <christandlg@yahoo.com>
maintainer=Gregor Christandl <christandlg@yahoo.com>
sentence=A library for the Bosch Sensortec BMP085 / BMP180 Digital Pressure Sensors.
paragraph=The library supports I2C (via the Wire Library) interfaces. Use of other I2C libraries (e.g. software I2C) is supported by inheritance. Does not block or delay (except for convenience functions) making it better suited for applications where non-blocking behaviour is preferred.
category=Sensors
url=https://bitbucket.org/christandlg/bmp180mi
architectures=*
includes=BMP180MI.h

View file

@ -0,0 +1,396 @@
//Multi interface Bosch Sensortec BMP280 pressure sensor library
// Copyright (c) 2018 Gregor Christandl <christandlg@yahoo.com>
// home: https://bitbucket.org/christandlg/BMP180
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
#include "BMP180MI.h"
BMP180MI::BMP180MI() :
command_(0x00),
sampling_mode_(BMP180MI::MODE_ULP),
up_(0L),
ut_(0l),
B5_(0L)
{
cal_params_ = {
0, //cp_AC1_
0, //cp_AC2_
0, //cp_AC3_
0, //cp_AC4_
0, //cp_AC5_
0, //cp_AC6_
0, //cp_B1_
0, //cp_B2_
0, //cp_MB_
0, //cp_MC_
0, //cp_MD_
};
}
BMP180MI::~BMP180MI()
{
//nothing to do here...
}
bool BMP180MI::begin()
{
//return false if the interface could not be initialized.
if (!beginInterface())
return false;
//read sensor ID.
uint8_t id = readID();
//check sensor ID. return false if sensor ID does not match a BMP180 ID.
if (id != BMP180MI::BMP180_ID)
return false;
//read compensation parameters
cal_params_ = readCalibrationParameters();
return true;
}
bool BMP180MI::measurePressure()
{
//return false if a measurement is already running.
if (readRegisterValue(BMP180_REG_CTRL_MEAS, BMP180_MASK_SCO))
return false;
command_ = BMP180_CMD_PRESS;
//start a measurement. command includes the 'start of conversion' bit.
writeRegisterValue(BMP180_REG_CTRL_MEAS, BMP180_MASK_OSS | BMP180_MASK_SCO | BMP180_MASK_MCTRL, (sampling_mode_ << 6) | command_);
return true;
}
bool BMP180MI::measureTemperature()
{
//return false if a measurement is already running.
if (readRegisterValue(BMP180_REG_CTRL_MEAS, BMP180_MASK_SCO))
return false;
command_ = BMP180_CMD_TEMP;
//start a measurement. command includes the 'start of conversion' bit.
writeRegisterValue(BMP180_REG_CTRL_MEAS, BMP180_MASK_SCO | BMP180_MASK_MCTRL, command_);
return true;
}
bool BMP180MI::hasValue()
{
if (readRegisterValue(BMP180_REG_CTRL_MEAS, BMP180_MASK_SCO))
return false;
switch (command_)
{
case BMP180_CMD_PRESS:
up_ = static_cast<int32_t>(readRegisterValueBurst(BMP180_REG_OUT, BMP180_MASK_PRESS, 3));
up_ >>= (8 - sampling_mode_);
break;
case BMP180_CMD_TEMP:
ut_ = static_cast<int32_t>(readRegisterValueBurst(BMP180_REG_OUT, BMP180_MASK_TEMP, 2));
break;
default:
return false;
}
return true;
}
float BMP180MI::getPressure()
{
int32_t p = 0;
int32_t B6 = B5_ - 4000;
int32_t X1 = (static_cast<int32_t>(cal_params_.cp_B2_) * ((B6 * B6) >> 12)) >> 11;
int32_t X2 = (static_cast<int32_t>(cal_params_.cp_AC2_) * B6) >> 11;
int32_t X3 = X1 + X2;
int32_t B3 = ((((static_cast<int32_t>(cal_params_.cp_AC1_) << 2) + X3) << sampling_mode_) + 2) >> 2;
X1 = (static_cast<int32_t>(cal_params_.cp_AC3_) * B6) >> 13;
X2 = (static_cast<int32_t>(cal_params_.cp_B1_) * ((B6 * B6) >> 12)) >> 16;
X3 = (X1 + X2 + 2) >> 2;
uint32_t B4 = static_cast<uint32_t>(cal_params_.cp_AC4_) * (static_cast<uint32_t>(X3 + 32768)) >> 15;
uint32_t B7 = static_cast<uint32_t>(up_ - B3) * (50000 >> sampling_mode_);
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 = p + ((X1 + X2 + 3791) >> 4);
return static_cast<float>(p);
}
float BMP180MI::getTemperature()
{
int32_t X1 = ((ut_ - static_cast<int32_t>(cal_params_.cp_AC6_)) * static_cast<int32_t>(cal_params_.cp_AC5_)) >> 15;
int32_t X2 = (static_cast<int32_t>(cal_params_.cp_MC_) << 11) / (X1 + static_cast<int32_t>(cal_params_.cp_MD_));
B5_ = X1 + X2;
int32_t T = (B5_ + 8) >> 4;
return static_cast<float>(T) * 0.1;
}
float BMP180MI::readTemperature()
{
if (!measureTemperature())
return NAN;
do
{
delay(10);
} while (!hasValue());
return getTemperature();
}
float BMP180MI::readPressure()
{
if (isnan(readTemperature()))
return NAN;
if (!measurePressure())
return NAN;
do
{
delay(10);
} while (!hasValue());
return getPressure();
}
uint8_t BMP180MI::readID()
{
return readRegisterValue(BMP180_REG_ID, BMP180_MASK_ID);
}
BMP180MI::BMP180CalParams BMP180MI::readCalibrationParameters()
{
BMP180MI::BMP180CalParams cal_params = {
0, //cp_AC1_
0, //cp_AC2_
0, //cp_AC3_
0, //cp_AC4_
0, //cp_AC5_
0, //cp_AC6_
0, //cp_B1_
0, //cp_B2_
0, //cp_MB_
0, //cp_MC_
0, //cp_MD_
};
//read compensation parameters
cal_params.cp_AC1_ = static_cast<int16_t>(readRegisterValueBurst(BMP180_REG_CAL_AC1, BMP180_MASK_CAL, 2));
cal_params.cp_AC2_ = static_cast<int16_t>(readRegisterValueBurst(BMP180_REG_CAL_AC2, BMP180_MASK_CAL, 2));
cal_params.cp_AC3_ = static_cast<int16_t>(readRegisterValueBurst(BMP180_REG_CAL_AC3, BMP180_MASK_CAL, 2));
cal_params.cp_AC4_ = readRegisterValueBurst(BMP180_REG_CAL_AC4, BMP180_MASK_CAL, 2);
cal_params.cp_AC5_ = readRegisterValueBurst(BMP180_REG_CAL_AC5, BMP180_MASK_CAL, 2);
cal_params.cp_AC6_ = readRegisterValueBurst(BMP180_REG_CAL_AC6, BMP180_MASK_CAL, 2);
cal_params.cp_B1_ = static_cast<int16_t>(readRegisterValueBurst(BMP180_REG_CAL_B1, BMP180_MASK_CAL, 2));
cal_params.cp_B2_ = static_cast<int16_t>(readRegisterValueBurst(BMP180_REG_CAL_B2, BMP180_MASK_CAL, 2));
cal_params.cp_MB_ = static_cast<int16_t>(readRegisterValueBurst(BMP180_REG_CAL_MB, BMP180_MASK_CAL, 2));
cal_params.cp_MC_ = static_cast<int16_t>(readRegisterValueBurst(BMP180_REG_CAL_MC, BMP180_MASK_CAL, 2));
cal_params.cp_MD_ = static_cast<int16_t>(readRegisterValueBurst(BMP180_REG_CAL_MD, BMP180_MASK_CAL, 2));
return cal_params;
}
void BMP180MI::resetToDefaults()
{
writeRegister(BMP180_REG_RESET, BMP180_CMD_RESET);
}
uint8_t BMP180MI::getSamplingMode()
{
return sampling_mode_;
}
bool BMP180MI::setSamplingMode(uint8_t mode)
{
switch (mode)
{
case BMP180MI::MODE_ULP:
case BMP180MI::MODE_STD:
case BMP180MI::MODE_HR:
case BMP180MI::MODE_UHR:
sampling_mode_ = mode;
break;
default:
return false;
}
return true;
}
uint8_t BMP180MI::getMaskShift(uint8_t mask)
{
uint8_t return_value = 0;
//count how many times the mask must be shifted right until the lowest bit is set
if (mask != 0)
{
while (!(mask & 1))
{
return_value++;
mask >>= 1;
}
}
return return_value;
}
uint8_t BMP180MI::setMaskedBits(uint8_t reg, uint8_t mask, uint8_t value)
{
//clear mask bits in register
reg &= (~mask);
//set masked bits in register according to value
return ((value << getMaskShift(mask)) & mask) | reg;
}
uint8_t BMP180MI::readRegisterValue(uint8_t reg, uint8_t mask)
{
return getMaskedBits(readRegister(reg), mask);
}
void BMP180MI::writeRegisterValue(uint8_t reg, uint8_t mask, uint8_t value)
{
uint8_t reg_val = readRegister(reg);
writeRegister(reg, setMaskedBits(reg_val, mask, value));
}
uint32_t BMP180MI::readRegisterValueBurst(uint8_t reg, uint32_t mask, uint8_t length)
{
return getMaskedBits(readRegisterBurst(reg, length), mask);
}
uint32_t BMP180MI::readRegisterBurst(uint8_t reg, uint8_t length)
{
if (length > 4)
return 0L;
uint32_t data = 0L;
for (uint8_t i = 0; i < length; i++)
{
data <<= 8;
data |= static_cast<uint32_t>(readRegister(reg));
}
return data;
}
//-----------------------------------------------------------------------
//BMP180I2C
BMP180I2C::BMP180I2C(uint8_t i2c_address) :
address_(i2c_address)
{
//nothing to do here...
}
BMP180I2C::~BMP180I2C()
{
//nothing to do here...
}
bool BMP180I2C::beginInterface()
{
return true;
}
uint8_t BMP180I2C::readRegister(uint8_t reg)
{
#if defined(ARDUINO_SAM_DUE)
//workaround for Arduino Due. The Due seems not to send a repeated start with the code above, so this
//undocumented feature of Wire::requestFrom() is used. can be used on other Arduinos too (tested on Mega2560)
//see this thread for more info: https://forum.arduino.cc/index.php?topic=385377.0
Wire.requestFrom(address_, 1, reg, 1, true);
#else
Wire.beginTransmission(address_);
Wire.write(reg);
Wire.endTransmission(false);
Wire.requestFrom(address_, static_cast<uint8_t>(1));
#endif
return Wire.read();
}
uint32_t BMP180I2C::readRegisterBurst(uint8_t reg, uint8_t length)
{
if (length > 4)
return 0L;
uint32_t data = 0L;
#if defined(ARDUINO_SAM_DUE)
//workaround for Arduino Due. The Due seems not to send a repeated start with the code below, so this
//undocumented feature of Wire::requestFrom() is used. can be used on other Arduinos too (tested on Mega2560)
//see this thread for more info: https://forum.arduino.cc/index.php?topic=385377.0
Wire.requestFrom(address_, length, data, length, true);
#else
Wire.beginTransmission(address_);
Wire.write(reg);
Wire.endTransmission(false);
Wire.requestFrom(address_, static_cast<uint8_t>(length));
for (uint8_t i = 0; i < length; i++)
{
data <<= 8;
data |= Wire.read();
}
#endif
return data;
}
void BMP180I2C::writeRegister(uint8_t reg, uint8_t value)
{
Wire.beginTransmission(address_);
Wire.write(reg);
Wire.write(value);
Wire.endTransmission();
}

266
lib/BMP180MI/src/BMP180MI.h Normal file
View file

@ -0,0 +1,266 @@
//Multi interface Bosch Sensortec BMP180 pressure sensor library
// Copyright (c) 2018 Gregor Christandl <christandlg@yahoo.com>
// home: https://bitbucket.org/christandlg/BMP180mi
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
#ifndef BMP180MI_H_
#define BMP180MI_H_
#include <Arduino.h>
#include <Wire.h>
class BMP180MI
{
public:
//pressure oversampling modes
enum sampling_mode_t : uint8_t
{
MODE_ULP = 0, //1 sample, ~4.5ms conversion time
MODE_STD = 1, //2 samples, ~7.5ms conversion time
MODE_HR = 2, //4 samples, ~13.5ms conversion time
MODE_UHR = 3 //8 samples, ~25.5ms conversion time
};
//compensation parameters
struct BMP180CalParams {
int16_t cp_AC1_;
int16_t cp_AC2_;
int16_t cp_AC3_;
uint16_t cp_AC4_;
uint16_t cp_AC5_;
uint16_t cp_AC6_;
int16_t cp_B1_;
int16_t cp_B2_;
int16_t cp_MB_;
int16_t cp_MC_;
int16_t cp_MD_;
};
static const uint8_t BMP180_ID = 0x55;
BMP180MI();
virtual ~BMP180MI();
bool begin();
//starts a pressure measurement. must be called as soon as possible after a temperature measurement.
//returns false if a measurement is currently in progress.
//@return true on success, false otherwise.
bool measurePressure();
//starts a temperature measurement. returns false if a measurement
//is currently in progress.
//@return true on success, false otherwise.
bool measureTemperature();
//@return true if a measurement was completed, false otherwise.
bool hasValue();
//@return the last measured pressure, in Pa.
float getPressure();
//@return the last measured temperature, in deg C.
float getTemperature();
//triggers a temperature measurement and returns the measured temperature, in deg C.
//convenience function. blocks until temperature conversion is finished. do not use in time ciritical applications.
//@return temperature in deg C or NAN if the measurement failed.
float readTemperature();
//triggers a temperature measurement followed by a pressure measurement and returns the measured pressure, in Pa.
//convenience function. blocks until pressure conversion is finished. do not use in time ciritical applications.
//@return pressure in Pa or NAN if the measurement failed.
float readPressure();
//@return the ID of the BMP180. the sensor will always return 0x55, so this function
//can be used as a communication check.
uint8_t readID();
/*
@return BMP180CalParams struct containing BMP180 calibration parameters. */
BMP180CalParams readCalibrationParameters();
/*
resets all registers to default values. */
void resetToDefaults();
/*
@return sampling mode as sampling_mode_t. */
uint8_t getSamplingMode();
/*
@param sampling mode as sampling_mode_t.
@return true on success, false otherwise. */
bool setSamplingMode(uint8_t mode);
private:
enum BMP180_register_t : uint8_t
{
BMP180_REG_ID = 0xD0, //contains 0x55 after power on
BMP180_REG_RESET = 0xE0, //write 0xB6 to reset
BMP180_REG_STATUS = 0xF3, //bit 0: im_update, bit 3: measuring
BMP180_REG_CTRL_MEAS = 0xF4, //sets data acquisition options of device
BMP180_REG_CONFIG = 0xF5, //sets the rate, filter and interface options of the device.
BMP180_REG_OUT = 0xF6, //raw conversion results
BMP180_REG_CAL_AC1 = 0xAA, //2 bytes each. can never be 0x0000 or oxFFFF
BMP180_REG_CAL_AC2 = 0xAC,
BMP180_REG_CAL_AC3 = 0xAE,
BMP180_REG_CAL_AC4 = 0xB0,
BMP180_REG_CAL_AC5 = 0xB2,
BMP180_REG_CAL_AC6 = 0xB4,
BMP180_REG_CAL_B1 = 0xB6,
BMP180_REG_CAL_B2 = 0xB8,
BMP180_REG_CAL_MB = 0xBA,
BMP180_REG_CAL_MC = 0xBC,
BMP180_REG_CAL_MD = 0xBE,
};
enum BMP180_command_t : uint8_t
{
BMP180_CMD_TEMP = 0x2E, //start temperature conversion
BMP180_CMD_PRESS = 0x34, //start pressure conversion
};
enum BMP180_mask_t : uint8_t
{
//register 0xD0
BMP180_MASK_ID = 0b11111111,
//register 0xE0
BMP180_MASK_RESET = 0b11111111,
//register 0xF4
BMP180_MASK_OSS = 0b11000000,
BMP180_MASK_SCO = 0b00100000,
BMP180_MASK_MCTRL = 0b00011111,
};
enum BMP180_mask_32bit_t : uint32_t
{
//register 0xF6
BMP180_MASK_PRESS = 0x00FFFFFF, //20 bits
BMP180_MASK_TEMP = 0x0000FFFF, //16 bits
};
static const uint16_t BMP180_MASK_CAL = 0xFFFF;
static const uint8_t BMP180_CMD_RESET = 0xB6;
virtual bool beginInterface() = 0;
/*
@param mask
@return number of bits to shift value so it fits into mask. */
uint8_t getMaskShift(uint8_t mask);
/*
@param register value of register.
@param mask mask of value in register
@return value of masked bits. */
template <class T> T getMaskedBits(T reg, T mask)
{
//extract masked bits
return ((reg & mask) >> getMaskShift(mask));
};
/*
@param register value of register
@param mask mask of value in register
@param value value to write into masked area
@param register value with masked bits set to value. */
uint8_t setMaskedBits(uint8_t reg, uint8_t mask, uint8_t value);
/*
reads the masked value from the register.
@param reg register to read.
@param mask mask of value.
@return masked value in register. */
uint8_t readRegisterValue(uint8_t reg, uint8_t mask);
/*
sets values in a register.
@param reg register to set values in
@param mask bits of register to set value in
@param value value to set */
void writeRegisterValue(uint8_t reg, uint8_t mask, uint8_t value);
/*
reads the masked values from multiple registers. maximum read length is 4 bytes.
@param reg register to read.
@param mask mask of value.
@param length number of bytes to read
@return register content */
uint32_t readRegisterValueBurst(uint8_t reg, uint32_t mask, uint8_t length);
/*
reads a register from the sensor. must be overwritten by derived classes.
@param reg register to read.
@return register content*/
virtual uint8_t readRegister(uint8_t reg) = 0;
/*
reads a series of registers from the sensor. must be overwritten by derived classes.
@param reg register to read.
@param length number of bytes to read
@return register content*/
virtual uint32_t readRegisterBurst(uint8_t reg, uint8_t length);
/*
writes a register to the sensor. must be overwritten by derived classes.
this function is also used to send direct commands.
@param reg register to write to.
@param value value writeRegister write to register. */
virtual void writeRegister(uint8_t reg, uint8_t value) = 0;
BMP180CalParams cal_params_;
uint8_t command_;
uint8_t sampling_mode_;
int32_t up_;
int32_t ut_;
int32_t B5_;
};
class BMP180I2C : public BMP180MI
{
public:
BMP180I2C(uint8_t i2c_address);
virtual ~BMP180I2C();
private:
bool beginInterface();
uint8_t readRegister(uint8_t reg);
uint32_t readRegisterBurst(uint8_t reg, uint8_t length);
void writeRegister(uint8_t reg, uint8_t value);
uint8_t address_;
};
#endif /* BMP180MI_H_ */