L14-Click 1.0
STM32WLE5CC LoRaWAN Sensor Platform
Loading...
Searching...
No Matches
tmphm_sht45.c
Go to the documentation of this file.
1/*
2 * MT 22.12.2025
3 *
4 * Temp&hum 23 click SHT45.pdf https://download.mikroe.com/documents/datasheets/SHT45-AD1B-R2_datasheet.pdf
5 *
6 * I could have taken the library directly from https://github.com/MikroElektronika/mikrosdk_click_v2/blob/master/clicks/temphum23/lib_temphum23/src/temphum23.c
7 * but there is a problem that I would need to pull in other modules.
8 * Therefore going the route of direct reading from I2C
9 *
10 * geminy:
11 * https://gemini.google.com/share/b64c25662edf
12 */
13
14#include "tmphm_sht45.h"
15
16#ifdef SENSOR_SHT45
17
18#include "i2c.h"
19#include "utils/mydefs.h"
20#include "mymems.h"
21#include <stdio.h>
22
23static uint16_t _tempHumAddr = 0x44;// - must be set via init 0x44; // or 0x45
24static int8_t _isTempHumSensor = 0;
25static int8_t _isOnOff = 0; // dummy
26
29
30static HAL_StatusTypeDef tempHum_onOff(I2C_HandleTypeDef *hi2c, uint8_t onOff)
31{
32 HAL_StatusTypeDef status = I2C_IsDeviceReadyMT(hi2c, (_tempHumAddr << 1), 2, 2); // real control
33
34 if (status == HAL_OK)
35 _isOnOff = onOff;
36 _isTempHumSensor = (status == HAL_OK);
37 return status;
38}
39
40int8_t tmphm_sht45_Is(I2C_HandleTypeDef *hi2c, int8_t tryInit)//
41{
42 if (!_isTempHumSensor && tryInit)
43 tmphm_sht45_Init(hi2c);
44 return _isTempHumSensor;
45}
46
47HAL_StatusTypeDef tmphm_sht45_IsOn(I2C_HandleTypeDef *hi2c, uint8_t *onOff)
48{
49 HAL_StatusTypeDef status = _isTempHumSensor ? HAL_OK : HAL_ERROR;
50
51 if (status == HAL_OK)
52 if (onOff != NULL)
53 *onOff = _isOnOff;
54 return status;
55}
56
57HAL_StatusTypeDef tmphm_sht45_On(I2C_HandleTypeDef *hi2c)
58{
59 HAL_StatusTypeDef status = tempHum_onOff(hi2c, 1);
60
61 _tmphm_sht45Data.IsDataValid = 0;
62 if (status == HAL_OK)
63 {
64 _memsMainBlock.Sens_TempHumStart++;
66 }
67 return status;
68}
69
70HAL_StatusTypeDef tmphm_sht45_Off(I2C_HandleTypeDef *hi2c)
71{
72 return tempHum_onOff(hi2c, 0);
73}
74
75
76HAL_StatusTypeDef tmphm_sht45_Init(I2C_HandleTypeDef *hi2c) //
77{
78 HAL_StatusTypeDef status = HAL_ERROR;
79
80 /*
81 for (_tempHumAddr = 0x44; _tempHumAddr <= 0x45; _tempHumAddr++) //
82 {
83 status = MY_I2C_IsDeviceReady(hi2c, _tempHumAddr << 1, 2, 2); // first check
84 _isTempHumSenzor = (status == HAL_OK);
85 if (_isTempHumSenzor)
86 break;
87 }
88 */
89 status = I2C_IsDeviceReadyMT(hi2c, (_tempHumAddr << 1), 2, 2);
90 _isTempHumSensor = (status == HAL_OK);
91 return status;
92}
93
94uint8_t tempHum_CheckCrc(uint8_t *data, uint8_t len, uint8_t checksum) //
95{
96 uint8_t crc = 0xFF; // Initialization
97 for (uint8_t i = 0; i < len; i++) {
98 crc ^= data[i];
99 for (uint8_t bit = 8; bit > 0; --bit) {
100 if (crc & 0x80) {
101 crc = (crc << 1) ^ 0x31;
102 } else {
103 crc = (crc << 1);
104 }
105 }
106 }
107 return (crc == checksum);
108}
109
110HAL_StatusTypeDef tmphm_sht45_Read(I2C_HandleTypeDef *hi2c) //
111{
112 uint8_t cmd = 0xFD; // High precision command
113 uint8_t buffer[6];
114 HAL_StatusTypeDef ret = HAL_ERROR;
115
116 if (_isTempHumSensor) //
117 {
118 do //
119 {
120 if (!_isOnOff)
121 {
122 ret = HAL_TIMEOUT;
123 break;
124 }
125 // 1. Send Command (Address 0x44 << 1 = 0x88)
126 ret = HAL_I2C_Master_Transmit(hi2c, (_tempHumAddr << 1), &cmd, 1, 100);
127 if (ret != HAL_OK)
128 break;
129
130 // 2. Wait for measurement (SHT45 takes ~8.2ms max)
131 HAL_Delay(10);
132
133 // 3. Read 6 bytes of data
134 ret = HAL_I2C_Master_Receive(hi2c, (_tempHumAddr << 1), buffer, 6, 100);
135 if (ret != HAL_OK)
136 break;
137
138 ret = HAL_ERROR;
139 // 4. Validate CRC for Temperature (buffer[0,1] vs buffer[2])
140 if (!tempHum_CheckCrc(&buffer[0], 2, buffer[2]))
141 break;
142
143 // 5. Validate CRC for Humidity (buffer[3,4] vs buffer[5])
144 if (!tempHum_CheckCrc(&buffer[3], 2, buffer[5]))
145 break;
146
147 // 6. Convert Raw to Physical Values
148 uint16_t t_raw = (buffer[0] << 8) | buffer[1];
149 uint16_t rh_raw = (buffer[3] << 8) | buffer[4];
150
151 _tmphm_sht45Data.Temperature = -45.0f + 175.0f * (float) t_raw / 65535.0f;
152 _tmphm_sht45Data.Humidity = -6.0f + 125.0f * (float) rh_raw / 65535.0f;
153
154 // Simple clipping for humidity (sensor can return slightly < 0 due to precision)
155 if (_tmphm_sht45Data.Humidity < 0)
156 _tmphm_sht45Data.Humidity = 0;
157 if (_tmphm_sht45Data.Humidity > 100)
158 _tmphm_sht45Data.Humidity = 100;
159 ret = HAL_OK;
160 _tmphm_sht45Data.IsDataValid = 1;
161 } while (0);
162 }
163 return ret;
164}
165
166void tmphm_sht45_LogData(char* buf)
167{
168 if (buf != NULL)
169 sprintf(buf, "|tempHum temp:" PRIf_02 " hum:" PRIf_02 " ", PRIf_02D(_tmphm_sht45Data.Temperature), PRIf_02D(_tmphm_sht45Data.Humidity));
170
171}
172
173#endif
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
static int8_t _isOnOff
Measurement data produced by the SHT45 temperature and humidity sensor. Populate by calling tmphm_sht...
Definition tmphm_sht45.h:34
void HAL_Delay(__IO uint32_t Delay)
Definition sys_app.c:369
HAL_StatusTypeDef tmphm_sht45_IsOn(I2C_HandleTypeDef *hi2c, uint8_t *onOff)
get state - sensor does not have on/off state - only for compatibility with others
Definition tmphm_sht45.c:47
HAL_StatusTypeDef tmphm_sht45_On(I2C_HandleTypeDef *hi2c)
Zapnutie sensora dummy.
Definition tmphm_sht45.c:57
HAL_StatusTypeDef tmphm_sht45_Init(I2C_HandleTypeDef *hi2c)
initialization, check if sensor is present or not. Checks main (0x44) and alternative address (0x45) ...
Definition tmphm_sht45.c:76
HAL_StatusTypeDef tmphm_sht45_Read(I2C_HandleTypeDef *hi2c)
read temperature and humidity from sensor, values are in _tempHumData
void tmphm_sht45_LogData(char *buf)
log data to buffer
static int8_t _isTempHumSensor
Definition tmphm_sht45.c:24
HAL_StatusTypeDef tmphm_sht45_Off(I2C_HandleTypeDef *hi2c)
turn off sensor - dummy
Definition tmphm_sht45.c:70
uint8_t tempHum_CheckCrc(uint8_t *data, uint8_t len, uint8_t checksum)
Definition tmphm_sht45.c:94
int8_t tmphm_sht45_Is(I2C_HandleTypeDef *hi2c, int8_t tryInit)
check if tempHum sensor is present
Definition tmphm_sht45.c:40
static HAL_StatusTypeDef tempHum_onOff(I2C_HandleTypeDef *hi2c, uint8_t onOff)
Definition tmphm_sht45.c:30
static uint16_t _tempHumAddr
Definition tmphm_sht45.c:23
tmphm_sht45_t _bck_tmphm_sht45Data
Snapshot copy of the last completed SHT45 measurement; used for LoRaWAN transmission.
Definition tmphm_sht45.c:28
tmphm_sht45_t _tmphm_sht45Data
Live measurement data from the SHT45 sensor; updated by tmphm_sht45_Read().
Definition tmphm_sht45.c:27