I2C отсутствует последний байт во время передачи
Я использую Nodemcu-32S для связи с устройством I2C (сенсорные панели). Я заметил, что при загрузке конфигурации CRC (контрольная сумма) всегда возвращается неверно. Немного покопавшись в логическом анализаторе, я понял, что он никогда не передает последний байт из моего конфигурационного массива, который является значением контрольной суммы. Функция, которую я использую для записи на шину I2C, выглядит следующим образом:
bool writeI2C(uint16_t address, uint8_t command, uint8_t *data, uint8_t dataLen)
{
byte err;
uint8_t dataPos = 0;
Wire.beginTransmission(address);
Wire.write(command);
for (dataPos; dataPos < dataLen; dataPos++)
{
Wire.write(data[dataPos]);
}
delay(70);
err = Wire.endTransmission();
if (err > 0)
{
Serial.printf("writeI2C Error Code: 0x0%d\n", err);
return false;
}
else
return true;
}
С помощью следующего вызова функции:
uint8_t config[128] = {0}; <- (the array is filled with values before the function call)
if (!writeI2C(SLAVE_ADDR, command, config, 128))
{
Serial.println("Failed to update config.");
continue; // try again
}
Согласно логике моей функции, она должна передавать адрес, затем регистр (в данном случае команду), за которым следует 128 байт данных (всего 130 байт). Однако с помощью моего логического анализатора я получаю только 129 "кусков" данных. Поэтому я решил добавить фиктивные записи, если
dataLen
удовлетворит условию:
bool writeI2C(uint16_t address, uint8_t command, uint8_t *data, uint8_t dataLen)
{
byte err;
uint8_t dataPos = 0;
Wire.beginTransmission(address);
Wire.write(command);
for (dataPos; dataPos < dataLen; dataPos++)
{
Wire.write(data[dataPos]);
}
if (dataLen > 100)
{
Wire.write(0x00);
Wire.write(0x00);
Wire.write(0x00);
Wire.write(0x00);
Wire.write(0x00);
}
err = Wire.endTransmission();
delay(70);
if (err > 0)
{
Serial.printf("writeI2C Error Code: 0x0%d\n", err);
return false;
}
else
return true;
}
Ни одна из фиктивных записей не выводится, и поведение остается прежним. Последние два байта должны быть: config[126] = 0x45
и config [127] = 0xC9
, но мой логический анализатор показывает, что передача останавливается на 0x45 + ACK
.
@Jebussy, 👍1
1 ответ
В пределах Wire.h.
:
#define I2C_BUFFER_LENGTH 128
Изменил длину буфера на 140, и он работает просто отлично.
- Отправка и получение различных типов данных через I2C в Arduino
- Как работают функции вне цикла void?
- Как отображать переменные на 0,96-дюймовом OLED-дисплее с библиотекой u8glib?
- Как отправить строку на мастер с помощью i2c
- Как выбрать альтернативные контакты I2C на ESP32?
- Что означает в I2C «NACK получен»?
- NodeMCU с RFID RC522 и LCD-модулем интерфейса I2C вместе
- Несколько датчиков I2C с одинаковым адресом