0
\$\begingroup\$

I am trying to read temperature and humidity data from the Si7021 temperature and humidity sensor on an STM32 NUCLEO-F746ZG over I2C, and then send it over UART to be viewed on a computer. After connecting the sensor to the board, and loading the below code (CubeIDE), I am not able to get temperature measurements from the sensor.

Update: When I use the debugger in CubeIDE, and step into the si7021_measure_temperature(&hi2c1) function, and step over each step, temp and tempC actually update with the correct temperature. However, if I step over the si7021_measure_temperature(&hi2c1) function while debugging, I still get the error. This makes me think it may be a clock error.

I am using the Si7021 library found here.

Firstly, I configured PB9 and PB8 for I2C communication:

PB8 and PB9 configured at SCL and SDA, respectively.

I then connected the sensor to the board (10k pull up resistors on SDA and SCL):

VIN --> 3.3v, GND --> GND, SDA --> PB9, SCL --> PB8.

I imported the library into my project, and included it in main.c with #include "si7021.h".

Within int main(void), I have this code:

HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_ETH_Init();
MX_USART3_UART_Init();
MX_USB_OTG_FS_PCD_Init();
MX_I2C1_Init();

uint8_t buffer[12];

Within the while(1) loop, I have the following code:

uint32_t temp = si7021_measure_temperature(&hi2c1);
float tempC = temp/100;
sprintf((char*)buffer, "%f\r\n", tempC);
HAL_UART_Transmit(&huart3, buffer, strlen((char*)buffer), 100); 
HAL_Delay(100);

This code compiles and uploads to the board without errors. When inspecting the data sent over serial to the computer via the serial monitor, all I get is repeated "655.000000" which is an error code in the library:

The output from Serial is always 655.000000

I tried the sensor with an Arduino, using example code, and it connects and reads temperature fine, so I know the sensor is not faulty. I also manually set temp = 1200, and 12 was successfully printed in the serial monitor, so I know UART is configured correctly.

Anything else I can check that may be configured incorrectly, which is stopping me from reading temperature from the sensor?

Edit: Below are my clock settings in case that is relevant too.

Clock settings

Edit 2: pictures url

\$\endgroup\$
14
  • \$\begingroup\$ Did u add pullup resistors to PB8 and PB9? \$\endgroup\$
    – Rodo
    Oct 17, 2023 at 23:57
  • \$\begingroup\$ @Rodo I just added 10kOhm pull up resistors between SDA and 3.3v, and SCL and 3.3v, and nothing has changed :( \$\endgroup\$
    – p1unge
    Oct 18, 2023 at 0:20
  • \$\begingroup\$ @p1unge Those pullup resistors are necessary for I²C to work. \$\endgroup\$
    – Hearth
    Oct 18, 2023 at 1:03
  • \$\begingroup\$ 10kOhm sounds to be on the high side. Try something like 6k2. \$\endgroup\$
    – MiNiMe
    Oct 18, 2023 at 1:08
  • 1
    \$\begingroup\$ The library signals you an error by returning 65535. You don't check for any errors and divide that to 655.0 and print it. Since you have a debugger, you can debug the code to see where and why it returns with an error. But the library still does not give you info what the I2C layer returned as error so you need to check there. You also don't show any MCU init code, so we don't even know if the I2C init or GPIO init are even called to use the I2C. \$\endgroup\$
    – Justme
    Oct 18, 2023 at 6:29

1 Answer 1

2
\$\begingroup\$

That's not a bug, that's a feature, and you are likely not always getting 655.0 but sometimes a correct result.

Single stepping makes it obvious.

The library is using "No Hold" type temperature read command, which means that it will not respond to any I2C operation while performing the temperature measurement and conversion internally.

That is backed by the fact that when single stepping the code, the conversion of temperature can complete and the chip can respond with a result due to delay.

In any case, please debug why I2C funtions, does not return with OK, and what is the reason they return with, and if it is an error, check what the error code is. Maybe try increasing the delays in the driver.

The driver should be more verbose that when there is an error, it should give more info what the error is. But such are most pieces of code you find on the net, because hey, it worked for the person who made it.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.