drivers: Add driver for BME280
This commit is contained in:
parent
aab48458da
commit
a0a76d66d2
@ -29,6 +29,11 @@ ifneq (,$(filter bmp180,$(USEMODULE)))
|
||||
USEMODULE += xtimer
|
||||
endif
|
||||
|
||||
ifneq (,$(filter bme280,$(USEMODULE)))
|
||||
FEATURES_REQUIRED += periph_i2c
|
||||
USEMODULE += xtimer
|
||||
endif
|
||||
|
||||
ifneq (,$(filter cc110x,$(USEMODULE)))
|
||||
USEMODULE += ieee802154
|
||||
USEMODULE += uuid
|
||||
|
||||
@ -67,6 +67,9 @@ endif
|
||||
ifneq (,$(filter jc42,$(USEMODULE)))
|
||||
USEMODULE_INCLUDES += $(RIOTBASE)/drivers/jc42/include
|
||||
endif
|
||||
ifneq (,$(filter bme280,$(USEMODULE)))
|
||||
USEMODULE_INCLUDES += $(RIOTBASE)/drivers/bme280/include
|
||||
endif
|
||||
ifneq (,$(filter cc2420,$(USEMODULE)))
|
||||
USEMODULE_INCLUDES += $(RIOTBASE)/drivers/cc2420/include
|
||||
endif
|
||||
|
||||
3
drivers/bme280/Makefile
Normal file
3
drivers/bme280/Makefile
Normal file
@ -0,0 +1,3 @@
|
||||
MODULE = bme280
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
||||
369
drivers/bme280/bme280.c
Normal file
369
drivers/bme280/bme280.c
Normal file
@ -0,0 +1,369 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Kees Bakker, SODAQ
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup drivers_bme280
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Device driver implementation for the BME280 temperature,
|
||||
* pressure and humidity sensor.
|
||||
*
|
||||
* @author Kees Bakker <kees@sodaq.com>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "log.h"
|
||||
#include "bme280.h"
|
||||
#include "bme280_internals.h"
|
||||
#include "bme280_params.h"
|
||||
#include "periph/i2c.h"
|
||||
#include "xtimer.h"
|
||||
|
||||
#define ENABLE_DEBUG (0)
|
||||
#include "debug.h"
|
||||
|
||||
static int read_calibration_data(bme280_t* dev);
|
||||
static int do_measurement(bme280_t* dev);
|
||||
static uint8_t get_ctrl_meas(bme280_t* dev);
|
||||
static uint8_t get_status(bme280_t* dev);
|
||||
static uint8_t read_u8_reg(bme280_t* dev, uint8_t reg);
|
||||
static void write_u8_reg(bme280_t* dev, uint8_t reg, uint8_t b);
|
||||
static uint16_t get_uint16_le(const uint8_t *buffer, size_t offset);
|
||||
static int16_t get_int16_le(const uint8_t *buffer, size_t offset);
|
||||
|
||||
#if ENABLE_DEBUG
|
||||
static void dump_buffer(const char *txt, uint8_t *buffer, size_t size);
|
||||
#define DUMP_BUFFER(txt, buffer, size) dump_buffer(txt, buffer, size)
|
||||
#else
|
||||
#define DUMP_BUFFER(txt, buffer, size)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Fine resolution temperature value, also needed for pressure and humidity.
|
||||
*/
|
||||
static int32_t t_fine;
|
||||
|
||||
/**
|
||||
* @brief The measurement registers, including temperature, pressure and humidity
|
||||
*
|
||||
* A temporary buffer for the memory map 0xF7..0xFE
|
||||
* These are read all at once and then used to compute the three sensor values.
|
||||
*/
|
||||
static uint8_t measurement_regs[8];
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
* BME280 Core API *
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
int bme280_init(bme280_t* dev, const bme280_params_t* params)
|
||||
{
|
||||
uint8_t chip_id;
|
||||
|
||||
dev->params = *params;
|
||||
|
||||
/* Initialize I2C interface */
|
||||
if (i2c_init_master(dev->params.i2c_dev, I2C_SPEED_NORMAL)) {
|
||||
DEBUG("[Error] I2C device not enabled\n");
|
||||
return BME280_ERR_I2C;
|
||||
}
|
||||
|
||||
/* Read chip ID */
|
||||
chip_id = read_u8_reg(dev, BME280_CHIP_ID_REG);
|
||||
if (chip_id != BME280_CHIP_ID) {
|
||||
DEBUG("[Error] Did not detect a BME280 at address %02x (%02X != %02X)\n",
|
||||
dev->params.i2c_addr, chip_id, BME280_CHIP_ID);
|
||||
return BME280_ERR_NODEV;
|
||||
}
|
||||
|
||||
/* Read compensation data, 0x88..0x9F, 0xA1, 0xE1..0xE7 */
|
||||
if (read_calibration_data(dev)) {
|
||||
DEBUG("[Error] Could not read calibration data\n");
|
||||
return BME280_ERR_NOCAL;
|
||||
}
|
||||
|
||||
return BME280_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns temperature in DegC, resolution is 0.01 DegC.
|
||||
* t_fine carries fine temperature as global value
|
||||
*/
|
||||
int16_t bme280_read_temperature(bme280_t* dev)
|
||||
{
|
||||
if (do_measurement(dev) < 0) {
|
||||
return INT16_MIN;
|
||||
}
|
||||
|
||||
bme280_calibration_t *cal = &dev->calibration; /* helper variable */
|
||||
|
||||
/* Read the uncompensated temperature */
|
||||
int32_t adc_T = (((uint32_t)measurement_regs[3 + 0]) << 12) |
|
||||
(((uint32_t)measurement_regs[3 + 1]) << 4) |
|
||||
((((uint32_t)measurement_regs[3 + 2]) >> 4) & 0x0F);
|
||||
|
||||
/*
|
||||
* Compensate the temperature value.
|
||||
* The following is code from Bosch's BME280_driver bme280_compensate_temperature_int32()
|
||||
* The variable names and the many defines have been modified to make the code
|
||||
* more readable.
|
||||
*/
|
||||
int32_t var1;
|
||||
int32_t var2;
|
||||
|
||||
var1 = ((((adc_T >> 3) - ((int32_t)cal->dig_T1 << 1))) * ((int32_t)cal->dig_T2)) >> 11;
|
||||
var2 = (((((adc_T >> 4) - ((int32_t)cal->dig_T1)) * ((adc_T >> 4) - ((int32_t)cal->dig_T1))) >> 12) *
|
||||
((int32_t)cal->dig_T3)) >> 14;
|
||||
|
||||
/* calculate t_fine (used for pressure and humidity too) */
|
||||
t_fine = var1 + var2;
|
||||
|
||||
return (t_fine * 5 + 128) >> 8;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns pressure in Pa
|
||||
*/
|
||||
uint32_t bme280_read_pressure(bme280_t *dev)
|
||||
{
|
||||
bme280_calibration_t *cal = &dev->calibration; /* helper variable */
|
||||
|
||||
/* Read the uncompensated pressure */
|
||||
int32_t adc_P = (((uint32_t)measurement_regs[0 + 0]) << 12) |
|
||||
(((uint32_t)measurement_regs[0 + 1]) << 4) |
|
||||
((((uint32_t)measurement_regs[0 + 2]) >> 4) & 0x0F);
|
||||
|
||||
int64_t var1;
|
||||
int64_t var2;
|
||||
int64_t p_acc;
|
||||
|
||||
/*
|
||||
* Compensate the pressure value.
|
||||
* The following is code from Bosch's BME280_driver bme280_compensate_pressure_int64()
|
||||
* The variable names and the many defines have been modified to make the code
|
||||
* more readable.
|
||||
*/
|
||||
var1 = ((int64_t)t_fine) - 128000;
|
||||
var2 = var1 * var1 * (int64_t)cal->dig_P6;
|
||||
var2 = var2 + ((var1 * (int64_t)cal->dig_P5) << 17);
|
||||
var2 = var2 + (((int64_t)cal->dig_P4) << 35);
|
||||
var1 = ((var1 * var1 * (int64_t)cal->dig_P3) >> 8) + ((var1 * (int64_t)cal->dig_P2) << 12);
|
||||
var1 = (((((int64_t)1) << 47) + var1)) * ((int64_t)cal->dig_P1) >> 33;
|
||||
/* Avoid division by zero */
|
||||
if (var1 == 0) {
|
||||
return UINT32_MAX;
|
||||
}
|
||||
|
||||
p_acc = 1048576 - adc_P;
|
||||
p_acc = (((p_acc << 31) - var2) * 3125) / var1;
|
||||
var1 = (((int64_t)cal->dig_P9) * (p_acc >> 13) * (p_acc >> 13)) >> 25;
|
||||
var2 = (((int64_t)cal->dig_P8) * p_acc) >> 19;
|
||||
p_acc = ((p_acc + var1 + var2) >> 8) + (((int64_t)cal->dig_P7) << 4);
|
||||
|
||||
return p_acc >> 8;
|
||||
}
|
||||
|
||||
uint16_t bme280_read_humidity(bme280_t *dev)
|
||||
{
|
||||
bme280_calibration_t *cal = &dev->calibration; /* helper variable */
|
||||
|
||||
/* Read the uncompensated pressure */
|
||||
int32_t adc_H = (((uint32_t)measurement_regs[6 + 0]) << 8) |
|
||||
(((uint32_t)measurement_regs[6 + 1]));
|
||||
|
||||
/*
|
||||
* Compensate the humidity value.
|
||||
* The following is code from Bosch's BME280_driver bme280_compensate_humidity_int32()
|
||||
* The variable names and the many defines have been modified to make the code
|
||||
* more readable.
|
||||
* The value is first computed as a value in %rH as unsigned 32bit integer
|
||||
* in Q22.10 format(22 integer 10 fractional bits).
|
||||
*/
|
||||
int32_t var1;
|
||||
|
||||
/* calculate x1*/
|
||||
var1 = (t_fine - ((int32_t)76800));
|
||||
/* calculate x1*/
|
||||
var1 = (((((adc_H << 14) - (((int32_t)cal->dig_H4) << 20) - (((int32_t)cal->dig_H5) * var1)) +
|
||||
((int32_t)16384)) >> 15) *
|
||||
(((((((var1 * ((int32_t)cal->dig_H6)) >> 10) *
|
||||
(((var1 * ((int32_t)cal->dig_H3)) >> 11) + ((int32_t)32768))) >> 10) +
|
||||
((int32_t)2097152)) * ((int32_t)cal->dig_H2) + 8192) >> 14));
|
||||
var1 = (var1 - (((((var1 >> 15) * (var1 >> 15)) >> 7) * ((int32_t)cal->dig_H1)) >> 4));
|
||||
var1 = (var1 < 0 ? 0 : var1);
|
||||
var1 = (var1 > 419430400 ? 419430400 : var1);
|
||||
/* First multiply to avoid losing the accuracy after the shift by ten */
|
||||
return (100 * ((uint32_t)var1 >> 12)) >> 10;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read compensation data, 0x88..0x9F, 0xA1, 0xE1..0xE7
|
||||
*
|
||||
* This function reads all calibration bytes at once. These are
|
||||
* the registers DIG_T1_LSB (0x88) upto and including DIG_H6 (0xE7).
|
||||
*/
|
||||
static int read_calibration_data(bme280_t* dev)
|
||||
{
|
||||
uint8_t buffer[128]; /* 128 should be enough to read all calibration bytes */
|
||||
int nr_bytes;
|
||||
int nr_bytes_to_read = (BME280_DIG_H6_REG - BME280_DIG_T1_LSB_REG) + 1;
|
||||
uint8_t offset = 0x88;
|
||||
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
nr_bytes = i2c_read_regs(dev->params.i2c_dev, dev->params.i2c_addr, offset,
|
||||
buffer, nr_bytes_to_read);
|
||||
if (nr_bytes != nr_bytes_to_read) {
|
||||
LOG_ERROR("Unable to read calibration data\n");
|
||||
return -1;
|
||||
}
|
||||
DUMP_BUFFER("Raw Calibration Data", buffer, nr_bytes);
|
||||
|
||||
/* All little endian */
|
||||
dev->calibration.dig_T1 = get_uint16_le(buffer, BME280_DIG_T1_LSB_REG - offset);
|
||||
dev->calibration.dig_T2 = get_int16_le(buffer, BME280_DIG_T2_LSB_REG - offset);
|
||||
dev->calibration.dig_T3 = get_int16_le(buffer, BME280_DIG_T3_LSB_REG - offset);
|
||||
|
||||
dev->calibration.dig_P1 = get_uint16_le(buffer, BME280_DIG_P1_LSB_REG - offset);
|
||||
dev->calibration.dig_P2 = get_int16_le(buffer, BME280_DIG_P2_LSB_REG - offset);
|
||||
dev->calibration.dig_P3 = get_int16_le(buffer, BME280_DIG_P3_LSB_REG - offset);
|
||||
dev->calibration.dig_P4 = get_int16_le(buffer, BME280_DIG_P4_LSB_REG - offset);
|
||||
dev->calibration.dig_P5 = get_int16_le(buffer, BME280_DIG_P5_LSB_REG - offset);
|
||||
dev->calibration.dig_P6 = get_int16_le(buffer, BME280_DIG_P6_LSB_REG - offset);
|
||||
dev->calibration.dig_P7 = get_int16_le(buffer, BME280_DIG_P7_LSB_REG - offset);
|
||||
dev->calibration.dig_P8 = get_int16_le(buffer, BME280_DIG_P8_LSB_REG - offset);
|
||||
dev->calibration.dig_P9 = get_int16_le(buffer, BME280_DIG_P9_LSB_REG - offset);
|
||||
|
||||
dev->calibration.dig_H1 = buffer[BME280_DIG_H1_REG - offset];
|
||||
dev->calibration.dig_H2 = get_int16_le(buffer, BME280_DIG_H2_LSB_REG - offset);
|
||||
dev->calibration.dig_H3 = buffer[BME280_DIG_H3_REG - offset];
|
||||
dev->calibration.dig_H4 = (((int16_t)buffer[BME280_DIG_H4_MSB_REG - offset]) << 4) +
|
||||
(buffer[BME280_DIG_H4_H5_REG - offset] & 0x0F);
|
||||
dev->calibration.dig_H5 = (((int16_t)buffer[BME280_DIG_H5_MSB_REG - offset]) << 4) +
|
||||
((buffer[BME280_DIG_H4_H5_REG - offset] & 0xF0) >> 4);
|
||||
dev->calibration.dig_H6 = buffer[BME280_DIG_H6_REG - offset];
|
||||
|
||||
DEBUG("[INFO] Chip ID = 0x%02X\n", buffer[BME280_CHIP_ID_REG - offset]);
|
||||
|
||||
/* Config is only be writable in sleep mode */
|
||||
(void)i2c_write_reg(dev->params.i2c_dev, dev->params.i2c_addr,
|
||||
BME280_CTRL_MEAS_REG, 0);
|
||||
|
||||
uint8_t b;
|
||||
|
||||
/* Config Register */
|
||||
/* spi3w_en unused */
|
||||
b = ((dev->params.t_sb & 7) << 5) | ((dev->params.filter & 7) << 2);
|
||||
write_u8_reg(dev, BME280_CONFIG_REG, b);
|
||||
|
||||
/*
|
||||
* Note from the datasheet about ctrl_hum: "Changes to this register only become effective
|
||||
* after a write operation to "ctrl_meas".
|
||||
* So, set ctrl_hum first.
|
||||
*/
|
||||
b = dev->params.humid_oversample & 7;
|
||||
write_u8_reg(dev, BME280_CTRL_HUMIDITY_REG, b);
|
||||
|
||||
b = ((dev->params.temp_oversample & 7) << 5) |
|
||||
((dev->params.press_oversample & 7) << 2) |
|
||||
(dev->params.run_mode & 3);
|
||||
write_u8_reg(dev, BME280_CTRL_MEAS_REG, b);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Start a measurement and read the registers
|
||||
*/
|
||||
static int do_measurement(bme280_t* dev)
|
||||
{
|
||||
/*
|
||||
* If settings has FORCED mode, then the device go to sleep after
|
||||
* it finished the measurement. To read again we have to set the
|
||||
* run_mode back to FORCED.
|
||||
*/
|
||||
uint8_t ctrl_meas = get_ctrl_meas(dev);
|
||||
uint8_t run_mode = ctrl_meas & 3;
|
||||
if (run_mode != dev->params.run_mode) {
|
||||
/* Set the run_mode back to what we want. */
|
||||
ctrl_meas &= ~3;
|
||||
ctrl_meas |= dev->params.run_mode;
|
||||
write_u8_reg(dev, BME280_CTRL_MEAS_REG, ctrl_meas);
|
||||
|
||||
/* Wait for measurement ready? */
|
||||
size_t count = 0;
|
||||
while (count < 10 && (get_status(dev) & 0x08) != 0) {
|
||||
++count;
|
||||
}
|
||||
/* What to do when measuring is still on? */
|
||||
}
|
||||
int nr_bytes;
|
||||
int nr_bytes_to_read = sizeof(measurement_regs);
|
||||
uint8_t offset = BME280_PRESSURE_MSB_REG;
|
||||
|
||||
nr_bytes = i2c_read_regs(dev->params.i2c_dev, dev->params.i2c_addr,
|
||||
offset, measurement_regs, nr_bytes_to_read);
|
||||
if (nr_bytes != nr_bytes_to_read) {
|
||||
LOG_ERROR("Unable to read temperature data\n");
|
||||
return -1;
|
||||
}
|
||||
DUMP_BUFFER("Raw Sensor Data", measurement_regs, nr_bytes);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint8_t get_ctrl_meas(bme280_t* dev)
|
||||
{
|
||||
return read_u8_reg(dev, BME280_CTRL_MEAS_REG);
|
||||
}
|
||||
|
||||
static uint8_t get_status(bme280_t* dev)
|
||||
{
|
||||
return read_u8_reg(dev, BME280_STAT_REG);
|
||||
}
|
||||
|
||||
static uint8_t read_u8_reg(bme280_t* dev, uint8_t reg)
|
||||
{
|
||||
uint8_t b;
|
||||
/* Assuming device is correct, it should return 1 (nr bytes) */
|
||||
(void)i2c_read_reg(dev->params.i2c_dev, dev->params.i2c_addr, reg, &b);
|
||||
return b;
|
||||
}
|
||||
|
||||
static void write_u8_reg(bme280_t* dev, uint8_t reg, uint8_t b)
|
||||
{
|
||||
/* Assuming device is correct, it should return 1 (nr bytes) */
|
||||
(void)i2c_write_reg(dev->params.i2c_dev, dev->params.i2c_addr, reg, b);
|
||||
}
|
||||
|
||||
static uint16_t get_uint16_le(const uint8_t *buffer, size_t offset)
|
||||
{
|
||||
return (((uint16_t)buffer[offset + 1]) << 8) + buffer[offset];
|
||||
}
|
||||
|
||||
static int16_t get_int16_le(const uint8_t *buffer, size_t offset)
|
||||
{
|
||||
return (((int16_t)buffer[offset + 1]) << 8) + buffer[offset];
|
||||
}
|
||||
|
||||
#if ENABLE_DEBUG
|
||||
static void dump_buffer(const char *txt, uint8_t *buffer, size_t size)
|
||||
{
|
||||
size_t ix;
|
||||
DEBUG("%s\n", txt);
|
||||
for (ix = 0; ix < size; ix++) {
|
||||
DEBUG("%02X", buffer[ix]);
|
||||
if ((ix + 1) == size || (((ix + 1) % 16) == 0)) {
|
||||
DEBUG("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
74
drivers/bme280/bme280_saul.c
Normal file
74
drivers/bme280/bme280_saul.c
Normal file
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Kees Bakker, SODAQ
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup driver_bme280
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief SAUL adoption for BME280 sensor.
|
||||
*
|
||||
* @author Kees Bakker <kees@sodaq.com>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "saul.h"
|
||||
|
||||
#include "bme280.h"
|
||||
|
||||
static int read_temperature(void *dev, phydat_t *res)
|
||||
{
|
||||
bme280_t *d = (bme280_t *)dev;
|
||||
|
||||
res->val[0] = bme280_read_temperature(d);
|
||||
res->unit = UNIT_TEMP_C;
|
||||
res->scale = -2;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int read_relative_humidity(void *dev, phydat_t *res)
|
||||
{
|
||||
bme280_t *d = (bme280_t *)dev;
|
||||
|
||||
res->val[0] = bme280_read_humidity(d);
|
||||
res->unit = UNIT_PERCENT;
|
||||
res->scale = -2;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int read_pressure(void *dev, phydat_t *res)
|
||||
{
|
||||
bme280_t *d = (bme280_t *)dev;
|
||||
|
||||
res->val[0] = bme280_read_pressure(d) / 100;
|
||||
res->unit = UNIT_PA;
|
||||
res->scale = 2;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
const saul_driver_t bme280_temperature_saul_driver = {
|
||||
.read = read_temperature,
|
||||
.write = saul_notsup,
|
||||
.type = SAUL_SENSE_TEMP,
|
||||
};
|
||||
|
||||
const saul_driver_t bme280_relative_humidity_saul_driver = {
|
||||
.read = read_relative_humidity,
|
||||
.write = saul_notsup,
|
||||
.type = SAUL_SENSE_HUM,
|
||||
};
|
||||
|
||||
const saul_driver_t bme280_pressure_saul_driver = {
|
||||
.read = read_pressure,
|
||||
.write = saul_notsup,
|
||||
.type = SAUL_SENSE_PRESS,
|
||||
};
|
||||
88
drivers/bme280/include/bme280_internals.h
Normal file
88
drivers/bme280/include/bme280_internals.h
Normal file
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Kees Bakker, SODAQ
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup drivers_bme280
|
||||
* @brief Internal addresses, registers, constants for the BME280 sensor.
|
||||
* @{
|
||||
* @file
|
||||
* @brief Internal addresses, registers, constants for the BME280 sensor.
|
||||
*
|
||||
* @author Kees Bakker <kees@sodaq.com>
|
||||
*/
|
||||
|
||||
#ifndef BME280_INTERNALS_H
|
||||
#define BME280_INTERNALS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @name BME280 registers
|
||||
* @{
|
||||
*/
|
||||
#define BME280_DIG_T1_LSB_REG 0x88
|
||||
#define BME280_DIG_T1_MSB_REG 0x89
|
||||
#define BME280_DIG_T2_LSB_REG 0x8A
|
||||
#define BME280_DIG_T2_MSB_REG 0x8B
|
||||
#define BME280_DIG_T3_LSB_REG 0x8C
|
||||
#define BME280_DIG_T3_MSB_REG 0x8D
|
||||
#define BME280_DIG_P1_LSB_REG 0x8E
|
||||
#define BME280_DIG_P1_MSB_REG 0x8F
|
||||
#define BME280_DIG_P2_LSB_REG 0x90
|
||||
#define BME280_DIG_P2_MSB_REG 0x91
|
||||
#define BME280_DIG_P3_LSB_REG 0x92
|
||||
#define BME280_DIG_P3_MSB_REG 0x93
|
||||
#define BME280_DIG_P4_LSB_REG 0x94
|
||||
#define BME280_DIG_P4_MSB_REG 0x95
|
||||
#define BME280_DIG_P5_LSB_REG 0x96
|
||||
#define BME280_DIG_P5_MSB_REG 0x97
|
||||
#define BME280_DIG_P6_LSB_REG 0x98
|
||||
#define BME280_DIG_P6_MSB_REG 0x99
|
||||
#define BME280_DIG_P7_LSB_REG 0x9A
|
||||
#define BME280_DIG_P7_MSB_REG 0x9B
|
||||
#define BME280_DIG_P8_LSB_REG 0x9C
|
||||
#define BME280_DIG_P8_MSB_REG 0x9D
|
||||
#define BME280_DIG_P9_LSB_REG 0x9E
|
||||
#define BME280_DIG_P9_MSB_REG 0x9F
|
||||
|
||||
#define BME280_DIG_H1_REG 0xA1
|
||||
|
||||
#define BME280_CHIP_ID 0x60 /* The identifier of the BME280 */
|
||||
#define BME280_CHIP_ID_REG 0xD0
|
||||
#define BME280_RST_REG 0xE0 /* Softreset Reg */
|
||||
|
||||
#define BME280_DIG_H2_LSB_REG 0xE1
|
||||
#define BME280_DIG_H2_MSB_REG 0xE2
|
||||
#define BME280_DIG_H3_REG 0xE3
|
||||
#define BME280_DIG_H4_MSB_REG 0xE4 /* H4[11:4] */
|
||||
#define BME280_DIG_H4_H5_REG 0xE5 /* H5[3:0] H4[3:0] */
|
||||
#define BME280_DIG_H5_MSB_REG 0xE6 /* H5[11:4] */
|
||||
#define BME280_DIG_H6_REG 0xE7
|
||||
|
||||
#define BME280_CTRL_HUMIDITY_REG 0xF2 /* Ctrl Humidity Reg */
|
||||
#define BME280_STAT_REG 0xF3 /* Status Reg */
|
||||
#define BME280_CTRL_MEAS_REG 0xF4 /* Ctrl Measure Reg */
|
||||
#define BME280_CONFIG_REG 0xF5 /* Configuration Reg */
|
||||
#define BME280_PRESSURE_MSB_REG 0xF7 /* Pressure MSB */
|
||||
#define BME280_PRESSURE_LSB_REG 0xF8 /* Pressure LSB */
|
||||
#define BME280_PRESSURE_XLSB_REG 0xF9 /* Pressure XLSB */
|
||||
#define BME280_TEMPERATURE_MSB_REG 0xFA /* Temperature MSB */
|
||||
#define BME280_TEMPERATURE_LSB_REG 0xFB /* Temperature LSB */
|
||||
#define BME280_TEMPERATURE_XLSB_REG 0xFC /* Temperature XLSB */
|
||||
#define BME280_HUMIDITY_MSB_REG 0xFD /* Humidity MSB */
|
||||
#define BME280_HUMIDITY_LSB_REG 0xFE /* Humidity LSB */
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* BME280_INTERNALS_H */
|
||||
/** @} */
|
||||
92
drivers/bme280/include/bme280_params.h
Normal file
92
drivers/bme280/include/bme280_params.h
Normal file
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Kees Bakker, SODAQ
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup drivers_bme280
|
||||
*
|
||||
* @{
|
||||
* @file
|
||||
* @brief Default configuration for BME280
|
||||
*
|
||||
* @author Kees Bakker <kees@sodaq.com>
|
||||
*/
|
||||
|
||||
#ifndef BME280_PARAMS_H
|
||||
#define BME280_PARAMS_H
|
||||
|
||||
#include "bme280.h"
|
||||
#include "saul_reg.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Set default configuration parameters for the BME280
|
||||
* @{
|
||||
*/
|
||||
#ifndef BME280_PARAM_I2C_DEV
|
||||
#define BME280_PARAM_I2C_DEV I2C_DEV(0)
|
||||
#endif
|
||||
#ifndef BME280_PARAM_I2C_ADDR
|
||||
#define BME280_PARAM_I2C_ADDR (0x77)
|
||||
#endif
|
||||
|
||||
/* Defaults for Weather Monitoring */
|
||||
#define BME280_PARAMS_DEFAULT \
|
||||
{ \
|
||||
.i2c_dev = BME280_PARAM_I2C_DEV, \
|
||||
.i2c_addr = BME280_PARAM_I2C_ADDR, \
|
||||
.t_sb = BME280_SB_0_5, \
|
||||
.filter = BME280_FILTER_OFF, \
|
||||
.run_mode = BME280_MODE_FORCED, \
|
||||
.temp_oversample = BME280_OSRS_X1, \
|
||||
.press_oversample = BME280_OSRS_X1, \
|
||||
.humid_oversample = BME280_OSRS_X1, \
|
||||
}
|
||||
/**@}*/
|
||||
|
||||
/**
|
||||
* @brief Configure BME280
|
||||
*/
|
||||
static const bme280_params_t bme280_params[] =
|
||||
{
|
||||
#ifdef BME280_PARAMS_BOARD
|
||||
BME280_PARAMS_BOARD,
|
||||
#else
|
||||
BME280_PARAMS_DEFAULT,
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The number of configured sensors
|
||||
*/
|
||||
#define BME280_NUMOF (sizeof(bme280_params) / sizeof(bme280_params[0]))
|
||||
|
||||
/**
|
||||
* @brief Configuration details of SAUL registry entries
|
||||
*
|
||||
* This two dimensional array contains static details of the sensors
|
||||
* for each device. Please be awar that the indexes are used in
|
||||
* auto_init_bme280, so make sure the indexes match.
|
||||
*/
|
||||
static const saul_reg_info_t bme280_saul_reg_info[BME280_NUMOF][3] =
|
||||
{
|
||||
{
|
||||
{ .name = "bme280-temp" },
|
||||
{ .name = "bme280-humidity" },
|
||||
{ .name = "bme280-press" },
|
||||
},
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* BME280_PARAMS_H */
|
||||
/** @} */
|
||||
223
drivers/include/bme280.h
Normal file
223
drivers/include/bme280.h
Normal file
@ -0,0 +1,223 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Kees Bakker, SODAQ
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup drivers_bme280 BME280
|
||||
* @ingroup drivers_sensors
|
||||
* @brief Device driver interface for the BME280 sensor
|
||||
*
|
||||
* @{
|
||||
* @file
|
||||
* @brief Device driver interface for the BME280 sensor.
|
||||
*
|
||||
* @details There are three sensor values that can be read: temperature,
|
||||
* pressure and humidity. The BME280 device usually measures them
|
||||
* all at once. It is possible to skip measuring either of the
|
||||
* values by changing the oversampling settings. The driver is
|
||||
* written in such a way that a measurement is only started from
|
||||
* the function that reads the temperature. In other words, you
|
||||
* always have to call bme280_read_temperature, and then optionally
|
||||
* you can call the other two.
|
||||
*
|
||||
* @author Kees Bakker <kees@sodaq.com>
|
||||
*/
|
||||
|
||||
#ifndef BME280_H
|
||||
#define BME280_H
|
||||
|
||||
#include "saul.h"
|
||||
#include "periph/i2c.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Calibration struct for the BME280 sensor
|
||||
*
|
||||
* This must be read from the device at startup.
|
||||
*/
|
||||
typedef struct {
|
||||
uint16_t dig_T1; /**< T1 coefficient */
|
||||
int16_t dig_T2; /**< T2 coefficient */
|
||||
int16_t dig_T3; /**< T3 coefficient */
|
||||
|
||||
uint16_t dig_P1; /**< P1 coefficient */
|
||||
int16_t dig_P2; /**< P2 coefficient */
|
||||
int16_t dig_P3; /**< P3 coefficient */
|
||||
int16_t dig_P4; /**< P4 coefficient */
|
||||
int16_t dig_P5; /**< P5 coefficient */
|
||||
int16_t dig_P6; /**< P6 coefficient */
|
||||
int16_t dig_P7; /**< P7 coefficient */
|
||||
int16_t dig_P8; /**< P8 coefficient */
|
||||
int16_t dig_P9; /**< P9 coefficient */
|
||||
|
||||
uint8_t dig_H1; /**< H1 coefficient */
|
||||
int16_t dig_H2; /**< H2 coefficient */
|
||||
uint8_t dig_H3; /**< H3 coefficient */
|
||||
int16_t dig_H4; /**< H4 coefficient */
|
||||
int16_t dig_H5; /**< H5 coefficient */
|
||||
int8_t dig_H6; /**< H6 coefficient */
|
||||
} bme280_calibration_t;
|
||||
|
||||
/**
|
||||
* @brief Values for t_sb field of the BME280 config register
|
||||
*/
|
||||
typedef enum {
|
||||
BME280_SB_0_5 = 0,
|
||||
BME280_SB_62_5 = 1,
|
||||
BME280_SB_125 = 2,
|
||||
BME280_SB_250 = 3,
|
||||
BME280_SB_500 = 4,
|
||||
BME280_SB_1000 = 5,
|
||||
BME280_SB_10 = 6,
|
||||
BME280_SB_20 = 7
|
||||
} bme280_t_sb_t;
|
||||
|
||||
/**
|
||||
* @brief Values for filter field of the BME280 config register
|
||||
*/
|
||||
typedef enum {
|
||||
BME280_FILTER_OFF = 0,
|
||||
BME280_FILTER_2 = 1,
|
||||
BME280_FILTER_4 = 2,
|
||||
BME280_FILTER_8 = 3,
|
||||
BME280_FILTER_16 = 4,
|
||||
} bme280_filter_t;
|
||||
|
||||
/**
|
||||
* @brief Values for mode field of the BME280 ctrl_meas register
|
||||
*/
|
||||
typedef enum {
|
||||
BME280_MODE_SLEEP = 0,
|
||||
BME280_MODE_FORCED = 1,
|
||||
BME280_MODE_FORCED2 = 2, /* Same as FORCED */
|
||||
BME280_MODE_NORMAL = 3
|
||||
} bme280_mode_t;
|
||||
|
||||
/**
|
||||
* @brief Values for oversampling settings
|
||||
*
|
||||
* These values are used for:
|
||||
* - osrs_h field of the BME280 ctrl_hum register
|
||||
* - osrs_t field of the BME280 ctrl_meas register
|
||||
* - osrs_p field of the BME280 ctrl_meas register
|
||||
*/
|
||||
typedef enum {
|
||||
BME280_OSRS_SKIPPED = 0,
|
||||
BME280_OSRS_X1 = 1,
|
||||
BME280_OSRS_X2 = 2,
|
||||
BME280_OSRS_X4 = 3,
|
||||
BME280_OSRS_X8 = 4,
|
||||
BME280_OSRS_X16 = 5,
|
||||
} bme280_osrs_t;
|
||||
|
||||
/**
|
||||
* @brief Parameters for the BME280 sensor
|
||||
*
|
||||
* These parameters are needed to configure the device at startup.
|
||||
*/
|
||||
typedef struct {
|
||||
/* I2C details */
|
||||
i2c_t i2c_dev; /**< I2C device which is used */
|
||||
uint8_t i2c_addr; /**< I2C address */
|
||||
|
||||
/* Config Register */
|
||||
bme280_t_sb_t t_sb; /**< standby */
|
||||
bme280_filter_t filter; /**< filter coefficient */
|
||||
uint8_t spi3w_en; /**< Enables 3-wire SPI interface */
|
||||
|
||||
/* ctrl_meas */
|
||||
bme280_mode_t run_mode; /**< ctrl_meas mode */
|
||||
bme280_osrs_t temp_oversample; /**< ctrl_meas osrs_t */
|
||||
bme280_osrs_t press_oversample; /**< ctrl_meas osrs_p */
|
||||
|
||||
/* ctrl_hum */
|
||||
bme280_osrs_t humid_oversample; /**< ctrl_hum osrs_h */
|
||||
} bme280_params_t;
|
||||
|
||||
/**
|
||||
* @brief Device descriptor for the BME280 sensor
|
||||
*/
|
||||
typedef struct {
|
||||
bme280_params_t params; /**< Device Parameters */
|
||||
bme280_calibration_t calibration; /**< Calibration Data */
|
||||
} bme280_t;
|
||||
|
||||
/**
|
||||
* @brief Status and error return codes
|
||||
*/
|
||||
enum {
|
||||
BME280_OK = 0, /**< everything was fine */
|
||||
BME280_ERR_I2C = -1, /**< error initializing the I2C bus */
|
||||
BME280_ERR_NODEV = -2, /**< did not detect BME280 */
|
||||
BME280_ERR_NOCAL = -3, /**< could not read calibration data */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief export SAUL endpoints
|
||||
* @{
|
||||
*/
|
||||
extern const saul_driver_t bme280_temperature_saul_driver;
|
||||
extern const saul_driver_t bme280_relative_humidity_saul_driver;
|
||||
extern const saul_driver_t bme280_pressure_saul_driver;
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief Initialize the given BME280 device
|
||||
*
|
||||
* @param[out] dev Initialized device descriptor of BME280 device
|
||||
* @param[in] params The parameters for the BME280 device (sampling rate, etc)
|
||||
*
|
||||
* @return BME280_OK on success
|
||||
* @return BME280_ERR_I2C
|
||||
* @return BME280_ERR_NODEV
|
||||
* @return BME280_ERR_NOCAL
|
||||
*/
|
||||
int bme280_init(bme280_t* dev, const bme280_params_t* params);
|
||||
|
||||
/**
|
||||
* @brief Read temperature value from the given BME280 device, returned in centi °C
|
||||
*
|
||||
* @param[in] dev Device descriptor of BME280 device to read from
|
||||
*
|
||||
* @returns The temperature in centi Celsius. In case of an error
|
||||
* it returns INT16_MIN.
|
||||
*/
|
||||
int16_t bme280_read_temperature(bme280_t* dev);
|
||||
|
||||
/**
|
||||
* @brief Read humidity value from the given BME280 device, returned in centi %RH
|
||||
*
|
||||
* @details This function should only be called after doing bme280_read_temperature
|
||||
* first.
|
||||
*
|
||||
* @param[in] dev Device descriptor of BME280 device to read from
|
||||
*
|
||||
* @returns Humidity in centi %RH (i.e. the percentage times 100)
|
||||
*/
|
||||
uint16_t bme280_read_humidity(bme280_t *dev);
|
||||
|
||||
/**
|
||||
* @brief Read air pressure value from the given BME280 device, returned in PA
|
||||
*
|
||||
* @details This function should only be called after doing bme280_read_temperature
|
||||
* first.
|
||||
*
|
||||
* @param[in] dev Device descriptor of BME280 device to read from
|
||||
*
|
||||
* @returns The air pressure in Pa
|
||||
*/
|
||||
uint32_t bme280_read_pressure(bme280_t *dev);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* BME280_H */
|
||||
/** @} */
|
||||
@ -294,6 +294,10 @@ void auto_init(void)
|
||||
extern void auto_init_bmp180(void);
|
||||
auto_init_bmp180();
|
||||
#endif
|
||||
#ifdef MODULE_BME280
|
||||
extern void auto_init_bme280(void);
|
||||
auto_init_bme280();
|
||||
#endif
|
||||
#ifdef MODULE_JC42
|
||||
extern void auto_init_jc42(void);
|
||||
auto_init_jc42();
|
||||
|
||||
75
sys/auto_init/saul/auto_init_bme280.c
Normal file
75
sys/auto_init/saul/auto_init_bme280.c
Normal file
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Kees Bakker, SODAQ
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup auto_init_saul
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Auto initialization of BME280 driver.
|
||||
*
|
||||
* @author Kees Bakker <kees@sodaq.com>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef MODULE_BME280
|
||||
|
||||
#include "log.h"
|
||||
#include "saul_reg.h"
|
||||
|
||||
#include "bme280_params.h"
|
||||
#include "bme280.h"
|
||||
|
||||
/**
|
||||
* @brief Allocation of memory for device descriptors
|
||||
*/
|
||||
static bme280_t bme280_devs[BME280_NUMOF];
|
||||
|
||||
/**
|
||||
* @brief Memory for the SAUL registry entries
|
||||
*/
|
||||
static saul_reg_t saul_entries[BME280_NUMOF * 3];
|
||||
|
||||
void auto_init_bme280(void)
|
||||
{
|
||||
size_t se_ix = 0;
|
||||
for (size_t i = 0; i < BME280_NUMOF; i++) {
|
||||
LOG_DEBUG("[auto_init_saul] initializing BME280 #%u\n", i);
|
||||
int res = bme280_init(&bme280_devs[i], &bme280_params[i]);
|
||||
if (res < 0) {
|
||||
LOG_ERROR("[auto_init_saul] error initializing BME280 #%i\n", i);
|
||||
}
|
||||
else {
|
||||
/* temperature */
|
||||
saul_entries[se_ix].dev = &bme280_devs[i];
|
||||
saul_entries[se_ix].name = bme280_saul_reg_info[i][0].name;
|
||||
saul_entries[se_ix].driver = &bme280_temperature_saul_driver;
|
||||
saul_reg_add(&saul_entries[se_ix]);
|
||||
se_ix++;
|
||||
|
||||
/* relative humidity */
|
||||
saul_entries[se_ix].dev = &bme280_devs[i];
|
||||
saul_entries[se_ix].name = bme280_saul_reg_info[i][1].name;
|
||||
saul_entries[se_ix].driver = &bme280_relative_humidity_saul_driver;
|
||||
saul_reg_add(&saul_entries[se_ix]);
|
||||
se_ix++;
|
||||
|
||||
/* pressure */
|
||||
saul_entries[se_ix].dev = &bme280_devs[i];
|
||||
saul_entries[se_ix].name = bme280_saul_reg_info[i][2].name;
|
||||
saul_entries[se_ix].driver = &bme280_pressure_saul_driver;
|
||||
saul_reg_add(&saul_entries[se_ix]);
|
||||
se_ix++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
typedef int dont_be_pedantic;
|
||||
#endif /* MODULE_BME280 */
|
||||
7
tests/driver_bme280/Makefile
Normal file
7
tests/driver_bme280/Makefile
Normal file
@ -0,0 +1,7 @@
|
||||
APPLICATION = driver_bme280
|
||||
include ../Makefile.tests_common
|
||||
|
||||
USEMODULE += bme280
|
||||
USEMODULE += xtimer
|
||||
|
||||
include $(RIOTBASE)/Makefile.include
|
||||
30
tests/driver_bme280/Readme.md
Normal file
30
tests/driver_bme280/Readme.md
Normal file
@ -0,0 +1,30 @@
|
||||
## About
|
||||
This is a test application for the BME280 Pressure, Temperature and
|
||||
Humidity sensor.
|
||||
|
||||
## Usage
|
||||
The application will initialize the BME280 device and display its
|
||||
calibration coefficients. More information can be found on the
|
||||
[Bosch website][1]
|
||||
And in this [BST-BME280_DS001-11 datasheet] [2]
|
||||
|
||||
Notice that it is necessary to first read the temperature even if only one
|
||||
of the other values (humidity or pressure) is needed. This is described in
|
||||
the above mentioned datasheet.
|
||||
|
||||
After initialization, every 2 seconds, the application:
|
||||
* reads and displays the temperature (d°C);
|
||||
* reads and displays the pressure (Pa);
|
||||
* reads and displays the humidity (%rH);
|
||||
|
||||
## Overruling default parameters
|
||||
|
||||
If your device is at a different I2C address than the default (0x77) you
|
||||
can build the test as follows:
|
||||
|
||||
export CFLAGS=-DBME280_PARAM_I2C_ADDR=0x76
|
||||
make -C tests/driver_bme280 BOARD=sodaq-autonomo
|
||||
|
||||
[1]: http://www.bosch-sensortec.com/en/bst/products/all_products/bme280
|
||||
|
||||
[2]: https://ae-bst.resource.bosch.com/media/_tech/media/datasheets/BST-BME280_DS001-11.pdf
|
||||
101
tests/driver_bme280/main.c
Normal file
101
tests/driver_bme280/main.c
Normal file
@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Kees Bakker, SODAQ
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup tests
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Test application for the BME280 temperature, pressure
|
||||
* and humidity sensor.
|
||||
*
|
||||
* @author Kees Bakker <kees@sodaq.com>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "bme280_params.h"
|
||||
#include "bme280.h"
|
||||
#include "xtimer.h"
|
||||
|
||||
#define MAINLOOP_DELAY (2 * 1000 * 1000u) /* 2 seconds delay between printf's */
|
||||
|
||||
int main(void)
|
||||
{
|
||||
bme280_t dev;
|
||||
int result;
|
||||
|
||||
puts("BME280 test application\n");
|
||||
|
||||
printf("+------------Initializing------------+\n");
|
||||
result = bme280_init(&dev, &bme280_params[0]);
|
||||
if (result == -1) {
|
||||
puts("[Error] The given i2c is not enabled");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (result == -2) {
|
||||
printf("[Error] The sensor did not answer correctly at address 0x%02X\n", bme280_params[0].i2c_addr);
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("Initialization successful\n\n");
|
||||
|
||||
printf("+------------Calibration Data------------+\n");
|
||||
printf("dig_T1: %u\n", dev.calibration.dig_T1);
|
||||
printf("dig_T2: %i\n", dev.calibration.dig_T2);
|
||||
printf("dig_T3: %i\n", dev.calibration.dig_T3);
|
||||
|
||||
printf("dig_P1: %u\n", dev.calibration.dig_P1);
|
||||
printf("dig_P2: %i\n", dev.calibration.dig_P2);
|
||||
printf("dig_P3: %i\n", dev.calibration.dig_P3);
|
||||
printf("dig_P4: %i\n", dev.calibration.dig_P4);
|
||||
printf("dig_P5: %i\n", dev.calibration.dig_P5);
|
||||
printf("dig_P6: %i\n", dev.calibration.dig_P6);
|
||||
printf("dig_P7: %i\n", dev.calibration.dig_P7);
|
||||
printf("dig_P8: %i\n", dev.calibration.dig_P8);
|
||||
printf("dig_P9: %i\n", dev.calibration.dig_P9);
|
||||
|
||||
printf("dig_H1: %u\n", dev.calibration.dig_H1);
|
||||
printf("dig_H2: %i\n", dev.calibration.dig_H2);
|
||||
printf("dig_H3: %i\n", dev.calibration.dig_H3);
|
||||
printf("dig_H4: %i\n", dev.calibration.dig_H4);
|
||||
printf("dig_H5: %i\n", dev.calibration.dig_H5);
|
||||
printf("dig_H6: %i\n", dev.calibration.dig_H6);
|
||||
|
||||
printf("\n+--------Starting Measurements--------+\n");
|
||||
while (1) {
|
||||
int16_t temperature;
|
||||
uint32_t pressure;
|
||||
uint16_t humidity;
|
||||
|
||||
/* Get temperature in centi degrees Celsius */
|
||||
temperature = bme280_read_temperature(&dev);
|
||||
|
||||
/* Get pressure in Pa */
|
||||
pressure = bme280_read_pressure(&dev);
|
||||
|
||||
/* Get pressure in %rH */
|
||||
humidity = bme280_read_humidity(&dev);
|
||||
|
||||
printf("Temperature [°C]: %d.%d\n"
|
||||
"Pressure [Pa]: %lu\n"
|
||||
"Humidity [%%rH]: %u.%02u\n"
|
||||
"\n+-------------------------------------+\n",
|
||||
temperature / 100, (temperature % 100) / 10,
|
||||
(unsigned long)pressure,
|
||||
(unsigned int)(humidity / 100), (unsigned int)(humidity % 100));
|
||||
|
||||
xtimer_usleep(MAINLOOP_DELAY);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user