Skip to main content
Graduate
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. 

    This topic has been closed for replies.
    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

    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

    Graduate
    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.

    Explorer
    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.

    Graduate
    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?

    Explorer
    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.

    Graduate
    August 27, 2025

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

    Explorer
    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.

    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.

    Graduate
    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?

    Explorer
    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.

    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

    Graduate
    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 

     

    LucaBrescianiAuthorAnswer
    Graduate
    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