Did the following steps to test if my temperature sensor HTU2X is working thoroughly. Selected my board (Nucleo-64 STM32F411RE) from STM32CubeIDE then enabled I2C1 for pins PB8 (as the SCL) and PB9 (as the SDA) as in the screenshot below, then saved the project.

Here's also the wiring:
Then wrote a run() function and ran it in main.c to do the job the following way:
lib.hpp
#ifndef INC_LIB_HPP_
#define INC_LIB_HPP_
#if __cplusplus
extern "C" {
#endif
inline I2C_HandleTypeDef hi2c1;
inline UART_HandleTypeDef huart2;
inline uint8_t buf[32];
inline HAL_StatusTypeDef ret;
inline int16_t val;
inline float temp_c;
void run();
void I2C1_Scan();
void HTU21D_Init();
#if __cplusplus
}
#endif
#endif
CODE EDIT:
lib.cpp
static constexpr uint8_t HTU21D_ADDR = (0x40 << 1); // 7-bit address shifted for HAL
void I2C1_Scan()
{
char msg[32];
bool found = false;
for (uint8_t addr7 = 1; addr7 < 127; addr7++)
{
uint16_t addr8 = addr7 << 1; // what HAL expects
if (HAL_I2C_IsDeviceReady(&hi2c1, addr8, 2, 1000) == HAL_OK)
{
// print in both 7-bit and 8-bit forms to avoid confusion
snprintf(msg, sizeof(msg), "Found: 0x%02X (7b), 0x%02X (8b)\r\n", addr7, addr8);
HAL_UART_Transmit(&huart2, (uint8_t*)msg, strlen(msg), HAL_MAX_DELAY);
found = true;
}
}
if( not found)
HAL_UART_Transmit(&huart2, (uint8_t*)"No Match!\r\n", 10, HAL_MAX_DELAY);
}
void HTU21D_Init(void)
{
uint8_t reset_cmd = 0xFE;
char msg[64];
// Wait after power-up (sensor needs ~15ms, give it 100ms)
HAL_Delay(100);
// Send soft reset command (0xFE)
auto result = HAL_I2C_Master_Transmit(&hi2c1, HTU21D_ADDR, &reset_cmd, 1, HAL_MAX_DELAY);
// Print numeric HAL status
snprintf(msg, sizeof(msg), "Soft reset status: %d\r\n", (int)result);
HAL_UART_Transmit(&huart2, (uint8_t*)msg, strlen(msg), HAL_MAX_DELAY);
// Wait after reset
HAL_Delay(100);
// Check if device is ready
result = HAL_I2C_IsDeviceReady(&hi2c1, HTU21D_ADDR, 3, 10000);
// Print numeric HAL status
snprintf(msg, sizeof(msg), "IsDeviceReady status: %d\r\n", (int)result);
HAL_UART_Transmit(&huart2, (uint8_t*)msg, strlen(msg), HAL_MAX_DELAY);
}
void run() {
static constexpr uint8_t REG_TEMP = 0x00;
HAL_Delay(100); // give power and peripherals time to settle
I2C1_Scan(); // check which devices are on the bus
HTU21D_Init(); // try reset + ready check
while (1)
{
buf[0] = REG_TEMP;
ret = HAL_I2C_Master_Transmit(&hi2c1, HTU21D_ADDR, buf, 1, HAL_MAX_DELAY);
if(ret != HAL_OK) {
snprintf(msg, sizeof(msg), "Transmit status: %d\r\n", (int)ret);
HAL_UART_Transmit(&huart2, (uint8_t*)msg, strlen(msg), HAL_MAX_DELAY);
}
else {
ret = HAL_I2C_Master_Receive(&hi2c1, HTU21D_ADDR, buf, 2, HAL_MAX_DELAY);
if(ret != HAL_OK)
strcpy((char*)buf, "ERROR Rx \r\n");
else {
val = ((int16_t)buf[0] << 4) | (buf[1] >> 4);
if(val > 0x7FF)
val |= 0xF000;
temp_c = val * 0.0625;
temp_c *= 100;
sprintf((char*)buf,
"%u.%02u C\r\n",
((unsigned int)temp_c / 100),
((unsigned int) temp_c % 100));
}
}
HAL_UART_Transmit(&huart2, buf, strlen((char*)buf), HAL_MAX_DELAY);
HAL_Delay(500);
} // End of whil(1)
}
The problem is that I get the Error Tx as output, shown below:

Any idea where the problem is and how to fix it please?
static constexpr uint8_t REG_TEMP = 0x00;
Based on datasheet page 10, there are two registers for reading the temperature measurement, register 0xE3 (with Holding the master during measurement, i.e. with clock stretching), or register 0xF3 without clock stretching. Your code is trying to read temperature measurement from register 0x00 which does not exist and therefore causing the device to return error.
With register 0xF3, the measurement takes up to 50ms to complete(see page 4 of the datasheet). The temperature data is returned in 3 bytes, first two bytes as the raw temperature data, plus one byte checksum, if you only read 2 bytes (which is acceptable), checksum will not be sent by the HTU21 (see page 11 of the datasheet).
static constexpr uint8_t REG_TEMP_NO_HOLD = 0xF3;
char msg[80]{0};
while (1)
{
uint8_t cmd = REG_TEMP_NO_HOLD;
int ret = HAL_I2C_Master_Transmit(&hi2c1, HTU21D_ADDR, &cmd, 1, HAL_MAX_DELAY);
if(ret != HAL_OK) {
snprintf(msg, sizeof(msg), "Transmit status: %d\r\n", ret);
}
else {
HAL_Delay(50); // as per datasheet page 4
uint8_t rx_data[3]{0};
ret = HAL_I2C_Master_Receive(&hi2c1, HTU21D_ADDR, rx_data, 3, HAL_MAX_DELAY);
if(ret != HAL_OK)
snprintf(msg, sizeof(msg), "ERROR Rx %d\r\n", ret);
else {
int16_t raw_temp = (rx_data[0] << 8) | rx_data[1]; // remove status bits
int16_t temp_c = (int16_t) (-46.85 + 175.72 * raw_temp / 65536);
snprintf(msg, sizeof(msg),
"Temp(C): %d, status: %d, checksum: %02x\r\n",
temp_c, rx_data[1] & 0x03, rx_data[2]);
}
}
HAL_UART_Transmit(&huart2, (const uint8_t*) msg, strlen(msg), HAL_MAX_DELAY);
HAL_Delay(500);
} // End of whil(1)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With