L14-Click 1.0
STM32WLE5CC LoRaWAN Sensor Platform
Loading...
Searching...
No Matches
bar_bmp585.c
Go to the documentation of this file.
1/*
2 * bar_bmp585.c
3 *
4 * Created on: 16. 2. 2026
5 * Author: Milan
6 */
7
8#include "bar_bmp585.h"
9
10#ifdef SENSOR_BAR_BMP585
11
12#include "i2c.h"
13#include "utils/mydefs.h"
14#include "mymems.h"
15#include "mysensors_base.h"
16#include <stdio.h>
17#include <math.h>
18#include "tmphm_sht45.h" // because of formula to sea level
19
20// BMP585 I2C Address (SDO connected to GND by default)
21#define BMP585_I2C_ADDR (0x46 << 1)
22
23// Register Map
24#define REG_CHIP_ID 0x01
25#define REG_STATUS 0x28
26#define REG_DATA_0 0x20 // Pressure data start
27#define REG_DATA_1 0x21
28#define REG_DATA_2 0x22
29#define REG_TEMP_DATA_0 0x1D // Temperature data start
30#define REG_TEMP_DATA_1 0x1E
31#define REG_TEMP_DATA_2 0x1F
32#define REG_OSR_CONFIG 0x36
33#define REG_ODR_CONFIG 0x37
34#define REG_INT_CONFIG 0x38
35#define REG_IF_CONFIG 0x39
36#define REG_CMD 0x7E
37
38// Chip ID value
39#define BMP585_CHIP_ID 0x51
40
41// Power modes
42#define BAR_MODE_STANDBY 0x00
43#define BAR_MODE_NORMAL 0x01
44#define BAR_MODE_FORCED 0x02
45#define BAR_MODE_DEEP_SLEEP 0x00 // Deep sleep is achieved via standby with specific config
46
47#define REG_FIFO_SEL 0x18
48#define REG_DSP_IIR 0x31
49
52static uint8_t _isBarometer = 0;
53
54/**
55 * @brief Check if sensor is turned on
56 */
57static HAL_StatusTypeDef bar_bmp585_IsOn(I2C_HandleTypeDef *hi2c, uint8_t *onOff)
58{
59 HAL_StatusTypeDef status = HAL_ERROR;
60
61 if (_isBarometer)
62 {
63 // Reading power control register
64 uint8_t pwr_ctrl = 0x00;
65 status = HAL_I2C_Mem_Read(hi2c, BMP585_I2C_ADDR, REG_ODR_CONFIG, 1, &pwr_ctrl, 1, 100);
66 if (status == HAL_OK)
67 if (onOff != 0)
68 *onOff = ((pwr_ctrl & 3) != 0); // Check if POWER_ODR is set (not in standby)
69 }
70 return status;
71}
72
73/**
74 * @brief Control sensor power mode
75 */
76static HAL_StatusTypeDef barometer_onOff(I2C_HandleTypeDef *hi2c, uint8_t onOff)
77{
78 HAL_StatusTypeDef status = HAL_ERROR;
79
80 if (_isBarometer)
81 {
82 // Configure ODR_CONFIG register, datasheet: Bar_bst-bmp585-ds003.pdf, chapter 8.34 Register(0x37)
83 // onOff = 0x00 for standby/deep sleep
84 // onOff = 0x01 for normal mode
85 // ODR - 0xC -> 80Hz
86 // ODR - 0x1C -> 1Hz allow DEEP standy: <5Hz and deep_dis = 0
87 // 7. deep_dis
88 // 6.-2. ODR
89 // 1.-0. POWER
90 uint8_t odr_config = 0b01110000 | ((onOff) ? 1 : 0);
91 status = HAL_I2C_Mem_Write(hi2c, BMP585_I2C_ADDR, REG_ODR_CONFIG, 1, &odr_config, 1, 100);
92 _isBarometer = (status == HAL_OK);
93 }
94 return status;
95}
96
97int8_t bar_bmp585_Is(I2C_HandleTypeDef *hi2c, int8_t tryInit)
98{
99 if (!_isBarometer && tryInit)
100 bar_bmp585_Init(hi2c);
101 return _isBarometer;
102}
103
104HAL_StatusTypeDef bar_bmp585_On(I2C_HandleTypeDef *hi2c)
105{
106 HAL_StatusTypeDef status = barometer_onOff(hi2c, 1);
107
108 _bar_bmp585Data.IsDataValid = 0;
109 if (status == HAL_OK)
110 {
111 _memsMainBlock.Sens_BarometerStart++;
113 HAL_Delay(5); // 4ms from deepsleep, 3ms sleep
114 }
115 return status;
116}
117
118HAL_StatusTypeDef bar_bmp585_Off(I2C_HandleTypeDef *hi2c)
119{
120 return barometer_onOff(hi2c, 0);
121}
122
123HAL_StatusTypeDef bar_bmp585_Init(I2C_HandleTypeDef *hi2c)
124{
125 HAL_StatusTypeDef status = I2C_IsDeviceReadyMT(hi2c, BMP585_I2C_ADDR, 2, 2); // first check
126
127 if (status == HAL_OK)
128 do
129 {
130 // Check CHIP_ID
131 uint8_t data = 0;
132 if ((status = HAL_I2C_Mem_Read(hi2c, BMP585_I2C_ADDR, REG_CHIP_ID, 1, &data, 1, 100)) != HAL_OK)
133 break;
134 if (data != BMP585_CHIP_ID)
135 {
136 status = HAL_ERROR;
137 break;
138 }
139 _isBarometer = 1; // because On/Off needs it
140
141 // Configure oversampling settings (OSR_CONFIG)
142 /*
143 * the configuration is in datasheet Bar_bst-bmp585-ds003.pdf, page, chapter 4.4.2
144 * 7. reserved
145 * 6. press_en
146 * 5-3 - OSR_T (temperature oversampling)
147 * 2-0 - OSR_P (pleasure overampling)
148 */
149 uint8_t osr_config = 0b01100100; // enable & high resolution
150 if ((status = HAL_I2C_Mem_Write(hi2c, BMP585_I2C_ADDR, REG_OSR_CONFIG, 1, &osr_config, 1, 100)) != HAL_OK)
151 break;
152
153 // for deep sleep:FIFO_SEL.fifo_frame_sel = DIS & DSP_IIR.set_iir_t = BYPASS & DSP_IIR.set_iir_p = BYPASS
154 uint8_t valDef = 0;
155 if ((status = HAL_I2C_Mem_Write(hi2c, BMP585_I2C_ADDR, REG_FIFO_SEL, 1, &valDef, 1, 100)) != HAL_OK)
156 break;
157 if ((status = HAL_I2C_Mem_Write(hi2c, BMP585_I2C_ADDR, REG_DSP_IIR, 1, &valDef, 1, 100)) != HAL_OK)
158 break;
159
160
161 // Check turning on/off
162 if ((status = bar_bmp585_On(hi2c)) != HAL_OK)
163 break;
164 if ((status = bar_bmp585_Off(hi2c)) != HAL_OK)
165 break;
166 } while (0);
167 _isBarometer = (status == HAL_OK);
168
169 return status;
170}
171
172HAL_StatusTypeDef bar_bmp585_Read(I2C_HandleTypeDef *hi2c)
173{
174 uint8_t raw_data[6]; // 3 bytes for pressure, 3 for temperature
175 HAL_StatusTypeDef status = HAL_ERROR;
176
177 if (_isBarometer)
178 {
179 do
180 {
181 // Check if sensor is turned on
182 if ((status = bar_bmp585_IsOn(hi2c, &raw_data[0])) != HAL_OK)
183 break;
184 if (!raw_data[0])
185 {
186 status = HAL_TIMEOUT;
187 break;
188 }
189
190 // Read Pressure (3 bytes) starting from DATA_0
191 if ((status = HAL_I2C_Mem_Read(hi2c, BMP585_I2C_ADDR, REG_DATA_0, 1, raw_data, 3, 100)) != HAL_OK)
192 break;
193
194 // Process Pressure (24-bit)
195 uint32_t raw_press = ((uint32_t)raw_data[2] << 16) | ((uint32_t)raw_data[1] << 8) | raw_data[0];
196
197 // Convert to hPa (output is in Pa * 64, so divide by 64 and then by 100 to get hPa)
198 _bar_bmp585Data.PressureSEA = _bar_bmp585Data.PressureABS = (float)raw_press / 6400.0f;
199
200 // Read Temperature (3 bytes) starting from TEMP_DATA_0
201 if ((status = HAL_I2C_Mem_Read(hi2c, BMP585_I2C_ADDR, REG_TEMP_DATA_0, 1, &raw_data[3], 3, 100)) != HAL_OK)
202 break;
203
204 // Process Temperature (24-bit)
205 uint32_t raw_temp = ((uint32_t)raw_data[5] << 16) | ((uint32_t)raw_data[4] << 8) | raw_data[3];
206
207 // Convert to Celsius (output is in Celsius * 65536, so divide by 65536)
208 _bar_bmp585Data.Temperature = (float)raw_temp / 65536.0f;
209 _bar_bmp585Data.IsDataValid = 1;
210
211 /*
212 * Calculate Sea Level Pressure
213 * Using barometric formula to convert station pressure to sea level pressure
214 * Psea = Pstation * [1 - (0.0065 * h) / (T + 273.15 + 0.0065 * h)]^(-5.257)
215 *
216 * Where:
217 * Pstation = measured pressure in hPa
218 * h = altitude in meters
219 * T = temperature in °C
220 */
221 // Relative pressure needs temperature value
222 if (_systemParams.SensAltitude > 0)
223 {
224#ifdef SENSOR_SHT45
225 float temp = (_tmphm_sht45Data.IsDataValid) ? _tmphm_sht45Data.Temperature : _bar_bmp585Data.Temperature;
226#else
227 float temp = _bar_bmp585Data.Temperature;
228#endif
229 _bar_bmp585Data.PressureSEA = _bar_bmp585Data.PressureABS
230 * pow(1.0 - (0.0065 * _systemParams.SensAltitude) / (temp + (0.0065 * _systemParams.SensAltitude) + 273.15), -5.257);
231 }
232 } while (0);
233 }
234 return status;
235}
236
237void bar_bmp585_LogData(char *buf)
238{
239 if (buf != NULL)
240 sprintf(buf, "|barometer ABS:" PRIf_02 ", SEA:" PRIf_02 ", temp:" PRIf_02 " ", PRIf_02D(_bar_bmp585Data.PressureABS), PRIf_02D(_bar_bmp585Data.PressureSEA),
241 PRIf_02D(_bar_bmp585Data.Temperature));
242}
243
244#endif
HAL_StatusTypeDef bar_bmp585_On(I2C_HandleTypeDef *hi2c)
Turn on sensor - wakeup the sensor and start to processing of pressure measure.
Definition bar_bmp585.c:104
HAL_StatusTypeDef bar_bmp585_Off(I2C_HandleTypeDef *hi2c)
Turn off sensor - stop measure and put sensor in very deep sleep mode.
Definition bar_bmp585.c:118
static HAL_StatusTypeDef bar_bmp585_IsOn(I2C_HandleTypeDef *hi2c, uint8_t *onOff)
Check if sensor is turned on.
Definition bar_bmp585.c:57
#define REG_TEMP_DATA_0
Definition bar_bmp585.c:29
#define REG_OSR_CONFIG
Definition bar_bmp585.c:32
#define REG_FIFO_SEL
Definition bar_bmp585.c:47
HAL_StatusTypeDef bar_bmp585_Read(I2C_HandleTypeDef *hi2c)
Read value from sensor, pressure and temperature. Sensor must be turned on before.
Definition bar_bmp585.c:172
void bar_bmp585_LogData(char *buf)
Log data to buffer.
Definition bar_bmp585.c:237
HAL_StatusTypeDef bar_bmp585_Init(I2C_HandleTypeDef *hi2c)
Initialize sensor, check if it really is this sensor. After check the sensor is turned off to save po...
Definition bar_bmp585.c:123
static HAL_StatusTypeDef barometer_onOff(I2C_HandleTypeDef *hi2c, uint8_t onOff)
Control sensor power mode.
Definition bar_bmp585.c:76
static uint8_t _isBarometer
Definition bar_bmp585.c:52
#define REG_ODR_CONFIG
Definition bar_bmp585.c:33
#define REG_CHIP_ID
Definition bar_bmp585.c:24
#define REG_DATA_0
Definition bar_bmp585.c:26
int8_t bar_bmp585_Is(I2C_HandleTypeDef *hi2c, int8_t tryInit)
Check if sensor is present.
Definition bar_bmp585.c:97
#define BMP585_I2C_ADDR
Definition bar_bmp585.c:21
#define BMP585_CHIP_ID
Definition bar_bmp585.c:39
#define REG_DSP_IIR
Definition bar_bmp585.c:48
bar_bmp585_t _bar_bmp585Data
Live measurement data from the BMP585 sensor; updated by bar_bmp585_Read().
Definition bar_bmp585.c:50
bar_bmp585_t _bck_bar_bmp585Data
Snapshot copy of the last completed BMP585 measurement; used for LoRaWAN transmission.
Definition bar_bmp585.c:51
This file contains all the function prototypes for the i2c.c file.
HAL_StatusTypeDef I2C_IsDeviceReadyMT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Trials, uint32_t Timeout)
Wrapper around HAL_I2C_IsDeviceReady() that recovers from a busy bus. If the HAL I2C bus is in a BUSY...
Definition i2c.c:158
#define PRIf_02D(fData)
Expands to integer and fractional arguments for use with PRIf_02. Splits a float/double into the inte...
Definition mydefs.h:38
#define PRIf_02
printf format string for printing a float/double as integer with 2 decimal places....
Definition mydefs.h:30
mems_MainBlock_t _memsMainBlock
Global instance of the main flash control block; loaded by mems_ReadMainBlock().
Definition mymems.c:29
HAL_StatusTypeDef mems_WriteMainBlock()
writing the main block on flash. The main block is stored on address 0
Definition mymems.c:142
systemParams_t _systemParams
Measurement data produced by the BMP585 barometric pressure sensor. Populated by bar_bmp585_Read(); c...
Definition bar_bmp585.h:30
void HAL_Delay(__IO uint32_t Delay)
Definition sys_app.c:369
tmphm_sht45_t _tmphm_sht45Data
Live measurement data from the SHT45 sensor; updated by tmphm_sht45_Read().
Definition tmphm_sht45.c:27