Отправка более BUFFER_LENGTH(32) байт в подчиненном ответе I2C
Мне нужно отправить 259 байт в качестве ответа на основной запрос чтения I2C. Насколько я знаю, в Wire.h и в HW (Arduino Nano) есть ограничение в 32 байта. Есть ли способ отправить 259-байтовый ответ или мне нужно выбрать другое оборудование?
Код:
void serveInitCommunication() {
Serial.println("serveInitCommunication()");
static unsigned int counter = 0;
auto answer = findInitAnswer(counter);
uint8_t buffer[260]; //максимальный размер из dataLengths[] в comm_init_data.h
memcpy_P(buffer, answer.dataPtrProgmem, answer.dataSize);
Serial.print(" dataSize:");
Serial.print(answer.dataSize);
Serial.print(" data:");
Serial.println(int(buffer[answer.dataSize - 1]));
auto bytesToWrite = answer.dataSize;
uint16_t bytesWritten{0};
while (bytesToWrite > BUFFER_LENGTH) {
Serial.println("Write part");
Wire.write(buffer + bytesWritten, BUFFER_LENGTH);
bytesToWrite -= BUFFER_LENGTH;
bytesWritten += BUFFER_LENGTH;
}
Serial.print("Bytes written:");
Serial.print(bytesWritten);
Serial.print(" Bytes yet to write:");
Serial.println(bytesToWrite);
Wire.write(buffer + bytesWritten, bytesToWrite);
counter++;
}
И это называется:
void requestHandler() {
char buff[100];
sprintf(buff, "requestHandler addr:0x%x counter:%d", readAddress, msgReadCounter);
Serial.println(buff);
if (readAddress == INIT_MSG_ADDRESS) {
serveInitCommunication();
}
}
Я попытался переместить serveInitCommunication()
в void loop()
и установить только флаг в requestHandler()
, но без успех. Отправка до 32 байт работает нормально. Tnx
update: uint8_t twi_transmit(const uint8_t*, uint8_t);
поэтому библиотека twi самостоятельно ограничивает данные до 255 байт
update2: есть хакерский способ сделать это, заменив twi.c twi_txBuffer и twi_txBufferLength буфером из скетча
@Libor Tomsik, 👍0
1 ответ
Ограничение чисто программное. Аппаратное обеспечение I2C имеет ограничение в один байт за раз, а программное обеспечение создает 32-байтовый буфер и передает из него каждый байт по очереди.
Хотя увеличить размер этого буфера вполне возможно, у вас могут возникнуть другие проблемы, когда вы превысите 255 байт, поскольку многие параметры и внутренние переменные для библиотеки ограничены 8-битными значениями.
Это также будет считаться очень "хакерским", поскольку вы не сможете легко обновить библиотеку Wire в будущем.
Лучшей стратегией было бы разбить ваши данные на фрагменты и сделать несколько запросов, каждый из которых говорил "Дайте мне номер фрагмента...", а затем повторно объединить их при получении.
- Считывание значений с емкостного сенсорного датчика TTP229 на arduino
- Не удается найти/подключить устройства I2C (SHT31 и SGP30)
- Отправка и получение различных типов данных через I2C в Arduino
- Как выбрать альтернативные контакты I2C на ESP32?
- Альтернативы библиотеке Wire для I2C
- Как перевести Arduino Nano в спящий режим с низким энергопотреблением (<0,05 мА)
- MAX30100 не работает
- Ведомое устройство Arduino с двумя мастерами, использующими одну и ту же шину I2C?
Я должен общаться с существующим HW. На данный момент я передал указатель данных и размер данных из скетча в twi.c и использую его напрямую. Действительно "хакерский" способ. Однако я надеюсь, что есть какой-то стандартный способ сделать это., @Libor Tomsik
Не используя программное обеспечение Arduino, нет. Он не предназначен для такого количества данных. На самом деле, I2C тоже не было..., @Majenko