i2c data rate calculation

I want to estimate the throughput of i2c lines and this is the calculation I have done:

Hardware architecture:

MCU <---> i2c mux TCA9548A <---> 8 i2c based IMU sensors MPU6050

What am I trying to do?

Sensors will connect to MCU via multiplexer. There will be a max wire length of 1 meter between MCU and any sensor. MCU will read all sensors cyclically and transmit the data to a PC or a mobile phone over bluetooth/wifi for further processing.

Total data from one sensor:

Accelerometer : 3 axis X 16 bits = 48 bits

Gyroscope : 3 axis X 16 bits = 48 bits

Each read will have some device address overhead = 31 bits (Edited as per JimmyB's comment)

Single read will require 48+48+31 = 127 bits

Assuming that my i2c clock is operating at 400 kHz, I will be able to transfer 1 bit every clock cycle, and hence 400,000 bits in a second.

One complete read = reading all sensors once, i.e. 127x8 = 1016 bits

Thus no. of times I can read all sensor values every second (RPS):

RPS = 400,000 / 1016 = 393.7 assuming my sensors are ready to supply data at that rate.

Notes from datasheet:

Output data rate for Gyro = 4 Hz to 8000 Hz

Output data rate for Accelero = 4Hz to 1000 Hz

Worst case scenario : My sensors will be at a distance of 1 meter (max) from the MCU. Taking into consideration increased bus capacitance and other things that might slow down data transfer, I am thinking 100 kHz will still be achievable (am I right in thinking so?).

Thus reduced RPS = 98.4

Are my calculations correct?

What precautions should I take to improve my data throughput? (twisted cable?, some i2c buffer?)

I did some research after posting this question. I found one i2c bus buffer P82B96 which allows me to have 400 kHz clock frequency for wire lengths exceeding 20 meters.

Limiting thing is program only I guess, provided my calculations are accurate.

• Don't forget about ACK bits and start and stop bits – alex.forencich Aug 9 '17 at 12:48
• "Each read will have some device address overhead = 14 bits" - The datasheet says you must first perform a write sending the register address to be read, then repeat-start to perform the read. So overhead per read would be 1+7+1+1+8+1+1+7+1+1 = 29 bits, plus 1 ACK bit per byte read, plus stop bit. – JimmyB Aug 9 '17 at 12:49
• You could implement 8× I2C channels in software with 8 pins and get rid of the muxes. Or 16 channels with 16 pins so you read everything in one go. – Harry Svensson Aug 9 '17 at 12:51
• @harrysvensson - Will software be more efficient? I think code will flow sequentially reading one value first and then only be able to move to next one - thereby giving me similar (if not less) throughput. I accept the savings on hardware costs but I want to understand the compromise that I will be making. – Whiskeyjack Aug 9 '17 at 13:48
• @Whiskeyjack you can write and read 8 bits in parallel with a port. The information you're sending and receiving will be transposed register and timewise. So instead of sending one register to the port, you're sending bit0 for channel 0 at pin0, bit0 for channel 1 at pin1... then next i2c clock you'll send bit1 for channel 0 at pin0.... bit1 for channel 7 at pin7.... after 8 i2c clocks you'll have sent everything. Maybe I explained it poorly, but it's transposed, that's what I'm trying to say. So I'd say the efficiency isn't too bad. – Harry Svensson Aug 9 '17 at 16:42

I'm not a huge fan of images with text... but this time excel was the right way to illustrate it. The data0 is one byte of data from accelerometer 0, data1 is one byte of data from accelerometer 1 etc.

Their data will be sent serially, but you will read in parallel. So the first byte you read will be all the first bits of 8 data registers. The second byte you read will be the all the second bits from the 8 accelerometers.

As far as I know, each shift and each "&" and each "|" takes at least one clock cycle. So in order to transpose you need to spend some hefty amount of time. For each reg->data you spend 8×AND + 7×OR + 7×shift (this is the solution I came up with on top of my head, it can most likely be optimized, especially the shifting). Then you need to load and read from memory, so I'll guess-assume 10 clocks. So you need to spend at least 8×(8+7+7+10)=256 clocks just to transpose the information. And you need to do it for every byte you read. So (48+48) bits / 8 = 12 bytes. 12×256 = 3072 clocks. I don't know if you got threading or how fast your CPU will be, but 3072 will at least be within the ball park of number of cycles needed to convert the things. It will be some more because you will need to set some interrupts and cases so you know which bit you're on, and function calling. So say 4000 clocks to read all the 96 bits. And all the programming will be.. boring to implement.

A tiny optimization I just realized, after each clock you can easily do the shifting. That will save several clocks, so 4000 total clocks -> 3500 total clocks. It's just an approximation.

This is how I would do it. And if I wouldn't have threads/multiple cores/enough speed available then I would split the load onto 2 microcontrollers and use an UART between them. One decodes data to reg and reg to data. The other just reads straight from UART at high speed and keeps the program you're intending to use. Or I would just get some cheap FPGA and implement 8 i2c channels there + an uart.