Skip to main content
Associate
January 26, 2025
Question

I2C communication between STM32L4R5 and esp32

  • January 26, 2025
  • 13 replies
  • 3206 views

I tried creating I2C connection between my stm32 board and esp32. I assume it is not working because of my code, due to the wiring being so simple in I2C communication, the pull up resistor is connected externally. Do you guys see any mistake in my code that could make my I2C to not work?  I cannot figure out why it would not work.

13 replies

ST Employee
January 29, 2025

Hello,

there seems to me two potentially problems. At first, there should be connected pull up resistor to both I2C pins (SDA and SCL). The second, you are shifting slave address 0x08 in: 

HAL_I2C_Master_Receive(&hi2c2, 0x08 << 1, &receivedByte, 1, 100)

 I would say, there should be:

HAL_I2C_Master_Receive(&hi2c2, 0x08, &receivedByte, 1, 100)

 

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
Karl Yamashita
Principal
January 29, 2025

@Hl_st wrote:

Hello,

there seems to me two potentially problems. At first, there should be connected pull up resistor to both I2C pins (SDA and SCL). The second, you are shifting slave address 0x08 in: 

HAL_I2C_Master_Receive(&hi2c2, 0x08 << 1, &receivedByte, 1, 100)

 I would say, there should be:

HAL_I2C_Master_Receive(&hi2c2, 0x08, &receivedByte, 1, 100)

 


Being that the slave address is 0x08 on the ESP32, then the OP is correct in shifting the slave address 0x08 left by 1 as indicated in the comments ST provides.

/**
 * @brief Transmits in master mode an amount of data in blocking mode.
 * @PAram hi2c Pointer to a I2C_HandleTypeDef structure that contains
 * the configuration information for the specified I2C.
 * @PAram DevAddress Target device address: The device 7 bits address value
 * in datasheet must be shifted to the left before calling the interface
 * @PAram pData Pointer to data buffer
 * @PAram Size Amount of data to be sent
 * @PAram Timeout Timeout duration
 * @retval HAL status
 */
HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData,
 uint16_t Size, uint32_t Timeout)
{
 uint32_t tickstart;
 uint32_t xfermode;

 

If a reply has proven helpful, click on Accept as Solution so that it'll show at top of the post.CAN Jammer an open source CAN bus hacking toolCANableV3 Open Source
Andrew Neil
Super User
January 31, 2025

@Karl Yamashita wrote:


 All other companies' I2C drivers does that automatically for you..


That's not true.

Sadly, there is inconsistency & confusion throughout the industry - both in hardware documentation, and software implementations.

https://www.avrfreaks.net/s/topic/a5C3l000000UZ4wEAG/t148636?comment=P-1418813 

https://www.avrfreaks.net/s/topic/a5C3l000000UcHrEAK/t160967?comment=P-1322043

https://www.avrfreaks.net/s/topic/a5C3l000000Ua6EEAS/t152560?comment=P-1244847

https://www.avrfreaks.net/s/topic/a5C3l000000UXMPEA4/t142031?comment=P-1150738

etc, etc, etc, ...

 

PS:

@ejeee  The ST HAL documentation is pretty clear on this:

/**
 * @brief Checks if target device is ready for communication.
 * @note This function is used with Memory devices
 * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
 * the configuration information for the specified I2C.
 * @param DevAddress Target device address: The device 7 bits address value
 * in datasheet must be shifted to the left before calling the interface
 * @param Trials Number of trials
 * @param Timeout Timeout duration
 * @retval HAL status
 */
HAL_StatusTypeDef HAL_I2C_IsDeviceReady( I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Trials, uint32_t Timeout )

 The I2C Slave address is 7 bits:

+----+----+----+----+----+----+----+
| A6 : A5 : A4 : A3 : A2 : A1 : A0 |
+----+----+----+----+----+----+----+

 You present that to the HAL in a byte as:

+----+----+----+----+----+----+----+----+
| A6 : A5 : A4 : A3 : A2 : A1 : A0 : 0 |
+----+----+----+----+----+----+----+----+

(well, strictly, you pass it in a uint16_t where the top byte is all zeros)

 

The documentation for the Arduino Wire I2C library says,

"Note: There are both 7 and 8-bit versions of I2C addresses"

That's not strictly true - The I2C Specification clearly defines the Slave Address to be bits.

What they mean is that many sources will (incorrectly) use "I2C address" to mean the combination of both the actual Address (7 bits) and the R/W bit.

The Arduino documentation goes on to say:

"7 bits identify the device, and the eighth bit determines if it’s being written to or read from."

Which is true.


This is a clue: If you see anything which talks about a slave having two addresses (one for read, one for write, which differ by just 1 in the LSB) then they are talking about the combination of Address + R/W bit.


The Arduino documentation further says: 

"The Wire library uses 7 bit addresses throughout. If you have a datasheet or sample code that uses 8-bit address, you’ll want to drop the low bit (i.e. shift the value one bit to the right), yielding an address between 0 and 127."

In other words, when you pass the Address to the Wire library, it must be like this:

+----+----+----+----+----+----+----+----+
| 0 | A6 : A5 : A4 : A3 : A2 : A1 : A0 |
+----+----+----+----+----+----+----+----+

 

In Summary:

 +----+----+----+----+----+----+----+----+
ST HAL requires: | A6 : A5 : A4 : A3 : A2 : A1 : A0 : 0 |
+----+----+----+----+----+----+----+----+

+----+----+----+----+----+----+----+----+
Arduino Wire requires: | 0 | A6 : A5 : A4 : A3 : A2 : A1 : A0 |
+----+----+----+----+----+----+----+----+

 

#I2CAddress #I2CAddressConfusion

A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
Andrew Neil
Super User
January 30, 2025

@ejeee wrote:

 I assume it is not working because of my code, .


Don't just jump to that conclusion!

First, use an oscilloscope to see what - if anything - is happening on the wires.

It could very well be a hardware problem.

That's why you need to show the schematics of your setup - see: How to write your question to maximize your chances to find a solution.

 


@ejeee wrote:

I tried creating I2C connection between my stm32 board and esp32. 


So which one is the Master, and which is the slave?

  • Have you tested your Master against a standard, well-known, known-working Slave?
  • Have you tested your Slave against a known-working Master?

Don't make the classic mistake of trying to do both ends of the link at once:

https://community.st.com/t5/stm32-mcus-products/i2c-communication-between-two-different-stm32-evk-boards/m-p/755042/highlight/true#M268963

 

A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
ejeeeAuthor
Associate
January 30, 2025

Hello,

Thank you for your advice! I did try to look at the SCL line, it shows some kind of square wave. But it seems there are a lot of noise of some sort in the SCL line. I do not have access to an oscilloscope at the moment. But, I will post my findings soon. 

Let's say I do not have access to the I2C Demo Board, what other way should I test my master and slave? Thanks for your help.

Andrew Neil
Super User
January 30, 2025

There are loads of low-cost "breakout" boards for common I2C devices...

AndrewNeil_0-1738248543073.png

 

A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
Associate II
November 10, 2025

Have a look at my post. it may be helpful.

ESP32 AND STM32 I2C INTERFACE 

Andrew Neil
Super User
November 10, 2025
A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
Associate II
November 10, 2025

yes meant to give the link but was facing some errors .... being new to the site 

MM..1
Super User
November 10, 2025

Seems in Arduino you miss order , right is

bool Wire.begin(uint8_t addr, int sdaPin, int sclPin, uint32_t frequency);