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

Serial.peek()

Serial.peek() читает следующий байт из буфера Serial, не удаляя его — в отличие от read(), байт остаётся на месте и будет возвращён снова при следующем вызове.

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

Описание

Serial.peek() читает следующий байт из буфера последовательного порта, но не удаляет его оттуда. Это принципиальное отличие от read(): после вызова peek() байт остаётся в буфере, и следующий вызов peek() вернёт тот же самый символ. Только read() действительно «съедает» байт и двигает указатель буфера вперёд.

Такое поведение удобно, когда нужно принять решение о дальнейшей обработке данных, не теряя первый символ. Например, можно посмотреть на заголовок пакета и выбрать нужный обработчик, а затем передать весь поток дальше уже через read().

Serial.peek() наследуется от класса Stream.

Синтаксис

Serial.peek()

Параметры

Функция допускает следующий объект:

Serial: объект последовательного порта. См. список доступных последовательных портов для каждой платы на странице Serial.

Возвращает

Первый байт из входящего буфера в виде числа от 0 до 255, или -1, если буфер пуст. Тип данных: int.

Важно помнить, что возвращаемый тип — int, а не byte. Значение -1 используется именно как сигнал об отсутствии данных, поэтому не приводите результат к byte до проверки на -1.

Пример кода

Следующий код заглядывает в буфер и печатает символ, не извлекая его:

void setup() {
  Serial.begin(9600);
  while (!Serial);

  Serial.println("Type something:");
}

void loop() {
  if (Serial.available()) {
    char nextChar = Serial.peek();  // Смотрим на следующий символ
    Serial.print("Next character will be: ");
    Serial.println(nextChar);

    char actualChar = Serial.read();  // Теперь действительно считываем его
    Serial.print("Read character: ");
    Serial.println(actualChar);
  }
}

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

  • Разбор протоколов с заголовком — проверяете первый байт пакета, чтобы определить его тип, и только потом читаете весь пакет целиком.
  • Условное чтение — нужно убедиться, что следующий символ — цифра или буква, прежде чем передавать данные в функцию разбора числа.
  • Синхронизация потока — ищете стартовый маркер ('$', '#' и т.п.) без потери байтов: смотрите через peek(), и если символ не тот — читаете и выбрасываете его через read().

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

  • peek() не блокирует выполнение программы: если буфер пуст, функция немедленно вернёт -1.
  • Перед вызовом peek() полезно проверить Serial.available() > 0, чтобы не обрабатывать ложное -1.
  • Не путайте -1 как «нет данных» с байтом 0xFF (255): они различаются именно потому, что возвращаемый тип int, а не byte.
  • Многократные вызовы peek() подряд всегда возвращают один и тот же байт — буфер не изменяется.
  • Если нужно пропустить нежелательный символ, используйте read()peek() сам по себе ничего не удаляет.

Полезные материалы