Why does the arduino I2C library have a 32-byte buffer limitation?

I discovered that i2c packets bigger than 32 bytes cannot be sent/received due to a 32-byte buffer limitation in the Arduino library. I am puzzled why this is so? Is it due to the Atmel MCU architecture? Why 32 bytes and not some other size? The more important question is ... is it possible to write a i2c library that does not have such a limitation? Otherwise, I will have to change to SPI or UART interface which is best to be avoided.

Look at the code for the library.

jremington: Look at the code for the library.

Aren't these question answerers wonderfully helpful

lightaiyee: I am puzzled why this is so?.

The author of the library chose 32 bytes.

Is it due to the Atmel MCU architecture?

No.

Why 32 bytes and not some other size?

If it is larger it uses more RAM. The library actually makes 5 x buffers, so the 32 bytes is 160 bytes of RAM out of possibly only 2048. If it is less large you fit less in the buffer.

The more important question is ... is it possible to write a i2c library that does not have such a limitation?

Of course. Just change 32 to some number of your choice in the library. In two places, as I recall.

Otherwise, I will have to change to SPI or UART interface which is best to be avoided

Oh, aye.

is it possible to write a i2c library that does not have such a limitation?

Is this an X-Y question? Why do you want a larger buffer?

b-james: Aren't these question answerers wonderfully helpful

Your response wasn't particularly helpful, you know.

Just sniping.

If it is larger it uses more RAM. The library actually makes 5 x buffers, so the 32 bytes is 160 bytes of RAM out of possibly only 2048. If it is less large you fit less in the buffer.

Why does the library want to make 5 x buffers? It is not RAM efficient. Is there any reason why the I2C library needs to be designed this way given that SPI and UART do not have similar issues?

Sorry for the late reply. I thought I enabled notifications.

The design of that library is poor, and doesn't support all the I2C functions, like repeated start.

Here is a new alternative that doesn't use any buffers (other than your own): http://www.dsscircuits.com/articles/arduino-i2c-master-library

The new library also features time-outs if something goes wrong.

moderator: edited link

In Wire.cpp there are two buffers, txBuffer, and rxBuffer. It seems they are for:

  • txBuffer - buffering Wire.write data until it gets an endTransmission
  • rxBuffer - buffer incoming data on a Wire.requestFrom

In twi.c there are three buffers, twi_masterBuffer, twi_txBuffer, and twi_rxBuffer.

  • twi_masterBuffer - during a Wire.requestFrom it waits until rxBuffer is fully read into, then copies the data into twi_masterBuffer. Subsequent Wire.read() call pull it from rxBuffer
  • twi_txBuffer - during a Wire.write the data in txBuffer is copied into twi_txBuffer and written from there during interrupt calls
  • twi_rxBuffer - during a slave receive data is placed in this buffer before the onReceive callback is called

I'm not sure if all these buffers are needed. Clearly the author thought they were, or possibly it was just because Wire.cpp was a C++ wrapper around the twi.c file.