Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Support for BMP280 Barometer Sensor #31

Open
wants to merge 1 commit into
base: upstream_shared
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
151 changes: 150 additions & 1 deletion Sensors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,155 @@ uint8_t Baro_update() { // first UT conversion is started in i
}
#endif

// ************************************************************************************************************
// I2C Barometer BOSCH BMP280
// ************************************************************************************************************
// I2C adress: 0x76 or 0x77 !!!Please make sure you set the correct address (BMP280_ADDR)
// ************************************************************************************************************

#if defined(BMP280)

#define BMP280_ADDR 0x76
#define i2c_read(ack) (ack) ? i2c_readAck() : i2c_readNak();

#define BMP280_CAL_REG_FIRST 0x88
#define BMP280_CAL_REG_LAST 0xA1
#define BMP280_CAL_DATA_SIZE (BMP280_CAL_REG_LAST+1 - BMP280_CAL_REG_FIRST)

#define BMP280_STATUS_REG 0xF3
#define BMP280_CONTROL_REG 0xF4
#define BMP280_CONFIG_REG 0xF5

#define BMP280_PRES_REG 0xF7
#define BMP280_TEMP_REG 0xFA
#define BMP280_RAWDATA_BYTES 6 // 3 bytes pressure, 3 bytes temperature

int64_t p; //temp variable for calculating pressure
uint32_t deadline;

static union _bmp280_cal_union {
uint8_t bytes[BMP280_CAL_DATA_SIZE];
struct {
uint16_t dig_t1;
int16_t dig_t2;
int16_t dig_t3;
uint16_t dig_p1;
int16_t dig_p2;
int16_t dig_p3;
int16_t dig_p4;
int16_t dig_p5;
int16_t dig_p6;
int16_t dig_p7;
int16_t dig_p8;
int16_t dig_p9;
};
} bmp280_cal;

/*
* read calibration registers
*/
static void bmp280_getcalibration(void)
{
memset(bmp280_cal.bytes, 0, sizeof(bmp280_cal));

i2c_read_reg_to_buf(BMP280_ADDR,
BMP280_CAL_REG_FIRST,
bmp280_cal.bytes,
BMP280_CAL_DATA_SIZE
);
}

void bmp280_set_ctrl(uint8_t osrs_t, uint8_t osrs_p, uint8_t mode)
{
i2c_writeReg(BMP280_ADDR, BMP280_CONTROL_REG,
((osrs_t & 0x7) << 5) | ((osrs_p & 0x7) << 2) | (mode & 0x3));
}

void bmp280_set_config(uint8_t t_sb, uint8_t filter, uint8_t spi3w_en)
{
i2c_writeReg(BMP280_ADDR, BMP280_CONFIG_REG,
((t_sb & 0x7) << 5) | ((filter & 0x7) << 2) | (spi3w_en & 1));
}

#define bmp280_24bit_reg(b1, b2, b3) ( \
((int32_t)(b1) << 16) \
| ((int32_t)(b2) << 8) \
| ((int32_t)(b3) ) \
)

/* Measures and calculates pressure and temperature
*
* This function updates global variables baroPressure and baroTemperature
*
* baroTemperature unit is 0.01 deg C
* baroPressure unit is Pa
*
*/

void bmp280_measure(void)
{
uint8_t data[BMP280_RAWDATA_BYTES];
int32_t temp_raw, pres_raw, t_fine;
int64_t var1, var2;

i2c_read_reg_to_buf(BMP280_ADDR, BMP280_PRES_REG, data, BMP280_RAWDATA_BYTES);
pres_raw = bmp280_24bit_reg(data[0], data[1], data[2]);
temp_raw = bmp280_24bit_reg(data[3], data[4], data[5]);

temp_raw >>= 4;
pres_raw >>= 4;

var1 = ((((temp_raw >> 3) - ((int32_t)bmp280_cal.dig_t1 << 1))) *
((int32_t)bmp280_cal.dig_t2)) >> 11;

var2 = (((((temp_raw >> 4) - ((int32_t)bmp280_cal.dig_t1)) *
((temp_raw >> 4) - ((int32_t)bmp280_cal.dig_t1))) >>12) *
((int32_t)bmp280_cal.dig_t3)) >> 14;

t_fine = var1 + var2;

baroTemperature = (t_fine * 5 + 128) >> 8;

var1 = ((int64_t)t_fine) - 128000;
var2 = var1 * var1 * (int64_t)bmp280_cal.dig_p6;
var2 = var2 + ((var1 * (int64_t)bmp280_cal.dig_p5) << 17);
var2 = var2 + (((int64_t)bmp280_cal.dig_p4) << 35);
var1 = ((var1 * var1 * (int64_t)bmp280_cal.dig_p3) >> 8) +
((var1 * (int64_t)bmp280_cal.dig_p2) << 12);
var1 = (((((int64_t)1) << 47) + var1)) * ((int64_t)bmp280_cal.dig_p1) >> 33;

if (var1 == 0) {
return 0; // avoid exception caused by division by zero
}
p = 1048576 - pres_raw;
p = (((p << 31) - var2) * 3125) / var1;
var1 = (((int64_t)bmp280_cal.dig_p9) * (p >> 13) * (p >> 13)) >> 25;
var2 = (((int64_t)bmp280_cal.dig_p8) * p) >> 19;

p = ((p + var1 + var2) >> 8) + (((int64_t)bmp280_cal.dig_p7) << 4);
baroPressure = p >> 8 ; //baroPressure in Pa

}

void Baro_init() {
bmp280_getcalibration();
bmp280_set_config(0, 4, 0); // 0.5 ms standby time, 16x filter, no 3-wire SPI
bmp280_set_ctrl(2, 5, 3); // T oversample x2, P over sample x16, normal mode
deadline = currentTime+5000;
}

//return 0: no data available, no computation ; 1: new value available and computation ;
uint8_t Baro_update() {
if (currentTime < deadline) return 0;
deadline = currentTime+3000;

Baro_Common();
bmp280_measure();

return 1;
}
#endif

// ************************************************************************************************************
// I2C Barometer MS561101BA
// ************************************************************************************************************
Expand Down Expand Up @@ -1536,4 +1685,4 @@ void initSensors() {
initS();
if (i2c_errors_count == 0) break; // no error during init => init ok
}
}
}
3 changes: 2 additions & 1 deletion config.h
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@

/* I2C barometer */
//#define BMP085
//#define BMP280
//#define MS561101BA

/* I2C magnetometer */
Expand Down Expand Up @@ -1228,4 +1229,4 @@ Also note, that maqgnetic declination changes with time, so recheck your value e
/*************************************************************************************************/

#endif /* CONFIG_H_ */

4 changes: 2 additions & 2 deletions def.h
Original file line number Diff line number Diff line change
Expand Up @@ -1686,7 +1686,7 @@
#define GYRO 0
#endif

#if defined(BMP085) || defined(MS561101BA)
#if defined(BMP085) || defined(BMP280) || defined(MS561101BA)
#define BARO 1
#else
#define BARO 0
Expand Down Expand Up @@ -2029,4 +2029,4 @@
#error "you use one feature that is no longer supported or has undergone a name change"
#endif

#endif /* DEF_H_ */
#endif /* DEF_H_ */