UART — Универсальный Асинхронный Приёмопередатчик
Универсальный асинхронный приёмопередатчик (Univsersal Asynchronos Reciever-Transmitter) — это физическое устройство приёма и передачи данных по двум проводам. Оно позволяет двум устройствам обмениваться данными на различных скоростях. В спецификацию UART не входят аналоговые уровни на которых ведётся общение между устройствами, UART это протокол передачи единиц и нулей, электрическую спецификацию на себя берут другие стандарты, такие как TTL (transistor-transistor logic — транзисторно-транзисторная логика), RS-232, RS-422, RS-485 и другие (RS [англ.recommended standard] — рекомендованный стандарт). На данный момент в микроконтроллерах используется в основном TTL (или точнее CMOS) UART для соединения не более двух устройств. В наших примерах мы часто называем его последовательным портом.
Подключение:
У каждого устройства, поддерживающего UART обычно обозначены два вывода: RX и TX. TX — означает transmit (передаю), RX — receive (принимаю). Отсюда становится понятно что RX одного устройства нужно подключать к TX другого. Если Вы подключите RX одного устройства к RX другого, то оба устройства будут слушать друг друга, вы соединили их входы. Если соединить TX и TX — это уже более опасно, это выходы низкого сопротивления устройств и если на одном будет логическая единица, а на втором ноль — по проводу пойдёт ток короткого замыкания (это зависит от конкретной программной или аппаратной реализации). Хотя в современных чипах от этого есть защита, на всякий случай, не стоит на неё ориентироваться. Так же необходимо объединить референсные уровни двух устройств (GND—GND), если не подразумевается гальваническая развязка.
Пример соединения двух UNO:

UART на Arduino:
На Arduino и Arduino-совместимых платах аппаратный UART обозначается символами RX и TX рядом с соответствующими выводами. На Arduino UNO/Piranha UNO это 0 и 1 цифровые выводы:
Arduino UNO/Piranha UNO

В скетче инициализируется функцией begin() в коде функции setup():
Пример:
Piranha ULTRA
На Piranha ULTRA присутствуют два аппаратных UART. Один на тех же выводах, что и UNO, второй на 8 (RX) и 9 (TX) выводах:

В Arduino IDE второй аппаратный UART называется Serial1 (Сериал один), и инициализируется так же как и первый:
Простой пример для копирования буфера первого UART'а во второй и наоборот:
Arduino MEGA
У Arduino MEGA, помимо UART'a на цифровых выводах 0 и 1 как и у UNO, присутствуют ещё три аппаратных UART. На плате это выводы 19 (RX1), 18 (TX1), 17 (RX2), 16 (TX2) и 15 (RX3), 14 (TX3) соответственно. UART совместимый по расположению с UNO обозначен RX0, TX0:

На заметку: На многих Arduino и Arduino-совместимых платах UART0 используется для загрузки скетчей, так что если Ваш скетч не загружается, проверьте эти выводы. Во время загрузки скетча к ним ничего не должно быть подключено.
Отладка проектов при помощи UART
В совокупности с монитором последовательного порта UART может быть очень полезен для отладки кода. Например, если не понятно доходит ли Ваш код до определённого места или какие значения принимает переменная, можно вызвать функцию println() и вывести значение переменной или какое-нибудь сообщение в монитор порта. В Arduino IDE монитор порта находится в меню Инструменты -> Монитор порта, так же его можно вызвать нажав пиктограмму лупы в правом верхнем углу главного окна Arduino IDE или вызвать с клавиатуры комбинацией клавиш Ctrl+Shift+M. Перед вызовом монитора порта необходимо выбрать порт с которым Вы хотите работать. Сделать это можно в меню Инструменты -> Порт.
Для удобства отладки можно указать директивы препроцессора языка Си #define , #ifdef , #ifndef
Пример:
Программный UART на Arduino
Помимо аппаратного UART в Arduino можно использовать программный. Программный порт хорошо подходит для простых проектов, не критичных к времени работы кода или для отладки проектов, позволяя не отключать модули использующие UART во время загрузки сетчей. При его использовании нужно лишь помнить что никакой другой код не может выполняться пока программа занимается считыванием данных из него и передача может осуществляться только в полудуплексном или симплексном режимах. Так же на программный RX можно назначать только те выводы, которые поддерживают прерывание по смене уровней. На UNO, например, это все цифровые выводы, кроме 13-го. Прежде чем собирать свой проект, проконсультируйтесь с инструкцией к конкретной плате.
Пример использования программного порта:
Далее к программному порту нужно обращаться через объект mySerial . Например: mySerial.write(data); .
UART на Raspberry Pi:
На Raspberry Pi UART находится на выводах колодки 8 — TX (GPIO14) и 10 — RX (GPIO15)

Перед работой с последовательным портом необходимо его включить. Сделать это можно из эмулятора терминала командой sudo raspi-config -> Interfacing options -> Serial -> No -> Yes -> OK -> Finish или из графической среды в главном меню -> Параметры -> Raspberry Pi Configuration -> Interfaces -> Serial Port
Пример работы с последовательным портом на Python:
Данный пример выводит строку «iArduino.ru» в последовательный порт Raspberry и ждёт данных из последовательного порта.
Подробнее о UART:
Параметры
При обозначении параметров UART принято использовать короткую запись ЦИФРА—БУКВА—ЦИФРА
- ЦИФРА — количество бит в кадре
- от 5 до 9 бит. Обычно 8.
- N — None (Отсутствует) без бита чётности
- E — Even (Чётный). Проверка данных на чётность. Перед стоп-битом в кадр добавляется бит: 0 если в кадре было нечётное количество единиц, 1 — если чётное.
- O — Odd (Нечётный). Проверка данных на нечётность. Перед стоп-битом в кадр добавляется бит: 1 если в кадре было нечётное количество единиц, 0 — если чётное.
- 1, 1.5, 2. Продолжительность стоп-бита (1, 1.5 или 2 битовых интервала)
Таким образом, стандартные настройки в Arduino: 8-N-1
Кадрирование данных
При приёме-передаче данных каждое устройство ориентируется на своё внутреннее тактирование. Обычно это тактирование от 8 до 16 раз быстрее скорости передачи данных и обычно отсчитывается от стартового бита. Именно поэтому необходимо чтобы оба устройства были настроены на одну и ту же скорость передачи.
Так же при передаче данных присутствуют синхронизирующие биты, именуемые старт-бит и стоп-бит. Старт-бит сигнализирует о начале передачи данных и стоп-бит, соответственно об окончании.
Рассмотрим кадр данных:
При разговорах о серийный протоколах принято использовать такие слова как кадр и пакет. Кадр — интервал от старт-бита до стоп-бита. Пакет — количество кадров полезных данных. При этом не стоит путать кадр и байт: байт — это только сами данные, не включающие в себя синхронизирующие и проверочные биты.
Старт-бит:
При отсутствии передачи линия удерживается в состоянии логической единицы (в случае TTL Arduino это 5 вольт или Vcc). Как только передающее устройство притягивает линию к 0 (GND или 0 вольт в случае Arduino), это сигнализирует принимающему устройству о том что сейчас будет передача данных.
Данные:
При появлении старт-бита на линии принимающее устройство начинает отсчитывать время в соответствии с установленной скоростью и считывать состояния линии через определённые промежутки времени в соответствии с установленным количеством бит данных, после этого.
Стоп-бит:
По завершении передачи данных принимающее устройство ожидает стоп-бит, который должен быть на уровне логической единицы. Если по завершении кадра удерживается логический ноль, значит данные неверны. Если логический ноль удерживается время, превышающее длину кадра в 1,5 раза, такое состояние именуется break (разрыв линии, исторически пошло от устройств, использующих токовую петлю для передачи данных). Некоторые передатчики вызывают это состояния специально перед посылкой пакета данных. Некоторые приёмники считают такое состояние за неправильно выставленную скорость и сбрасывают свои настройки на установки «по умолчанию».
Скорость передачи данных
Скорость изменения логических уровней (импульсов) на линии принято измерять в бодах. Единица измерения названа так в честь французского изобретателя Жана Мориса Эмиля Бодо.
Скорость при использовании UART может быть любой, единственное требование — скорости передающего и принимающего должны быть одинаковы. Стандартная скорость UART принята за 9600 бод. Arduino без проблем и лишних настроек может принимать и передавать данные на скоростях до 115200 бод.
Так как при передаче данных присутствуют синхронизирующие биты, именуемые старт-бит и стоп-бит, не совсем корректно говорить, что скорость 9600 бод равна 9600 битам в секунду. Если речь идёт о полезных данных, то реальная скорость на 20% ниже. Например, если выставлены параметры 8-N-1 и 9600 бод, то на передачу одного байта уходит десять бит, и 9600/10 = 960 байт, что равно 7680 битам в секунду.
Методы связи
UART позволяет одновременно передавать и принимать данные, однако не всегда это возможно или нужно. Например, если Вам нужно только получать не критические данные (которые можно проверить следующим пакетом, например расстояние, посылаемое лидаром каждые несколько сотен миллисекунд) от цифрового датчика или любого другого устройства и не нужно ничего передавать, такой метод называется симплексным. Всего различают три метода связи:
Передача данных между микроконтроллерами Arduino через последовательный интерфейс

Обмен данными между двумя платами Arduino очень полезен. В больших проектах можно назначить несколько микроконтроллеров для управления техническими процессами.
Реализовать обмен данными между двумя микроконтроллерами Arduino можно с использованием последовательного интерфейса передачи данных. Для этого будут использоваться контакты RX-0 и TX-1.
Схема подключения микроконтроллеров Arduino UNO

Контакт Arduino UNO -1 RX-0 подключается к контакту TX-1 Arduino UNO -2 и на оборот контакт TX-1 Arduino UNO -1 подключается к контакту RX-0 Arduino UNO -2.
Обратите внимание, что необходимо обязательно подключить контакты GND. В противном случае обмен данными происходить не будет!
Код C++ для микроконтроллера Arduino UNO -1
Микроконтроллер Arduino UNO -1 будет отправлять целочисленные данные через последовательный интерфейс на микроконтроллер Arduino UNO -2.
Код C++ для микроконтроллера Arduino UNO -2
Микроконтроллер Arduino UNO -2 будет получать целочисленные данные через последовательный интерфейс от микроконтроллера Arduino UNO -1.
Результат работы в консоли микроконтроллера Arduino UNO -1

Результат работы в консоли микроконтроллера Arduino UNO -2

Более подробную инструкцию вы можете получить посмотрев видео «Связь между двумя платами Arduino».
Обмен данными между двумя Arduino при помощи программного UART
Коммуникация по последовательному порту , по умному называемая как универсальный асинхронный прием / передача (UART), как правило, используется для программирования и отладки Arduino через порт USB. Существуют разные датчики и приборы, которые используют UART как метод основной связи, и иногда нам нужно объединять два и больше Arduino между собой для обмена информацией.
Тем не менее, у большинства Arduino имеется только один последовательный порт, который используется при связи по USB. Но как же связать такой контроллер с другим? Конечно использование Arduino типа Mega или подобного решает эту задачу, ведь у него до четырех последовательных портов, но если нужна связь с простыми платами из линейки Ардуино, тут нужно искать другой выход. Существует особая программная библиотека, которая имитирует UART порт на других цифровых контактах. У нее имеются несколько недостатков, но в общем она работает.
Так что нам понадобится для демонстрации подобной коммуникации:
2 Arduino контроллера
Выполните следующие шаги, для подключения двух Arduino UNO, с помощью программного последовательного порта:
1. Например, воспользуемся выводами 8 и 9 для RX и TX на обоих Arduino, соедините контакт 8 на одном Arduino с контактом 9 на другом, и контакт 9 на первом Arduino подключить с контактом 8 на втором.
2. Соедините общий провод GND обеих Arduino вместе.
3. Подключите один Arduino к USB компьютера, и соедините вывод 5В этого контроллера с таким же выводом другого или подайте на второй отдельное питание.
Вот реализация с использованием выводов 8 и 9 для RX и TX:

Следующий код разделен на две части. Arduino мастер будет получать команды от компьютера и передавать их по программному последовательному порту. Вот первая часть кода:
// Подключаем библиотеку Software Serial
// Объявляем задействованные дискретные каналы контроллера для связи
SoftwareSerial softSerial(8, 9); // RX, TX>
Serial.begin(9600); // Обычная скорость передачи данных
softSerial.begin(9600); // инициализация программного последовательного порта
// Проверяем получение команд от компьютера
// Отправляем полученную команду компьютера на программный UART
А вот и код подчиненного (слейва), который интерпретирует символы, отправленные от мастера. Если пришол символ «а», он включит встроенный светодиод. Если получен символ «х», то светодиод будет потушен:
// Подключение библиотеки Software Serial
// Назначение задействованных дискретных каналов
SoftwareSerial softSerial(8, 9); // RX, TX
// Дискретный канал, на котором висит встроенный светодиод
softSerial.begin(9600); // Инициализация программного последовательного порта
pinMode(LED, OUTPUT); // Определение светодиодного вывода как выход
// Проверяем, есть ли что-нибудь в буфере программного последовательного порта
// Читаем один символ из буфера программного последовательного порта и сохраняем его переменную com
int com = softSerial.read();
// Действуем соответственно полученному символу
Как это работает
Программный последовательный порт имитирует стандартный последовательный порт на различных цифровых выводах Arduino. Это довольно удобно в целом, но нужно понимать, что это программная имитация, не поддержанная аппаратно. Это означает, что при этом тратятся общие ресурсы контроллера, в частности время выполнения цикла программы и памяти. А вообще, оно работает просто как обычный последовательный порт. Все функции, присутствующие в нормальном последовательном порте также присутствуют и в программном.
Разбор кода
Для начала взглянем на программу мастера, который получает команды по обычному последовательному порту с компьютера и отправляет подчиненному контроллеру. В начале кода мы подключаем библиотеку SoftwareSerial.h
Дальше нам нужно объявить объект нашей библиотеки. Это делается соответственно следующему синтаксису:
SoftwareSerial softSerial(8, 9); // RX, TX
При этом будет вызвана параллельная связь, в данном случае программная. Она будет использовать вывод 8 для чтения (RX) и вывод 9 для передачи (TX). Далее подробнее остановимся на том, какие именно выводы следует выбирать.
Используя объявленный объект библиотеки, мы можем использовать все функции, характерные для обычного аппаратного параллельного порта, такие как softSerial.read(), softSerial.write() и так далее. В следующей части кода мы проверяем пришло ли что-нибудь с аппаратного порта. И если что-то пришло, мы считываем это и отправляем в программный порт:
В коде подчиненного контроллера использована самая простая реализация управления светодиодом командами через последовательный порт с одной только разницей, что тут используются команды с программного порта. Меняется только синтаксис и вместо привычных функций Serial.read(), Serial.available() и так далее нужно писать softSerial.read() и softSerial.available().
Программный UART имеет некоторые важные ограничения и недостатки. Вот некоторые из них.
Использование выводов
Мы не можем использовать любые дискретные выводы плат Arduino для организации программного порта. Для Tx, вообще-то можем использовать любые, но для Rx можно использовать только те, которые поддерживают внешние прерывания. У плат Arduino Leonardo и Micro могут быть использованы только выводы 8, 9, 10, 11, 14, 15 и 16, в то время как у Mega или Mega 2560 могут быть использованы только выводы 10, 11, 12, 13, 50, 51, 52, 53, 62, 63, 64, 65, 66, 67, 68 и 69.
What is TX and RX on Arduino
It’s important to consider that these RX and TX are specific to device itself means if you want to communicate between two Arduino the RX pin of first one will be connected to the TX pin of second one and similarly TX pin of first one with RX pin of second one:
Serial Interfaces have two modes: half and full duplex:-
- Full duplex means you can send and receive data at same time
- Half duplex communication means that devices can either transmit or receive data at once
Serial Communication using RX/TX in Arduino
All Arduino boards have one or more serial ports known as UART (Universal Asynchronous Receiver & Transmitter). UART allows users to take inputs and output from the Arduino board so we can monitor our program. TX and RX pins classification on different boards are given here:
BOARD SERIAL PINS SERIAL 1 PINS SERIAL 2 PINS SERIAL 3 PINS Uno, Nano, Mini 0 (RX),1(TX) Mega 0 (RX),1(TX) 19(RX),18(TX) 17(RX),16(TX) 15 (RX),14(TX) I have shown Serial pins RX and TX at pin location 0 and 1 respectively on the Arduino UNO board.
Note: In some older Arduino models like Mini, RX and TX pins are used for communication between your computer and board, which means if you connect any other external devices to these pins it can interfere with that communication, resulting in failing to upload your sketch over board. Some Arduino boards have separate ports for Serial communication with your computer and Serial1 communication port for any external device you want to connect that uses UART protocols.TX/RX LEDs
TX and RX LEDs on the board flash when any kind of data is being transmitted or received using the USB serial port between your computer and Arduino board. Remember these LEDs don’t flash if serial communication is done through 0(RX),1(TX) pins on your board. These two pins are designated for connecting your own serial device whether the USB serial cable is connected or not. TX led blinking means the board is sending something via Serial.print() function.
UART Protocols Infrastructure Require for TX/RX
If you want to communicate with any external device than there are some requirements to be met to establish your connection via serial communication, now I will discuss some of those:
1: Required Pins – Overall UART infrastructure required two pins as discussed above RX/TX pins. RX for receiving & TX for transmitting.
2: Packet Structure – UART stands for (Universal Asynchronous Receiver & Transmitter) here the acronym A is important which stands for Asynchronous, UART is asynchronous communication because of no common clock sharing between devices. Both devices where serial communication is required must agree on the same structure at what data is being sent and at what speed the data is sent; this will help UART to sample the data and convert raw data into data packets.
3: Baud rate – Same data rate is a must for sharing data between two UART devices, both devices must be configured at the same data rate for sending and receiving. Common data rates used for TX/RX pins in Arduino includes 9600 & 115200 baud but some UARTS devices support higher data rates.
Conclusion
We have discussed most of the factors required for communication using TX/RX pins. Embedded systems and Arduino boards required serial communication between integrated circuits. These two pins have a significant use in establishing that communication.
About the author

Kashif
I am an Electrical Engineer. I love to write about electronics. I am passionate about writing and sharing new ideas related to emerging technologies in the field of electronics.