cancel
Showing results for 
Search instead for 
Did you mean: 

STM32L031 I2C (SHT40) driver help

LPetr.1
Senior

Hello. I have STM32L031 nucleo board: https://www.st.com/resource/en/user_manual/um1956-stm32-nucleo32-boards-mb1180-stmicroelectronics.pdf

And I am trying to write SHT40 driver for it. I have Adafruit SHT40 I2C temperature/humidity sensor:

https://www.adafruit.com/product/4885

 

I follow simple steps to setup my STM32 board for I2C:

  1. Enable I2C peripheral on STM32CubeMX:
    LPetr1_0-1695020911951.png
  2. Connect the Adafruit board to the STM32L031 Nucleo board:
    LPetr1_1-1695021176962.png

     

  3. Write function to read temperature/humidity data from the SHT40 sensor:

 

 

 

 

 

 

static void SHT40_measure(){
	HAL_StatusTypeDef ret;
	uint8_t data_tx[1] = {0xFD};
	uint8_t data_rx[6];
	ret = HAL_I2C_Master_Transmit(&hi2c1, 0x44, data_tx, 1, 1000);
	if ( ret != HAL_OK ) {
	  printf("Error Tx\r\n");
	}
	else{
		//read bytes
		 HAL_Delay(10);
		 ret =  HAL_I2C_Master_Receive(&hi2c1, 0x44, (uint8_t*)&data_rx, 6,1000);
		 if ( ret != HAL_OK ) {
			 printf("Error Rx\r\n");
		 }
		 else{
			 for(int i = 0; i < 6 ; i++){
				 printf("data_rx[%i] = %u \n",i,data_rx[i]);
			 }
			 float t_ticks = data_rx[0] * 256 + data_rx[1];
			 float rh_ticks = data_rx[3] * 256 + data_rx[4];

			 float t_degC = -45 + 175 * t_ticks/65535;
			 float rh_pRH = -6 + 125 * rh_ticks/65535;

			 printf("t_degC = %.2d \n",t_degC);
			 printf("rh_pRH = %.2d \n",rh_pRH);
		 }
	}
}​

 

 

 

 

 

 

The results are as following (Serial console):

 

 

 

 

 

 

Trying to read SHT40 sensor 
Error Tx

 

 

 

 

 

 

And the logic analyzer shows the following:

LPetr1_2-1695021357630.png

 

I would appreciate any help. I have double checked everything and cannot spot a mistake.. What could be an issue with my I2C and why would it write such a garbage (when monitoring through logic analyzer?). It should write data 0xFD to the address 0x44

 

UPDATE

What I am confused about is why the I2C does not work as it supposed to. I have even disconnected SH40 sensor from my board and trying to send a dummy I2C command such as:

 

 

  uint8_t test_data = 0x88;
  HAL_I2C_Master_Transmit(&hi2c1, 0xf0, &test_data, 1, 0xff);

 

 

And from what I understand, it should send 2 bytes of data via I2C bus. First byte contains the device address, in this case (0xF0) and then 2nd byte the actual data, in this case (0x88).

Monitoring through logic analyzer:

LPetr1_0-1695024574843.png

This looks like a total garbage. The I2C line does not even have 16 clock cycles. What could cause this? It feels like I2C clock is cutting off early and not able to send all the required data.

 

12 REPLIES 12

Yes. I have connected 22kOhm pull-up resistors to both SCL/SDA pins.
Perhaps there is an issue with my I2C config:

LPetr1_0-1695027727894.png


I dont recall that I had to manually set Rise and Fall time parameters. I have tested the I2C on the stm32f407 and that microcontroller does not even have such options:

LPetr1_1-1695027777730.png

 

 

Also, Could there be an issue with my clock settings:

LPetr1_2-1695027809378.png

And yes, I have also tried to wire it to other SCL/SDA pins but the results are identical.

 

 

 

I have found the issues behind why I could not communicate with the SH40:

Since the I2C adresses are 7-bit, I need to do the following:

#define SHT40_ADDRESS (0x44 << 1)


and then I can use this in I2C write/read functions:

ret = HAL_I2C_Master_Transmit(&hi2c1, SHT40_ADDRESS, &data_tx, 1, 1);

 If I do not shift the address byte to the left by one, it will not be correct.

Trevor Jones
Senior

I have the same STM32C031 running a SHT40 on this new prototype. (Now running correctly)

The code is Cube assisted and running on Visual Studio.

I have the Vcc at 2.2v and had a similar issue.

I was getting nothing on the IIC pins on the scope.

In the cube, I had to enable pullups on those pins and maximum output speed set to Very Fast, then it all started working on the scope.

I have 10k pullups on the PCB, but checking the prototype, these parts were not installed :( my bad.

Now I can see it running on the scope

The other issue I had was the processor clocking rate.

To save power I run SysClock at 750KHz,  (The HSI-48 clock is divided by 64)

To fix the issue caused by this, I found the IIC timing configuration needed adjusting.

The cube suggested for 100KHz operation, the Timing configuration value 0x00000002, which didn't work,

I incremented and tested values 3,4,5,6,7,8,9,a,b,c  manually in main,c, found 9,a,b,c all worked ok.

Adjusted the cube to run the IIC at 48KHz producing a timing config of 0x0000000A  and it all runs sweet.

But then, the address is different for these chips, SHT40 can be address 0x44,0x45,0x46.

I had to run a check on the actual SHT40 address and found this one responds to 0x45 addressing.

 

image.png