4 years, 7 months ago.

i2c.frequency(400000) causes huge slowdown

When I put this near the beginning of my program, sometimes it runs as expected (speed of I2C bus increases about 4 times the default), and other times it seems to cause I2C to run at about 1/20th the normal speed.

i2c.frequency( 400000 );

By 'sometimes' I mean about 50% of the time. Typically the problem appears when I change an unrelated part of the code somewhere else, like if I change the value parameters of a uart printf call. For example, simply changing this: pc.printf("%f\n", someFloat ); ... to this: pc.printf("%f\n", anotherFloat ); and compiling again is enough to trigger the problem. Once the problem has manifested, changing back to someFloat doesn't help, I need to move the i2c.frequency call a bit.

Almost every time, I can 'fix' this problem by slightly changing the location of the I2C frequency call among the other things my program does on startup, and then compile again. The other startup things are unrelated to I2C, for example just setting LED outputs to their initial off state.

If the i2c.frequency call is removed, the program always runs as expected, but it's not as fast as I need it to be.

Maybe I'm missing something here... are there other considerations I need to take into account when setting the I2C frequency? Do I need to wait for some time after setting it before using the bus? (I tried 2 seconds but it made no difference)

Side note: where is the API documentation for the I2C class? The main page (https://os.mbed.com/handbook/I2C) links to this page for the API details, but this page does not exist: https://os.mbed.com/users/mbed_official/code/mbed/docs/tip/classmbed_1_1I2C.html In the IDE under the mbed library it says "Documentation not ready" and running "Update docs" from under the Compile button makes no difference. How am I supposed to know what functions the I2C class has??

Hello Chris,

What is your target board? Do you observe the same issue when building for other targets?

Could you please show us some short example code?

NOTE: To show your code in nice format after pasting it here enclose it with <<code>> and <</code>> tags, each on separate line. Like:

<<code>>
Your source
code.
<</code>>

You can find the I2C API documentation here. Mbed's full API list is available here.

posted by Zoltan Hudak 03 Oct 2019

Testing.... I just wrote a reply and got "This page isn’t working HTTP ERROR 400" when I submitted, and my post is gone. Not gonna waste my time re-typing it if the form is broken...

posted by iforce2d Chris 04 Oct 2019

Okay, the comment form seems to be working now?!? Holy Christ that's annoying. Let's see if I can remember what I had last time...

Hi Zoltan

Thanks for the reply.

I am using an InterruptIn that seems to be interfering with the I2C operation. It reads a PPM signal (about 400 rises per second) which I copied from here: https://os.mbed.com/users/edy05/code/PPM/ In the ISR I added a memcpy call which copies 12 bytes every 8th time, maybe this was a bad idea.

When the PPM signal is inactive, or the I2C bus speed is the default there are no problems at all. When the PPM signal is active and the I2C speed is set to 400kHz, after a few moments I start to get I2C errors. Earlier I said that the bus simply slowed, but that was my misunderstanding - it seems like it's having difficulty reading correctly at all.

I tried removing the memcpy call in the ISR and it has been ok since then, but I have not tested much since it's the end of another frustrating day and I need to sleep for now.

The target board is STM32F103CBT6, have not tried on others. The full code is here, if I can come up with something simpler I'll add it later: https://os.mbed.com/users/iforce2d/code/04_I2C_MPU6050/

Now let me Ctrl+C this to clipboard before posting, just in case...

posted by iforce2d Chris 04 Oct 2019

1 Answer

4 years, 6 months ago.

Hi Chris,

This is something found from the I2C Speed page: The I2C bus is intended for inter-IC communication and this usually means small data packets. Since the timing can never be determined exactly and the transmitted information is often short the accuracy of the bus clock is of very little relevance in most applications.

To be on the safe side it is – in case of doubt – a much better idea to keep the maximum bit rate below the maximum rating at any time rather than exceeding it occasionally.

So it might have something to do how long data packets you send and how long wires you have between I2C devices.

Regards, Pekka