Arduino Serial: Введение, использование Serial Monitor и не только

Эта статья является частью серии руководств по последовательной связи Arduino, охватывающей основы серийной коммуникации, Serial Monitor и практическое применение.

Серия включает:

  • Введение, использование Serial Monitor и не только

  • Обзор различных библиотек Serial

  • Команды Serial: подробное описание

  • Данные Serial

  • Начало работы с использованием Serial для отправки команд

  • ASCII данные и использование маркеров для разделения данных

Основы Serial Monitor Arduino

Начало работы

Serial Monitor необходим для вывода сообщений при разработке и отладке скетчей. Вот базовый пример:

Макетная плата с Arduino
// Базовый пример serial print 01. Hello World

void setup()
{
    Serial.begin(9600);
    while (!Serial);
    Serial.print("Hello World");
}

void loop()
{
}

Открытие Serial Monitor

Чтобы открыть Serial Monitor в Arduino IDE, перейдите в меню Tools > Serial Monitor, или нажмите Ctrl+Shift+M в Windows.

Открытие Serial Monitor в Arduino IDE

После загрузки этого скетча и открытия Serial Monitor вы должны увидеть надпись «Hello World».

Hello World в Serial Monitor

Настройка скорости передачи (Baud Rate)

Скорость передачи, указанная в коде, должна совпадать с настройкой Serial Monitor. В примере выше Serial.begin(9600) устанавливает скорость Arduino на 9600 бод. Если в мониторе отображаются искаженные символы вместо текста, проверьте, что скорость совпадает.

Serial.begin(9600);

Если скорости не совпадают, вы увидите искаженные символы вместо читаемого текста. Распространённые несовпадения скоростей приводят к мусорному выводу:

  • 4800 бод: отображает повреждённые символы

  • 19200 бод: отображает повреждённые символы

  • Сильно несовпадающие скорости: могут не давать вообще никакого вывода

Ошибка скорости передачи 1 Ошибка скорости передачи 2 Ошибка скорости передачи 3

Понимание скоростей передачи

Скорость 9600 бод означает 9600 бит в секунду. Arduino использует распространённый протокол 8N1, который использует 10 бит на каждый символ. Это означает (9600/10) 960 символов в секунду.

Распространённые скорости включают 38400 и 115200 бод для более быстрой связи. Аппаратный Serial на Arduino с частотой 16 МГц может поддерживать скорости до 2 000 000 бит/с при определённых условиях.

Выбор скорости передачи

Инструкция while (!Serial)

На платах с прямым USB-подключением (Leonardo и др.) серийный канал требует время для инициализации. Команда while (!Serial) приостанавливает выполнение до готовности серийного канала, предотвращая потерю данных.

На стандартных Arduino с мостом USB-Serial (Uno, Mega, Nano) это менее критично, но всё равно полезно.

while (!Serial) { ; }

Символы конца строки (EOL)

Проблема: строки на одной строке

// Базовый пример serial print 02. Без переноса строки

void setup()
{
    Serial.begin(9600);
    while (!Serial);
    Serial.print("Hello World");
    Serial.print("Another string");
}

void loop()
{
}

Это выведет «Hello WorldAnother string» на одной строке.

Вывод без переноса строки

Решение: использование println()

// Базовый пример serial print 03. Добавление переносов строки с println

void setup()
{
    Serial.begin(9600);
    while (!Serial);
    Serial.println("Hello World");
    Serial.println("Another string");
}

void loop()
{
}

Serial.println() автоматически добавляет символы окончания строки. Два управляющих символа EOL:

  • \r (Carriage Return, возврат каретки): перемещает курсор в начало строки без перехода на следующую

  • \n (Line Feed, перевод строки): перемещает курсор вниз без возврата в начало

  • \r\n (End of Line, конец строки): комбинированный эффект

В качестве альтернативы можно добавить «\r\n» вручную к вызовам Serial.print().

Вывод с переносом строки

Форматирование вывода символами табуляции

Для выровненных столбцов с данными переменной длины используйте символ табуляции «\t»:

byte potPin = 17;
byte switch1_pin = 14;
byte switch2_pin = 15;

int potVal = 0;
boolean switch1State = 0;
boolean switch2State = 0;

void setup()
{
  Serial.begin(115200);
  while (!Serial);
  Serial.println("");
  Serial.println("Pot\tSwitch1\tSwitch2");
}

void loop()
{
  potVal = analogRead(potPin);
  switch1State = digitalRead(switch1_pin);
  switch2State = digitalRead(switch2_pin);

  Serial.print(potVal);  Serial.print("\t");  Serial.print(switch1State);  Serial.print("\t");  Serial.println(switch2State);

  delay(500);
}

Символы табуляции выравнивают столбцы независимо от длины данных, обеспечивая читаемое форматирование вывода.

Форматирование вывода с табуляцией

Понимание протокола 8N1

8N1 — один из наиболее распространённых последовательных протоколов, означающий: 8 бит данных, без чётности (no parity) и 1 стоп-бит. Название немного вводит в заблуждение, так как на самом деле используется 10 бит — к ним добавляется стартовый бит.

10 бит состоят из: 1 стартовый бит + 8 бит данных + 0 бит чётности + 1 стоп-бит.

Ошибка передачи (Transmission Error)

Ошибка передачи возникает, когда частота хост-микропроцессора и настроенная скорость передачи не совпадают точно. Различия в тактовой частоте создают дрейф синхронизации — иногда тики синхронизируются идеально, иногда выравниваются приблизительно (система самокорректируется), а иногда они расходятся значительно (вызывая искажённую или неудачную связь).

Руководство включает таблицу ошибок передачи, показывающую процент ошибок при различных скоростях передачи для разных частот процессора. Если нет особых требований, последовательная связь Arduino имеет встроенные допуски на эти расхождения.

Таблица ошибок передачи

Размер буфера Serial

Большинство Arduino с 1023+ байтами ОЗУ имеют 64-символьный буфер ввода/вывода для Serial.

Проблемы с входным буфером

Когда входной буфер полностью заполняется, поступающие данные отбрасываются. Например, при получении 200 байт с 64-байтным буфером байты 65-200 будут потеряны. Если чтение начнётся примерно с байта 100, байты 65-99 останутся потерянными, в то время как байты 100+ будут сохраняться в теперь доступном пространстве буфера, создавая пробелы в последовательности данных.

Предотвращение требует постоянного опустошения буфера для поддержания доступного пространства.

Поведение выходного буфера

Когда выходной буфер заполняется во время передачи, функции print() и write() блокируются, пока не освободится место для оставшихся данных.

Дополнительные ресурсы

Если вы хотите узнать больше о UART, что это такое и как он работает, смотрите статью о Serial UART.


Оригинал статьи: martyncurrey.com