L14-Click 1.0
STM32WLE5CC LoRaWAN Sensor Platform
Loading...
Searching...
No Matches
bar_ils22qs.c
Go to the documentation of this file.
1/*
2 * bar_ils22qs.c
3 *
4 * Created on: 27. 12. 2025
5 * Author: Milan
6 */
7
8#include "bar_ils22qs.h"
9
10#ifdef SENSOR_BAR_ILS22QS
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 see low level
19
20// ILPS22QS I2C Address (SDO connected to GND by default on Barometer 8 Click)
21#define ILPS22QS_I2C_ADDR (0x5C << 1)
22
23// Register Map
24#define REG_WHO_AM_I 0x0F
25#define REG_CTRL_REG1 0x10
26#define REG_PRESS_OUT_XL 0x28
27#define REG_PRESS_OFFSET 0x1A // MT 10.1.2026 factory offset
28// Device ID
29#define ILPS22QS_ID 0xB4
30
33static uint8_t _isBarometer = 0;
34
35static HAL_StatusTypeDef bar_ils22qs_IsOn(I2C_HandleTypeDef *hi2c, uint8_t *onOff)
36{
37 HAL_StatusTypeDef status = HAL_ERROR;
38
39 if (_isBarometer)
40 {
41 // reading CTRL_REG1
42 uint8_t ctrl1 = 0x00;
43 status = HAL_I2C_Mem_Read(hi2c, ILPS22QS_I2C_ADDR, REG_CTRL_REG1, 1, &ctrl1, 1, 100);
44 if (status == HAL_OK)
45 if (onOff != 0)
46 *onOff = ((ctrl1 & 0x50) != 0);
47 }
48 return status;
49
50}
51
52static HAL_StatusTypeDef barometer_onOff(I2C_HandleTypeDef *hi2c, uint8_t onOff)
53{
54 HAL_StatusTypeDef status = HAL_ERROR;
55
56 if (_isBarometer)
57 {
58 // Configure CTRL_REG1
59 // 0x50 = 01010000 -> ODR: 50Hz & ON, AVG: 0 Low-pass filter disabled
60 uint8_t ctrl1 = onOff; //0x50;
61 status = HAL_I2C_Mem_Write(hi2c, ILPS22QS_I2C_ADDR, REG_CTRL_REG1, 1, &ctrl1, 1, 100);
62 _isBarometer = (status == HAL_OK);
63 }
64 return status;
65}
66
67int8_t bar_ils22qs_Is(I2C_HandleTypeDef *hi2c, int8_t tryInit)
68{
69 if (!_isBarometer && tryInit)
70 bar_ils22qs_Init(hi2c);
71 return _isBarometer;
72}
73
74HAL_StatusTypeDef bar_ils22qs_On(I2C_HandleTypeDef *hi2c)
75{
76 // Configure CTRL_REG1
77 // 0x50 = 01010000 -> ODR: 50Hz & ON, AVG: 0 Low-pass filter disabled
78 /*
79 * 7 6 5 4 3 2 1 0
80 0 ODR3 ODR2 ODR1 ODR0 AVG2 AVG1 AVG0
81 */
82 const uint8_t val = 0b00011010;
83 HAL_StatusTypeDef status = barometer_onOff(hi2c, val);
84
85 _bar_ils22qsData.IsDataValid = 0;
86 if (status == HAL_OK)
87 {
88 _memsMainBlock.Sens_BarometerStart++;
90 }
91 return status;
92}
93
94HAL_StatusTypeDef bar_ils22qs_Off(I2C_HandleTypeDef *hi2c)
95{
96 // Configure CTRL_REG1
97 // 0x00 = 00000000 -> ODR: 50Hz & ON, AVG: 0 Low-pass filter disabled
98 return barometer_onOff(hi2c, 0x00);
99}
100
101HAL_StatusTypeDef bar_ils22qs_Init(I2C_HandleTypeDef *hi2c)
102{
103 HAL_StatusTypeDef status = I2C_IsDeviceReadyMT(hi2c, ILPS22QS_I2C_ADDR, 2, 2); // first check
104
105 if (status == HAL_OK)
106 do
107 {
108 // check who am'I
109 uint8_t data = 0;
110 if ((status = HAL_I2C_Mem_Read(hi2c, ILPS22QS_I2C_ADDR, REG_WHO_AM_I, 1, &data, 1, 100)) != HAL_OK)
111 break;
112 if (data != ILPS22QS_ID)
113 {
114 status = HAL_ERROR;
115 break;
116 }
117 _isBarometer = 1; // because On/Off needs it
118 // check turning on/off
119 if ((status = bar_ils22qs_On(hi2c)) != HAL_OK)
120 break;
121 if ((status = bar_ils22qs_Off(hi2c)) != HAL_OK)
122 break;
123 } while (0);
124 _isBarometer = (status == HAL_OK);
125
126 return status;
127}
128
129HAL_StatusTypeDef bar_ils22qs_Read(I2C_HandleTypeDef *hi2c)
130{
131 uint8_t raw_data[5]; // 3 bytes for pressure, 2 for temperature
132 HAL_StatusTypeDef status = HAL_ERROR;
133
134 if (_isBarometer)
135 {
136 do
137 {
138 // check if sensor is turned on
139 if ((status = bar_ils22qs_IsOn(hi2c, &raw_data[0])) != HAL_OK)
140 break;
141 if (!raw_data[0])
142 {
143 status = HAL_TIMEOUT;
144 break;
145 }
146
147 if ((status = HAL_I2C_Mem_Read(hi2c, ILPS22QS_I2C_ADDR, REG_PRESS_OFFSET, 1, raw_data, 2, 100)) != HAL_OK)
148 break;
149 //uint32_t factoryOffset = (uint32_t)raw_data[1] << 16 | (uint32_t)raw_data[0];
150
151 // Read Pressure (3 bytes) and Temperature (2 bytes) starting from PRESS_OUT_XL
152 // Using auto-increment feature of the sensor
153 if ((status = HAL_I2C_Mem_Read(hi2c, ILPS22QS_I2C_ADDR, REG_PRESS_OUT_XL, 1, raw_data, 5, 100)) != HAL_OK)
154 break;
155
156 // Process Pressure (24-bit signed)
157 int32_t raw_press = (int32_t) ((uint32_t) raw_data[2] << 16 | (uint32_t) raw_data[1] << 8 | raw_data[0]);
158 // Handle negative sign for 24-bit
159 if (raw_press & 0x800000)
160 raw_press |= 0xFF000000;
161
162 _bar_ils22qsData.PressureSEA = _bar_ils22qsData.PressureABS = (float) raw_press / 4096.0f;
163
164 // Process Temperature (16-bit signed)
165 int16_t raw_temp = (int16_t) ((uint16_t) raw_data[4] << 8 | raw_data[3]);
166 _bar_ils22qsData.Temperature = (float) raw_temp / 100.0f;
167 _bar_ils22qsData.IsDataValid = 1;
168
169 /*
170 * Absolute vs. Relative Pressure
171
172 Absolute (Station) Pressure: This is what your ILPS22QS measures. It is the actual weight of the air pressing on the sensor in Rožňava.
173 Since Rožňava is at an elevation of approximately 310 meters above sea level, the air is "thinner" and the pressure is lower (around 968 hPa).
174
175 Relative (Sea Level) Pressure: This is what the Slovak Hydro-meteorological institute reports (1005 hPa).
176 It is a calculated value: "What would the pressure be if my room was at 0 meters altitude?"
177 How to calculate Sea Level Pressure
178
179 To match the official report, you need to apply the barometric formula. For altitudes under 11,000 meters, we use this approximation:
180 Psea​=Pstation​⋅(1−T+0.0065⋅h+273.150.0065⋅h​)−5.257
181
182 Where:
183
184 Pstation​ = 968 hPa (your sensor reading)
185
186 h = Elevation of Rožňava (≈310 meters)
187
188 T = Temperature in °C (from your Temp&Hum 23 sensor)
189 */
190 // relative pressure needs temperature value
191 if (_systemParams.SensAltitude > 0)
192 {
193#ifdef SENSOR_SHT45
194 float temp = (_tmphm_sht45Data.IsDataValid) ? _tmphm_sht45Data.Temperature :_bar_ils22qsData.Temperature;
195#else
196 float temp = _bar_ils22qsData.Temperature;
197#endif
198 _bar_ils22qsData.PressureSEA = _bar_ils22qsData.PressureABS
199 * pow(1.0 - (0.0065 * _systemParams.SensAltitude) / (temp + (0.0065 * _systemParams.SensAltitude) + 273.15), -5.257);
200 }
201 } while (0);
202 }
203 return status;
204}
205
206void bar_ils22qs_LogData(char *buf)
207{
208 if (buf != NULL)
209 sprintf(buf, "|barometer ABS:" PRIf_02 ", SEA:" PRIf_02 ", temp:" PRIf_02 " ", PRIf_02D(_bar_ils22qsData.PressureABS), PRIf_02D(_bar_ils22qsData.PressureSEA),
210 PRIf_02D(_bar_ils22qsData.Temperature));
211}
212
213#endif
static uint8_t _isBarometer
Definition bar_bmp585.c:49
#define ILPS22QS_ID
Definition bar_ils22qs.c:29
int8_t bar_ils22qs_Is(I2C_HandleTypeDef *hi2c, int8_t tryInit)
Check if the ILPS22QS barometric pressure sensor is present on the I2C bus.
Definition bar_ils22qs.c:67
HAL_StatusTypeDef bar_ils22qs_Init(I2C_HandleTypeDef *hi2c)
Initialise the ILPS22QS sensor and verify it is present on the I2C bus. The sensor is put into low-po...
HAL_StatusTypeDef bar_ils22qs_Read(I2C_HandleTypeDef *hi2c)
read value from sensor, pressure and temperature. Sensor must be turned on before
#define ILPS22QS_I2C_ADDR
Definition bar_ils22qs.c:21
static HAL_StatusTypeDef bar_ils22qs_IsOn(I2C_HandleTypeDef *hi2c, uint8_t *onOff)
Definition bar_ils22qs.c:35
#define REG_PRESS_OFFSET
Definition bar_ils22qs.c:27
#define REG_PRESS_OUT_XL
Definition bar_ils22qs.c:26
static HAL_StatusTypeDef barometer_onOff(I2C_HandleTypeDef *hi2c, uint8_t onOff)
Definition bar_ils22qs.c:52
HAL_StatusTypeDef bar_ils22qs_On(I2C_HandleTypeDef *hi2c)
turn on sensor
Definition bar_ils22qs.c:74
#define REG_WHO_AM_I
Definition bar_ils22qs.c:24
void bar_ils22qs_LogData(char *buf)
log data to buffer
#define REG_CTRL_REG1
Definition bar_ils22qs.c:25
HAL_StatusTypeDef bar_ils22qs_Off(I2C_HandleTypeDef *hi2c)
turn off sensor
Definition bar_ils22qs.c:94
bar_ils22qs_t _bar_ils22qsData
Live measurement data from the ILPS22QS sensor; updated by bar_ils22qs_Read().
Definition bar_ils22qs.c:31
bar_ils22qs_t _bck_bar_ils22qsData
Snapshot copy of the last completed ILPS22QS measurement; used for LoRaWAN transmission.
Definition bar_ils22qs.c:32
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:27
HAL_StatusTypeDef mems_WriteMainBlock()
writing the main block on flash. The main block is stored on address 0
Definition mymems.c:117
systemParams_t _systemParams
Measurement data produced by the ILPS22QS barometric pressure sensor. Populated by bar_ils22qs_Read()...
Definition bar_ils22qs.h:33
tmphm_sht45_t _tmphm_sht45Data
Live measurement data from the SHT45 sensor; updated by tmphm_sht45_Read().
Definition tmphm_sht45.c:27