7 years, 8 months ago.

I2C on Nucleo boards is not working correctly....

I am trying to communicate with I2C devices with my nucleo boards (F103RB, F401RE, L476RG) and the operation is not stable. I tried different slaves like AM2320 sensor, SG1306 display and the simple scanner program is finding the slave sometimes, but most scans are failing.

Here is the scanner program:

#include "mbed.h"

I2C i2c(I2C_SDA , I2C_SCL );
Serial pc(SERIAL_TX, SERIAL_RX);
DigitalOut myled(LED1);

int main() {
    pc.printf("\nI2C Scanner");
    //i2c.frequency(100000);
    while(1) {
        int error, address;
        int nDevices;

        pc.printf("Scanning...\n");

         nDevices = 0;

          for(address = 1; address < 127; address++ )
          {
            i2c.start();
            error = i2c.write(address << 1); //We shift it left because mbed takes in 8 bit addreses
            i2c.stop();
            if (error == 1)
            {
              pc.printf("I2C device found at address 0x%X", address); //Returns 7-bit addres
              nDevices++;
            }

          }
          if (nDevices == 0)
            pc.printf("No I2C devices found\n");
          else
            pc.printf("\ndone\n");

            wait(2);           // wait 2 seconds for next scan
            myled = !myled;
            }
        }

I tried also to communicate with I2C devices using various libraries but no success with every nucleo board. Is the code of I2C for STM32 is working correctly? PS. I have 2K2 pullup resistors on SDA/SCL

3 Answers

7 years, 7 months ago.

Hi, I haven't experienced any similar problem. At first, try different mbed boards, if available (LPC1768 for example). If all the i2c peripherals are working properly, the problem is at Nucleo. Then, try other i2c pins (each board have more than one, see product pages). Try reduce i2c clock. And at last, but not least, hook up a simple logic analyzer for deeper time-related debugging (saleae for example, or build one using the). I hope this helps.

7 years, 7 months ago.

Hi, i am also experiencing the same issue. i am unable to communicate reliably via I2c using the NUCLEO-F446RE. The same code runs without any issues on the FRDM-K64F.

I am also experiencing the same issue on the same board. Were you able to manage it by other method?

posted by Nilesh Vora 09 Dec 2016
7 years, 7 months ago.

Unfortunately a lot of mbed platforms have problems with the i2c.start, i2c.stop and i2c byte write and byte read operations. This is mainly due to the way the I2C engines have been implemented. The byte operations work fine on the original NXP lpc1768, lpc11u24, but not or at least not reliably on later NXP platforms and on several other platforms. The NXP lpc8xx I2C engine for example can not really generate a separate start condition followed by a separate write for the slaveaddress. You should first load the dataregister with the slave address, then generate the start and send the slaveaddress in one operation. This does not match with the mbed I2C API. You should therefor use the I2C blockwrite operations instead of the byte operations unless you have done serious testing first. Some people propose to get rid of the byte operations completely. They may still be useful in some cases, but at least the documentation should be improved to understand all limitations. I also propose to modify the ic2.start API to include the slaveaddress as parameter. That would solve several problems with the current implementation.

If it's a known issue, why haven't fixed yet? i2c is a common protocol for a really wide range of sensors and peripherals.

posted by Tamas Szekffy 12 Aug 2016

As explained above the problem with the byte write and read operations probably cant be fixed for all platforms. The reliable solution is to use the blockwrite operations. I think these block methods are the ones used in the mbed library validation tests for the platforms. I do agree that improvements are needed and possible on the master byte write and read operation (API, implementation and documentation). BTW The I2C slave implementation is also rather clumsy and could be improved and become more easy to use.

posted by Wim Huiskamp 13 Aug 2016