Raspberry Pi и Pi4J. Урок 4. UART — Работа с последовательным портом

UART (Universal Asynchronous Receiver/Transmitter) — универсальный асинхронный приёмопередатчик, интерфейс для связи цифровых устройств, предназначенный для передачи данных в последовательной форме. Очень распространён и весьма востребован, имеет аппаратную реализацию во многих микроконтроллерах (Wiki).

Pi4J предоставляет возможность работы с UART из Java. Все классы и интерфейсы для инициализации и работы с последовательным портом находятся в пакете com.pi4j.io.serial.*;.

Если вы ещё не установили Pi4J переходите на страницу Установка Pi4J на Raspberry Pi и Orange Pi, Banana Pi.

Внимание:
Всегда помните, что логические уровни сигнала шины GPIO составляет 3.3 В и использование сигналов с уровнем 5 В недопустимо!

Настройка UART на Raspberry Pi

По умолчанию последовательный порт на Raspberry Pi настроен как консольный порт для связи с ОС Linux. Если вы хотите использовать этот последовательный порт, вы должны отключить ОС от использования этого порта.

В Raspberry Pi введите следующую команду в окне терминала, чтобы включить UART и отключить консоль на последовательный порт,

Выберите «Interfacing Options»
Настройка UART на Raspberry Pi (1)
После «Interfacing Options» выберите «Serial», чтобы включить UART
Настройка UART на Raspberry Pi (2)
Затем выберите «No», чтобы отключить консоль на последовательный порт
Настройка UART на Raspberry Pi (3)
В конце попросит включить аппаратный последовательный порт, выберите «Да»
Настройка UART на Raspberry Pi (4)
Всё, UART включен, консоль отключена
Настройка UART на Raspberry Pi
Перезагрузите Raspberry Pi.

Настройка UART на Orange Pi под Armbian

Все модели Orange Pi на базе SoC Allwinner H3 имеют по 4 UART порта. Один отдельный (UART0), что используется как консольный порт для связи с ОС Linux, а остальные находятся на гребёнке GPIO (UART1, UART2 и UART3). По умолчанию включён только UART0. Чтобы использовать и остальные, для начала необходимо включить их. UART2 так-же можно использовать как JTAG, а UART3 как SPI.

Orange Pi (H3 Soc) GPIO - pinoutOrange Pi ZeroOrange Pi Zero PlusOrange Pi Zero Plus 2 и Orange Pi R1 имеют по 3 UART порта.

Orange Pi Zero GPIO PINOUT (Распиновка)

И так, для начала сделаем резервную копию script.bin, чтобы, в случае чего, смогли вернуть обратно все настройки:

Чтобы редактировать бинарный файл script.bin, нужно конвертировать в редактируемый файл fex:

Редактируем файл script.fex с помощью утилиты nano:

Находим разделы [uart0] ... [uart3]:

Включаем нужный UART порт, для этого нужно установить параметр uart_used = 1. Я включил все порты, но это не рекомендуется:

Сохраняем и закрываем файл:

Конвертируем измененный файл script.fex обратно в script.bin:

Перезагружаем ОС:

Проверяем доступные последовательные порты под Linux:

Доступные последовательные порты под Linux (Orange Pi PC Armbian)

Интерфейс Serial

Этот интерфейс предоставляет набор функций для настройки и инициализации последовательной связи. Ниже вы найдёте описание всех методов этого интерфейса.

open(String, int, int, int, int, int)

Открывает и инициализирует последовательное соединение и устанавливает параметры связи.

Параметры
String device — Адрес устройства последовательного порта. Вы можете использовать константу DEFAULT_COM_PORT, если хотите получить доступ к последовательному порту по умолчанию. ВНИМАНИЕ: параметр device может содержать не более 128 символов.
int baud — Скорость передачи данных для последовательного порта. (Пользовательская скорость передачи не поддерживается).
int dataBits — Биты данных. (5, 6, 7, 8).
int parity — Параметр четности. (None, Event, Odd, Mark, Space).
int stopBits — Стоповые биты. (1, 2).
int flowControl — Управление потоком передачи данных. (none, hardware, software).
Бросает
IOException — в случае какой-либо ошибки.

open(String, int)

Открывает и инициализирует последовательное соединение и устанавливает параметры связи. Этот метод будет использовать следующие параметры последовательной конфигурации по умолчанию:

  • DATA BITS = 8
  • PARITY = NONE
  • STOP BITS = 1
  • FLOW CONTROL = NONE

Параметры
String device — Адрес устройства последовательного порта. Вы можете использовать константу DEFAULT_COM_PORT, если хотите получить доступ к последовательному порту по умолчанию. ВНИМАНИЕ: параметр device может содержать не более 128 символов.
int baud — Скорость передачи данных для последовательного порта. (Пользовательская скорость передачи не поддерживается).
Бросает
IOException — в случае какой-либо ошибки.

open(String, Baud, DataBits, Parity, StopBits, FlowControl)

Открывает и инициализирует последовательное соединение и устанавливает параметры связи.

Параметры
String device — Адрес устройства последовательного порта. Вы можете использовать константу DEFAULT_COM_PORT, если хотите получить доступ к последовательному порту по умолчанию. ВНИМАНИЕ: параметр device может содержать не более 128 символов.
Baud baud — Скорость передачи данных для последовательного порта. (Пользовательская скорость передачи не поддерживается).
DataBits dataBits — Биты данных. (5, 6, 7, 8).
Parity parity — Параметр четности. (None, Event, Odd, Mark, Space).
StopBits stopBits — Стоповые биты. (1, 2).
FlowControl flowControl — Управление потоком передачи данных. (none, hardware, software).
Бросает
IOException — в случае какой-либо ошибки.

open(SerialConfig)

Открывает и инициализирует последовательное соединение и устанавливает параметры связи.

Параметры
SerialConfig serialConfig — Объект конфигурации последовательной связи, содержащий адрес устройства, скорость передачи данных, бит данных, контроль четности, стоп-биты и параметры управления потоком.
Бросает
IOException — в случае какой-либо ошибки.

close()

Этот метод вызывается, чтобы закрыть текущий открытый последовательный порт.

Бросает
IllegalStateException — если последовательный порт еще не открыт.
IOException — в случае какой-либо ошибки.

isOpen()

Этот метод вызывается, чтобы определить, если последовательный порт открыт.

Возвращает
значение true, если последовательный порт уже открыт.

isClosed()

Этот метод вызывается, чтобы определить, если последовательный порт закрыт.

Возвращает
значение true, если последовательный порт находится в закрытом состоянии.

flush()

Принудительная передача любых оставшихся данных в буфере передачи последовательного порт. Обратите внимание, что это не заставляет передавать данные, но отбрасывает их.

Бросает
IllegalStateException — если последовательный порт еще не открыт.
IOException — в случае какой-либо ошибки.

discardInput()

Отбрасывает любые данные в буфере последовательного приема (ввода).

Бросает
IllegalStateException — если последовательный порт еще не открыт.
IOException — в случае какой-либо ошибки.

discardOutput()

Отбрасывает любые данные в последовательном буфере передачи (вывода).

Бросает
IllegalStateException — если последовательный порт еще не открыт.
IOException — в случае какой-либо ошибки.

discardAll()

Отбрасывает любые данные в буферах последовательного приема и передачи.

Бросает
IllegalStateException — если последовательный порт еще не открыт.
IOException — в случае какой-либо ошибки.

sendBreak()

Отправляет сигнал BREAK подключенному устройству не менее 0.25 секунды и не более 0.5 секунд

Бросает
IllegalStateException — если последовательный порт еще не открыт.
IOException — в случае какой-либо ошибки.

sendBreak(int)

Параметры
int duration — Длительность (в миллисекундах) для отправки сигнала BREAK.
Бросает
IllegalStateException — если последовательный порт еще не открыт.
IOException — в случае какой-либо ошибки.

setBreak(boolean)

Отправляет постоянный сигнал BREAK на подключенное устройство. (включение/выключение сигнала BREAK) При включении будет посылать непрерывный поток нулевых битов, а передача других данных невозможна.

Параметры
boolean enabled — Состояние включения или выключения для управления сигналом BREAK.
Бросает
IllegalStateException — если последовательный порт еще не открыт.
IOException — в случае какой-либо ошибки.

setRTS(boolean)

Управляет состоянием контакта RTS (запрос-на-отправку). Когда включено, это приведет к тому, что вывод RTS будет находиться в состоянии HIGH.

Параметры
boolean enabled — Включить или отключить состояние, чтобы контролировать состояние контакта RTS.
Бросает
IllegalStateException — если последовательный порт еще не открыт.
IOException — в случае какой-либо ошибки.

setDTR(boolean)

Контролирует состояние вывода DTR (состояние готовности к передаче данных). При включении этого вывод DTR будет установлен в высокое состояние.

Параметры
boolean enabled — Включить или отключить состояние, чтобы контролировать состояние контакта RTS.
Бросает
IllegalStateException — если последовательный порт еще не открыт.
IOException — в случае какой-либо ошибки.

getRTS()

Возвращает состояние вывода RTS (запрос на отправку).

Бросает
IllegalStateException — если последовательный порт еще не открыт.
IOException — в случае какой-либо ошибки.

getDTR()

Возвращает состояние вывода DTR (состояние готовности к передаче данных).

Бросает
IllegalStateException — если последовательный порт еще не открыт.
IOException — в случае какой-либо ошибки.

getCTS()

Возвращает состояние вывода CTS (clean-to-send).

Бросает
IllegalStateException — если последовательный порт еще не открыт.
IOException — в случае какой-либо ошибки.

getDSR()

Возвращает состояние вывода DSR (data-set-ready).

Бросает
IllegalStateException — если последовательный порт еще не открыт.
IOException — в случае какой-либо ошибки.

getRI()

Возвращает состояние вывода RI (ring-indicator).

Бросает
IllegalStateException — если последовательный порт еще не открыт.
IOException — в случае какой-либо ошибки.

getCD()

Возвращает состояние вывода CD (carrier-detect).

Бросает
IllegalStateException — если последовательный порт еще не открыт.
IOException — в случае какой-либо ошибки.

addListener(SerialDataEventListener…)

Метод для регистрации слушателя для событий последовательных данных (приём данных).

Параметры
SerialDataEventListener... listener — Экземпляр класса, который реализует интерфейс SerialListener.

removeListener(SerialDataEventListener…)

Метод для отмены регистрации слушателя для событий последовательных данных (приём данных).

Параметры
SerialDataEventListener... listener — Экземпляр класса, который реализует интерфейс SerialListener.

getFileDescriptor()

Этот метод возвращает дескриптор файла последовательного устройства

getInputStream()

Этот метод возвращает поток входных данных для буфера приема последовательного порта

getOutputStream()

Этот метод возвращает поток выходных данных для буфера передачи последовательного порта

isBufferingDataReceived()

Этот метод возвращает состояние буферизации данных, полученных от последовательного устройства / порта.

Возвращает
true, если включена буферизация; иначе false

setBufferingDataReceived(boolean)

Этот метод управляет состоянием буферизации данных, полученных от последовательного устройства / порта.

Если состояние буферизации включено, все байты данных, полученные от последовательного порта, будут скопированы в буфер приема данных. Вы можете использовать методы getInputStream() или read() для доступа к этим данным. Данные также будут доступны через событие SerialDataEvent. Важно знать, что если вы используете буферизацию данных, данные будут продолжать скапливаться в памяти, пока ваша программа не освободит поток данных.

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

Параметры
boolean enabled — Устанавливает состояние поведения буферизации.

Интерфейс SerialDataReader

Интерфейс SerialDataReader предоставляет набор функций для чтения данных из последовательного порта.

Интерфейс SerialDataWriter

Интерфейс SerialDataWriter предоставляет набор функций для записи данных в последовательный порт.

Подключение PL2303 к Orange Pi One

Для начала нужно выбрать платформу, если у вас Raspberry Pi, тогда этого делать не надо.

Чтобы работать с последовательным портом нужно создать экземпляр класса Serial с помощью утилиты SerialFactory.

Данные могут быть отправлены несколькими способами, самый простой способ — с использованием методов write(...) и writeln(...). Также можно использовать и выходной поток OutputStream outputStream = serial.getOutputStream();.

Прочесть полученные данные можно с помощью методов read(...), но в таком случае нужно постоянно проверять наличие данных в буффере. Лучще всего зарегистрировать слушатель SerialDataEventListener.

Слушатель SerialDataEventListener — это уведомляемый о поступлении новых данных в последовательном пору объект. Чтобы слушатель смог реагировать на событие источника он должен быть им зарегистрирован, т.е. подключен к источнику. Listener должен реализовывать метод dataReceived(...) для получения и обработки уведомлений о событии.

Listener находится в постоянном ожидании, пока в источнике, в котором он зарегистрирован, не наступит соответствующее событие, при возникновении которого слушатель получает управление. Также слушателю передается объект события (Serial который содержется в SerialDataEvent), чтобы он смог правильно на него отреагировать. Таким образом, источник вызывает метод-обработчик события (public void dataReceived(SerialDataEvent event)), определенный в классе, являющемся блоком прослушивания.

После обработки события слушатель возвращает управление. Таким образом, для обработки события вызываются только те слушатели, которые на него «подписались», т.е. были зарегистрированы источником.

Создаём объект конфигурации последовательной связи (SerialConfig), содержащий адрес устройства, скорость передачи данных, бит данных, контроль четности, стоп-биты и параметры управления потоком.

и задаём эти конфигурации.

С помощью метода open(...) открываем UART порт.

Схема подключения

Чтобы проверить UART на Orange Pi, я подключил его к компьютеру через преобразователь PL2303. В этом случае используется порт UART3.Raspberry Pi и Pi4J. Урок 4. UART - Работа с последовательным портом (Orange Pi One + PL2303HX)

Пример программы

Эта программа получает по UART данные в виде текста и выводит данный текст в консоль, также выводит текст в шестнадцатеричном формате. Для отправки использовал Terminal v1.9b.

Проверяем код:

  1. создаём java файл и вставляем код;
  2. компилируем файл;
  3. запускаем программу.

Результат

Raspberry Pi и Pi4J. Урок 4. UART - Работа с последовательным портом (Orange Pi PC + PL2303) Raspberry Pi и Pi4J. Урок 4. UART - Terminal 1.9b (Orange Pi PC + PL2303)Как мы видим данные получены и программа работает правильно.

Похожие записи

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *