Максимальное количество записей Arduino I2C на передачу
Существует ли ограничение на количество команд Wire.write()
, последовательно выполняемых между командой Wire.beginTransmission()
и командой Wire.endTransmission( )
для библиотеки Arduino Wire?
@pascalm, 👍3
Обсуждение3 ответа
Быстрый взгляд на исходный код показывает, что имеется буфер фиксированной длины в 32 байта:
Из заголовочного файла wire.h
:
#define BUFFER_LENGTH 32
И из реализации функции write
:
size_t TwoWire::write(uint8_t data)
{
if(transmitting){
// в режиме ведущего передатчика
// не беспокойтесь, если буфер заполнен
if(txBufferLength >= BUFFER_LENGTH){
setWriteError();
return 0;
}
// поместить байт в буфер tx
txBuffer[txBufferIndex] = data;
++txBufferIndex;
// обновляем количество в буфере
txBufferLength = txBufferIndex;
}else{
// в ведомом режиме отправки
// ответ мастеру
twi_transmit(&data, 1);
}
return 1;
}
Я почти уверен, что буфер расходуется через прерывание во время передачи, поэтому вы можете передать более 32 байтов, если перед записью убедитесь, что буфер не заполнен., @Nick Johnson
@NickJohnson Может быть, я не видел весь код, но, согласно документации, передача не начинается, пока вы не вызовете endTransmission
, поэтому я предполагаю, что несколько записей до этого могут переполниться. В любом случае следует проверить код возврата функции., @Roger Rowland
хорошо, спасибо, это точно соответствует тому, что я испытываю, можно отправить максимум 32 байта. Это аппаратное ограничение или просто буфер, установленный в оперативной памяти, другими словами, могу ли я просто увеличить его? например #define BUFFER_LENGTH 64?, @pascalm
@Roger Вы правы, передача не начнется, пока вы не вызовете endTransmission. Ура, новая тупость библиотеки Arduino!, @Nick Johnson
@pascalm Это определенно не аппаратная проблема. Было бы сложно увеличить размер буфера без изменения библиотек Arduino, но вместо этого вы могли бы вызывать вызовы низкоуровневых функций endTransmission с помощью собственного буфера: https://github.com/arduino/Arduino/blob/db8cbf24c99dc930b9ccff1a43d018c81f178535/hardware /arduino/avr/libraries/Wire/utility/twi.c#L177, @Nick Johnson
хорошо, спасибо, тогда я немного углублюсь в этот код :), @pascalm
В библиотеках TWI и Wire используется пять буферов. Они определены как 32 байта.
В wire.h:
#define BUFFER_LENGTH 32
В Wire.cpp:
uint8_t TwoWire::rxBuffer[BUFFER_LENGTH];
...
uint8_t TwoWire::txBuffer[BUFFER_LENGTH];
В twi.h:
#define TWI_BUFFER_LENGTH 32
В 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];
Итак, вы сразу используете 5 x 32 байта (160 байт).
Вы можете увеличить это значение, скажем, до 64 байт, учитывая, что ваши 160 байт теперь составляют 320 байт, а оперативной памяти у вас немного.
Комментарии к endTransmission()
верны. После вызова Wire.beginTransmission()
фактически ничего не передается до вызова endTransmission()
. Это позволяет вам заполнить буфер на досуге, а затем позволить библиотеке выполнять запись в зависимости от времени.
Ссылка
- I2C
- Проводная библиотека
Размер буфера можно увеличить.
Следует перейти к файлу twi.h, файлу Wire.h и установить нужную длину переменной: BUFFER_LENGTH
- Отправка и получение различных типов данных через I2C в Arduino
- Как работают функции вне цикла void?
- Как отображать переменные на 0,96-дюймовом OLED-дисплее с библиотекой u8glib?
- Как отправить строку на мастер с помощью i2c
- Как выбрать альтернативные контакты I2C на ESP32?
- Что означает в I2C «NACK получен»?
- NodeMCU с RFID RC522 и LCD-модулем интерфейса I2C вместе
- Несколько датчиков I2C с одинаковым адресом
@pascalm Не волнуйтесь, ответы тоже будут перенесены., @Roger Rowland