Add support and sample of use of BME280 temp/humidity/pressure sensor
This commit is contained in:
parent
b90795782a
commit
fb82a6f0b2
3 changed files with 588 additions and 0 deletions
304
source/examples/bme280/bme280.cpp
Normal file
304
source/examples/bme280/bme280.cpp
Normal file
|
@ -0,0 +1,304 @@
|
|||
/****************************************************************************
|
||||
* extdrv/bme280_humidity_sensor.c
|
||||
*
|
||||
* BME280 I2C Barometric, humidity and temperature sensor driver
|
||||
*
|
||||
* Copyright 2016 Nathael Pajani <nathael.pajani@ed3l.fr>
|
||||
*
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*************************************************************************** */
|
||||
|
||||
|
||||
#include <cstdint>
|
||||
#include <errno.h>
|
||||
|
||||
#include "bme280.h"
|
||||
|
||||
|
||||
/* Sensor config
|
||||
* Performs configuration of the sensor and recovers calibration data from sensor's internal
|
||||
* memory.
|
||||
* Return value:
|
||||
* Upon successfull completion, returns 0. On error, returns a negative integer
|
||||
* equivalent to errors from glibc.
|
||||
*/
|
||||
#define CONF_BUF_SIZE 6
|
||||
bme280::bme280(MicroBit* uB, MicroBitI2C* uBi2c, uint8_t addr, uint8_t humidity_os, uint8_t temp_os,
|
||||
uint8_t pressure_os, uint8_t sensor_mode, uint8_t standby, uint8_t coeff)
|
||||
:
|
||||
uBit(uB), i2c(uBi2c), address(addr), probe_ok(0), humidity_oversampling(humidity_os), temp_oversampling(temp_os), pressure_oversampling(pressure_os), mode(sensor_mode), standby_len(standby), filter_coeff(coeff)
|
||||
{
|
||||
int ret = 0;
|
||||
char cmd_buf[CONF_BUF_SIZE] = {
|
||||
BME280_REGS(ctrl_humidity), (uint8_t)BME280_CTRL_HUM(humidity_oversampling),
|
||||
BME280_REGS(ctrl_measure), (uint8_t)BME280_CTRL_MEA(pressure_oversampling, temp_oversampling, mode),
|
||||
BME280_REGS(config), (uint8_t)BME280_CONFIG(standby_len, filter_coeff),
|
||||
};
|
||||
|
||||
if (probe_sensor() != 1) {
|
||||
probe_ok = 0;
|
||||
uBit->display.scroll("No Device");
|
||||
}
|
||||
/* Send the configuration */
|
||||
ret = i2c->write(address, cmd_buf, CONF_BUF_SIZE);
|
||||
if (ret != MICROBIT_OK) {
|
||||
probe_ok = 0;
|
||||
uBit->display.scroll("Conf Error");
|
||||
}
|
||||
/* Get the calibration data */
|
||||
if (get_calibration_data() != MICROBIT_OK)
|
||||
uBit->display.scroll("Calibration Error");
|
||||
}
|
||||
|
||||
|
||||
/* Check the sensor presence, return 1 if found */
|
||||
#define PROBE_BUF_SIZE 1
|
||||
int bme280::probe_sensor()
|
||||
{
|
||||
char cmd_buf[PROBE_BUF_SIZE] = {BME280_REGS(chip_id)};
|
||||
uint8_t id = 0;
|
||||
|
||||
/* Did we already probe the sensor ? */
|
||||
if (probe_ok != 1) {
|
||||
i2c->write(address, cmd_buf,1,true);
|
||||
int ret = i2c->read(address, (char*)&id, 1);
|
||||
if (ret == MICROBIT_OK && id != BME280_ID) {
|
||||
probe_ok = 0;
|
||||
} else {
|
||||
probe_ok = 1;
|
||||
}
|
||||
}
|
||||
return probe_ok;
|
||||
}
|
||||
|
||||
|
||||
/* Get calibration data from internal sensor memory
|
||||
* These values are required to compute the pressure, temperature and humidity values
|
||||
* from the uncompensated "raw" values read from the sensor ADC result registers.
|
||||
* Calibration data for pressure and temperature is aligned, packed, and in little
|
||||
* endian byte order, so it is stored directly to the cal structure.
|
||||
* Calibration data for humidity is split among different registers and not aligned,
|
||||
* so we use a temporary data buffer.
|
||||
* Note : On the LPC822 the I2C bus requires some time to go idle, so we need to
|
||||
* sleep some time between two conscutive I2C access.
|
||||
* this should be done in the I2C driver, but is not yet implemented, so it is
|
||||
* done here. These msleep() calls may be removed for other micro-controllers, and
|
||||
* when the I2C driver for the LPC822 is imporved.
|
||||
* Return value:
|
||||
* Upon successfull completion, returns 0. On error, returns a negative integer
|
||||
* equivalent to errors from glibc.
|
||||
*/
|
||||
#define CAL_CMD_SIZE 1
|
||||
int bme280::get_calibration_data()
|
||||
{
|
||||
int ret = 0;
|
||||
char cmd_buf[CAL_CMD_SIZE] = { BME280_CAL_REGS(T)};
|
||||
|
||||
/* Give some time for I2C bus to go idle */
|
||||
uBit->sleep(1);
|
||||
/* Easy part : Temperature and Presure calibration data is packed, aligned, and
|
||||
* in little endian byte order */
|
||||
/* Start by reading temperature calibration data */
|
||||
i2c->write(address,cmd_buf,1,true);
|
||||
ret = i2c->read(address, (char*)&(cal.T1), BME280_CAL_REGS_T_LEN);
|
||||
if (ret != MICROBIT_OK) {
|
||||
probe_ok = 0;
|
||||
return ret;
|
||||
}
|
||||
uBit->sleep(1); /* Again some time for I2C bus to go idle */
|
||||
/* Read pressure calibration data */
|
||||
cmd_buf[0] = BME280_CAL_REGS(P);
|
||||
i2c->write(address,cmd_buf,1,true);
|
||||
ret = i2c->read(address, (char*)&(cal.P1), BME280_CAL_REGS_P_LEN);
|
||||
if (ret != MICROBIT_OK) {
|
||||
probe_ok = 0;
|
||||
return ret;
|
||||
}
|
||||
uBit->sleep(1); /* ... */
|
||||
|
||||
/* Read humidity calibration data. This one is split among bytes and not aligned. use
|
||||
* temporary data buffer and then copy to calibration structure. */
|
||||
/* First part */
|
||||
uint8_t data[BME280_CAL_REGS_H_LEN];
|
||||
|
||||
cmd_buf[0] = BME280_CAL_REGS(Ha);
|
||||
i2c->write(address,cmd_buf,1,true);
|
||||
ret = i2c->read(address, (char*)data, BME280_CAL_REGS_Ha_LEN);
|
||||
if (ret != MICROBIT_OK) {
|
||||
probe_ok = 0;
|
||||
return ret;
|
||||
}
|
||||
uBit->sleep(1); /* ... */
|
||||
/* Second part */
|
||||
cmd_buf[0] = BME280_CAL_REGS(Hb);
|
||||
i2c->write(address,cmd_buf,1,true);
|
||||
ret = i2c->read(address, (char*)data+BME280_CAL_REGS_Ha_LEN, BME280_CAL_REGS_Hb_LEN);
|
||||
if (ret != MICROBIT_OK) {
|
||||
probe_ok = 0;
|
||||
return ret;
|
||||
}
|
||||
/* And store in calibration structure */
|
||||
cal.H1 = data[0];
|
||||
cal.H2 = ((data[1] & 0xFF) | ((data[2] & 0xFF) << 8));
|
||||
cal.H3 = data[3];
|
||||
cal.H4 = (((data[4] & 0xFF) << 4) | (data[5] & 0x0F));
|
||||
cal.H5 = (((data[6] & 0xFF) << 4) | ((data[5] & 0xF0) >> 4));
|
||||
cal.H6 = data[7];
|
||||
|
||||
return MICROBIT_OK;
|
||||
}
|
||||
|
||||
|
||||
/* Humidity, Temperature and Pressure Read
|
||||
* Performs a read of the data from the sensor.
|
||||
* 'hum', 'temp' and 'pressure': integer addresses for conversion result.
|
||||
* Return value(s):
|
||||
* Upon successfull completion, returns 0 and the raw sensor values read are placed in the
|
||||
* provided integer(s). On error, returns a negative integer equivalent to errors from
|
||||
* glibc.
|
||||
*/
|
||||
#define READ_CMD_SIZE 1
|
||||
int bme280::sensor_read(uint32_t* pressure, int32_t* temp, uint16_t* hum)
|
||||
{
|
||||
int ret = 0;
|
||||
char cmd_buf[READ_CMD_SIZE] = { BME280_REGS(raw_data)};
|
||||
uint8_t data[BME280_DATA_SIZE];
|
||||
|
||||
if (probe_ok != 1) {
|
||||
if (probe_sensor() != 1) {
|
||||
return -1;
|
||||
}
|
||||
uBit->sleep(1);
|
||||
}
|
||||
|
||||
/* Start by reading all data */
|
||||
i2c->write(address,cmd_buf,1,true);
|
||||
ret = i2c->read(address, (char*)data, BME280_DATA_SIZE);
|
||||
if (ret != MICROBIT_OK) {
|
||||
probe_ok = 0;
|
||||
return ret;
|
||||
}
|
||||
if (pressure != NULL) {
|
||||
*pressure = BME280_DATA_20(data[0], data[1], data[2]);
|
||||
}
|
||||
if (temp != NULL) {
|
||||
*temp = BME280_DATA_20(data[3], data[4], data[5]);
|
||||
}
|
||||
if (hum != NULL) {
|
||||
*hum = BME280_DATA_16(data[6], data[7]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Compute actual temperature from uncompensated temperature
|
||||
* Param :
|
||||
* - utemp : uncompensated (raw) temperature value read from sensor
|
||||
* Returns the value in 0.01 degree Centigrade
|
||||
* Output value of "5123" equals 51.23 DegC.
|
||||
*/
|
||||
int bme280::compensate_temperature(int utemp)
|
||||
{
|
||||
int tmp1 = 0, tmp2 = 0;
|
||||
int temperature = 0;
|
||||
|
||||
/* Calculate tmp1 */
|
||||
tmp1 = ((((utemp >> 3) - ((int)cal.T1 << 1))) * cal.T2) >> 11;
|
||||
/* Calculate tmp2 */
|
||||
tmp2 = (((utemp >> 4) - (int)cal.T1) * ((utemp >> 4) - (int)cal.T1)) >> 12;
|
||||
tmp2 = (tmp2 * cal.T3) >> 14;
|
||||
/* Calculate t_fine */
|
||||
fine_temp = tmp1 + tmp2;
|
||||
/* Calculate temperature */
|
||||
temperature = (fine_temp * 5 + 128) >> 8;
|
||||
return temperature;
|
||||
}
|
||||
|
||||
/* Compute actual pressure from uncompensated pressure
|
||||
* Returns the value in Pascal(Pa) or 0 on error (invalid value which would cause division by 0).
|
||||
* Output value of "96386" equals 96386 Pa = 963.86 hPa = 963.86 millibar
|
||||
*/
|
||||
uint32_t bme280::compensate_pressure(int uncomp_pressure)
|
||||
{
|
||||
int tmp1 = 0, tmp2 = 0, tmp3 = 0;
|
||||
uint32_t pressure = 0;
|
||||
|
||||
/* Calculate tmp1 */
|
||||
tmp1 = (fine_temp >> 1) - 64000;
|
||||
/* Calculate tmp2 */
|
||||
tmp2 = (((tmp1 >> 2) * (tmp1 >> 2)) >> 11) * cal.P6;
|
||||
tmp2 = tmp2 + ((tmp1 * cal.P5) << 1);
|
||||
tmp2 = (tmp2 >> 2) + (cal.P4 << 16);
|
||||
/* Update tmp1 */
|
||||
tmp3 = (cal.P3 * (((tmp1 >> 2) * (tmp1 >> 2)) >> 13)) >> 3;
|
||||
tmp1 = (tmp3 + ((cal.P2 * tmp1) >> 1)) >> 18;
|
||||
tmp1 = (((32768 + tmp1)) * (int)cal.P1) >> 15;
|
||||
/* Calculate pressure */
|
||||
pressure = ((uint32_t)(1048576 - uncomp_pressure) - (tmp2 >> 12)) * 3125;
|
||||
|
||||
/* Avoid exception caused by division by zero */
|
||||
if (tmp1 == 0) {
|
||||
return 0;
|
||||
}
|
||||
if (pressure < 0x80000000) {
|
||||
pressure = (pressure << 1) / ((uint32_t)tmp1);
|
||||
} else {
|
||||
pressure = (pressure / (uint32_t)tmp1) * 2;
|
||||
}
|
||||
|
||||
tmp1 = (cal.P9 * ((int)(((pressure >> 3) * (pressure >> 3)) >> 13))) >> 12;
|
||||
tmp2 = (((int)(pressure >> 2)) * cal.P8) >> 13;
|
||||
pressure = (uint32_t)((int)pressure + ((tmp1 + tmp2 + cal.P7) >> 4));
|
||||
|
||||
return pressure;
|
||||
}
|
||||
|
||||
|
||||
/* Compute actual humidity from uncompensated humidity
|
||||
* Returns the value in 0.01 %rH
|
||||
* Output value of "4132" equals 41.32 %rH.
|
||||
*/
|
||||
uint32_t bme280::compensate_humidity(int uncomp_humidity)
|
||||
{
|
||||
int tmp1 = 0, tmp2 = 0, tmp3 = 0;
|
||||
uint32_t humidity = 0;
|
||||
|
||||
/* Calculate tmp1 */
|
||||
tmp1 = fine_temp - 76800;
|
||||
/* Calculate tmp2 */
|
||||
tmp2 = ((uncomp_humidity << 14) - (cal.H4 << 20) - (cal.H5 * tmp1) + 16384) >> 15;
|
||||
/* Calculate tmp3 */
|
||||
tmp3 = ((((tmp1 * cal.H6) >> 10) * (((tmp1 * (int)cal.H3) >> 11) + 32768)) >> 10) + 2097152;
|
||||
/* Update tmp1 */
|
||||
tmp1 = tmp2 * ((tmp3 * cal.H2 + 8192) >> 14);
|
||||
tmp1 = tmp1 - (((((tmp1 >> 15) * (tmp1 >> 15)) >> 7) * (int)cal.H1) >> 4);
|
||||
if (tmp1 < 0) {
|
||||
tmp1 = 0;
|
||||
}
|
||||
if (tmp1 > 419430400) {
|
||||
tmp1 = 419430400;
|
||||
}
|
||||
humidity = (uint32_t)(tmp1 >> 12);
|
||||
/* Convert from 32bit integer in Q22.10 format (22 integer 10 fractional bits) to a value
|
||||
* in 0.01 %rH :
|
||||
* A value of 42313 represents 42313 / 1024 = 41.321 %rH, convert it to 4132, which is 41.32 %rH.
|
||||
*/
|
||||
humidity = ((humidity >> 10) * 100) + ((((humidity & 0x3FF) * 1000) >> 10) / 10);
|
||||
return humidity;
|
||||
|
||||
}
|
224
source/examples/bme280/bme280.h
Normal file
224
source/examples/bme280/bme280.h
Normal file
|
@ -0,0 +1,224 @@
|
|||
/****************************************************************************
|
||||
* bme280.h
|
||||
*
|
||||
* BME280 I2C Barometric, humidity and temperature sensor driver
|
||||
*
|
||||
* Copyright 2016 Nathael Pajani <nathael.pajani@ed3l.fr>
|
||||
* Copyright 2022 Anthony Chomienne <anthony@mob-dev.fr>
|
||||
*
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*************************************************************************** */
|
||||
|
||||
/**
|
||||
* This code is mainly an adaptation of code provided by Techno-Innov (Nathael Pajani <nathael.pajani@ed3l.fr>)
|
||||
* www.techno-innov.fr
|
||||
* http://git.techno-innov.fr
|
||||
*/
|
||||
|
||||
#ifndef BME280_H
|
||||
#define BME280_H
|
||||
|
||||
#include <cstdint>
|
||||
#include <MicroBit.h>
|
||||
|
||||
#define BME280_ADDR 0xEC
|
||||
|
||||
struct bme280_calibration_data {
|
||||
/* Temperature */
|
||||
uint16_t T1; /* 0x88 */
|
||||
int16_t T2; /* 0x8A */
|
||||
int16_t T3; /* 0x8C */
|
||||
/* Pressure */
|
||||
uint16_t P1; /* 0x8E */
|
||||
int16_t P2; /* 0x90 */
|
||||
int16_t P3; /* 0x92 */
|
||||
int16_t P4; /* 0x94 */
|
||||
int16_t P5; /* 0x96 */
|
||||
int16_t P6; /* 0x98 */
|
||||
int16_t P7; /* 0x9A */
|
||||
int16_t P8; /* 0x9C */
|
||||
int16_t P9; /* 0x9E */
|
||||
/* Humidity */
|
||||
uint8_t H1; /* 0xA1 */
|
||||
int16_t H2; /* 0xE1 .. 0xE2 */
|
||||
uint8_t H3; /* 0xE3 */
|
||||
int16_t H4; /* 0xE4 .. 0xE5[3:0] */
|
||||
int16_t H5; /* 0xE5[7:4] .. 0xE6 */
|
||||
int8_t H6; /* 0xE7 */
|
||||
};
|
||||
|
||||
#define BME280_DATA_SIZE 8
|
||||
struct bme280_data {
|
||||
uint8_t pressure[3]; /* 0xF7 .. 0xF9 */
|
||||
uint8_t temperature[3]; /* 0xFA .. 0xFC */
|
||||
uint8_t humidity[2]; /* 0xFD .. 0xFE */
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
|
||||
struct bme280_calibration_regs {
|
||||
/* Temperature */
|
||||
uint16_t T[3]; /* 0x88 .. 0x8D */
|
||||
/* Pressure */
|
||||
uint16_t P[9]; /* 0x8E .. 0x9F */
|
||||
/* Humidity */
|
||||
uint8_t res0[1];
|
||||
uint8_t Ha; /* 0xA1 */
|
||||
uint8_t res1[63];
|
||||
uint8_t Hb[7]; /* 0xE1 .. 0xE7 */
|
||||
};
|
||||
#define BME280_CAL_REGS(x) (((uint8_t)offsetof(struct bme280_calibration_regs, x)) + 0x88)
|
||||
#define BME280_CAL_REGS_T_LEN 6
|
||||
#define BME280_CAL_REGS_P_LEN 18
|
||||
#define BME280_CAL_REGS_Ha_LEN 1
|
||||
#define BME280_CAL_REGS_Hb_LEN 7
|
||||
#define BME280_CAL_REGS_H_LEN (BME280_CAL_REGS_Ha_LEN + BME280_CAL_REGS_Hb_LEN)
|
||||
|
||||
struct bme280_internal_regs {
|
||||
uint8_t chip_id; /* 0xD0 - Value should be 0x60 */
|
||||
uint8_t reserved0[15];
|
||||
uint8_t reset; /* 0xE0 */
|
||||
uint8_t reserved1[17];
|
||||
uint8_t ctrl_humidity; /* 0xF2 */
|
||||
uint8_t status; /* 0xF3 */
|
||||
uint8_t ctrl_measure; /* 0xF4 */
|
||||
uint8_t config; /* 0xF5 */
|
||||
uint8_t reserved2[1];
|
||||
union {
|
||||
uint8_t raw_data[8]; /* 0xF7 .. 0xFE */
|
||||
struct bme280_data data;
|
||||
};
|
||||
} __attribute__ ((__packed__));
|
||||
#define BME280_REGS(x) (((uint8_t)offsetof(struct bme280_internal_regs, x)) + 0xD0)
|
||||
|
||||
|
||||
#define BME280_ID 0x60
|
||||
#define BME280_RESET_MAGIC 0xB6
|
||||
|
||||
/* Oversampling values */
|
||||
#define BME280_SKIP 0x00
|
||||
#define BME280_OS_x1 0x01
|
||||
#define BME280_OS_x2 0x02
|
||||
#define BME280_OS_x4 0x03
|
||||
#define BME280_OS_x8 0x04
|
||||
#define BME280_OS_x16 0x05
|
||||
|
||||
/* Mode values */
|
||||
#define BME280_SLEEP 0x00
|
||||
#define BME280_FORCED 0x01
|
||||
#define BME280_NORMAL 0x03
|
||||
|
||||
/* Control registers helpers */
|
||||
#define BME280_CTRL_HUM(hum) ((hum) & 0x07)
|
||||
#define BME280_CTRL_MEA(pres, temp, mode) \
|
||||
( (((temp) & 0x07) << 5) | (((pres) & 0x07) << 2) | ((mode) & 0x03) )
|
||||
|
||||
|
||||
/* Standby */
|
||||
#define BME280_SB_05ms 0x00
|
||||
#define BME280_SB_10ms 0x06
|
||||
#define BME280_SB_20ms 0x07
|
||||
#define BME280_SB_62ms 0x01
|
||||
#define BME280_SB_125ms 0x02
|
||||
#define BME280_SB_250ms 0x03
|
||||
#define BME280_SB_500ms 0x04
|
||||
#define BME280_SB_1000ms 0x05
|
||||
|
||||
/* Filter */
|
||||
#define BME280_FILT_OFF 0x00
|
||||
#define BME280_FILT_2 0x01
|
||||
#define BME280_FILT_4 0x02
|
||||
#define BME280_FILT_8 0x03
|
||||
#define BME280_FILT_16 0x04
|
||||
|
||||
/* Config register helper */
|
||||
#define BME280_CONFIG(stb, filt) ( (((stb) & 0x07) << 5) | (((filt) & 0x07) << 2) )
|
||||
|
||||
|
||||
/* Data helpers */
|
||||
#define BME280_DATA_20(msb, lsb, xlsb) ((((msb) & 0xFF) << 12) | (((lsb) & 0xFF) << 4) | (((xlsb) & 0xF0) >> 4))
|
||||
#define BME280_DATA_16(msb, lsb) ((((msb) & 0xFF) << 8) | ((lsb) & 0xFF))
|
||||
|
||||
class bme280 {
|
||||
|
||||
public:
|
||||
/* Sensor config
|
||||
* Performs configuration of the sensor and recovers calibration data from sensor's internal
|
||||
* memory.
|
||||
*/
|
||||
bme280(MicroBit* uB, MicroBitI2C* uBi2c, uint8_t addr = BME280_ADDR, uint8_t humidity_oversampling = BME280_OS_x16,
|
||||
uint8_t temp_oversampling = BME280_OS_x16, uint8_t pressure_oversampling = BME280_OS_x16, uint8_t mode = BME280_NORMAL,
|
||||
uint8_t standby_len = BME280_SB_62ms, uint8_t filter_coeff = BME280_FILT_OFF);
|
||||
|
||||
/* Check the sensor presence, return 1 if found */
|
||||
int probe_sensor();
|
||||
|
||||
/* Humidity, Temperature and Pressure Read
|
||||
* Performs a read of the data from the sensor.
|
||||
* 'hum', 'temp' and 'pressure': integer addresses for conversion result.
|
||||
* Return value(s):
|
||||
* Upon successfull completion, returns 0 and the raw sensor values read are placed in the
|
||||
* provided integer(s). On error, returns a negative integer equivalent to errors from
|
||||
* glibc.
|
||||
*/
|
||||
int sensor_read(uint32_t* pressure, int32_t* temp, uint16_t* hum);
|
||||
|
||||
|
||||
/* Compute actual temperature from uncompensated temperature
|
||||
* Param :
|
||||
* - conf : bme280_sensor_configuration structure, with calibration data read from sensor
|
||||
* - utemp : uncompensated (raw) temperature value read from sensor
|
||||
* Returns the value in 0.01 degree Centigrade
|
||||
* Output value of "5123" equals 51.23 DegC.
|
||||
*/
|
||||
int compensate_temperature(int utemp);
|
||||
|
||||
|
||||
/* Compute actual pressure from uncompensated pressure
|
||||
* Returns the value in Pascal(Pa) or 0 on error (invalid value which would cause division by 0).
|
||||
* Output value of "96386" equals 96386 Pa = 963.86 hPa = 963.86 millibar
|
||||
*/
|
||||
uint32_t compensate_pressure(int uncomp_pressure);
|
||||
|
||||
|
||||
/* Compute actual humidity from uncompensated humidity
|
||||
* Returns the value in 0.01 %rH
|
||||
* Output value of "4132" equals 41.32 %rH.
|
||||
*/
|
||||
uint32_t compensate_humidity(int uncomp_humidity);
|
||||
|
||||
private:
|
||||
|
||||
int get_calibration_data();
|
||||
|
||||
|
||||
MicroBit* uBit;
|
||||
MicroBitI2C* i2c;
|
||||
uint8_t address;
|
||||
uint8_t probe_ok;
|
||||
uint8_t humidity_oversampling;
|
||||
uint8_t temp_oversampling;
|
||||
uint8_t pressure_oversampling;
|
||||
uint8_t mode;
|
||||
uint8_t standby_len;
|
||||
uint8_t filter_coeff;
|
||||
struct bme280_calibration_data cal;
|
||||
int fine_temp;
|
||||
|
||||
};
|
||||
|
||||
#endif /* BME280_H */
|
||||
|
||||
|
60
source/examples/bme280/main.cpp
Normal file
60
source/examples/bme280/main.cpp
Normal file
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 British Broadcasting Corporation.
|
||||
This software is provided by Lancaster University by arrangement with the BBC.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "MicroBit.h"
|
||||
#include "bme280.h"
|
||||
|
||||
MicroBit uBit;
|
||||
MicroBitI2C i2c(I2C_SDA0,I2C_SCL0);
|
||||
|
||||
int main()
|
||||
{
|
||||
// Initialise the micro:bit runtime.
|
||||
uBit.init();
|
||||
|
||||
bme280 bme(&uBit,&i2c);
|
||||
uint32_t pressure = 0;
|
||||
int32_t temp = 0;
|
||||
uint16_t humidite = 0;
|
||||
|
||||
while(true)
|
||||
{
|
||||
bme.sensor_read(&pressure, &temp, &humidite);
|
||||
int tmp = bme.compensate_temperature(temp);
|
||||
int pres = bme.compensate_pressure(pressure)/100;
|
||||
int hum = bme.compensate_humidity(humidite);
|
||||
ManagedString display = "Temp:" + ManagedString(tmp/100) + "." + (tmp > 0 ? ManagedString(tmp%100): ManagedString((-tmp)%100))+" C";
|
||||
uBit.display.scroll(display.toCharArray());
|
||||
display = "Humi:" + ManagedString(hum/100) + "." + ManagedString(tmp%100)+" rH";
|
||||
uBit.display.scroll(display.toCharArray());
|
||||
display = "Pres:" + ManagedString(pres)+" hPa";
|
||||
uBit.display.scroll(display.toCharArray());
|
||||
uBit.sleep(1000);
|
||||
}
|
||||
|
||||
release_fiber();
|
||||
|
||||
}
|
||||
|
Loading…
Reference in a new issue