Отправка более 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 буфером из скетча

, 👍0


1 ответ


1

Ограничение чисто программное. Аппаратное обеспечение I2C имеет ограничение в один байт за раз, а программное обеспечение создает 32-байтовый буфер и передает из него каждый байт по очереди.

Хотя увеличить размер этого буфера вполне возможно, у вас могут возникнуть другие проблемы, когда вы превысите 255 байт, поскольку многие параметры и внутренние переменные для библиотеки ограничены 8-битными значениями.

Это также будет считаться очень "хакерским", поскольку вы не сможете легко обновить библиотеку Wire в будущем.

Лучшей стратегией было бы разбить ваши данные на фрагменты и сделать несколько запросов, каждый из которых говорил "Дайте мне номер фрагмента...", а затем повторно объединить их при получении.

,

Я должен общаться с существующим HW. На данный момент я передал указатель данных и размер данных из скетча в twi.c и использую его напрямую. Действительно "хакерский" способ. Однако я надеюсь, что есть какой-то стандартный способ сделать это., @Libor Tomsik

Не используя программное обеспечение Arduino, нет. Он не предназначен для такого количества данных. На самом деле, I2C тоже не было..., @Majenko