2025-08-31 2:48 AM - edited 2025-08-31 2:50 AM
To get my first sensor project done and after selecting my board, I enabled I2C1 which triggered pins PB6 and PB7 as shown below:
Then used code below (in main.c) with the purpose that the LED is on when the temperature is higher than 40 degrees and off otherwise.
#include "main.h"
extern I2C_HandleTypeDef hi2c1; // I2C handle from CubeMX
#define HTU21D_ADDR (0x40 << 1) // 7-bit address shifted for HAL
#define TRIGGER_TEMP_MEASURE_HOLD 0xE3
I2C_HandleTypeDef hi2c1;
UART_HandleTypeDef huart2;
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART2_UART_Init(void);
static void MX_I2C1_Init(void);
float HTU21D_ReadTemperature(void)
{
uint8_t cmd = TRIGGER_TEMP_MEASURE_HOLD;
uint8_t data[2];
// Send temperature measurement command
HAL_I2C_Master_Transmit(&hi2c1, HTU21D_ADDR, &cmd, 1, HAL_MAX_DELAY);
// Receive 2 bytes (temperature)
HAL_I2C_Master_Receive(&hi2c1, HTU21D_ADDR, data, 2, HAL_MAX_DELAY);
// Combine and mask status bits
uint16_t rawTemp = (data[0] << 8) | data[1];
rawTemp &= 0xFFFC;
// Convert to Celsius
float temp = -46.85 + 175.72 * ((float)rawTemp / 65536.0);
return temp;
}
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART2_UART_Init();
MX_I2C1_Init();
while (1)
{
if ( HTU21D_ReadTemperature() > 40.0f)
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET); // LED ON
else
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET); // LED OFF
HAL_Delay(1000); // check every 1s
}
}
The wiring is also this way:
PB6 -> Sensor's SCL (there's also a 220 Ohm resister between SCL and MCU 3.3V)
PB7 -> Sensor's SDL (there's also another 220 Ohm resister between SDL and MCU 3.3V)
sensor's GND -> MCU GND
sensor's VCC -> MCU 3.3V
The issue is that the LED is on while the room's temperature is obviously less than 40 degrees!
Any idea where the problem is, please?
2025-08-31 12:24 PM - edited 2025-08-31 12:27 PM
1- What I2C-functions do you mean? I defined merely the HTU21D_ReadTemperature function. Do you mean it?
Below is also a screenshot of the board and connections.
2- Does it look completely correct?
They are:
PB6 -> Sensor's SCL
PB7 -> Sensor's SDL
sensor's GND -> MCU GND
sensor's 3.3V -> MCU 3.3V
A 3K resister between SCL and sensor's 3.3V
A 3K resister between SDL and sensor's 3.3V
3- Should I use a higher resister, eg 4, 5, 6 or 7K?
I ordered the sensor online and there's no schematic-recommendation with it to see.
I also tested the HAL_I2C_IsDeviceReady function before while(1) the way below:
is_ready = HAL_I2C_IsDeviceReady(&hi2c1, res_trans, res_recev, 10000);
The value of all three res_trans, res_recev and is_ready are zero at first but is_ready becomes 1 after calling that function.
4- Have I used the function correctly? And is that 1 mean the device is ready?
2025-08-31 3:24 PM
1 is HAL_ERROR which means the sensor is not connected properly. Recheck connections, including VCC/GND/SDA/SCL. Perhaps show a picture of the setup.
Get HAL_I2C_IsDeviceReady to return HAL_OK before you do anything else with the sensor.
I doubt the pullup resistor value is the problem here. Anything between about 120 Ohm and 10 kOhm will generally work.
> PB7 -> Sensor's SDL (there's also another 220 Ohm resister between SDL and MCU 3.3V)
What is SDL? There is no SDL pin
2025-08-31 4:04 PM
Here's a picture and detailed explanation on the connections:
PB6 (purple wire) -> Sensor's SCL
PB7 (grey wire) -> Sensor's SDA
sensor's GND (yellow wire) -> MCU GND
sensor's 3.3V (red wire) -> MCU 3.3V
One leg of a 3K resister is put into the sensor's SCL pin and the other leg into sensor's 3.3V
One leg of another 3K resister is put into the sensor's SDA pin and other leg into sensor's 3.3V
1- Are the connections correct?
2- Used HAL_I2C_IsDeviceReady like in code below:
#include "main.h"
extern I2C_HandleTypeDef hi2c1; // I2C handle from CubeMX
#define HTU21D_ADDR (0x40 << 1) // 7-bit address shifted for HAL
#define TRIGGER_TEMP_MEASURE_HOLD 0xE3
I2C_HandleTypeDef hi2c1;
UART_HandleTypeDef huart2;
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART2_UART_Init(void);
static void MX_I2C1_Init(void);
float HTU21D_ReadTemperature(void)
{
uint8_t cmd = TRIGGER_TEMP_MEASURE_HOLD;
uint8_t data[2];
// Check if device is ready
if (HAL_I2C_IsDeviceReady(&hi2c1, HTU21D_ADDR, 3, 100) != HAL_OK)
// Device not responding -> return error value
return -999.0f;
// Receive 2 bytes (temperature)
HAL_I2C_Master_Receive(&hi2c1, HTU21D_ADDR, data, 2, HAL_MAX_DELAY);
// Send temperature measurement command
HAL_I2C_Master_Transmit(&hi2c1, HTU21D_ADDR, &cmd, 1, HAL_MAX_DELAY);
// Receive 2 bytes (temperature)
// HAL_I2C_Master_Receive(&hi2c1, HTU21D_ADDR, data, 2, HAL_MAX_DELAY);
// Combine and mask status bits
uint16_t rawTemp = (data[0] << 8) | data[1];
rawTemp &= 0xFFFC;
// Convert to Celsius
float temp = -46.85 + 175.72 * ((float)rawTemp / 65536.0);
return temp;
}
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART2_UART_Init();
MX_I2C1_Init();
while (1)
{
float temperature = HTU21D_ReadTemperature();
if (temperature == -999.0f)
{
// Sensor not responding → blink LED fast as error indication
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);
HAL_Delay(100);
}
else
{
if (temperature > 40.0f)
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET); // LED ON
else
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET); // LED OFF
HAL_Delay(1000); // check every 1s
}
}
}
The device is not ready and the LED blinks fast, so there's a problem with making the device ready. Not?
And SDL was a typo, sorry, I meant SDA.
2025-09-02 2:49 AM
Hello @TechyAry
Could you please share the device datasheet?
2025-09-02 1:50 PM
You don't check the HAL status when you call HAL_I2C_Master_Transmit or HAL_I2C_Master_Receive.
You're trying to calculate temperature with data that might not even be valid without first checking HAL status.
Check with an oscilloscope to be sure your signals are pulled up and you see data activity. Most scopes will have a I2C decoder so you can see if it ACK/NAK