mirror of
https://github.com/utkumaden/esp-idf-bmx280
synced 2025-01-23 13:36:33 +01:00
Push current work.
This commit is contained in:
parent
7ace133e3d
commit
a9902750c2
@ -31,4 +31,107 @@ menu "BMX280 Options"
|
|||||||
default 5
|
default 5
|
||||||
help
|
help
|
||||||
Number of ticks to wait for I2C read/write operations.
|
Number of ticks to wait for I2C read/write operations.
|
||||||
|
|
||||||
|
menu "Default Configuration"
|
||||||
|
choice BMX280_DEFAULT_TEMPERATURE_OVERSAMPLING
|
||||||
|
prompt "Temperature Oversampling"
|
||||||
|
default BMX280_DEFAULT_TEMPERATURE_OVERSAMPLING_X2
|
||||||
|
help
|
||||||
|
Refer to BMP280/BME280 Datasheet for more information.
|
||||||
|
config BMX280_DEFAULT_TEMPERATURE_OVERSAMPLING_NONE
|
||||||
|
bool "None"
|
||||||
|
config BMX280_DEFAULT_TEMPERATURE_OVERSAMPLING_X1
|
||||||
|
bool "x1"
|
||||||
|
config BMX280_DEFAULT_TEMPERATURE_OVERSAMPLING_X2
|
||||||
|
bool "x2"
|
||||||
|
config BMX280_DEFAULT_TEMPERATURE_OVERSAMPLING_X4
|
||||||
|
bool "x4"
|
||||||
|
config BMX280_DEFAULT_TEMPERATURE_OVERSAMPLING_X8
|
||||||
|
bool "x8"
|
||||||
|
config BMX280_DEFAULT_TEMPERATURE_OVERSAMPLING_X16
|
||||||
|
bool "x16"
|
||||||
|
endchoice
|
||||||
|
|
||||||
|
choice BMX280_DEFAULT_PRESSURE_OVERSAMPLING
|
||||||
|
prompt "Pressure Oversampling"
|
||||||
|
default BMX280_DEFAULT_PRESSURE_OVERSAMPLING_X16
|
||||||
|
help
|
||||||
|
Refer to BMP280/BME280 Datasheet for more information.
|
||||||
|
config BMX280_DEFAULT_PRESSURE_OVERSAMPLING_NONE
|
||||||
|
bool "None"
|
||||||
|
config BMX280_DEFAULT_PRESSURE_OVERSAMPLING_X1
|
||||||
|
bool "x1"
|
||||||
|
config BMX280_DEFAULT_PRESSURE_OVERSAMPLING_X2
|
||||||
|
bool "x2"
|
||||||
|
config BMX280_DEFAULT_PRESSURE_OVERSAMPLING_X4
|
||||||
|
bool "x4"
|
||||||
|
config BMX280_DEFAULT_PRESSURE_OVERSAMPLING_X8
|
||||||
|
bool "x8"
|
||||||
|
config BMX280_DEFAULT_PRESSURE_OVERSAMPLING_X16
|
||||||
|
bool "x16"
|
||||||
|
endchoice
|
||||||
|
|
||||||
|
choice BMX280_DEFAULT_STANDBY
|
||||||
|
prompt "Cyclic Measurement Standby Time"
|
||||||
|
default BMX280_DEFAULT_STANDBY_0M5
|
||||||
|
help
|
||||||
|
Refer to BMP280/BME280 Datasheet for more information.
|
||||||
|
config BMX280_DEFAULT_STANDBY_0M5
|
||||||
|
bool "0.5ms"
|
||||||
|
config BMX280_DEFAULT_STANDBY_62M5
|
||||||
|
bool "62.5ms"
|
||||||
|
config BMX280_DEFAULT_STANDBY_125M
|
||||||
|
bool "125ms"
|
||||||
|
config BMX280_DEFAULT_STANDBY_250M
|
||||||
|
bool "250ms"
|
||||||
|
config BMX280_DEFAULT_STANDBY_500M
|
||||||
|
bool "500ms"
|
||||||
|
config BMX280_DEFAULT_STANDBY_1000M
|
||||||
|
bool "1000ms"
|
||||||
|
config BMX280_DEFAULT_STANDBY_10M
|
||||||
|
bool "BMP280: 2000ms // BME280: 10ms"
|
||||||
|
config BMX280_DEFAULT_STANDBY_20M
|
||||||
|
bool "BMP280: 4000ms // BME280: 20ms"
|
||||||
|
endchoice
|
||||||
|
|
||||||
|
choice BMX280_DEFAULT_IIR
|
||||||
|
prompt "IIR Filter Sensitivity"
|
||||||
|
default BMX280_DEFAULT_IIR_X16
|
||||||
|
help
|
||||||
|
Refer to BMP280/BME280 Datasheet for more information.
|
||||||
|
config BMX280_DEFAULT_IIR_NONE
|
||||||
|
bool "Filter Off"
|
||||||
|
config BMX280_DEFAULT_IIR_X2
|
||||||
|
bool "x2"
|
||||||
|
config BMX280_DEFAULT_IIR_X4
|
||||||
|
bool "x4"
|
||||||
|
config BMX280_DEFAULT_IIR_X8
|
||||||
|
bool "x8"
|
||||||
|
config BMX280_DEFAULT_IIR_X16
|
||||||
|
bool "x16"
|
||||||
|
endchoice
|
||||||
|
|
||||||
|
menu "BME280 Specific Options"
|
||||||
|
depends on !(BMX280_EXPECT_BMP280)
|
||||||
|
|
||||||
|
choice BMX280_DEFAULT_HUMIDITY_OVERSAMPLING
|
||||||
|
prompt "Humidity Oversampling"
|
||||||
|
default BMX280_DEFAULT_HUMIDITY_OVERSAMPLING_X1
|
||||||
|
help
|
||||||
|
Refer to BME280 Datasheet for more information.
|
||||||
|
config BMX280_DEFAULT_HUMIDITY_OVERSAMPLING_NONE
|
||||||
|
bool "None"
|
||||||
|
config BMX280_DEFAULT_HUMIDITY_OVERSAMPLING_X1
|
||||||
|
bool "x1"
|
||||||
|
config BMX280_DEFAULT_HUMIDITY_OVERSAMPLING_X2
|
||||||
|
bool "x2"
|
||||||
|
config BMX280_DEFAULT_HUMIDITY_OVERSAMPLING_X4
|
||||||
|
bool "x4"
|
||||||
|
config BMX280_DEFAULT_HUMIDITY_OVERSAMPLING_X8
|
||||||
|
bool "x8"
|
||||||
|
config BMX280_DEFAULT_HUMIDITY_OVERSAMPLING_X16
|
||||||
|
bool "x16"
|
||||||
|
endchoice
|
||||||
|
endmenu
|
||||||
|
endmenu
|
||||||
endmenu
|
endmenu
|
254
bmx280.c
254
bmx280.c
@ -6,6 +6,10 @@
|
|||||||
#include "bmx280.h"
|
#include "bmx280.h"
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
// [BME280] Register address of humidity least significant byte.
|
// [BME280] Register address of humidity least significant byte.
|
||||||
#define BMX280_REG_HUMI_LSB 0xFE
|
#define BMX280_REG_HUMI_LSB 0xFE
|
||||||
// [BME280] Register address of humidity most significant byte.
|
// [BME280] Register address of humidity most significant byte.
|
||||||
@ -40,7 +44,7 @@
|
|||||||
#define BMX280_REG_CAL_LO 0x88
|
#define BMX280_REG_CAL_LO 0x88
|
||||||
|
|
||||||
// Register address for sensor reset.
|
// Register address for sensor reset.
|
||||||
#define BXM280_REG_RESET 0xE0
|
#define BMX280_REG_RESET 0xE0
|
||||||
// Chip reset vector.
|
// Chip reset vector.
|
||||||
#define BMX280_RESET_VEC 0xB6
|
#define BMX280_RESET_VEC 0xB6
|
||||||
|
|
||||||
@ -56,9 +60,37 @@
|
|||||||
#define BMP280_ID2 0x58
|
#define BMP280_ID2 0x58
|
||||||
|
|
||||||
struct bmx280_t{
|
struct bmx280_t{
|
||||||
|
// I2C port.
|
||||||
i2c_port_t i2c_port;
|
i2c_port_t i2c_port;
|
||||||
|
// Slave Address of sensor.
|
||||||
uint8_t slave;
|
uint8_t slave;
|
||||||
|
// Chip ID of sensor
|
||||||
uint8_t chip_id;
|
uint8_t chip_id;
|
||||||
|
// Compensation data
|
||||||
|
struct {
|
||||||
|
uint16_t T1;
|
||||||
|
int16_t T2;
|
||||||
|
int16_t T3;
|
||||||
|
uint16_t P1;
|
||||||
|
int16_t P2;
|
||||||
|
int16_t P3;
|
||||||
|
int16_t P4;
|
||||||
|
int16_t P5;
|
||||||
|
int16_t P6;
|
||||||
|
int16_t P7;
|
||||||
|
int16_t P8;
|
||||||
|
int16_t P9;
|
||||||
|
#if !(CONFIG_BMX280_EXPECT_BMP280)
|
||||||
|
uint8_t H1;
|
||||||
|
int16_t H2;
|
||||||
|
uint8_t H3;
|
||||||
|
int16_t H4;
|
||||||
|
int16_t H5;
|
||||||
|
int8_t H6;
|
||||||
|
#endif
|
||||||
|
} cmps;
|
||||||
|
// Storage for a variable proportional to temperature.
|
||||||
|
int32_t t_fine;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -98,18 +130,25 @@ static esp_err_t bmx280_read(bmx280_t *bmx280, uint8_t addr, uint8_t *dout, size
|
|||||||
{
|
{
|
||||||
// Write register address
|
// Write register address
|
||||||
i2c_master_start(cmd);
|
i2c_master_start(cmd);
|
||||||
i2c_master_write_byte(cmd, bmx280->slave | I2C_MASTER_READ, true);
|
i2c_master_write_byte(cmd, bmx280->slave | I2C_MASTER_WRITE, true);
|
||||||
i2c_master_write_byte(cmd, addr, true);
|
i2c_master_write_byte(cmd, addr, true);
|
||||||
i2c_master_stop(cmd);
|
i2c_master_stop(cmd);
|
||||||
|
|
||||||
|
err = i2c_master_cmd_begin(bmx280->i2c_port, cmd, CONFIG_BMX280_TIMEOUT);
|
||||||
|
i2c_cmd_link_delete(cmd);
|
||||||
|
|
||||||
|
if (err == ESP_OK && (cmd = i2c_cmd_link_create()))
|
||||||
|
{
|
||||||
// Read Registers
|
// Read Registers
|
||||||
i2c_master_start(cmd);
|
i2c_master_start(cmd);
|
||||||
i2c_master_read(cmd, dout, size, true);
|
i2c_master_write_byte(cmd, bmx280->slave | I2C_MASTER_READ, true);
|
||||||
|
i2c_master_read(cmd, dout, size, I2C_MASTER_LAST_NACK);
|
||||||
i2c_master_stop(cmd);
|
i2c_master_stop(cmd);
|
||||||
|
|
||||||
err = i2c_master_cmd_begin(bmx280->i2c_port, cmd, 5);
|
err = i2c_master_cmd_begin(bmx280->i2c_port, cmd, CONFIG_BMX280_TIMEOUT);
|
||||||
|
|
||||||
i2c_cmd_link_delete(cmd);
|
i2c_cmd_link_delete(cmd);
|
||||||
|
}
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -135,7 +174,7 @@ static esp_err_t bmx280_write(bmx280_t* bmx280, uint8_t addr, const uint8_t *din
|
|||||||
}
|
}
|
||||||
i2c_master_stop(cmd);
|
i2c_master_stop(cmd);
|
||||||
|
|
||||||
err = i2c_master_cmd_begin(bmx280->i2c_port, cmd, 5);
|
err = i2c_master_cmd_begin(bmx280->i2c_port, cmd, CONFIG_BMX280_TIMEOUT);
|
||||||
i2c_cmd_link_delete(cmd);
|
i2c_cmd_link_delete(cmd);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@ -161,7 +200,7 @@ static esp_err_t bmx280_probe_address(bmx280_t *bmx280)
|
|||||||
#endif
|
#endif
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
ESP_LOGI("bmx280", "Probe success: address=%hhu, id=%hhu", bmx280->slave, bmx280->chip_id);
|
ESP_LOGI("bmx280", "Probe success: address=%hhx, id=%hhx", bmx280->slave, bmx280->chip_id);
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -170,7 +209,7 @@ static esp_err_t bmx280_probe_address(bmx280_t *bmx280)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ESP_LOGW("bmx280", "Probe failure: address=%hhu, id=%hhu, reason=%s", bmx280->slave, bmx280->chip_id, esp_err_to_name(err));
|
ESP_LOGW("bmx280", "Probe failure: address=%hhx, id=%hhx, reason=%s", bmx280->slave, bmx280->chip_id, esp_err_to_name(err));
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -200,3 +239,202 @@ static esp_err_t bmx280_probe(bmx280_t *bmx280)
|
|||||||
return err;
|
return err;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static esp_err_t bmx280_reset(bmx280_t *bmx280)
|
||||||
|
{
|
||||||
|
const static uint8_t din[] = { BMX280_RESET_VEC };
|
||||||
|
return bmx280_write(bmx280, BMX280_REG_RESET, din, sizeof din);
|
||||||
|
}
|
||||||
|
|
||||||
|
static esp_err_t bmx280_calibrate(bmx280_t *bmx280)
|
||||||
|
{
|
||||||
|
// Honestly, the best course of action is to read the high and low banks
|
||||||
|
// into a buffer, then put them in the calibration values. Makes code
|
||||||
|
// endian agnostic, and overcomes struct packing issues.
|
||||||
|
// Also the BME280 high bank is weird.
|
||||||
|
//
|
||||||
|
// Write and pray to optimizations is my new motto.
|
||||||
|
|
||||||
|
ESP_LOGI("bmx280", "Reading out calibration values...");
|
||||||
|
|
||||||
|
esp_err_t err;
|
||||||
|
uint8_t buf[26];
|
||||||
|
|
||||||
|
// Low Bank
|
||||||
|
err = bmx280_read(bmx280, BMX280_REG_CAL_LO, buf, sizeof buf);
|
||||||
|
|
||||||
|
if (err != ESP_OK) return err;
|
||||||
|
|
||||||
|
ESP_LOGI("bmx280", "Read Low Bank.");
|
||||||
|
|
||||||
|
bmx280->cmps.T1 = buf[0] | (buf[1] << 8);
|
||||||
|
bmx280->cmps.T2 = buf[2] | (buf[3] << 8);
|
||||||
|
bmx280->cmps.T3 = buf[4] | (buf[5] << 8);
|
||||||
|
bmx280->cmps.P1 = buf[6] | (buf[7] << 8);
|
||||||
|
bmx280->cmps.P2 = buf[8] | (buf[9] << 8);
|
||||||
|
bmx280->cmps.P3 = buf[10] | (buf[11] << 8);
|
||||||
|
bmx280->cmps.P4 = buf[12] | (buf[13] << 8);
|
||||||
|
bmx280->cmps.P5 = buf[14] | (buf[15] << 8);
|
||||||
|
bmx280->cmps.P6 = buf[16] | (buf[17] << 8);
|
||||||
|
bmx280->cmps.P7 = buf[18] | (buf[19] << 8);
|
||||||
|
bmx280->cmps.P8 = buf[20] | (buf[21] << 8);
|
||||||
|
bmx280->cmps.P9 = buf[22] | (buf[23] << 8);
|
||||||
|
|
||||||
|
#if !(CONFIG_BMX280_EXPECT_BMP280)
|
||||||
|
|
||||||
|
#if CONFIG_BMX280_EXPECT_DETECT
|
||||||
|
if (bmx280_isBME(bmx280->chip_id)) // Only conditional for detect scenario.
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
// First get H1 out of the way.
|
||||||
|
bmx280->cmps.H1 = buf[23];
|
||||||
|
|
||||||
|
err = bmx280_read(bmx280, BMX280_REG_CAL_HI, buf, 7);
|
||||||
|
|
||||||
|
if (err != ESP_OK) return err;
|
||||||
|
|
||||||
|
ESP_LOGI("bmx280", "Read High Bank.");
|
||||||
|
|
||||||
|
bmx280->cmps.H2 = buf[0] | (buf[1] << 8);
|
||||||
|
bmx280->cmps.H3 = buf[2];
|
||||||
|
bmx280->cmps.H4 = (buf[3] << 4) | (buf[4] & 0x0F);
|
||||||
|
bmx280->cmps.H5 = (buf[4] >> 4) | (buf[5] << 4);
|
||||||
|
bmx280->cmps.H6 = buf[6];
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
bmx280_t* bmx280_create(i2c_port_t port)
|
||||||
|
{
|
||||||
|
bmx280_t* bmx280 = malloc(sizeof(bmx280_t));
|
||||||
|
if (bmx280)
|
||||||
|
{
|
||||||
|
memset(bmx280, 0, sizeof(bmx280_t));
|
||||||
|
|
||||||
|
bmx280->i2c_port = port;
|
||||||
|
bmx280->slave = 0xDE;
|
||||||
|
bmx280->chip_id = 0xAD;
|
||||||
|
}
|
||||||
|
return bmx280;
|
||||||
|
}
|
||||||
|
|
||||||
|
void bmx280_close(bmx280_t *bmx280)
|
||||||
|
{
|
||||||
|
free(bmx280);
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t bmx280_init(bmx280_t* bmx280)
|
||||||
|
{
|
||||||
|
if (bmx280 == NULL) return ESP_ERR_INVALID_ARG;
|
||||||
|
|
||||||
|
esp_err_t error = bmx280_probe(bmx280) || bmx280_reset(bmx280);
|
||||||
|
|
||||||
|
if (error == ESP_OK)
|
||||||
|
{
|
||||||
|
// Give the sensor 10 ms delay to reset.
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(10));
|
||||||
|
|
||||||
|
// Read calibration data.
|
||||||
|
bmx280_calibrate(bmx280);
|
||||||
|
|
||||||
|
ESP_LOGI("bmx280", "Dumping calibration...");
|
||||||
|
ESP_LOG_BUFFER_HEX("bmx280", &bmx280->cmps, sizeof(bmx280->cmps));
|
||||||
|
}
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t bmx280_configure(bmx280_t* bmx280, bmx280_config_t *cfg)
|
||||||
|
{
|
||||||
|
if (bmx280 == NULL || cfg == NULL) return ESP_ERR_INVALID_ARG;
|
||||||
|
if (!bmx280_validate(bmx280)) return ESP_ERR_INVALID_STATE;
|
||||||
|
|
||||||
|
// Always set ctrl_meas first.
|
||||||
|
uint8_t num = (cfg->t_sampling << 5) | (cfg->p_sampling << 2) | BMX280_MODE_SLEEP;
|
||||||
|
esp_err_t err = bmx280_write(bmx280, BMX280_REG_MESCTL, &num, sizeof num);
|
||||||
|
|
||||||
|
if (err) return err;
|
||||||
|
|
||||||
|
// We can set cfg now.
|
||||||
|
num = (cfg->t_standby << 5) | (cfg->iir_filter << 2);
|
||||||
|
err = bmx280_write(bmx280, BMX280_REG_CONFIG, &num, sizeof num);
|
||||||
|
|
||||||
|
if (err) return err;
|
||||||
|
|
||||||
|
#if !(CONFIG_BMX280_EXPECT_BMP280)
|
||||||
|
#if CONFIG_BMX280_EXPECT_DETECT
|
||||||
|
if (bmx280_isBME(bmx280->chip_id))
|
||||||
|
#elif CONFIG_BMX280_EXPECT_BME280
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
num = cfg->h_sampling;
|
||||||
|
err = bmx280_write(bmx280, BMX280_REG_HUMCTL, &num, sizeof(num));
|
||||||
|
|
||||||
|
if (err) return err;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// f = 0;
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// HERE BE DRAGONS
|
||||||
|
// This code is revised from the Bosch code within the datasheet of the BME280.
|
||||||
|
// I do not understand it enough to tell you what it does.
|
||||||
|
// No touchies.
|
||||||
|
|
||||||
|
// Returns temperature in DegC, resolution is 0.01 DegC. Output value of “5123” equals 51.23 DegC.
|
||||||
|
// t_fine carries fine temperature as global value
|
||||||
|
int32_t BME280_compensate_T_int32(bmx280_t *bmx280, int32_t adc_T)
|
||||||
|
{
|
||||||
|
int32_t var1, var2, T;
|
||||||
|
var1 = ((((adc_T>>3) -((int32_t)bmx280->cmps.T1<<1))) * ((int32_t)bmx280->cmps.T2)) >> 11;
|
||||||
|
var2 =(((((adc_T>>4) -((int32_t)bmx280->cmps.T1)) * ((adc_T>>4) -((int32_t)bmx280->cmps.T1))) >> 12) * ((int32_t)bmx280->cmps.T3)) >> 14;
|
||||||
|
bmx280->t_fine = var1 + var2;
|
||||||
|
T = (bmx280->t_fine * 5 + 128) >> 8;
|
||||||
|
return T;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns pressure in Pa as unsigned 32 bit integer in Q24.8 format (24 integer bits and 8 fractional bits).
|
||||||
|
// Output value of “24674867” represents 24674867/256 = 96386.2 Pa = 963.862 hPa
|
||||||
|
uint32_t BME280_compensate_P_int64(bmx280_t *bmx280, int32_t adc_P)
|
||||||
|
{
|
||||||
|
int64_t var1, var2, p;
|
||||||
|
var1 = ((int64_t)bmx280->t_fine) -128000;
|
||||||
|
var2 = var1 * var1 * (int64_t)bmx280->cmps.P6;
|
||||||
|
var2 = var2 + ((var1*(int64_t)bmx280->cmps.P5)<<17);
|
||||||
|
var2 = var2 + (((int64_t)bmx280->cmps.P4)<<35);
|
||||||
|
var1 = ((var1 * var1 * (int64_t)bmx280->cmps.P3)>>8) + ((var1 * (int64_t)bmx280->cmps.P2)<<12);
|
||||||
|
var1 = (((((int64_t)1)<<47)+var1))*((int64_t)bmx280->cmps.P1)>>33;
|
||||||
|
if(var1 == 0){
|
||||||
|
return 0; // avoid exception caused by division by zero
|
||||||
|
}
|
||||||
|
p = 1048576-adc_P;
|
||||||
|
p = (((p<<31)-var2)*3125)/var1;
|
||||||
|
var1 = (((int64_t)bmx280->cmps.P9) * (p>>13) * (p>>13)) >> 25;
|
||||||
|
var2 =(((int64_t)bmx280->cmps.P8) * p) >> 19;
|
||||||
|
p = ((p + var1 + var2) >> 8) + (((int64_t)bmx280->cmps.P7)<<4);
|
||||||
|
return (uint32_t)p;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !CONFIG_BMX280_EXPECT_BMP280
|
||||||
|
|
||||||
|
// Returns humidity in %RH as unsigned 32 bit integer in Q22.10 format (22 integer and 10 fractional bits).
|
||||||
|
// Output value of “47445” represents 47445/1024 = 46.333 %RH
|
||||||
|
uint32_t bme280_compensate_H_int32(bmx280_t *bmx280, int32_t adc_H)
|
||||||
|
{
|
||||||
|
int32_t v_x1_u32r;
|
||||||
|
v_x1_u32r = (bmx280->t_fine -((int32_t)76800));
|
||||||
|
v_x1_u32r = (((((adc_H << 14) -(((int32_t)bmx280->cmps.H4) << 20) -(((int32_t)bmx280->cmps.H5) * v_x1_u32r)) + ((int32_t)16384)) >> 15) * (((((((v_x1_u32r * ((int32_t)bmx280->cmps.H6)) >> 10) * (((v_x1_u32r * ((int32_t)bmx280->cmps.H3)) >> 11) + ((int32_t)32768))) >> 10) + ((int32_t)2097152)) * ((int32_t)bmx280->cmps.H2) + 8192) >> 14));
|
||||||
|
v_x1_u32r = (v_x1_u32r -(((((v_x1_u32r >> 15) * (v_x1_u32r >> 15)) >> 7) * ((int32_t)bmx280->cmps.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(uint32_t)(v_x1_u32r>>12);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// END OF DRAGONS
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#define _BMX280_H_
|
#define _BMX280_H_
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <limits.h>
|
||||||
#include "driver/i2c.h"
|
#include "driver/i2c.h"
|
||||||
#include "sdkconfig.h"
|
#include "sdkconfig.h"
|
||||||
|
|
||||||
@ -15,15 +16,63 @@
|
|||||||
*/
|
*/
|
||||||
typedef struct bmx280_t bmx280_t;
|
typedef struct bmx280_t bmx280_t;
|
||||||
|
|
||||||
bmx280_t* bmx280_create();
|
#include "bmx280_bits.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an instance of the BMX280 driver.
|
||||||
|
* @param port The I2C port to use.
|
||||||
|
* @return A non-null pointer to the driver structure on success.
|
||||||
|
*/
|
||||||
|
bmx280_t* bmx280_create(i2c_port_t port);
|
||||||
|
/**
|
||||||
|
* Destroy your the instance.
|
||||||
|
* @param bmx280 The instance to destroy.
|
||||||
|
*/
|
||||||
void bmx280_close(bmx280_t* bmx280);
|
void bmx280_close(bmx280_t* bmx280);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Probe for the sensor and read calibration data.
|
||||||
|
* @param bmx280 Driver structure.
|
||||||
|
*/
|
||||||
esp_err_t bmx280_init(bmx280_t* bmx280);
|
esp_err_t bmx280_init(bmx280_t* bmx280);
|
||||||
esp_err_t bmx280_configure(bmx280_t* bmx280);
|
/**
|
||||||
|
* Configure the sensor with the given parameters.
|
||||||
|
* @param bmx280 Driver structure.
|
||||||
|
* @param configuration The configuration to use.
|
||||||
|
*/
|
||||||
|
esp_err_t bmx280_configure(bmx280_t* bmx280, bmx280_config_t *cfg);
|
||||||
|
|
||||||
esp_err_t bmx280_setCyclicMeasure(bmx280_t* bmx280);
|
esp_err_t bmx280_setMode(bmx280_t* bmx280, bmx280_mode_t mode);
|
||||||
|
|
||||||
esp_err_t bmx280_forceMeasurement(bmx280_t* bmx280);
|
bool bmx280_isSampling(bmx280_t* bmx280);
|
||||||
esp_err_t bmx280_readOutFloat(bmx280_t* bmx280, float* temperature, float* pressure, float* humidity);
|
|
||||||
|
/**
|
||||||
|
* Read sensor values as fixed point numbers.
|
||||||
|
* @param bmx280 Driver structure.
|
||||||
|
* @param temperature The temperature in C (0.01 degree C increments)
|
||||||
|
* @param pressure The pressure in Pa (1/256 Pa increments)
|
||||||
|
* @param humidity The humidity in %RH (1/1024 %RH increments) (UINT32_MAX when invlaid.)
|
||||||
|
*/
|
||||||
|
esp_err_t bmx280_readout(bmx280_t *bmx280, int32_t *temperature, uint32_t *pressure, uint32_t *humidity);
|
||||||
|
|
||||||
|
static inline void bmx280_readout2float(bmx280_t *bmx280, int32_t* tin, uint32_t *pin, uint32_t *hin, float *tout, float *pout, float *hout)
|
||||||
|
{
|
||||||
|
*tout = (float)*tin * 0.1f;
|
||||||
|
*pout = (float)*pin * (1.0f/256.0f);
|
||||||
|
*hout = (*hin == UINT32_MAX) ? -1.0f : (float)*hin * (1.0f/1024.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline esp_err_t bmx280_readoutFloat(bmx280_t *bmx280, float* temperature, float* pressure, float* humidity)
|
||||||
|
{
|
||||||
|
int32_t t; uint32_t p, h;
|
||||||
|
esp_err_t err = bmx280_readout(bmx280, &t, &p, &h);
|
||||||
|
|
||||||
|
if (err == ESP_OK)
|
||||||
|
{
|
||||||
|
bmx280_readout2float(bmx280, &t, &p, &h, temperature, pressure, humidity);
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
158
include/bmx280_bits.h
Normal file
158
include/bmx280_bits.h
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
#ifndef _BMX280_DEFAULT_H_
|
||||||
|
#define _BMX280_DEFAULT_H_
|
||||||
|
#ifndef _BMX280_H_
|
||||||
|
#error Never include "bmx280_bits.h" by itself. Remove this reference and use "bmx280.h" instead.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef enum bmx280_tsmpl_t {
|
||||||
|
BMX280_TEMPERATURE_OVERSAMPLING_NONE = 0x0,
|
||||||
|
BMX280_TEMPERATURE_OVERSAMPLING_X1,
|
||||||
|
BMX280_TEMPERATURE_OVERSAMPLING_X2,
|
||||||
|
BMX280_TEMPERATURE_OVERSAMPLING_X4,
|
||||||
|
BMX280_TEMPERATURE_OVERSAMPLING_X8,
|
||||||
|
BMX280_TEMPERATURE_OVERSAMPLING_X16,
|
||||||
|
} bmx280_tsmpl_t;
|
||||||
|
|
||||||
|
typedef enum bmx280_psmpl_t {
|
||||||
|
BMX280_PRESSURE_OVERSAMPLING_NONE = 0x0,
|
||||||
|
BMX280_PRESSURE_OVERSAMPLING_X1,
|
||||||
|
BMX280_PRESSURE_OVERSAMPLING_X2,
|
||||||
|
BMX280_PRESSURE_OVERSAMPLING_X4,
|
||||||
|
BMX280_PRESSURE_OVERSAMPLING_X8,
|
||||||
|
BMX280_PRESSURE_OVERSAMPLING_X16,
|
||||||
|
} bmx280_psmpl_t;
|
||||||
|
|
||||||
|
#if !(CONFIG_BMX280_EXPECT_BMP280)
|
||||||
|
typedef enum bme280_hsmpl_t {
|
||||||
|
BMX280_HUMIDITY_OVERSAMPLING_NONE = 0x0,
|
||||||
|
BMX280_HUMIDITY_OVERSAMPLING_X1,
|
||||||
|
BMX280_HUMIDITY_OVERSAMPLING_X2,
|
||||||
|
BMX280_HUMIDITY_OVERSAMPLING_X4,
|
||||||
|
BMX280_HUMIDITY_OVERSAMPLING_X8,
|
||||||
|
BMX280_HUMIDITY_OVERSAMPLING_X16,
|
||||||
|
} bme280_hsmpl_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef enum bmx280_tstby_t {
|
||||||
|
BMX280_STANDBY_0M5 = 0x0,
|
||||||
|
BMX280_STANDBY_62M5,
|
||||||
|
BMX280_STANDBY_125M,
|
||||||
|
BMX280_STANDBY_250M,
|
||||||
|
BMX280_STANDBY_500M,
|
||||||
|
BMX280_STANDBY_1000M,
|
||||||
|
BME280_STANDBY_10M,
|
||||||
|
BME280_STANDBY_20M,
|
||||||
|
BMP280_STANDBY_2000M = BME280_STANDBY_10M,
|
||||||
|
BMP280_STANDBY_4000M = BME280_STANDBY_20M,
|
||||||
|
} bmx280_tstby_t;
|
||||||
|
|
||||||
|
typedef enum bmx280_iirf_t {
|
||||||
|
BMX280_IIR_NONE = 0x0,
|
||||||
|
BMX280_IIR_X1,
|
||||||
|
BMX280_IIR_X2,
|
||||||
|
BMX280_IIR_X4,
|
||||||
|
BMX280_IIR_X8,
|
||||||
|
BMX280_IIR_X16,
|
||||||
|
} bmx280_iirf_t;
|
||||||
|
|
||||||
|
typedef enum bmx280_mode_t {
|
||||||
|
/** Sensor does no measurements. */
|
||||||
|
BMX280_MODE_SLEEP,
|
||||||
|
/** Sensor is in a forced measurement cycle. Sleeps after finishing. */
|
||||||
|
BMX280_MODE_FORCE,
|
||||||
|
/** Sensor does measurements. Never sleeps. */
|
||||||
|
BMX280_MODE_CYCLE,
|
||||||
|
} bmx280_mode_t;
|
||||||
|
|
||||||
|
typedef struct bmx280_config_t {
|
||||||
|
bmx280_tsmpl_t t_sampling;
|
||||||
|
bmx280_tsmpl_t p_sampling;
|
||||||
|
bmx280_tstby_t t_standby;
|
||||||
|
bmx280_iirf_t iir_filter;
|
||||||
|
#if !(CONFIG_BMX280_EXPECT_BMP280)
|
||||||
|
bmx280_tsmpl_t h_sampling;
|
||||||
|
#endif
|
||||||
|
} bmx280_config_t;
|
||||||
|
|
||||||
|
#if (CONFIG_BMX280_DEFAULT_TEMPERATURE_OVERSAMPLING_NONE)
|
||||||
|
#define BMX280_DEFAULT_TEMPERATURE_OVERSAMPLING BMX280_TEMPERATURE_OVERSAMPLING_NONE
|
||||||
|
#elif (CONFIG_BMX280_DEFAULT_TEMPERATURE_OVERSAMPLING_X1)
|
||||||
|
#define BMX280_DEFAULT_TEMPERATURE_OVERSAMPLING BMX280_TEMPERATURE_OVERSAMPLING_X1
|
||||||
|
#elif (CONFIG_BMX280_DEFAULT_TEMPERATURE_OVERSAMPLING_X2)
|
||||||
|
#define BMX280_DEFAULT_TEMPERATURE_OVERSAMPLING BMX280_TEMPERATURE_OVERSAMPLING_X2
|
||||||
|
#elif (CONFIG_BMX280_DEFAULT_TEMPERATURE_OVERSAMPLING_X4)
|
||||||
|
#define BMX280_DEFAULT_TEMPERATURE_OVERSAMPLING BMX280_TEMPERATURE_OVERSAMPLING_X4
|
||||||
|
#elif (CONFIG_BMX280_DEFAULT_TEMPERATURE_OVERSAMPLING_X8)
|
||||||
|
#define BMX280_DEFAULT_TEMPERATURE_OVERSAMPLING BMX280_TEMPERATURE_OVERSAMPLING_X8
|
||||||
|
#else
|
||||||
|
#define BMX280_DEFAULT_TEMPERATURE_OVERSAMPLING BMX280_TEMPERATURE_OVERSAMPLING_X16
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_BMX280_DEFAULT_PRESSURE_OVERSAMPLING_NONE
|
||||||
|
#define BMX280_DEFAULT_PRESSURE_OVERSAMPLING BMX280_PRESSURE_OVERSAMPLING_NONE
|
||||||
|
#elif CONFIG_BMX280_DEFAULT_PRESSURE_OVERSAMPLING_X1
|
||||||
|
#define BMX280_DEFAULT_PRESSURE_OVERSAMPLING BMX280_PRESSURE_OVERSAMPLING_X1
|
||||||
|
#elif CONFIG_BMX280_DEFAULT_PRESSURE_OVERSAMPLING_X2
|
||||||
|
#define BMX280_DEFAULT_PRESSURE_OVERSAMPLING BMX280_PRESSURE_OVERSAMPLING_X2
|
||||||
|
#elif CONFIG_BMX280_DEFAULT_PRESSURE_OVERSAMPLING_X4
|
||||||
|
#define BMX280_DEFAULT_PRESSURE_OVERSAMPLING BMX280_PRESSURE_OVERSAMPLING_X4
|
||||||
|
#elif CONFIG_BMX280_DEFAULT_PRESSURE_OVERSAMPLING_X8
|
||||||
|
#define BMX280_DEFAULT_PRESSURE_OVERSAMPLING BMX280_PRESSURE_OVERSAMPLING_X8
|
||||||
|
#else
|
||||||
|
#define BMX280_DEFAULT_PRESSURE_OVERSAMPLING BMX280_PRESSURE_OVERSAMPLING_X16
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (CONFIG_BMX280_DEFAULT_STANDBY_0M5)
|
||||||
|
#define BMX280_DEFAULT_STANDBY BMX280_STANDBY_0M5
|
||||||
|
#elif (CONFIG_BMX280_DEFAULT_STANDBY_62M5)
|
||||||
|
#define BMX280_DEFAULT_STANDBY BMX280_STANDBY_62M5
|
||||||
|
#elif (CONFIG_BMX280_DEFAULT_STANDBY_125M)
|
||||||
|
#define BMX280_DEFAULT_STANDBY BMX280_STANDBY_125M
|
||||||
|
#elif (CONFIG_BMX280_DEFAULT_STANDBY_250M)
|
||||||
|
#define BMX280_DEFAULT_STANDBY BMX280_STANDBY_250M
|
||||||
|
#elif (CONFIG_BMX280_DEFAULT_STANDBY_500M)
|
||||||
|
#define BMX280_DEFAULT_STANDBY BMX280_STANDBY_500M
|
||||||
|
#elif (CONFIG_BMX280_DEFAULT_STANDBY_1000M)
|
||||||
|
#define BMX280_DEFAULT_STANDBY BMX280_STANDBY_1000M
|
||||||
|
#elif (CONFIG_BMX280_DEFAULT_STANDBY_10M)
|
||||||
|
#define BMX280_DEFAULT_STANDBY BME280_STANDBY_10M
|
||||||
|
#else
|
||||||
|
#define BMX280_DEFAULT_STANDBY BMX280_STANDBY_20M
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (CONFIG_BMX280_DEFAULT_IIR_NONE)
|
||||||
|
#define BMX280_DEFAULT_IIR BMX280_IIR_NONE
|
||||||
|
#elif (CONFIG_BMX280_DEFAULT_IIR_X2)
|
||||||
|
#define BMX280_DEFAULT_IIR BMX280_IIR_X2
|
||||||
|
#elif (CONFIG_BMX280_DEFAULT_IIR_X4)
|
||||||
|
#define BMX280_DEFAULT_IIR BMX280_IIR_X4
|
||||||
|
#elif (CONFIG_BMX280_DEFAULT_IIR_X8)
|
||||||
|
#define BMX280_DEFAULT_IIR BMX280_IIR_X8
|
||||||
|
#else
|
||||||
|
#define BMX280_DEFAULT_IIR BMX280_IIR_X16
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_BMX280_EXPECT_BMP280
|
||||||
|
#if (CONFIG_BMX280_DEFAULT_HUMIDITY_OVERSAMPLING_NONE)
|
||||||
|
#define BMX280_DEFAULT_HUMIDITY_OVERSAMPLING BMX280_HUMIDITY_OVERSAMPLING_NONE
|
||||||
|
#elif (CONFIG_BMX280_DEFAULT_HUMIDITY_OVERSAMPLING_X1)
|
||||||
|
#define BMX280_DEFAULT_HUMIDITY_OVERSAMPLING BMX280_HUMIDITY_OVERSAMPLING_X1
|
||||||
|
#elif (CONFIG_BMX280_DEFAULT_HUMIDITY_OVERSAMPLING_X2)
|
||||||
|
#define BMX280_DEFAULT_HUMIDITY_OVERSAMPLING BMX280_HUMIDITY_OVERSAMPLING_X2
|
||||||
|
#elif (CONFIG_BMX280_DEFAULT_HUMIDITY_OVERSAMPLING_X4)
|
||||||
|
#define BMX280_DEFAULT_HUMIDITY_OVERSAMPLING BMX280_HUMIDITY_OVERSAMPLING_X4
|
||||||
|
#elif (CONFIG_BMX280_DEFAULT_HUMIDITY_OVERSAMPLING_X8)
|
||||||
|
#define BMX280_DEFAULT_HUMIDITY_OVERSAMPLING BMX280_HUMIDITY_OVERSAMPLING_X8
|
||||||
|
#else
|
||||||
|
#define BMX280_DEFAULT_HUMIDITY_OVERSAMPLING BMX280_HUMIDITY_OVERSAMPLING_X16
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !(CONFIG_BMX280_EXPECT_BMP280)
|
||||||
|
#define BMX280_DEFAULT_CONFIG ((bmx280_config_t) { BMX280_DEFAULT_TEMPERATURE_OVERSAMPLING, BMX280_DEFAULT_PRESSURE_OVERSAMPLING, BMX280_DEFAULT_STANDBY, BMX280_DEFAULT_IIR, BMX280_DEFAULT_HUMIDITY_OVERSAMPLING })
|
||||||
|
#else
|
||||||
|
#define BMX280_DEFAULT_CONFIG ((bmx280_config_t) { BMX280_DEFAULT_TEMPERATURE_OVERSAMPLING, BMX280_DEFAULT_PRESSURE_OVERSAMPLING, BMX280_DEFAULT_STANDBY, BMX280_DEFAULT_IIR})
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue
Block a user