Serial.readBytes()
Serial.readBytes() читает из последовательного порта ровно столько байт, сколько указано в length, и записывает их в массив buffer, ожидая данные до истечения таймаута.
Полная статья
Описание
Serial.readBytes() читает байты из последовательного порта и записывает их в массив-буфер. Функция завершает работу в одном из двух случаев: либо прочитано ровно столько байтов, сколько указано в параметре length, либо истёк таймаут ожидания (настраивается через Serial.setTimeout()).
Это блокирующая функция — скетч будет стоять на месте, пока не придут нужные данные или не выйдет время. По умолчанию таймаут равен 1000 мс, но его можно изменить под свои нужды.
Serial.readBytes() наследуется от класса Stream.
Синтаксис
Serial.readBytes(buffer, length)
Параметры
Serial— объект последовательного порта. На платах с несколькими UART (например, Mega) можно использоватьSerial1,Serial2и т. д. Список доступных портов для каждой платы смотрите на странице Serial.buffer— массив типаcharилиbyte, куда будут записаны принятые байты. Убедитесь, что массив достаточно большой: функция не проверяет границы и может записать данные за пределы выделенной памяти, если буфер меньшеlength.length— сколько байт нужно прочитать. Тип данных:int.
Возвращает
Функция возвращает количество байт, фактически записанных в буфер, тип size_t. Если данных не поступило до истечения таймаута, вернётся 0.
Как читать результат. Возвращаемое значение стоит всегда проверять: если оно меньше length, значит, данные пришли не полностью — либо отправитель прислал меньше байт, либо таймаут слишком короткий. Это частая причина, по которой буфер оказывается заполнен нулями или мусором в конце.
Пример кода
Следующий код создаёт буфер на 5 символов и сохраняет в нём входящие байты из последовательного порта.
char data[6]; // 5 байт + нулевой терминатор
void setup() {
Serial.begin(9600);
while (!Serial);
Serial.println("Send 5 characters:");
}
void loop() {
if (Serial.available() >= 5) {
int bytesRead = Serial.readBytes(data, 5);
data[bytesRead] = '\0'; // Добавляем нулевой терминатор строки
Serial.print("Received: ");
Serial.println(data);
}
}
Где применяется
- Приём пакетов фиксированной длины — например, когда внешнее устройство всегда присылает ровно N байт за раз (датчики, модули GPS, Bluetooth-модули).
- Чтение бинарных протоколов — когда данные приходят не в виде текста, а как последовательность байт с заранее известной структурой.
- Синхронизация с компьютером — ПК отправляет команду фиксированного размера, Arduino читает её целиком и разбирает.
- Работа с несколькими UART — на платах с несколькими портами можно вызывать
Serial1.readBytes(),Serial2.readBytes()независимо.
Практические замечания
- Функция блокирует выполнение до получения нужного числа байт или истечения таймаута. Если это мешает работе программы, рассмотрите
Serial.available()в связке с ручным чтением. - Размер буфера должен быть не меньше
length. Если после чтения вы хотите работать с данными как со строкой C, выделите ещё один байт под'\0'. - Таймаут по умолчанию — 1000 мс. Если устройство отправляет данные медленно или с паузами, увеличьте его через Serial.setTimeout(). Если скорость важна, уменьшите.
- Нулевой терминатор не добавляется автоматически. Если вы хотите работать с буфером как со строкой C, добавьте
buffer[n] = '\0'вручную после чтения. - Возвращаемое значение
0не всегда означает ошибку — возможно, данные просто ещё не пришли. Проверьте соединение, скорость (Serial.begin()), и совпадает лиlengthс тем, сколько байт реально отправляет источник.