Главная chevron_right Функции chevron_right Связь chevron_right Wire.write()

Wire.write()

Wire.write() помещает байты в I²C-буфер контроллера (данные уйдут при Wire.endTransmission()) или формирует ответ периферии внутри Wire.onRequest().

Полная статья

Описание

Wire.write() — основной инструмент для передачи данных по шине I²C, и его поведение зависит от того, в какой роли работает плата.

Когда плата выступает контроллером, Wire.write() не отправляет данные немедленно — она накапливает байты в буфере, который открывается вызовом Wire.beginTransmission(address). Реальная передача по шине происходит только при вызове Wire.endTransmission(). Это означает, что между Wire.beginTransmission(address) и Wire.endTransmission() можно вызвать Wire.endTransmission() несколько раз, чтобы последовательно сложить в буфер адрес регистра, команду и данные.

Когда плата работает как периферийное устройство, Wire.write() вызывают внутри обработчика Wire.onRequest(): именно здесь устройство готовит байты, которые контроллер считает при следующем запросе.

Функция является частью библиотеки Wire.

Синтаксис

  • Wire.write(value)
  • Wire.write(string)
  • Wire.write(data, length)

Параметры

  • value — один байт для отправки. Допустимый тип данных: byte.
  • string — строка в стиле C, передаётся как последовательность байтов. Допустимый тип данных: char*.
  • data — массив байтов для передачи. Допустимый тип данных: byte[].
  • length — сколько байтов из массива data нужно отправить. Допустимый тип данных: size_t.

Возвращает

Количество байтов, фактически принятых в буфер (в режиме контроллера) или отправленных в ответ (в режиме периферии). В большинстве случаев это значение не нужно проверять, но при отладке оно покажет, не переполнился ли буфер: если вернулось меньше, чем вы передали, часть данных потеряна.

Тип данных: size_t.

Пример кода

В примере контроллер отправляет один байт устройству с адресом 0x2C:

byte value = 0;

void setup() {
  Wire.begin();
}

void loop() {
  Wire.beginTransmission(0x2C);
  Wire.write(value);
  byte result = Wire.endTransmission();

  value++;
  if (value == 64) {
    value = 0;
  }

  delay(500);
}

Пример ответа периферийного устройства на запрос контроллера:

void setup() {
  Wire.begin(0x08);
  Wire.onRequest(requestEvent);
}

void requestEvent() {
  Wire.write("OK");
}

void loop() {
}

Где применяется

  • Запись в регистры I²C-устройств — сначала отправляется адрес регистра, затем одно или несколько значений одной транзакцией.
  • Передача команд датчику или модулю — контроллер формирует пакет через Wire.write() и завершает его через Wire.endTransmission().
  • Ответ периферийного устройства — внутри Wire.onRequest() устройство возвращает байты контроллеру по запросу.
  • Передача бинарных данных фиксированной длины — удобно использовать вариант с массивом data и length, чтобы отправить структуру целиком.

Практические замечания

  • В режиме контроллера Wire.write() не отправляет данные сразу. Байты накапливаются в буфере; отправка по шине происходит только при вызове Wire.endTransmission().
  • В режиме периферии вызывайте Wire.write() внутри onRequest(). Именно эти байты контроллер и получит в ответ на свой запрос.
  • Следите за размером буфера. Если суммарный объём данных превысит внутренний буфер Wire, лишние байты будут молча отброшены — возвращаемое значение поможет это обнаружить.
  • Строки отправляются побайтово, без терминатора. Wire.write("OK") передаст символы O и K, но нулевой байт '\0' в конце как '\0' не добавляется автоматически.
  • Проверяйте результат Wire.endTransmission(). Даже если Wire.write() успешно приняла байты в буфер, устройство на шине может не подтвердить свой адрес или данные — об этом сообщит код ошибки endTransmission().

Примечания и предупреждения

Не путайте Wire.write() с Serial.print(): Wire.write() передаёт сырые байты, а не текстовое представление числа. Например, Wire.write(65) отправит байт со значением 65 (символ 'A'), тогда как Serial.print(65) вывела бы строку "65". Если нужно передать число в виде текста, сначала преобразуйте его в строку и используйте вариант с char*, либо отправляйте ASCII-символы по одному.