Is there any limit on the number of Wire.write() commands consecutively in between the Wire.beginTransmission() command and the Wire.endTransmission() command for the Arduino Wire library?
-
@pascalm Don't worry, the answers would get migrated too. – Roger Rowland May 22 '15 at 13:08
-
@pascalm The question is not about electronic design but arduino related software library. As we could see, it ccould be answered on this site too, but this way the useful information won't be available to the lot using arduino.se but the less using this site. – May 22 '15 at 13:13
3 Answers
There are five buffers used by the TWI and Wire library. They are defined as 32 bytes.
In wire.h:
#define BUFFER_LENGTH 32
In Wire.cpp:
uint8_t TwoWire::rxBuffer[BUFFER_LENGTH];
...
uint8_t TwoWire::txBuffer[BUFFER_LENGTH];
In twi.h:
#define TWI_BUFFER_LENGTH 32
In twi.c:
static uint8_t twi_masterBuffer[TWI_BUFFER_LENGTH];
...
static uint8_t twi_txBuffer[TWI_BUFFER_LENGTH];
...
static uint8_t twi_rxBuffer[TWI_BUFFER_LENGTH];
So immediately you are using 5 x 32 bytes (160 bytes).
You could increase that to (say) 64 bytes, bearing in mind your 160 byte overhead is now 320 bytes, and you don't have a lot of RAM.
The comments about endTransmission() are correct. After a Wire.beginTransmission() nothing is actually transmitted until the endTransmission() call. This lets you fill up the buffer at your leisure, and then let the library do the writes in a fairly timing-specific way.
Reference
- 38,184
- 13
- 65
- 124
A quick look at the source code implies that there is a fixed length buffer of 32 bytes:
From the header file wire.h:
#define BUFFER_LENGTH 32
And from the implementation of the write function:
size_t TwoWire::write(uint8_t data)
{
if(transmitting){
// in master transmitter mode
// don't bother if buffer is full
if(txBufferLength >= BUFFER_LENGTH){
setWriteError();
return 0;
}
// put byte in tx buffer
txBuffer[txBufferIndex] = data;
++txBufferIndex;
// update amount in buffer
txBufferLength = txBufferIndex;
}else{
// in slave send mode
// reply to master
twi_transmit(&data, 1);
}
return 1;
}
- 600
- 1
- 4
- 8
-
I'm fairly certain that buffer gets consumed via the interrupt during transmission, so you could transmit more than 32 bytes as long as you check that the buffer's not full before writing. – Nick Johnson May 22 '15 at 12:46
-
@NickJohnson Maybe, I didn't eyeball all the code, but according to the documentation, transmission doesn't begin until you call
endTransmissionso I assume multiple writes before then might overflow. The function's return code should be examined in any case. – Roger Rowland May 22 '15 at 12:47 -
ok, thanks, this corresponds exactly to what I am experiencing, a maximum of 32 bytes can be sent. Is this a hardware restriction or simply a buffer that is set up in ram, in other words, could i simply augment it? eg #define BUFFER_LENGTH 64? – pascalm May 22 '15 at 13:02
-
2@Roger You're right, it doesn't start transmitting until you call endTransmission. Hooray, a new Arduino library stupidity! – Nick Johnson May 22 '15 at 13:02
-
@pascalm It's definitely not a hardware issue. It'd be difficult to increase the buffer size without modifying the Arduino libs, but you could instead call the low-level functions endTransmission calls with your own buffer: https://github.com/arduino/Arduino/blob/db8cbf24c99dc930b9ccff1a43d018c81f178535/hardware/arduino/avr/libraries/Wire/utility/twi.c#L177 – Nick Johnson May 22 '15 at 13:03
-
The buffer size can be increased.
Should go to the twi.h fil, Wire.h file and set the desired length of the variable: BUFFER_LENGTH
- 1