Skip to main content
Associate II
August 27, 2025
Solved

I2C Debugging with Platformio

  • August 27, 2025
  • 6 replies
  • 1075 views

Hi everyone: i received in these days a custom PCB i designed based on the STM32F411 microcontroller:

I wanted to experiment with such MCUs and make a custom board with them for the first time; i was also interested in making it compatible with the arduino framework through PlatformIO as i am already experienced with that environment.

I started running some tests and i turned out that i was able to program it in DFU mode and to use the serial monitor just fine; however the problems started when i tryed to use I2C sensors like this BME280 Breackout board i got from Amazon: i started simple by connecting it up to 3V3, same GND ans the STM32 board, and SDA and SCL according to the attached PCB schematic.

I also used this code in the platformio's main.c file:

#include <Arduino.h>
#include <Wire.h>

int nDevices = 0;

void setup() {
 Wire.begin(PB7, PB6);
 Serial.begin(115200);
 delay(100);
 pinMode(PC13, OUTPUT);
 Serial.println("I2C pronto!");

 // Scan I2C
 byte error, address;
 for (address = 1; address < 127; address++) {
 Wire.beginTransmission(address);
 error = Wire.endTransmission();
 if (error == 0) {
 Serial.print("Device found on 0x");
 Serial.println(address, HEX);
 nDevices++;
 }
 delay(5); // Add small delay between attempts
 }
}

void loop() {
 if(nDevices != 0){
 digitalWrite(PC13, !digitalRead(PC13));
 delay(1000);
 } else {
 Serial.println("No I2C Device Found");
 delay(1000);
 }
}

and this in the platformio.ini file:

; PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html

[env:genericSTM32F411CE]
platform = ststm32
board = genericSTM32F411CE
framework = arduino
upload_protocol = dfu
build_flags =
 -D PIO_FRAMEWORK_ARDUINO_ENABLE_CDC
 -D USBCON
 -D HSE_VALUE=8000000

When the code runs it basically doesn't find any I2C devices connected.

 

Since this is my first time working with STM32 it's i made some mistake for sure, but i can't spot it.

Any help would be apreciated. 

Best answer by LucaBresciani

Hey everyone, i wanted to tell you that a solution has been found: a person on the PlatformIO Forum found an error in my code: basically i was using the wrong command to assign I2C pins to the microcontroller GPIOs in the platformio.ini file.

This is the updated and working version:

; PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html

[env:genericSTM32F411CE] 
platform = ststm32 
board = genericSTM32F411CE
framework = arduino 
upload_protocol = dfu 
build_flags = 
 -D PIO_FRAMEWORK_ARDUINO_ENABLE_CDC 
 -D USBCON 
 -D HSE_VALUE=8000000 
 -D PIN_WIRE_SDA=PB7 
 -D PIN_WIRE_SCL=PB6

Here is also a link to the conversation on the other forum where everything is explained more deeply.

 

Thanks everyone for the support and see you next time

6 replies

Andrew Neil
Super User
August 27, 2025

@LucaBresciani wrote:

compatible with the arduino framework . 


So using the STM32Duino core?

The place for STM32Duino questions is https://www.stm32duino.com/ 

Or https://github.com/stm32duino

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
August 27, 2025

Thanks, i will definitely post my question there, but i wanted to know first if there were some evident electrical problems with my design, and that's why i am asking that question here.

Ozone
Principal
August 27, 2025

I'm not familiar with the Arduino / platform.io environment and code.
However, the BME280 module looks like the one from Soldered Electronics.
Here is what another site says :

Using the I2C interface

Because the I2C interface does not require level shifting when used with a 5V MCU, it is typically the preferred interface to use.

The CSB (Chip Select Bus) pin determines which bus to use.  A logic HIGH selects the I2C bus.  A 10K pull-up resistor on the module pulls this pin HIGH and so the I2C bus is selected by default unless this pin is grounded.

The module supports two different I2C addresses, either 0x76 or 0x77 which allows up to 2 sensors to b ...

Check you have this pull-up.

Associate II
August 27, 2025

Thanks for the answer: I've already tested the sensor with a standard arduino board with the same code and the arduino is capable of recognising the sensor's address just fine.

 

My main concern after reading your message is that the STM32 i am using is not a 5V MCU like arduino; can that be the cause of some incompatibility issues?

Ozone
Principal
August 27, 2025

> My main concern after reading your message is that the STM32 i am using is not a 5V MCU like arduino; can that be the cause of some incompatibility issues?

This might well be.
I remember some notes about an onboard regulator, working with +5V supplied externally.
Read the short tutorial I linked to, and check if you need a 5V supply.
This is easy with Discover / Nucleo boards, as they expose the +5V from the USB supply on the connectors.

Associate II
August 27, 2025

Ok, so I will try with a level shifter and let you know. 

Ozone
Principal
August 27, 2025

The linked document says :

Note that this device operates at 3.3V.  If it is being used with a 5V MCU, it should be powered off the 3.3V output.  The good news is that the I2C interface is an open-drain interface with 10K pull-up resistors to the modules Vcc (3.3V) and so it can be used without level shifting.

Thus you don't need level shifters for I2C, and must not operate it with 5V.

 

For your I2C issue, I would highly recommend a scope or a logic analyser.
The cheapest LA models (Chinese Saleae Logic clones for a few bucks) work fine, and 8 channels are more than enough.
It is very tough to debug a communication bus issue without seeing what's going on.

Andrew Neil
Super User
August 27, 2025

@Ozone wrote:

For your I2C issue, I would highly recommend a scope or a logic analyser.


Indeed!

I would strongly recommend that you use an oscilloscope first, to check that the signals are good in the analogue domain; ie, clean, correct levels, good edges, etc.

without these basic analogue things being correct, your logic analyser may give misleading results ...

 


@Ozone wrote:

It is very tough to debug a communication bus issue without seeing what's going on.


Absolutely!

@LucaBresciani the signals on the wires are the only things that the external device sees; it neither knows nor cares what microcontroller you use - far less what software tools you use.

Hence being able to see those signals is absolutely key to getting the interface working.

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
August 27, 2025

Unfortunately i don't have access to an oscilloscope right now and getting one sounds like a big investment right now. Do you kwno any cheaper models (under 150 bucks) on amazon that i can get for a few weeks and then refound after?

Ozone
Principal
August 27, 2025

You might get used oscilloscope for relatively cheap.

But what I especially meant were logic analysers. Starting with a simple 8-channel DIN device like this: https://sigrok.org/wiki/MCU123_Saleae_Logic_clone

You can get similiar (compatible) devices from all sorts of electronics distributors, including Amazon, for 10 to 20€, or even less.
This site ( https://sigrok.org/wiki/Main_Page ) provides free PC based software as well.
I'm using it with Sigrok/Pulseview under Linux.
As a bonus, this software comes with protocol decoders for all the standard stuff, including RS232, SPI, and I2C.

Andrew Neil
Super User
August 27, 2025

@Ozone wrote:

But what I especially meant were logic analysers.


But it's important to also be able to see the "analogue" domain.

I'm sure there must be low-cost devices available...

 

Here's a Raspberry Pi shield:

https://cpc.farnell.com/whadda/wpsh206/oscilloscope-board-raspberry-pi/dp/SC19412

It only goes up to ~100kHz, but that should be OK for slow I2C.

 

A USB pen-like "oscilloscoe" for £32:

https://thedebugstore.com/products/penscopedaq-usb-oscilloscope-rk-system-uk

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
August 28, 2025

Thanks everyone for the suggestions: i found a used Hanmatek DOS1102 that should get outside my door in about 10 days (that's unfortunately what you get as delay time when buying second hand).

When it arrives i will start some more serius debugging 

 

LucaBrescianiAuthorBest answer
Associate II
August 28, 2025

Hey everyone, i wanted to tell you that a solution has been found: a person on the PlatformIO Forum found an error in my code: basically i was using the wrong command to assign I2C pins to the microcontroller GPIOs in the platformio.ini file.

This is the updated and working version:

; PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html

[env:genericSTM32F411CE] 
platform = ststm32 
board = genericSTM32F411CE
framework = arduino 
upload_protocol = dfu 
build_flags = 
 -D PIO_FRAMEWORK_ARDUINO_ENABLE_CDC 
 -D USBCON 
 -D HSE_VALUE=8000000 
 -D PIN_WIRE_SDA=PB7 
 -D PIN_WIRE_SCL=PB6

Here is also a link to the conversation on the other forum where everything is explained more deeply.

 

Thanks everyone for the support and see you next time