Feature/ms561101ba03 (#308)
Driver for the ms561101ba03 barometric pressure sensor
This commit is contained in:
parent
44124409e4
commit
34d783a289
5 changed files with 366 additions and 0 deletions
4
examples/ms561101ba03/Makefile
Normal file
4
examples/ms561101ba03/Makefile
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
PROGRAM = ms561101ba03
|
||||||
|
EXTRA_COMPONENTS = extras/i2c extras/ms561101ba03
|
||||||
|
ESPBAUD = 460800
|
||||||
|
include ../../common.mk
|
39
examples/ms561101ba03/main.c
Normal file
39
examples/ms561101ba03/main.c
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
/*
|
||||||
|
* Example of using MS561101ba03 driver
|
||||||
|
*
|
||||||
|
* Copyright (C) 2016 Bernhard Guillon <Bernhard.Guillon@web.de>
|
||||||
|
*
|
||||||
|
* Loosely based on main.c with:
|
||||||
|
* Copyright (C) 2016 Ruslan V. Uss <unclerus@gmail.com>
|
||||||
|
* BSD Licensed as described in the file LICENSE
|
||||||
|
*/
|
||||||
|
#include <esp/uart.h>
|
||||||
|
#include <espressif/esp_common.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <i2c/i2c.h>
|
||||||
|
#include <ms561101ba03/ms561101ba03.h>
|
||||||
|
|
||||||
|
#define SCL_PIN 5
|
||||||
|
#define SDA_PIN 4
|
||||||
|
|
||||||
|
void user_init(void)
|
||||||
|
{
|
||||||
|
i2c_init(SCL_PIN, SDA_PIN);
|
||||||
|
|
||||||
|
uart_set_baud(0, 115200);
|
||||||
|
printf("SDK version:%s\n\n", sdk_system_get_sdk_version());
|
||||||
|
|
||||||
|
ms561101ba03_config_data_t conf = {0,0,0,0,0,0};
|
||||||
|
ms561101ba03_result_t result = {0,0};
|
||||||
|
ms561101ba03_t device= {MS561101BA03_ADDR_CSB_LOW, MS561101BA03_OSR_4096, conf, result, 0};
|
||||||
|
|
||||||
|
while (!ms561101ba03_init(&device))
|
||||||
|
printf("Device not found\n");
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
if (!ms561101ba03_get_sensor_data(&device))
|
||||||
|
printf("Error reading sensor data from device");
|
||||||
|
printf("Temperature in C * 100: %i \nPressure in mbar * 100: %i\n", device.result.temperature, device.result.pressure);
|
||||||
|
}
|
||||||
|
}
|
9
extras/ms561101ba03/component.mk
Normal file
9
extras/ms561101ba03/component.mk
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
# Component makefile for extras/ms561101ba03
|
||||||
|
|
||||||
|
# expected anyone using this driver includes it as 'ms561101ba03/ms561101ba03.h'
|
||||||
|
INC_DIRS += $(ms561101ba03_ROOT)..
|
||||||
|
|
||||||
|
# args for passing into compile rule generation
|
||||||
|
ms561101ba03_SRC_DIR = $(ms561101ba03_ROOT)
|
||||||
|
|
||||||
|
$(eval $(call component_compile_rules,ms561101ba03))
|
218
extras/ms561101ba03/ms561101ba03.c
Normal file
218
extras/ms561101ba03/ms561101ba03.c
Normal file
|
@ -0,0 +1,218 @@
|
||||||
|
/*
|
||||||
|
* Driver for barometic pressure sensor ms511-01BA03
|
||||||
|
*
|
||||||
|
* Copyright (C) 2016 Bernhard Guillon <Bernhard.Guillon@web.de>
|
||||||
|
*
|
||||||
|
* Loosely based on hmc5831 with:
|
||||||
|
* Copyright (C) 2016 Ruslan V. Uss <unclerus@gmail.com>
|
||||||
|
* BSD Licensed as described in the file LICENSE
|
||||||
|
*/
|
||||||
|
#include "ms561101ba03.h"
|
||||||
|
#include <i2c/i2c.h>
|
||||||
|
#include <espressif/esp_common.h>
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
|
||||||
|
#define CONVERT_D1 0x40
|
||||||
|
#define CONVERT_D2 0x50
|
||||||
|
#define ADC_READ 0x00
|
||||||
|
|
||||||
|
/*
|
||||||
|
* FIXME:
|
||||||
|
* The chip has different response times for the different oversampling rates
|
||||||
|
* (0.5 ms/1.1ms/2.1ms/4.1ms/8.22ms)
|
||||||
|
* For now use a save value.
|
||||||
|
*/
|
||||||
|
#define CONVERSION_TIME 20 / portTICK_PERIOD_MS // milliseconds
|
||||||
|
|
||||||
|
static const uint8_t RESET = 0x1E;
|
||||||
|
|
||||||
|
static inline bool reset(uint8_t addr)
|
||||||
|
{
|
||||||
|
uint8_t buf[1] = { RESET };
|
||||||
|
return i2c_slave_write(addr, buf, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool read_prom(ms561101ba03_t *dev)
|
||||||
|
{
|
||||||
|
uint8_t tmp[2] = {0,0};
|
||||||
|
|
||||||
|
if (!i2c_slave_read(dev->addr, 0xA2 , tmp, 2))
|
||||||
|
return false;
|
||||||
|
dev->config_data.sens = tmp[0] << 8 | tmp[1];
|
||||||
|
|
||||||
|
if (!i2c_slave_read(dev->addr, 0xA4 , tmp, 2))
|
||||||
|
return false;
|
||||||
|
dev->config_data.off = tmp[0] << 8 | tmp[1];
|
||||||
|
|
||||||
|
if (!i2c_slave_read(dev->addr, 0xA6 , tmp, 2))
|
||||||
|
return false;
|
||||||
|
dev->config_data.tcs = tmp[0] << 8 | tmp[1];
|
||||||
|
|
||||||
|
if (!i2c_slave_read(dev->addr, 0xA8 , tmp, 2))
|
||||||
|
return false;
|
||||||
|
dev->config_data.tco = tmp[0] << 8 | tmp[1];
|
||||||
|
|
||||||
|
if (!i2c_slave_read(dev->addr, 0xAA , tmp, 2))
|
||||||
|
return false;
|
||||||
|
dev->config_data.t_ref = tmp[0] << 8 | tmp[1];
|
||||||
|
|
||||||
|
if (!i2c_slave_read(dev->addr, 0xAC , tmp, 2))
|
||||||
|
return false;
|
||||||
|
dev->config_data.tempsens = tmp[0] << 8 | tmp[1];
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool start_pressure_conversion(ms561101ba03_t *dev) //D1
|
||||||
|
{
|
||||||
|
uint8_t buf = CONVERT_D1 + dev->osr;
|
||||||
|
return i2c_slave_write(dev->addr, &buf, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool start_temperature_conversion(ms561101ba03_t *dev) //D2
|
||||||
|
{
|
||||||
|
uint8_t buf = CONVERT_D2 + dev->osr;
|
||||||
|
return i2c_slave_write(dev->addr, &buf, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool read_adc(uint8_t addr, uint32_t *result)
|
||||||
|
{
|
||||||
|
*result = 0;
|
||||||
|
uint8_t tmp[3];
|
||||||
|
if (!i2c_slave_read(addr, 0x00, tmp, 3))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
*result = (tmp[0] << 16) | (tmp[1] << 8) | tmp[2];
|
||||||
|
|
||||||
|
// If we are to fast the ADC will return 0 instead of the actual result
|
||||||
|
if (*result == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void calc_dt(ms561101ba03_t *dev, uint32_t digital_temperature)
|
||||||
|
{
|
||||||
|
// Difference between actual and reference digital_temperature
|
||||||
|
// dT = D2 - T_ref = D2 - C5 *2^8
|
||||||
|
dev->dT = digital_temperature - ((int32_t)dev->config_data.t_ref << 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int32_t calc_temp(ms561101ba03_t *dev)
|
||||||
|
{
|
||||||
|
// Actual temerature (-40...85C with 0.01 resulution)
|
||||||
|
// TEMP = 20C +dT * TEMPSENSE =2000 + dT * C6 / 2^23
|
||||||
|
return (int32_t)((int64_t)2000 +(int64_t)dev->dT * (int64_t)dev->config_data.tempsens / (int64_t)8388608);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int64_t calc_off(ms561101ba03_t *dev)
|
||||||
|
{
|
||||||
|
// Offset at actual temperature
|
||||||
|
// OFF=OFF_t1 + TCO * dT = OFF_t1(C2) * 2^16 + (C4*dT)/2^7
|
||||||
|
return (int64_t)((int64_t)dev->config_data.off * (int64_t)65536) + (((int64_t)dev->config_data.tco * (int64_t)dev->dT ) /(int64_t)128);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int64_t calc_sens(ms561101ba03_t *dev)
|
||||||
|
{
|
||||||
|
// Senisitivity at actual temperature
|
||||||
|
// SENS=SENS_t1 + TCS *dT = SENS_t1(C1) *2^15 + (TCS(C3) *dT)/2^8
|
||||||
|
return (int64_t)(((int64_t)dev->config_data.sens) *(int64_t)32768) + (((int64_t)dev->config_data.tcs * (int64_t)dev->dT ) /(int64_t)256);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int32_t calc_p(uint32_t digital_pressure, int64_t sens, int64_t off)
|
||||||
|
{
|
||||||
|
// Temperature compensated pressure (10...1200mbar with 0.01mbar resolution
|
||||||
|
// P = digital pressure value * SENS - OFF = (D1 * SENS/2^21 -OFF)/2^15
|
||||||
|
return (int32_t) (((int64_t)digital_pressure * (int64_t)((int64_t)sens / (int64_t)0x200000) - (int64_t)off) / (int64_t)32768);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool get_raw_temperature(ms561101ba03_t *dev, uint32_t *result)
|
||||||
|
{
|
||||||
|
if (!start_temperature_conversion(dev))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
vTaskDelay(CONVERSION_TIME);
|
||||||
|
|
||||||
|
if (!read_adc(dev->addr, result))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool get_raw_pressure(ms561101ba03_t *dev, uint32_t *result)
|
||||||
|
{
|
||||||
|
if (!start_pressure_conversion(dev))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
vTaskDelay(CONVERSION_TIME);
|
||||||
|
|
||||||
|
if (!read_adc(dev->addr, result))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////Public//////////////////////////////////////
|
||||||
|
|
||||||
|
bool ms561101ba03_get_sensor_data(ms561101ba03_t *dev)
|
||||||
|
{
|
||||||
|
// Second order temperature compensation see datasheet p8
|
||||||
|
uint32_t raw_pressure = 0;
|
||||||
|
if (!get_raw_pressure(dev, &raw_pressure))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
uint32_t raw_temperature = 0;
|
||||||
|
if(!get_raw_temperature(dev, &raw_temperature))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
calc_dt(dev, raw_temperature);
|
||||||
|
int64_t temp = calc_temp(dev);
|
||||||
|
int64_t off = calc_off(dev);
|
||||||
|
int64_t sens = calc_sens(dev);
|
||||||
|
|
||||||
|
//Set defaults for temp >= 2000
|
||||||
|
int64_t t_2 = 0;
|
||||||
|
int64_t off_2 = 0;
|
||||||
|
int64_t sens_2 = 0;
|
||||||
|
int64_t help = 0;
|
||||||
|
if (temp < 2000)
|
||||||
|
{
|
||||||
|
//Low temperature
|
||||||
|
t_2 = ((dev->dT * dev->dT) >> 31); // T2 = dT^2/2^31
|
||||||
|
help = (temp-2000);
|
||||||
|
help = 5 * help * help;
|
||||||
|
off_2 = help >> 1; // OFF_2 = 5 * (TEMP - 2000)^2/2^1
|
||||||
|
sens_2 = help >> 2; // SENS_2 = 5 * (TEMP - 2000)^2/2^2
|
||||||
|
if(temp < -1500)
|
||||||
|
{
|
||||||
|
// Very low temperature
|
||||||
|
help = (temp+1500);
|
||||||
|
help = help * help;
|
||||||
|
off_2 = off_2 + 7 * help; // OFF_2 = OFF_2 + 7 * (TEMP + 1500)^2
|
||||||
|
sens_2 = sens_2 + ((11 * help) >> 1); // SENS_2 = SENS_2 + 7 * (TEMP + 1500)^2/2^1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
temp = temp - t_2;
|
||||||
|
off = off - off_2;
|
||||||
|
sens = sens - sens_2;
|
||||||
|
|
||||||
|
dev->result.pressure = calc_p(raw_pressure, sens, off);
|
||||||
|
dev->result.temperature = (int32_t)temp;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ms561101ba03_init(ms561101ba03_t *dev)
|
||||||
|
{
|
||||||
|
// First of all we need to reset the chip
|
||||||
|
if(!reset(dev->addr))
|
||||||
|
return false;
|
||||||
|
// Wait a bit for the device to reset
|
||||||
|
vTaskDelay(CONVERSION_TIME);
|
||||||
|
// Get the config
|
||||||
|
if(!read_prom(dev))
|
||||||
|
return false;
|
||||||
|
// Every thing went fine
|
||||||
|
return true;
|
||||||
|
}
|
96
extras/ms561101ba03/ms561101ba03.h
Normal file
96
extras/ms561101ba03/ms561101ba03.h
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
/*
|
||||||
|
* Driver for barometic pressure sensor MS5611-01BA03
|
||||||
|
*
|
||||||
|
* Copyright (C) 2016 Bernhard Guillon <Bernhard.Guillon@begu.org>
|
||||||
|
*
|
||||||
|
* Loosely based on hmc5831 with:
|
||||||
|
* Copyright (C) 2016 Ruslan V. Uss <unclerus@gmail.com>
|
||||||
|
* BSD Licensed as described in the file LICENSE
|
||||||
|
*/
|
||||||
|
#ifndef EXTRAS_MS561101BA03_H_
|
||||||
|
#define EXTRAS_MS561101BA03_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MS561101BA03_ADDR_CSB_HIGH 0x76
|
||||||
|
#define MS561101BA03_ADDR_CSB_LOW 0x77
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Oversampling ratio
|
||||||
|
*/
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
MS561101BA03_OSR_256 = 0x00, //!< 256 samples per measurement
|
||||||
|
MS561101BA03_OSR_512 = 0x02, //!< 512 samples per measurement
|
||||||
|
MS561101BA03_OSR_1024 = 0x04, //!< 1024 samples per measurement
|
||||||
|
MS561101BA03_OSR_2048 = 0x06, //!< 2048 samples per measurement
|
||||||
|
MS561101BA03_OSR_4096 = 0x08 //!< 4096 samples per measurement
|
||||||
|
} ms561101ba03_osr_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configuration data
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint16_t sens; //!< C1 Pressure sensitivity | SENS_t1
|
||||||
|
uint16_t off; //!< C2 Pressure offset | OFF_t1
|
||||||
|
uint16_t tcs; //!< C3 Temperature coefficient of pressure sensitivity | TCS
|
||||||
|
uint16_t tco; //!< C4 Temperature coefficient of pressuer offset | TCO
|
||||||
|
uint16_t t_ref; //!< C5 Reference temperature | T_ref
|
||||||
|
uint16_t tempsens; //!< C6 Temperature coefficient of the temperature | TEMPSENSE
|
||||||
|
} ms561101ba03_config_data_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Result
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int32_t pressure; //!< Compensated pressure from 10 mbar to 1200 mbar with 0.01 mbar resolution
|
||||||
|
int32_t temperature; //!< Temperature from -40 C to 85 C with 0.01 C resulution
|
||||||
|
} ms561101ba03_result_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Device descriptor
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint8_t addr; //!< I2C address
|
||||||
|
ms561101ba03_osr_t osr; //!< Oversampling setting
|
||||||
|
ms561101ba03_config_data_t config_data; //!< Device configuration, filled upon initalize
|
||||||
|
ms561101ba03_result_t result; //!< Result, filled upon co
|
||||||
|
int32_t dT; //!< delta temperature, filled uppon co and for internal use only
|
||||||
|
} ms561101ba03_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize device and read its configuration
|
||||||
|
* @param dev Pointer to device descriptor
|
||||||
|
* @return true if no errors occured
|
||||||
|
*/
|
||||||
|
bool ms561101ba03_init(ms561101ba03_t *dev);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get sensor data with second order temperature compensation
|
||||||
|
*
|
||||||
|
* The result will be:
|
||||||
|
* Compensated pressure from 10 mbar to 1200 mbar with 0.01 mbar resolution
|
||||||
|
* dev->result.pressure
|
||||||
|
*
|
||||||
|
* Temperature from -40 C to 85 C with 0.01 C resulution
|
||||||
|
* dev->result.temperature
|
||||||
|
*
|
||||||
|
* @param dev Pointer to device descriptor
|
||||||
|
* @return true if no errors occured
|
||||||
|
*/
|
||||||
|
bool ms561101ba03_get_sensor_data(ms561101ba03_t *dev);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* EXTRAS_MS561101BA03_H_ */
|
Loading…
Reference in a new issue