commit
95081a1e9f
4 changed files with 369 additions and 179 deletions
|
@ -6,43 +6,55 @@
|
||||||
#include "FreeRTOS.h"
|
#include "FreeRTOS.h"
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
|
|
||||||
|
#include "i2c/i2c.h"
|
||||||
#include "bmp280/bmp280.h"
|
#include "bmp280/bmp280.h"
|
||||||
|
|
||||||
// In forced mode user initiate measurement each time.
|
// In forced mode user initiate measurement each time.
|
||||||
// In normal mode measurement is done continuously with specified standby time.
|
// In normal mode measurement is done continuously with specified standby time.
|
||||||
// #define MODE_FORCED
|
// #define MODE_FORCED
|
||||||
|
|
||||||
const uint8_t scl_pin = 5;
|
const uint8_t scl_pin = 0;
|
||||||
const uint8_t sda_pin = 4;
|
const uint8_t sda_pin = 2;
|
||||||
|
|
||||||
#ifdef MODE_FORCED
|
#ifdef MODE_FORCED
|
||||||
static void bmp280_task_forced(void *pvParameters)
|
static void bmp280_task_forced(void *pvParameters)
|
||||||
{
|
{
|
||||||
bmp280_params_t params;
|
bmp280_params_t params;
|
||||||
float pressure, temperature;
|
float pressure, temperature, humidity;
|
||||||
|
|
||||||
bmp280_init_default_params(¶ms);
|
bmp280_init_default_params(¶ms);
|
||||||
params.mode = BMP280_MODE_FORCED;
|
params.mode = BMP280_MODE_FORCED;
|
||||||
|
|
||||||
|
bmp280_t bmp280_dev;
|
||||||
|
bmp280_dev.i2c_addr = BMP280_I2C_ADDRESS_0;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
while (!bmp280_init(¶ms, scl_pin, sda_pin)) {
|
while (!bmp280_init(&bmp280_dev, ¶ms)) {
|
||||||
printf("BMP280 initialization failed\n");
|
printf("BMP280 initialization failed\n");
|
||||||
vTaskDelay(1000 / portTICK_RATE_MS);
|
vTaskDelay(1000 / portTICK_RATE_MS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool bme280p = bmp280_dev.id == BME280_CHIP_ID;
|
||||||
|
printf("BMP280: found %s\n", bme280p ? "BME280" : "BMP280");
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
vTaskDelay(1000 / portTICK_RATE_MS);
|
vTaskDelay(1000 / portTICK_RATE_MS);
|
||||||
if (!bmp280_force_measurement()) {
|
if (!bmp280_force_measurement(&bmp280_dev)) {
|
||||||
printf("Failed initiating measurement\n");
|
printf("Failed initiating measurement\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
while (bmp280_is_measuring()) {}; // wait for measurement to complete
|
// wait for measurement to complete
|
||||||
|
while (bmp280_is_measuring(&bmp280_dev)) {};
|
||||||
|
|
||||||
if (!bmp280_read(&temperature, &pressure)) {
|
if (!bmp280_read_float(&bmp280_dev, &temperature, &pressure, &humidity)) {
|
||||||
printf("Temperature/pressure reading failed\n");
|
printf("Temperature/pressure reading failed\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
printf("Pressure: %.2f Pa, Temperature: %.2f C\n", pressure, temperature);
|
printf("Pressure: %.2f Pa, Temperature: %.2f C", pressure, temperature);
|
||||||
|
if (bme280p)
|
||||||
|
printf(", Humidity: %.2f\n", humidity);
|
||||||
|
else
|
||||||
|
printf("\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,22 +62,33 @@ static void bmp280_task_forced(void *pvParameters)
|
||||||
static void bmp280_task_normal(void *pvParameters)
|
static void bmp280_task_normal(void *pvParameters)
|
||||||
{
|
{
|
||||||
bmp280_params_t params;
|
bmp280_params_t params;
|
||||||
float pressure, temperature;
|
float pressure, temperature, humidity;
|
||||||
|
|
||||||
bmp280_init_default_params(¶ms);
|
bmp280_init_default_params(¶ms);
|
||||||
|
|
||||||
|
bmp280_t bmp280_dev;
|
||||||
|
bmp280_dev.i2c_addr = BMP280_I2C_ADDRESS_0;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
while (!bmp280_init(¶ms, scl_pin, sda_pin)) {
|
while (!bmp280_init(&bmp280_dev, ¶ms)) {
|
||||||
printf("BMP280 initialization failed\n");
|
printf("BMP280 initialization failed\n");
|
||||||
vTaskDelay(1000 / portTICK_RATE_MS);
|
vTaskDelay(1000 / portTICK_RATE_MS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool bme280p = bmp280_dev.id == BME280_CHIP_ID;
|
||||||
|
printf("BMP280: found %s\n", bme280p ? "BME280" : "BMP280");
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
vTaskDelay(1000 / portTICK_RATE_MS);
|
vTaskDelay(1000 / portTICK_RATE_MS);
|
||||||
if (!bmp280_read(&temperature, &pressure)) {
|
if (!bmp280_read_float(&bmp280_dev, &temperature, &pressure, &humidity)) {
|
||||||
printf("Temperature/pressure reading failed\n");
|
printf("Temperature/pressure reading failed\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
printf("Pressure: %.2f Pa, Temperature: %.2f C\n", pressure, temperature);
|
printf("Pressure: %.2f Pa, Temperature: %.2f C", pressure, temperature);
|
||||||
|
if (bme280p)
|
||||||
|
printf(", Humidity: %.2f\n", humidity);
|
||||||
|
else
|
||||||
|
printf("\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -80,6 +103,8 @@ void user_init(void)
|
||||||
printf("SDK version : %s\n", sdk_system_get_sdk_version());
|
printf("SDK version : %s\n", sdk_system_get_sdk_version());
|
||||||
printf("GIT version : %s\n", GITSHORTREV);
|
printf("GIT version : %s\n", GITSHORTREV);
|
||||||
|
|
||||||
|
i2c_init(scl_pin, sda_pin);
|
||||||
|
|
||||||
#ifdef MODE_FORCED
|
#ifdef MODE_FORCED
|
||||||
xTaskCreate(bmp280_task_forced, (signed char *)"bmp280_task", 256, NULL, 2, NULL);
|
xTaskCreate(bmp280_task_forced, (signed char *)"bmp280_task", 256, NULL, 2, NULL);
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
# Driver for BMP280 absolute barometric pressure sensor
|
# Driver for BMP280 and BME280 absolute barometric pressure sensors
|
||||||
|
|
||||||
The driver works only with BMP280 sensor. For BMP080/BMP180 there's a separate
|
The driver works only with BMP280 and BME280 sensors. For BMP080/BMP180 there's
|
||||||
driver. Even though BMP280 is a successor of BMP180 they are not compatible.
|
a separate driver. Even though BMP280 is a successor of BMP180 they are not
|
||||||
They have different registers and different operation modes.
|
compatible. They have different registers and different operation modes.
|
||||||
BMP280 supports two ways of communication: spi and i2c.
|
BMP280 supports two ways of communication: spi and i2c. This driver provides
|
||||||
This driver provides only i2c communication.
|
only i2c communication.
|
||||||
The driver is written for [esp-open-rtos](https://github.com/SuperHouse/esp-open-rtos)
|
The driver is written for [esp-open-rtos](https://github.com/SuperHouse/esp-open-rtos)
|
||||||
framework and requires [i2c driver](https://github.com/SuperHouse/esp-open-rtos/tree/master/extras/i2c)
|
framework and requires [i2c driver](https://github.com/SuperHouse/esp-open-rtos/tree/master/extras/i2c)
|
||||||
from it.
|
from it.
|
||||||
|
@ -18,17 +18,21 @@ from it.
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
Connect BMP280 module to you ESP8266 module and specify SCL and SDA pins:
|
Connect BMP280 or BME280 module to you ESP8266 module and initialize the I2C SCL and SDA pins:
|
||||||
|
|
||||||
```
|
```
|
||||||
const uint8_t scl_pin = 5;
|
const uint8_t scl_pin = 0;
|
||||||
const uint8_t sda_pin = 4;
|
const uint8_t sda_pin = 2;
|
||||||
|
i2c_init(scl_pin, sda_pin);
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Pull up SDO pin of BMP280 in order to have address 0x77.
|
Pull up SDO pin of BMP280 in order to have address 0x77 `BMP280_I2C_ADDRESS_1`.
|
||||||
Or pull down SDO pin and change `#define BMP280_ADDRESS 0x77` to
|
Or pull down SDO pin for address 0x76 `BMP280_I2C_ADDRESS_0`. Otherwise your
|
||||||
`#define BMP280_ADDRESS 0x76`. Otherwise your sensor will not work.
|
sensor will not work.
|
||||||
By default address 0x77 is used, so SDO pin should be high.
|
|
||||||
|
The BMP280 or BME280 are auto-detected at initialization based on the chip ID
|
||||||
|
and this ID is stored in the device descriptor.
|
||||||
|
|
||||||
BMP280 supports two operation modes.
|
BMP280 supports two operation modes.
|
||||||
|
|
||||||
|
@ -48,21 +52,26 @@ whose time is defined by standby_time.
|
||||||
### Forced mode
|
### Forced mode
|
||||||
|
|
||||||
```
|
```
|
||||||
const uint8_t scl_pin = 5;
|
|
||||||
const uint8_t sda_pin = 4;
|
|
||||||
bmp280_params_t params;
|
bmp280_params_t params;
|
||||||
float pressure, temperature;
|
float pressure, temperature, humidity;
|
||||||
|
|
||||||
bmp280_init_default_params(¶ms);
|
bmp280_init_default_params(¶ms);
|
||||||
params.mode = BMP280_MODE_FORCED;
|
params.mode = BMP280_MODE_FORCED;
|
||||||
bmp280_init(¶ms, scl_pin, sda_pin);
|
|
||||||
|
bmp280_t bmp280_dev;
|
||||||
|
bmp280_dev.i2c_addr = BMP280_I2C_ADDRESS_0;
|
||||||
|
bmp280_init(&bmp280_dev, ¶ms);
|
||||||
|
bool bme280p = bmp280_dev.id == BME280_CHIP_ID;
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
bmp280_force_measurement();
|
bmp280_force_measurement(&bmp280_dev));
|
||||||
while (bmp280_is_measuring()) {}; // wait for measurement to complete
|
// wait for measurement to complete
|
||||||
|
while (bmp280_is_measuring(&bmp280_dev)) {};
|
||||||
|
|
||||||
bmp280_read(&temperature, &pressure);
|
bmp280_read_float(&bmp280_dev, &temperature, &pressure, &humidity);
|
||||||
printf("Pressure: %.2f Pa, Temperature: %.2f C\n", pressure, temperature);
|
printf("Pressure: %.2f Pa, Temperature: %.2f C", pressure, temperature);
|
||||||
|
if (bme280p)
|
||||||
|
printf(", Humidity: %.2f\n", humidity);
|
||||||
vTaskDelay(1000 / portTICK_RATE_MS);
|
vTaskDelay(1000 / portTICK_RATE_MS);
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
@ -71,14 +80,22 @@ while (1) {
|
||||||
|
|
||||||
```
|
```
|
||||||
bmp280_params_t params;
|
bmp280_params_t params;
|
||||||
float pressure, temperature;
|
float pressure, temperature, humidity;
|
||||||
|
|
||||||
bmp280_init_default_params(¶ms);
|
bmp280_init_default_params(¶ms);
|
||||||
bmp280_init(¶ms, scl_pin, sda_pin);
|
|
||||||
|
bmp280_t bmp280_dev;
|
||||||
|
bmp280_dev.i2c_addr = BMP280_I2C_ADDRESS_0;
|
||||||
|
bmp280_init(&bmp280_dev, ¶ms);
|
||||||
|
bool bme280p = bmp280_dev.id == BME280_CHIP_ID;
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
bmp280_read(&temperature, &pressure);
|
bmp280_read_float(&bmp280_dev, &temperature, &pressure, &humidity);
|
||||||
printf("Pressure: %.2f Pa, Temperature: %.2f C\n", pressure, temperature);
|
printf("Pressure: %.2f Pa, Temperature: %.2f C", pressure, temperature);
|
||||||
|
if (bme280p)
|
||||||
|
printf(", Humidity: %.2f\n", humidity);
|
||||||
|
else
|
||||||
|
printf("\n");
|
||||||
vTaskDelay(1000 / portTICK_RATE_MS);
|
vTaskDelay(1000 / portTICK_RATE_MS);
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
|
@ -21,10 +21,10 @@
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
#include <stddef.h>
|
||||||
#include "bmp280.h"
|
#include "bmp280.h"
|
||||||
#include "i2c/i2c.h"
|
#include "i2c/i2c.h"
|
||||||
|
|
||||||
|
|
||||||
#ifdef BMP280_DEBUG
|
#ifdef BMP280_DEBUG
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#define debug(fmt, ...) printf("%s" fmt "\n", "bmp280: ", ## __VA_ARGS__);
|
#define debug(fmt, ...) printf("%s" fmt "\n", "bmp280: ", ## __VA_ARGS__);
|
||||||
|
@ -46,116 +46,150 @@
|
||||||
#define BMP280_REG_CONFIG 0xF5 /* bits: 7-5 t_sb; 4-2 filter; 0 spi3w_en */
|
#define BMP280_REG_CONFIG 0xF5 /* bits: 7-5 t_sb; 4-2 filter; 0 spi3w_en */
|
||||||
#define BMP280_REG_CTRL 0xF4 /* bits: 7-5 osrs_t; 4-2 osrs_p; 1-0 mode */
|
#define BMP280_REG_CTRL 0xF4 /* bits: 7-5 osrs_t; 4-2 osrs_p; 1-0 mode */
|
||||||
#define BMP280_REG_STATUS 0xF3 /* bits: 3 measuring; 0 im_update */
|
#define BMP280_REG_STATUS 0xF3 /* bits: 3 measuring; 0 im_update */
|
||||||
|
#define BMP280_REG_CTRL_HUM 0xF2 /* bits: 2-0 osrs_h; */
|
||||||
#define BMP280_REG_RESET 0xE0
|
#define BMP280_REG_RESET 0xE0
|
||||||
#define BMP280_REG_ID 0xD0
|
#define BMP280_REG_ID 0xD0
|
||||||
#define BMP280_REG_CALIB 0x88
|
#define BMP280_REG_CALIB 0x88
|
||||||
|
#define BMP280_REG_HUM_CALIB 0x88
|
||||||
|
|
||||||
|
|
||||||
#define BMP280_CHIP_ID 0x58 /* BMP280 has chip-id 0x58 */
|
|
||||||
#define BMP280_RESET_VALUE 0xB6
|
#define BMP280_RESET_VALUE 0xB6
|
||||||
|
|
||||||
typedef struct __attribute__((packed)) {
|
|
||||||
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_Calib;
|
|
||||||
|
|
||||||
static BMP280_Calib calib_data;
|
|
||||||
|
|
||||||
void bmp280_init_default_params(bmp280_params_t *params)
|
void bmp280_init_default_params(bmp280_params_t *params)
|
||||||
{
|
{
|
||||||
params->mode = BMP280_MODE_NORMAL;
|
params->mode = BMP280_MODE_NORMAL;
|
||||||
params->filter = BMP280_FILTER_OFF;
|
params->filter = BMP280_FILTER_OFF;
|
||||||
params->oversampling = BMP280_STANDARD;
|
params->oversampling = BMP280_STANDARD;
|
||||||
|
params->oversampling_humidity = BMP280_STANDARD;
|
||||||
params->standby = BMP280_STANDBY_250;
|
params->standby = BMP280_STANDBY_250;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint8_t read_register8(uint8_t addr)
|
static bool read_register16(uint8_t i2c_addr, uint8_t addr, uint16_t *value)
|
||||||
{
|
{
|
||||||
uint8_t r = 0;
|
uint8_t d[] = {0, 0};
|
||||||
if (!i2c_slave_read(BMP280_ADDRESS, addr, &r, 1)) {
|
if (i2c_slave_read(i2c_addr, addr, d, sizeof(d))) {
|
||||||
r = 0;
|
*value = d[0] | (d[1] << 8);
|
||||||
}
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Even though value is signed the actual value is always positive.
|
|
||||||
* So, no need to take care of sign bit.
|
|
||||||
*/
|
|
||||||
static bool read_register24(uint8_t addr, int32_t *value)
|
|
||||||
{
|
|
||||||
uint8_t d[] = {0, 0, 0};
|
|
||||||
if (i2c_slave_read(BMP280_ADDRESS, addr, d, sizeof(d))) {
|
|
||||||
*value = d[0];
|
|
||||||
*value <<= 8;
|
|
||||||
*value |= d[1];
|
|
||||||
*value <<= 4;
|
|
||||||
*value |= d[2]>>4;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool check_chip_id()
|
static bool read_calibration_data(bmp280_t *dev)
|
||||||
{
|
{
|
||||||
return (read_register8(BMP280_REG_ID)==BMP280_CHIP_ID);
|
uint8_t i2c_addr = dev->i2c_addr;
|
||||||
}
|
|
||||||
|
if (read_register16(i2c_addr, 0x88, &dev->dig_T1) &&
|
||||||
|
read_register16(i2c_addr, 0x8a, (uint16_t *)&dev->dig_T2) &&
|
||||||
|
read_register16(i2c_addr, 0x8c, (uint16_t *)&dev->dig_T3) &&
|
||||||
|
read_register16(i2c_addr, 0x8e, &dev->dig_P1) &&
|
||||||
|
read_register16(i2c_addr, 0x90, (uint16_t *)&dev->dig_P2) &&
|
||||||
|
read_register16(i2c_addr, 0x92, (uint16_t *)&dev->dig_P3) &&
|
||||||
|
read_register16(i2c_addr, 0x94, (uint16_t *)&dev->dig_P4) &&
|
||||||
|
read_register16(i2c_addr, 0x96, (uint16_t *)&dev->dig_P5) &&
|
||||||
|
read_register16(i2c_addr, 0x98, (uint16_t *)&dev->dig_P6) &&
|
||||||
|
read_register16(i2c_addr, 0x9a, (uint16_t *)&dev->dig_P7) &&
|
||||||
|
read_register16(i2c_addr, 0x9c, (uint16_t *)&dev->dig_P8) &&
|
||||||
|
read_register16(i2c_addr, 0x9e, (uint16_t *)&dev->dig_P9)) {
|
||||||
|
|
||||||
static bool read_calibration_data()
|
|
||||||
{
|
|
||||||
if (!i2c_slave_read(BMP280_ADDRESS, BMP280_REG_CALIB,
|
|
||||||
(uint8_t*)&calib_data, sizeof(calib_data))) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
debug("Calibration data received:");
|
debug("Calibration data received:");
|
||||||
debug("dig_T1=%d", calib_data.dig_T1);
|
debug("dig_T1=%d", dev->dig_T1);
|
||||||
debug("dig_T2=%d", calib_data.dig_T2);
|
debug("dig_T2=%d", dev->dig_T2);
|
||||||
debug("dig_T3=%d", calib_data.dig_T3);
|
debug("dig_T3=%d", dev->dig_T3);
|
||||||
debug("dig_P1=%d", calib_data.dig_P1);
|
debug("dig_P1=%d", dev->dig_P1);
|
||||||
debug("dig_P2=%d", calib_data.dig_P2);
|
debug("dig_P2=%d", dev->dig_P2);
|
||||||
debug("dig_P3=%d", calib_data.dig_P3);
|
debug("dig_P3=%d", dev->dig_P3);
|
||||||
debug("dig_P4=%d", calib_data.dig_P4);
|
debug("dig_P4=%d", dev->dig_P4);
|
||||||
debug("dig_P5=%d", calib_data.dig_P5);
|
debug("dig_P5=%d", dev->dig_P5);
|
||||||
debug("dig_P6=%d", calib_data.dig_P6);
|
debug("dig_P6=%d", dev->dig_P6);
|
||||||
debug("dig_P7=%d", calib_data.dig_P7);
|
debug("dig_P7=%d", dev->dig_P7);
|
||||||
debug("dig_P8=%d", calib_data.dig_P8);
|
debug("dig_P8=%d", dev->dig_P8);
|
||||||
debug("dig_P9=%d", calib_data.dig_P9);
|
debug("dig_P9=%d", dev->dig_P9);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool write_register8(uint8_t addr, uint8_t value)
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool read_hum_calibration_data(bmp280_t *dev)
|
||||||
|
{
|
||||||
|
uint8_t i2c_addr = dev->i2c_addr;
|
||||||
|
uint16_t h4, h5;
|
||||||
|
|
||||||
|
if (i2c_slave_read(i2c_addr, 0xa1, &dev->dig_H1, 1) &&
|
||||||
|
read_register16(i2c_addr, 0xe1, (uint16_t *)&dev->dig_H2) &&
|
||||||
|
i2c_slave_read(i2c_addr, 0xe3, &dev->dig_H3, 1) &&
|
||||||
|
read_register16(i2c_addr, 0xe4, &h4) &&
|
||||||
|
read_register16(i2c_addr, 0xe5, &h5) &&
|
||||||
|
i2c_slave_read(i2c_addr, 0xe7, (uint8_t *)&dev->dig_H6, 1)) {
|
||||||
|
dev->dig_H4 = (h4 & 0x00ff) << 4 | (h4 & 0x0f00) >> 8;
|
||||||
|
dev->dig_H5 = h5 >> 4;
|
||||||
|
debug("Calibration data received:");
|
||||||
|
debug("dig_H1=%d", dev->dig_H1);
|
||||||
|
debug("dig_H2=%d", dev->dig_H2);
|
||||||
|
debug("dig_H3=%d", dev->dig_H3);
|
||||||
|
debug("dig_H4=%d", dev->dig_H4);
|
||||||
|
debug("dig_H5=%d", dev->dig_H5);
|
||||||
|
debug("dig_H6=%d", dev->dig_H6);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool write_register8(uint8_t i2c_addr, uint8_t addr, uint8_t value)
|
||||||
{
|
{
|
||||||
uint8_t d[] = {addr, value};
|
uint8_t d[] = {addr, value};
|
||||||
|
|
||||||
return i2c_slave_write(BMP280_ADDRESS, d, 2);
|
return i2c_slave_write(i2c_addr, d, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool bmp280_init(bmp280_params_t *params, uint8_t scl_pin, uint8_t sda_pin)
|
bool bmp280_init(bmp280_t *dev, bmp280_params_t *params)
|
||||||
{
|
{
|
||||||
i2c_init(scl_pin, sda_pin);
|
uint8_t i2c_addr = dev->i2c_addr;
|
||||||
if (!check_chip_id()) {
|
|
||||||
debug("Sensor not found or wrong sensor version");
|
if (i2c_addr != BMP280_I2C_ADDRESS_0 && i2c_addr != BMP280_I2C_ADDRESS_1) {
|
||||||
|
debug("Invalid I2C address");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!read_calibration_data()) {
|
if (!i2c_slave_read(i2c_addr, BMP280_REG_ID, &dev->id, 1)) {
|
||||||
|
debug("Sensor not found");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dev->id != BMP280_CHIP_ID && dev->id != BME280_CHIP_ID) {
|
||||||
|
debug("Sensor wrong version");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Soft reset.
|
||||||
|
if (!write_register8(i2c_addr, BMP280_REG_RESET, BMP280_RESET_VALUE)) {
|
||||||
|
debug("Failed resetting sensor");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait until finished copying over the NVP data.
|
||||||
|
while (1) {
|
||||||
|
uint8_t status;
|
||||||
|
if (i2c_slave_read(i2c_addr, BMP280_REG_STATUS, &status, 1) && (status & 1) == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!read_calibration_data(dev)) {
|
||||||
debug("Failed to read calibration data");
|
debug("Failed to read calibration data");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (dev->id == BME280_CHIP_ID && !read_hum_calibration_data(dev)) {
|
||||||
|
debug("Failed to read humidity calibration data");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t config = (params->standby << 5) | (params->filter << 2);
|
uint8_t config = (params->standby << 5) | (params->filter << 2);
|
||||||
debug("Writing config reg=%x", config);
|
debug("Writing config reg=%x", config);
|
||||||
if (!write_register8(BMP280_REG_CONFIG, config)) {
|
if (!write_register8(i2c_addr, BMP280_REG_CONFIG, config)) {
|
||||||
debug("Failed configuring sensor");
|
debug("Failed configuring sensor");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -170,30 +204,46 @@ bool bmp280_init(bmp280_params_t *params, uint8_t scl_pin, uint8_t sda_pin)
|
||||||
uint8_t ctrl = (oversampling_temp << 5) | (params->oversampling << 2)
|
uint8_t ctrl = (oversampling_temp << 5) | (params->oversampling << 2)
|
||||||
| (params->mode);
|
| (params->mode);
|
||||||
|
|
||||||
debug("Writing ctrl reg=%x", ctrl);
|
|
||||||
if (!write_register8(BMP280_REG_CTRL, ctrl)) {
|
if (dev->id == BME280_CHIP_ID) {
|
||||||
|
// Write crtl hum reg first, only active after write to BMP280_REG_CTRL.
|
||||||
|
uint8_t ctrl_hum = params->oversampling_humidity;
|
||||||
|
debug("Writing ctrl hum reg=%x", ctrl_hum);
|
||||||
|
if (!write_register8(i2c_addr, BMP280_REG_CTRL_HUM, ctrl_hum)) {
|
||||||
debug("Failed controlling sensor");
|
debug("Failed controlling sensor");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
debug("Writing ctrl reg=%x", ctrl);
|
||||||
|
if (!write_register8(i2c_addr, BMP280_REG_CTRL, ctrl)) {
|
||||||
|
debug("Failed controlling sensor");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool bmp280_force_measurement()
|
bool bmp280_force_measurement(bmp280_t *dev)
|
||||||
{
|
{
|
||||||
uint8_t ctrl = read_register8(BMP280_REG_CTRL);
|
uint8_t ctrl;
|
||||||
|
if (!i2c_slave_read(dev->i2c_addr, BMP280_REG_CTRL, &ctrl, 1))
|
||||||
|
return false;
|
||||||
ctrl &= ~0b11; // clear two lower bits
|
ctrl &= ~0b11; // clear two lower bits
|
||||||
ctrl |= BMP280_MODE_FORCED;
|
ctrl |= BMP280_MODE_FORCED;
|
||||||
debug("Writing ctrl reg=%x", ctrl);
|
debug("Writing ctrl reg=%x", ctrl);
|
||||||
if (!write_register8(BMP280_REG_CTRL, ctrl)) {
|
if (!write_register8(dev->i2c_addr, BMP280_REG_CTRL, ctrl)) {
|
||||||
debug("Failed starting forced mode");
|
debug("Failed starting forced mode");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool bmp280_is_measuring()
|
bool bmp280_is_measuring(bmp280_t *dev)
|
||||||
{
|
{
|
||||||
uint8_t status = read_register8(BMP280_REG_STATUS);
|
uint8_t status;
|
||||||
|
if (!i2c_slave_read(dev->i2c_addr, BMP280_REG_STATUS, &status, 1))
|
||||||
|
return false;
|
||||||
if (status & (1 << 3)) {
|
if (status & (1 << 3)) {
|
||||||
debug("Status: measuring");
|
debug("Status: measuring");
|
||||||
return true;
|
return true;
|
||||||
|
@ -207,82 +257,130 @@ bool bmp280_is_measuring()
|
||||||
*
|
*
|
||||||
* Return value is in degrees Celsius.
|
* Return value is in degrees Celsius.
|
||||||
*/
|
*/
|
||||||
static inline float compensate_temperature(int32_t raw_temp, int32_t *fine_temp)
|
static inline int32_t compensate_temperature(bmp280_t *dev,
|
||||||
|
int32_t adc_temp, int32_t *fine_temp)
|
||||||
{
|
{
|
||||||
int32_t var1, var2, T;
|
int32_t var1, var2;
|
||||||
|
|
||||||
var1 = ((((raw_temp>>3) - ((int32_t)calib_data.dig_T1<<1)))
|
var1 = ((((adc_temp >> 3) - ((int32_t)dev->dig_T1 << 1)))
|
||||||
* ((int32_t)calib_data.dig_T2)) >> 11;
|
* (int32_t)dev->dig_T2) >> 11;
|
||||||
|
var2 = (((((adc_temp >> 4) - (int32_t)dev->dig_T1)
|
||||||
var2 = (((((raw_temp>>4) - ((int32_t)calib_data.dig_T1))
|
* ((adc_temp >> 4) - (int32_t)dev->dig_T1)) >> 12)
|
||||||
* ((raw_temp>>4) - ((int32_t)calib_data.dig_T1))) >> 12)
|
* (int32_t)dev->dig_T3) >> 14;
|
||||||
* ((int32_t)calib_data.dig_T3)) >> 14;
|
|
||||||
|
|
||||||
*fine_temp = var1 + var2;
|
*fine_temp = var1 + var2;
|
||||||
T = (*fine_temp * 5 + 128) >> 8;
|
return (*fine_temp * 5 + 128) >> 8;
|
||||||
return (float)T/100;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compensation algorithm is taken from BMP280 datasheet.
|
* Compensation algorithm is taken from BMP280 datasheet.
|
||||||
*
|
*
|
||||||
* Return value is in Pa.
|
* Return value is in Pa, 24 integer bits and 8 fractional bits.
|
||||||
*/
|
*/
|
||||||
static inline float compensate_pressure(int32_t raw_press, int32_t fine_temp)
|
static inline uint32_t compensate_pressure(bmp280_t *dev,
|
||||||
|
int32_t adc_press, int32_t fine_temp)
|
||||||
{
|
{
|
||||||
int64_t var1, var2, p;
|
int64_t var1, var2, p;
|
||||||
|
|
||||||
var1 = ((int64_t)fine_temp) - 128000;
|
var1 = (int64_t)fine_temp - 128000;
|
||||||
var2 = var1 * var1 * (int64_t)calib_data.dig_P6;
|
var2 = var1 * var1 * (int64_t)dev->dig_P6;
|
||||||
var2 = var2 + ((var1*(int64_t)calib_data.dig_P5)<<17);
|
var2 = var2 + ((var1 * (int64_t)dev->dig_P5) << 17);
|
||||||
var2 = var2 + (((int64_t)calib_data.dig_P4)<<35);
|
var2 = var2 + (((int64_t)dev->dig_P4) << 35);
|
||||||
var1 = ((var1 * var1 * (int64_t)calib_data.dig_P3)>>8) +
|
var1 = ((var1 * var1 * (int64_t)dev->dig_P3) >> 8) +
|
||||||
((var1 * (int64_t)calib_data.dig_P2)<<12);
|
((var1 * (int64_t)dev->dig_P2) << 12);
|
||||||
var1 = (((((int64_t)1)<<47)+var1))*((int64_t)calib_data.dig_P1)>>33;
|
var1 = (((int64_t)1 << 47) + var1) * ((int64_t)dev->dig_P1) >> 33;
|
||||||
|
|
||||||
if (var1 == 0) {
|
if (var1 == 0) {
|
||||||
return 0; // avoid exception caused by division by zero
|
return 0; // avoid exception caused by division by zero
|
||||||
}
|
}
|
||||||
|
|
||||||
p = 1048576 - raw_press;
|
p = 1048576 - adc_press;
|
||||||
p = (((p << 31) - var2) * 3125) / var1;
|
p = (((p << 31) - var2) * 3125) / var1;
|
||||||
var1 = (((int64_t)calib_data.dig_P9) * (p>>13) * (p>>13)) >> 25;
|
var1 = ((int64_t)dev->dig_P9 * (p >> 13) * (p >> 13)) >> 25;
|
||||||
var2 = (((int64_t)calib_data.dig_P8) * p) >> 19;
|
var2 = ((int64_t)dev->dig_P8 * p) >> 19;
|
||||||
|
|
||||||
p = ((p + var1 + var2) >> 8) + (((int64_t)calib_data.dig_P7)<<4);
|
p = ((p + var1 + var2) >> 8) + ((int64_t)dev->dig_P7 << 4);
|
||||||
return (float)p/256;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool bmp280_read(float *temperature, float *pressure)
|
/**
|
||||||
|
* Compensation algorithm is taken from BME280 datasheet.
|
||||||
|
*
|
||||||
|
* Return value is in Pa, 24 integer bits and 8 fractional bits.
|
||||||
|
*/
|
||||||
|
static inline uint32_t compensate_humidity(bmp280_t *dev,
|
||||||
|
int32_t adc_hum, int32_t fine_temp)
|
||||||
{
|
{
|
||||||
int32_t raw_pressure;
|
int32_t v_x1_u32r;
|
||||||
int32_t raw_temp;
|
|
||||||
|
v_x1_u32r = fine_temp - (int32_t)76800;
|
||||||
|
v_x1_u32r = ((((adc_hum << 14) - ((int32_t)dev->dig_H4 << 20) -
|
||||||
|
((int32_t)dev->dig_H5 * v_x1_u32r)) +
|
||||||
|
(int32_t)16384) >> 15) *
|
||||||
|
(((((((v_x1_u32r * (int32_t)dev->dig_H6) >> 10) *
|
||||||
|
(((v_x1_u32r * (int32_t)dev->dig_H3) >> 11) +
|
||||||
|
(int32_t)32768)) >> 10) + (int32_t)2097152) *
|
||||||
|
(int32_t)dev->dig_H2 + 8192) >> 14);
|
||||||
|
v_x1_u32r = v_x1_u32r - (((((v_x1_u32r >> 15) * (v_x1_u32r >> 15)) >> 7) *
|
||||||
|
(int32_t)dev->dig_H1) >> 4);
|
||||||
|
v_x1_u32r = v_x1_u32r < 0 ? 0 : v_x1_u32r;
|
||||||
|
v_x1_u32r = v_x1_u32r > 419430400 ? 419430400 : v_x1_u32r;
|
||||||
|
return v_x1_u32r >> 12;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool bmp280_read_fixed(bmp280_t *dev, int32_t *temperature,
|
||||||
|
uint32_t *pressure, uint32_t *humidity)
|
||||||
|
{
|
||||||
|
int32_t adc_pressure;
|
||||||
|
int32_t adc_temp;
|
||||||
|
uint8_t data[8];
|
||||||
|
|
||||||
|
// Only the BME280 supports reading the humidity.
|
||||||
|
if (dev->id != BME280_CHIP_ID) {
|
||||||
|
if (humidity)
|
||||||
|
*humidity = 0;
|
||||||
|
humidity = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Need to read in one sequence to ensure they match.
|
||||||
|
size_t size = humidity ? 8 : 6;
|
||||||
|
if (!i2c_slave_read(dev->i2c_addr, 0xf7, data, size)) {
|
||||||
|
debug("Failed reading");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
adc_pressure = data[0] << 12 | data[1] << 4 | data[2] >> 4;
|
||||||
|
adc_temp = data[3] << 12 | data[4] << 4 | data[5] >> 4;
|
||||||
|
debug("ADC temperature: %d", adc_temp);
|
||||||
|
debug("ADC pressure: %d", adc_pressure);
|
||||||
|
|
||||||
int32_t fine_temp;
|
int32_t fine_temp;
|
||||||
|
*temperature = compensate_temperature(dev, adc_temp, &fine_temp);
|
||||||
|
*pressure = compensate_pressure(dev, adc_pressure, fine_temp);
|
||||||
|
|
||||||
if (!read_register24(BMP280_REG_TEMP, &raw_temp)) {
|
if (humidity) {
|
||||||
debug("Failed reading temperature");
|
int32_t adc_humidity = data[6] << 8 | data[7];
|
||||||
return false;
|
debug("ADC humidity: %d", adc_humidity);
|
||||||
|
*humidity = compensate_humidity(dev, adc_humidity, fine_temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!read_register24(BMP280_REG_PRESSURE, &raw_pressure)) {
|
|
||||||
debug("Failed reading pressure");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
debug("Raw temperature: %d", raw_temp);
|
|
||||||
debug("Raw pressure: %d", raw_pressure);
|
|
||||||
|
|
||||||
*temperature = compensate_temperature(raw_temp, &fine_temp);
|
|
||||||
*pressure = compensate_pressure(raw_pressure, fine_temp);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool bmp280_soft_reset()
|
bool bmp280_read_float(bmp280_t *dev, float *temperature,
|
||||||
|
float *pressure, float *humidity)
|
||||||
{
|
{
|
||||||
if (!write_register8(BMP280_REG_RESET, BMP280_RESET_VALUE)) {
|
int32_t fixed_temperature;
|
||||||
debug("Failed resetting sensor");
|
uint32_t fixed_pressure;
|
||||||
return false;
|
uint32_t fixed_humidity;
|
||||||
}
|
if (bmp280_read_fixed(dev, &fixed_temperature, &fixed_pressure,
|
||||||
|
humidity ? &fixed_humidity : NULL)) {
|
||||||
|
*temperature = (float)fixed_temperature/100;
|
||||||
|
*pressure = (float)fixed_pressure/256;
|
||||||
|
if (humidity)
|
||||||
|
*humidity = (float)fixed_humidity/1024;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
|
@ -33,10 +33,14 @@
|
||||||
// #define BMP280_DEBUG
|
// #define BMP280_DEBUG
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BMP280 address is 0x77 if SDO pin is high,
|
* BMP280 or BME280 address is 0x77 if SDO pin is high, and is 0x76 if
|
||||||
* Address is 0x76 if SDO pin is low.
|
* SDO pin is low.
|
||||||
*/
|
*/
|
||||||
#define BMP280_ADDRESS 0x77
|
#define BMP280_I2C_ADDRESS_0 0x76
|
||||||
|
#define BMP280_I2C_ADDRESS_1 0x77
|
||||||
|
|
||||||
|
#define BMP280_CHIP_ID 0x58 /* BMP280 has chip-id 0x58 */
|
||||||
|
#define BME280_CHIP_ID 0x60 /* BME280 has chip-id 0x60 */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mode of BMP280 module operation.
|
* Mode of BMP280 module operation.
|
||||||
|
@ -78,8 +82,8 @@ typedef enum {
|
||||||
BMP280_STANDBY_250 = 3, /* stand by time 250ms */
|
BMP280_STANDBY_250 = 3, /* stand by time 250ms */
|
||||||
BMP280_STANDBY_500 = 4, /* stand by time 500ms */
|
BMP280_STANDBY_500 = 4, /* stand by time 500ms */
|
||||||
BMP280_STANDBY_1000 = 5, /* stand by time 1s */
|
BMP280_STANDBY_1000 = 5, /* stand by time 1s */
|
||||||
BMP280_STANDBY_2000 = 6, /* stand by time 2s */
|
BMP280_STANDBY_2000 = 6, /* stand by time 2s BMP280, 10ms BME280 */
|
||||||
BMP280_STANDBY_4000 = 7, /* stand by time 4s */
|
BMP280_STANDBY_4000 = 7, /* stand by time 4s BMP280, 20ms BME280 */
|
||||||
} BMP280_StandbyTime;
|
} BMP280_StandbyTime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -90,10 +94,37 @@ typedef struct {
|
||||||
BMP280_Mode mode;
|
BMP280_Mode mode;
|
||||||
BMP280_Filter filter;
|
BMP280_Filter filter;
|
||||||
BMP280_Oversampling oversampling; // pressure oversampling
|
BMP280_Oversampling oversampling; // pressure oversampling
|
||||||
|
BMP280_Oversampling oversampling_humidity;
|
||||||
BMP280_StandbyTime standby;
|
BMP280_StandbyTime standby;
|
||||||
} bmp280_params_t;
|
} bmp280_params_t;
|
||||||
|
|
||||||
|
|
||||||
|
typedef 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;
|
||||||
|
|
||||||
|
/* Humidity compensation for BME280 */
|
||||||
|
uint8_t dig_H1;
|
||||||
|
int16_t dig_H2;
|
||||||
|
uint8_t dig_H3;
|
||||||
|
int16_t dig_H4;
|
||||||
|
int16_t dig_H5;
|
||||||
|
int8_t dig_H6;
|
||||||
|
|
||||||
|
uint8_t i2c_addr; /* I2C address. */
|
||||||
|
uint8_t id; /* Chip ID */
|
||||||
|
} bmp280_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize default parameters.
|
* Initialize default parameters.
|
||||||
* Default configuration:
|
* Default configuration:
|
||||||
|
@ -105,33 +136,52 @@ typedef struct {
|
||||||
void bmp280_init_default_params(bmp280_params_t *params);
|
void bmp280_init_default_params(bmp280_params_t *params);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize BMP280 module.
|
* Initialize BMP280 module, probes for the device, soft resets the device,
|
||||||
|
* reads the calibration constants, and configures the device using the supplied
|
||||||
|
* parameters. Returns true on success otherwise false.
|
||||||
|
*
|
||||||
|
* The I2C address is assumed to have been initialized in the dev, and
|
||||||
|
* may be either BMP280_I2C_ADDRESS_0 or BMP280_I2C_ADDRESS_1. If the I2C
|
||||||
|
* address is unknown then try initializing each in turn.
|
||||||
|
*
|
||||||
|
* This may be called again to soft reset the device and initialize it again.
|
||||||
*/
|
*/
|
||||||
bool bmp280_init(bmp280_params_t *params, uint8_t scl_pin, uint8_t sda_pin);
|
bool bmp280_init(bmp280_t *dev, bmp280_params_t *params);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start measurement in forced mode.
|
* Start measurement in forced mode.
|
||||||
* The module remains in forced mode after this call.
|
* The module remains in forced mode after this call.
|
||||||
* Do not call this method in normal mode.
|
* Do not call this method in normal mode.
|
||||||
*/
|
*/
|
||||||
bool bmp280_force_measurement();
|
bool bmp280_force_measurement(bmp280_t *dev);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if BMP280 is busy with measuring temperature/pressure.
|
* Check if BMP280 is busy with measuring temperature/pressure.
|
||||||
* Return true if BMP280 is busy.
|
* Return true if BMP280 is busy.
|
||||||
*/
|
*/
|
||||||
bool bmp280_is_measuring();
|
bool bmp280_is_measuring(bmp280_t *dev);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read compensated temperature and pressure data.
|
* Read compensated temperature and pressure data:
|
||||||
|
*
|
||||||
|
* Temperature in degrees Celsius times 100.
|
||||||
|
*
|
||||||
|
* Pressure in Pascals in fixed point 24 bit integer 8 bit fraction format.
|
||||||
|
*
|
||||||
|
* Humidity is optional and only read for the BME280, in percent relative
|
||||||
|
* humidity as a fixed point 22 bit interger and 10 bit fraction format.
|
||||||
|
*/
|
||||||
|
bool bmp280_read_fixed(bmp280_t *dev, int32_t *temperature,
|
||||||
|
uint32_t *pressure, uint32_t *humidity);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read compensated temperature and pressure data:
|
||||||
* Temperature in degrees Celsius.
|
* Temperature in degrees Celsius.
|
||||||
* Pressure in Pascals.
|
* Pressure in Pascals.
|
||||||
|
* Humidity is optional and only read for the BME280, in percent relative
|
||||||
|
* humidity.
|
||||||
*/
|
*/
|
||||||
bool bmp280_read(float *temperature, float *pressure);
|
bool bmp280_read_float(bmp280_t *dev, float *temperature,
|
||||||
|
float *pressure, float *humidity);
|
||||||
/**
|
|
||||||
* Restart BMP280 module.
|
|
||||||
*/
|
|
||||||
bool bmp280_soft_reset();
|
|
||||||
|
|
||||||
#endif // __BMP280_H__
|
#endif // __BMP280_H__
|
||||||
|
|
Loading…
Reference in a new issue