Перейти к основному содержимому

UART

Робот обменивается данными через UART-модули

UART часто встречается в робототехнике: через него Arduino пишет сообщения в Serial Monitor, Bluetooth-модуль HC-06 получает команды, GPS-модуль отправляет координаты, а USB-TTL адаптер помогает прошивать и отлаживать платы. Снаружи это выглядит просто: два устройства обмениваются байтами по линиям TX и RX.

Коротко

UART — асинхронный последовательный интерфейс. Для обычного двустороннего обмена соединяют TX первого устройства с RX второго, TX второго с RX первого и обязательно объединяют GND. Скорость, число битов данных, чётность и стоповые биты должны совпадать у обеих сторон.

Правильное соединение UART: TX одной платы идёт на RX другой, а в обратную сторону нужна вторая линия

Зачем это нужно

В роботе UART удобно использовать для прямого канала между двумя устройствами. Например, смартфон отправляет команду через Bluetooth-модуль, модуль передаёт байты на Arduino, а Arduino включает моторы или светодиод.

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

Главная идея

Передатчик TX выдаёт последовательность битов, а приёмник RX восстанавливает байты по заранее согласованной скорости. Отдельной линии такта нет: обе стороны должны знать, сколько длится один бит.

Для популярной настройки 8N1 один байт передаётся как кадр:

стартовый бит -> 8 бит данных -> 1 стоповый бит

Кадр UART 8N1

Если скорость выбрана 9600, то обе стороны должны работать на 9600 бод. Если одна сторона настроена на 9600, а другая на 115200, приёмник увидит не текст, а набор случайных символов.

Провода и сигналы

ЛинияНаправлениеЗачем нужна
TXвыход передатчикаотправляет биты
RXвход приёмникапринимает биты
GNDобщий проводзадаёт общий ноль для логических уровней
VCCпитание, если оно требуетсяпитает модуль, но не является линией UART

Главное правило: TX соединяют с противоположным RX. Два TX напрямую соединять нельзя: оба вывода могут пытаться выдавать разные уровни.

Где находятся пины

ПлатаUART-пины по умолчаниюКомментарий
Arduino UnoD0/RX, D1/TXэти пины связаны с USB-Serial мостом, поэтому внешний модуль может мешать загрузке скетча
Arduino MegaSerial на 0/1, также есть Serial1, Serial2, Serial3удобно для нескольких UART-устройств
ESP32 DevKitUART0 обычно занят USB-отладкой; дополнительные UART можно назначать на подходящие GPIOв Arduino core для ESP32 пины можно задавать в Serial.begin(...)
ESP8266основной UART обычно связан с USB-адаптеромсвободных аппаратных UART меньше, чем у ESP32

Для учебных стендов с Arduino Uno часто используют библиотеку SoftwareSerial, чтобы не занимать D0/D1 во время прошивки и работы Serial Monitor.

Подключение устройства к Arduino Uno: HC-06

HC-06 подключён к Arduino Uno через UART

HC-06 — Bluetooth-модуль, который со стороны Arduino общается обычным UART. Он принимает символы от телефона и отдаёт их в микроконтроллер.

Контакт HC-06Куда подключить на Arduino UnoЗачем
TXDD10, программный RXArduino принимает байты от модуля
RXDD11, программный TX через делитель уровняArduino отправляет байты модулю
GNDGNDобщий ноль
VCCпитание модуля по его документацииобычно готовые платы HC-06 питают от 5 В, но логика входа остаётся около 3,3 В

Если модуль работает с логикой 3,3 В, на его вход RXD не стоит напрямую подавать 5 В с Arduino Uno. Для учебного макета используют делитель напряжения или готовый преобразователь уровней.

Пример с несколькими Arduino

Две Arduino Uno можно соединить по UART для простого обмена строками:

Arduino AArduino B
D1/TXD0/RX
D0/RXD1/TX
GNDGND

Одна плата отправляет строку, другая читает её из последовательного порта. В реальной лабораторной работе лучше сначала отключить внешние соединения от D0/D1 при загрузке скетча, а затем подключить их снова. Более удобный вариант — использовать SoftwareSerial на других цифровых пинах.

Минимальная проверка идеи:

// Передатчик
void setup() {
Serial.begin(9600);
}

void loop() {
Serial.println("LED_ON");
delay(1000);
}
// Приёмник
void setup() {
Serial.begin(9600);
pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
if (Serial.available()) {
String command = Serial.readStringUntil('\n');
if (command == "LED_ON") {
digitalWrite(LED_BUILTIN, HIGH);
}
}
}

Это учебный пример, а не готовый протокол управления роботом. Для моторов и опасных действий добавляют тайм-аут связи, проверку диапазонов и понятные команды остановки.

Частые ошибки

ОшибкаЧто произойдёт
TX подключили к TXприёмник не получает данные, возможен конфликт выходов
забыли GNDлогические уровни становятся неопределёнными
разные скороститекст превращается в «мусор»
заняли D0/D1 на Arduino Unoмогут возникнуть проблемы с загрузкой скетча и Serial Monitor
перепутали уровни 5 В и 3,3 Ввход модуля можно повредить
ждут целую команду одним чтениемстрока может прийти частями

Что запомнить про UART

  • Для двустороннего UART нужны две информационные линии: TX -> RX и RX <- TX.
  • Общий GND обязателен даже при отдельном питании.
  • Скорость и формат кадра должны совпадать.
  • UART передаёт поток байтов, а границы команд придумывает программа.
  • На Arduino Uno пины D0/D1 связаны с USB-Serial мостом, поэтому для внешних модулей часто берут программный UART.

Практика

  1. Нарисуйте соединение двух Arduino Uno по UART и подпишите каждый провод.
  2. Найдите на плате Arduino Uno пины D0/RX и D1/TX.
  3. Подключите HC-06 к Arduino через SoftwareSerial и отправьте один символ с телефона.
  4. Измените скорость только на одной стороне и посмотрите, как меняется вывод.

Проверьте себя

  1. Почему TX подключают к RX, а не к TX?
  2. Зачем нужен общий GND?
  3. Что означает настройка 9600 8N1?
  4. Почему один вызов чтения не всегда равен одной команде?
Ориентиры для самопроверки

Сначала ответьте без подсказки. Ответ можно считать полным, если вы:

  • формулируете основную мысль своими словами;
  • называете важные условия, ограничения или меры безопасности;
  • для схемы, кода или расчёта показываете ход решения и ожидаемый результат.

Если один из пунктов объяснить не получается, найдите соответствующую главу статьи, перечитайте её и повторите ответ.

Словарь статьи

  • UART — асинхронный последовательный интерфейс без отдельной линии такта.
  • Бодовая скорость — число символьных интервалов в секунду; для обычного UART обычно совпадает с числом битов в секунду.
  • Кадр UART — стартовый бит, биты данных, необязательная чётность и стоповые биты.
  • TX/RX — линии передачи и приёма.
  • Буфер — область памяти, где принятые байты ждут обработки программой.

Связанные темы

  • I2C — адресная двухпроводная шина для нескольких устройств.
  • 1-Wire — общая линия данных и ROM-коды устройств.
  • SPI — синхронный обмен с отдельным тактом и выбором устройства.
  • Сравнение протоколов — как выбрать интерфейс под задачу.
  • Отладка обмена — как проверять питание, уровни и сигналы.

Источники