-
Notifications
You must be signed in to change notification settings - Fork 497
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #152 from pimoroni/driver/bme280
Driver for BME280 and BMP280
- Loading branch information
Showing
34 changed files
with
1,131 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
include(bme280.cmake) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
set(DRIVER_NAME bme280) | ||
add_library(${DRIVER_NAME} INTERFACE) | ||
|
||
target_sources(${DRIVER_NAME} INTERFACE | ||
${CMAKE_CURRENT_LIST_DIR}/bme280.cpp | ||
${CMAKE_CURRENT_LIST_DIR}/src/bme280.c) | ||
|
||
target_include_directories(${DRIVER_NAME} INTERFACE | ||
${CMAKE_CURRENT_LIST_DIR}/src | ||
${CMAKE_CURRENT_LIST_DIR}) | ||
|
||
target_link_libraries(${DRIVER_NAME} INTERFACE pico_stdlib hardware_i2c pimoroni_i2c) | ||
|
||
target_compile_definitions(${DRIVER_NAME} INTERFACE | ||
BME280_FLOAT_ENABLE | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
#include "bme280.hpp" | ||
#include "pico/stdlib.h" | ||
|
||
namespace pimoroni { | ||
bool BME280::init() { | ||
int8_t result; | ||
|
||
if(interrupt != PIN_UNUSED) { | ||
gpio_set_function(interrupt, GPIO_FUNC_SIO); | ||
gpio_set_dir(interrupt, GPIO_IN); | ||
gpio_pull_up(interrupt); | ||
} | ||
|
||
device.intf_ptr = new i2c_intf_ptr{.i2c = i2c, .address = address}; | ||
device.intf = bme280_intf::BME280_I2C_INTF; | ||
device.read = (bme280_read_fptr_t)&read_bytes; | ||
device.write = (bme280_write_fptr_t)&write_bytes; | ||
device.delay_us = (bme280_delay_us_fptr_t)&delay_us; | ||
|
||
result = bme280_init(&device); | ||
if(result != BME280_OK) return false; | ||
|
||
configure(BME280_FILTER_COEFF_2, BME280_STANDBY_TIME_0_5_MS, BME280_OVERSAMPLING_16X, BME280_OVERSAMPLING_2X, BME280_OVERSAMPLING_1X); | ||
|
||
return true; | ||
} | ||
|
||
bool BME280::configure(uint8_t filter, uint8_t standby_time, uint8_t os_pressure, uint8_t os_temp, uint8_t os_humidity, uint8_t mode) { | ||
int8_t result; | ||
|
||
settings.filter = filter; | ||
settings.standby_time = standby_time; | ||
settings.osr_p = os_pressure; | ||
settings.osr_t = os_temp; | ||
settings.osr_h = os_humidity; | ||
|
||
result = bme280_set_sensor_settings(BME280_ALL_SETTINGS_SEL, &device); | ||
if(result != BME280_OK) return false; | ||
|
||
result = bme280_set_sensor_mode(mode, &device); | ||
if(result != BME280_OK) return false; | ||
|
||
return true; | ||
} | ||
|
||
BME280::bme280_reading BME280::read_forced() { | ||
bme280_reading reading; | ||
int8_t result; | ||
|
||
reading.status = false; | ||
|
||
result = bme280_set_sensor_mode(BME280_FORCED_MODE, &device); | ||
if(result != BME280_OK) return reading; | ||
|
||
uint32_t req_delay = bme280_cal_meas_delay(&device.settings); | ||
device.delay_us(req_delay, device.intf_ptr); | ||
|
||
bme280_data data; | ||
reading.status = bme280_get_sensor_data(BME280_ALL, &data, &device) == BME280_OK; | ||
reading.temperature = data.temperature; | ||
reading.pressure = data.pressure; | ||
reading.humidity = data.humidity; | ||
return reading; | ||
} | ||
|
||
BME280::bme280_reading BME280::read() { | ||
bme280_reading reading; | ||
bme280_data data; | ||
reading.status = bme280_get_sensor_data(BME280_ALL, &data, &device) == BME280_OK; | ||
reading.temperature = data.temperature; | ||
reading.pressure = data.pressure; | ||
reading.humidity = data.humidity; | ||
return reading; | ||
} | ||
|
||
I2C* BME280::get_i2c() const { | ||
return i2c; | ||
} | ||
|
||
int BME280::get_int() const { | ||
return interrupt; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
#pragma once | ||
|
||
#include "hardware/i2c.h" | ||
#include "hardware/gpio.h" | ||
#include "src/bme280.h" | ||
#include "src/bme280_defs.h" | ||
#include "stdio.h" | ||
#include "common/pimoroni_i2c.hpp" | ||
|
||
namespace pimoroni { | ||
class BME280 { | ||
public: | ||
static const uint8_t DEFAULT_I2C_ADDRESS = 0x76; | ||
static const uint8_t ALTERNATE_I2C_ADDRESS = 0x77; | ||
static const uint8_t DEFAULT_INT_PIN = I2C_DEFAULT_INT; | ||
|
||
struct i2c_intf_ptr { | ||
I2C *i2c; | ||
int8_t address; | ||
}; | ||
|
||
struct bme280_reading { | ||
float temperature; | ||
float pressure; | ||
float humidity; | ||
bool status; | ||
}; | ||
|
||
bool debug = false; | ||
|
||
bool init(); | ||
bool configure(uint8_t filter, uint8_t standby_time, uint8_t os_pressure, uint8_t os_temp, uint8_t os_humidity, uint8_t mode=BME280_NORMAL_MODE); | ||
|
||
BME280() : BME280(new I2C()) {} | ||
BME280(uint8_t address) : BME280(new I2C(), address) {} | ||
BME280(I2C *i2c, uint8_t address = DEFAULT_I2C_ADDRESS, uint interrupt = PIN_UNUSED) : i2c(i2c), address(address), interrupt(interrupt) {} | ||
|
||
// For print access in micropython | ||
I2C* get_i2c() const; | ||
int get_int() const; | ||
|
||
bme280_reading read(); | ||
BME280::bme280_reading read_forced(); | ||
|
||
// Bindings for bme280_dev | ||
static int8_t write_bytes(uint8_t reg_addr, uint8_t *reg_data, uint16_t length, void *intf_ptr) { | ||
BME280::i2c_intf_ptr* i2c = (BME280::i2c_intf_ptr *)intf_ptr; | ||
|
||
uint8_t buffer[length + 1]; | ||
buffer[0] = reg_addr; | ||
for(int x = 0; x < length; x++) { | ||
buffer[x + 1] = reg_data[x]; | ||
} | ||
|
||
int result = i2c->i2c->write_blocking(i2c->address, buffer, length + 1, false); | ||
|
||
return result == PICO_ERROR_GENERIC ? BME280_E_COMM_FAIL : BME280_OK; | ||
}; | ||
|
||
static int8_t read_bytes(uint8_t reg_addr, uint8_t *reg_data, uint16_t length, void *intf_ptr) { | ||
BME280::i2c_intf_ptr* i2c = (BME280::i2c_intf_ptr *)intf_ptr; | ||
|
||
int result = i2c->i2c->write_blocking(i2c->address, ®_addr, 1, true); | ||
result = i2c->i2c->read_blocking(i2c->address, reg_data, length, false); | ||
|
||
return result == PICO_ERROR_GENERIC ? BME280_E_COMM_FAIL : BME280_OK; | ||
}; | ||
|
||
static void delay_us(uint32_t period, void *intf_ptr) { | ||
sleep_us(period); | ||
} | ||
|
||
private: | ||
bme280_dev device; | ||
bme280_settings settings; | ||
|
||
I2C *i2c; | ||
|
||
// interface pins with our standard defaults where appropriate | ||
int8_t address = DEFAULT_I2C_ADDRESS; | ||
uint interrupt = DEFAULT_INT_PIN; | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
include(bmp280.cmake) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
set(DRIVER_NAME bmp280) | ||
add_library(${DRIVER_NAME} INTERFACE) | ||
|
||
target_sources(${DRIVER_NAME} INTERFACE | ||
${CMAKE_CURRENT_LIST_DIR}/bmp280.cpp | ||
${CMAKE_CURRENT_LIST_DIR}/src/bmp280.c) | ||
|
||
target_include_directories(${DRIVER_NAME} INTERFACE | ||
${CMAKE_CURRENT_LIST_DIR}/src | ||
${CMAKE_CURRENT_LIST_DIR}) | ||
|
||
target_link_libraries(${DRIVER_NAME} INTERFACE pico_stdlib hardware_i2c pimoroni_i2c) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
#include "bmp280.hpp" | ||
#include "pico/stdlib.h" | ||
|
||
namespace pimoroni { | ||
bool BMP280::init() { | ||
int8_t result; | ||
|
||
if(interrupt != PIN_UNUSED) { | ||
gpio_set_function(interrupt, GPIO_FUNC_SIO); | ||
gpio_set_dir(interrupt, GPIO_IN); | ||
gpio_pull_up(interrupt); | ||
} | ||
|
||
device.intf_ptr = new i2c_intf_ptr{.i2c = i2c, .address = address}; | ||
device.intf = BMP280_I2C_INTF; | ||
device.read = (bmp280_com_fptr_t)&read_bytes; | ||
device.write = (bmp280_com_fptr_t)&write_bytes; | ||
device.delay_ms = (bmp280_delay_fptr_t)&delay_ms; | ||
|
||
result = bmp280_init(&device); | ||
if(result != BMP280_OK) return false; | ||
|
||
result = bmp280_set_config(&conf, &device); | ||
if(result != BMP280_OK) return false; | ||
|
||
configure(BMP280_FILTER_COEFF_2, BMP280_ODR_1000_MS, BMP280_OS_4X, BMP280_OS_4X); | ||
|
||
return true; | ||
} | ||
|
||
bool BMP280::configure(uint8_t filter, uint8_t odr, uint8_t os_pressure, uint8_t os_temp, uint8_t mode) { | ||
int8_t result; | ||
|
||
conf.filter = filter; | ||
conf.odr = odr; | ||
conf.os_pres = os_pressure; | ||
conf.os_temp = os_temp; | ||
|
||
result = bmp280_set_config(&conf, &device); | ||
if(result != BMP280_OK) return false; | ||
|
||
result = bmp280_set_power_mode(mode, &device); | ||
if(result != BMP280_OK) return false; | ||
|
||
return true; | ||
} | ||
|
||
BMP280::bmp280_reading BMP280::read() { | ||
bmp280_reading result; | ||
bmp280_get_uncomp_data(&ucomp_data, &device); | ||
|
||
int32_t temperature; | ||
result.status = bmp280_get_comp_temp_32bit(&temperature, ucomp_data.uncomp_temp, &device); | ||
result.temperature = 0.01f * temperature; | ||
|
||
result.status &= bmp280_get_comp_pres_32bit(&result.pressure, ucomp_data.uncomp_press, &device); | ||
|
||
return result; | ||
} | ||
|
||
I2C* BMP280::get_i2c() const { | ||
return i2c; | ||
} | ||
|
||
int BMP280::get_int() const { | ||
return interrupt; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
#pragma once | ||
|
||
#include "hardware/i2c.h" | ||
#include "hardware/gpio.h" | ||
#include "src/bmp280.h" | ||
#include "src/bmp280_defs.h" | ||
#include "stdio.h" | ||
#include "common/pimoroni_i2c.hpp" | ||
|
||
namespace pimoroni { | ||
class BMP280 { | ||
public: | ||
static const int8_t DEFAULT_I2C_ADDRESS = 0x76; | ||
static const uint8_t ALTERNATE_I2C_ADDRESS = 0x77; | ||
static const uint DEFAULT_INT_PIN = I2C_DEFAULT_INT; | ||
|
||
struct i2c_intf_ptr { | ||
I2C *i2c; | ||
int8_t address; | ||
}; | ||
|
||
struct bmp280_reading { | ||
double temperature; | ||
uint32_t pressure; | ||
bool status; | ||
}; | ||
|
||
bool debug = false; | ||
|
||
bool init(); | ||
bool configure(uint8_t filter, uint8_t odr, uint8_t os_pressure, uint8_t os_temp, uint8_t mode = BMP280_NORMAL_MODE); | ||
|
||
BMP280() : BMP280(new I2C()) {} | ||
BMP280(uint8_t address) : BMP280(new I2C(), address) {} | ||
BMP280(I2C *i2c, uint8_t address = DEFAULT_I2C_ADDRESS, uint interrupt = PIN_UNUSED) : i2c(i2c), address(address), interrupt(interrupt) {} | ||
|
||
// For print access in micropython | ||
I2C* get_i2c() const; | ||
int get_int() const; | ||
|
||
bmp280_reading read(); | ||
|
||
// Bindings for bmp280_dev | ||
static int8_t write_bytes(void *intf_ptr, uint8_t reg_addr, uint8_t *reg_data, uint16_t length) { | ||
BMP280::i2c_intf_ptr* i2c = (BMP280::i2c_intf_ptr *)intf_ptr; | ||
|
||
uint8_t buffer[length + 1]; | ||
buffer[0] = reg_addr; | ||
for(int x = 0; x < length; x++) { | ||
buffer[x + 1] = reg_data[x]; | ||
} | ||
|
||
int result = i2c->i2c->write_blocking(i2c->address, buffer, length + 1, false); | ||
|
||
return result == PICO_ERROR_GENERIC ? 1 : 0; | ||
}; | ||
|
||
static int8_t read_bytes(void *intf_ptr, uint8_t reg_addr, uint8_t *reg_data, uint16_t length) { | ||
BMP280::i2c_intf_ptr* i2c = (BMP280::i2c_intf_ptr *)intf_ptr; | ||
|
||
int result = i2c->i2c->write_blocking(i2c->address, ®_addr, 1, true); | ||
result = i2c->i2c->read_blocking(i2c->address, reg_data, length, false); | ||
|
||
return result == PICO_ERROR_GENERIC ? 1 : 0; | ||
}; | ||
|
||
static void delay_ms(uint32_t period, void *intf_ptr) { | ||
sleep_ms(period); | ||
} | ||
|
||
private: | ||
bmp280_dev device; | ||
bmp280_config conf; | ||
bmp280_uncomp_data ucomp_data; | ||
|
||
I2C *i2c; | ||
|
||
// interface pins with our standard defaults where appropriate | ||
int8_t address = DEFAULT_I2C_ADDRESS; | ||
uint interrupt = DEFAULT_INT_PIN; | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
include("${CMAKE_CURRENT_LIST_DIR}/bme280_basic.cmake") |
Oops, something went wrong.