В начало | Зарегистрироваться | Заказать наши киты почтой
 
 
 
 

Обмен данными между Java-приложением и МК. Часть 1. По проводу, USB-UART

📆14 июля 2022   ✒️AYAN   🔎2.387   💬2  

Приветствую всех жителей и гостей кибер-города Датагор! Работа устройства на базе микроконтроллера часто требует двустороннего обмена данными с приложениями на компьютере или смартфоне. Реализации проводного и беспроводного вариантов такого обмена и будет посвящена статья.
В данной части рассматривается проводной обмен посредством связки протоколов USB-UART.

Задание

Примем в качестве примера устройство:
• передающее с заданной периодичностью значение температуры Java-приложению на компьютере,
• управляющее RGB-лентой, яркость и цвет светодиодов которой задаётся Java-приложением.

Для его создания нам понадобятся:
1. Микроконтроллер ATmega328p (далее — «МК») с частотой тактирования 8 МГц.
2. RGB-лента WS2812B.
3. Температурный датчик DS18B20.
4. USB-UART адаптер.
5. Подтягивающий резистор на 4.7 kОм.
6. Блок питания от смартфона на 5 В.

Схема соединений и алгоритм работы

представлена на Рисунке 1.
Обмен данными между Java-приложением и МК. Часть 1. По проводу, USB-UART
Рисунок 1. Схема соединений устройства


Как видно из видео выше, алгоритм обмена данными следующий:
а) Каждые 2 секунды МК считывает показания DS18B20 и передаёт 4 байта, содержащие знак температуры, а также десятки, единицы и десятые доли значения температуры для их отражения в лэйбле Java-приложения.

б) При каждом изменении положения ползунка любого из трёх слайдеров Java-приложения цвет текстового поля меняется соответствующим образом, а значения красной, зелёной и синей его составляющих передаются в МК для соответствующей корректировки цвета светодиодов RGB-ленты.

Создание Java-приложения и прошивки для МК



Время 0:00 - Пишем Java-приложение с ипользованием jSerialComm
Время 2:15 - Пишем прошивку для МК
Время 6:12 - Как это работает. Проводной обмен данными в действии

Программа для Atmega328P, Atmega8A

Программа для МК оформлена на языках Си и ассемблер в Visual Studio Code.
Второй вариант прошивки расположен в подвале статьи и расчитан на применение ATMEGA8A.

Контроль за температурным датчиком. Код обмена данными между МК и DS18B20 достаточно подробно пояснялся в в моей предыдущей датагорской статье, поэтому лишь приведу его содержимое.

OneWire.h

OneWire.c

DS18B20.h

DS18B20.c


Считывание значения температуры осуществляется, как уже говорилось выше, с периодичностью в 2 секунды, для чего использовалось прерывание по переполнению счётчика таймера TIMER1.

timer.h

timer.c

Как видите:
• тактовая частота МК делится на 256, что даёт прерывание раз в 256×65535 / 8000000 = 2 секунды.
• в обработчике прерывания поднимается флаг timerFlag, уведомляя основной цикл о наступлении времени измерения температуры.

Контроль за RGB-лентой

На Рисунке 2 представлена выдержка из выложенного в архив статьи даташита WS2812B.

Рисунок 2. Параметры записи в WS2812B:
а) формат слова, определяющего цвет и яркость светодиода
б) тайминг записи бинарных «0» и «1»


Как видно из Рисунка 2а, цвет и яркость каждого отдельного светодиода ленты определяется значением 24-битного числа, запись которого начинается со старшего бита зелёной составляющей и завершается младшим битом синей. Сама запись значения бита (бинарные «0» или «1») осуществляется чередованием высоких и низких состояний на выводе DIN WS2812B (т.е. — на пине PC5 МК), с таймингом согласно Рисунка 2б.

Запись последовательности из N 24-битных чисел приводит к изменению состояния первых N светодиодов в ленте в прямой очерёдности, т. е. первое число записывается в первый от входа DIN светодиод, второе — во второй и. т. д. При этом, промежуток времени между записью двух соседних чисел не должен превышать 280 мкс, иначе контроллер ленты сбросится и вновь начнёт запись с первого светодиода.

Для пояснения сказанного выше, на Рисунке 3 представлены случаи записи последовательности из чисел 0xff0000, 0×00ff00 и 0×0000ff, обуславливающими максимальную интенсивность зелёной, красной и синей составляющей, соответственно, когда интервал времени:
а) не превышает 280 мкс во всех случаях,
б) превышает 280 мкс между записью второго и третьего числа.


Рисунок 3. Результат записи последовательности чисел в ленту из трёх светодиодов
а) интервал между записью чисел не превышает 280 мкс
б) интервал между записью второго и третьего чисел превышает 280 мкс


Из вышеизложенного следует, что изменить значение N-го по счёту светодиода в ленте можно, лишь записав в неё N чисел, в т. ч.:
• первые (N-1) чисел — текущие значения светодиодов, предшествующих N-му,
• последнее число — новое значение N-го светодиода.

В плоскости программы это означает необходимость хранения текущего значения всех светодиодов в ленте. Код заметно упрощается, если разбить 24-битные числа на 8-битные составляющие по каждому цвету.
Тогда, буфер для хранения в случае с девятью светодиодами будем выглядеть так:

#define STRIP_LENGTH   9
#define GRB_NUM        (STRIP_LENGTH * 3)

grbValue[GRB_NUM];

Обеспечить средствами Си тайминг согласно Рисунка 2б мне не удалось, поскольку период тактового импульса при частоте 8 МГц составляет 125 нс. При этом, установка управляющего пина в высокое, а затем низкое состояние
PORTC |= (1 << PC5);
PORTC &= ~(1 << PC5);
использует более 4-х тактов (т.е. 500 нс), что превышает 380 нс, отведённые даташитом для высокого состояния бинарного числа «0». Как итог — некорректная работа ленты.

С учётом изложенного, было принято решение оформить фрагмент записи в WS2812B на ассемблере. Чтобы не изобретать велосипед, я обратился к интернету, где обнаружил статью Mike Silva — «Driving WS2812 RGB LEDs». Статья написана доступным языком, с подробными комментариями, поэтому сразу приведу окончательный вариант кода с переводом комментариев, а затем дам несколько пояснений.

WS2812B.S

1. Алгоритм работы кода сводится к тому, чтобы уложиться в 10 тактов при записи бита элемента буфера grbValue, в т.ч:
• 3 такта (375 нс) в состоянии High и 7 тактов (875 нс) в состоянии Low пина PC5 — для бинарного «0»,
• 7 тактов (875 нс) в состоянии High и 3 такта (375 нс) в состоянии Low пина PC5 — для бинарного «1».

2. По стандартам Си, первый аргумент фукнции помещается в пару r24–r25, а второй — в пару r22–r23. Именно из этих регистров при вызове из Си-файла
stripRefresh(grbValue, sizeof(grbValue));
ассемблер-код считывает адрес буфера и количество его элементов.

3. В комментариях к коду первый столбец — число тактов на исполнение инструкции, второй — оно же, но с нарастающим результатом.

Далее были созданы хидер- и Си-файлы strip, в которых:
а) объявлены:
• внешней функция stripRefresh () посредством ключевого слова extern,
• вспомогательные переменные redValue, greenValue, blueValue и stripState,

б) прописаны функции:
setLedColor (), которая записывает требуемые значения красной, зелёной и синей составляющих в соответствующие элементы буфера grbValue,
stripSetColor (), устанавливающая все светодиоды ленты в заданный цвет,
stripOff (), гасящая все светодиоды ленты.

strip.h

strip.c

Обмен данными с Java-приложением

Обмен данными с Java-приложением осуществляется по протоколу UART на следующих условиях:
а) Скорость обмена — 9600.
б) Приём данных — через прерывание RX.

Serial.h

Serial.c

Как видите, в обработчике прерывания поступающий от Java-приложения четырёх-байтный массив сохраняется в буфере receivedByte, а затем поднимается флаг receiveFlag, уведомляющий основной цикл о поступлении новых данных.

Общий контроль за устройством

Общий контроль за устройством осуществляется из файлов device посредством двух функций:
1. deviceInit () обеспечивает инициализацию:
• протокола UART,
• термодатчика,
• RGB-ленты,
• таймера.

2. deviceControl ():
• при поднятии флага receiveFlag сбрасывает последний, анализирует значение нулевого из 4-х принятых байтов и, если его значение равно заданному (87), копирует значения первого, второго и третьего байтов в переменные redValue, greenValue и blueValue, соотвественно, а затем обновляет цвет светодиодов RGB-ленты. Указанная проверка нулевого байта введена для исключения ошибок в принятых данных.
• при поднятии флага timerFlag сбрасывает последний, считывает текущее значение температуры, раскладывает его на десятки, единицы и десятые доли, а затем передаёт Java-приложению.

device.h

device.c

Java-приложение

Проект приложения разбит для удобства на три класса, которые отвечают:
MyFrame — за графически интерфейс,
MySerial — за обмен данными с МК,
Main — за общий контроль и диспетчеризацию данных между двумя предыдущими классами.

Класс MyFrame

В конструкторе класса MyFrame создаётся фрэйм, включающий следующий элементы:
а) Пять ComboBox — для выбора таких параметров обмена, как скорость, количество битов данных, количество стоп-битов, чётности, номера COM-порта.
б) Button — кнопка «Open» для соединения с выбранным COM-портом.
в) Три Slider — для выбора значения красной, зелёной и синей составляющей цвета RGB-ленты.
г) TextField — для отображения выбранного цвета.
д) Label — для отображения значения температуры, принимаемого от МК.

Результат работы конструктора представлен на Рисунке 4.


Рисунок 4. Результат работы конструктора класса MyFrame


Методы класса MyFrame:
actionPerformed () при нажатии «Open» поднимает флаг openCloseButtonFlag,
stateChanged () при движении ползунка любого из слайдеров меняет соответствующим образом цвет TextField, а также поднимает флаг slidersFlag.
showMessageDialog () выводит на экран сообщение заданного содержания, в частности — об успешном соединении с COM-портом.

Реакция на поднятие указанных флагов прописана в классе Main и будет рассмотрена ниже.

MyFrame.java


Класс MySerial

Класс MySerial содержит четыре метода следующего назначения:
а) openPort () и closePort () обеспечивают соединение с COM-портом и отсоединение, соответственно.
б) sendColorData () передаёт МК выбранное слайдерами значение цвета.
в) SerialEventBasedReading () принимает от МК 4 байта со значением температуры и объединяет их в строковую переменную dataBuffer.

MySerial.java


Класс Main

В классе Main создаются экземпляры frame и serial классов MyFrame и MySerial, соответственно, а затем запускается задача, метод run () которой по прерыванию таймера с периодичностью 200 мс:
1. Проверяет флаг openCloseButtonFlag и, если он поднят:
• сбрасывает флаг,
• в случае, если текущая функция кнопки — соединение с портом, меняет название кнопки с «Open» на «Close», обеспечивает соединение с портом и выдаёт сообщение об удачной/неудачной попытке соединения,
• в случае, если текущая функция кнопки — отключение порта, меняет название кнопки с «Close» на «Open», отключает порт и выдаёт соответствующее сообщение,

2. Если переменная dataBuffer — не пустая, отображает её содержимое в Label, а затем очищает.

3. Проверяет флаг slidersFlag и, если он поднят:
• сбрасывает флаг,
• передаёт МК новое значение цвета RGB-ленты.

Main.java



Файлы и ссылки

🎁Отличный бесплатный программный редактор Visual Studio Code
🎁Даташит ws2812b.pdf
🎁Приложение на Java - java-app.7z  866.14 Kb ⇣ 9
🎁Код для ATMEGA328P.7z  9.51 Kb ⇣ 8
🎁Код для ATMEGA8A.7z  3.32 Kb ⇣ 9

Спасибо за внимание! Продолжение следует.

Камрад, рассмотри датагорские рекомендации

🌼 Полезные и проверенные железяки, можно брать

Опробовано в лаборатории редакции или читателями.




 

Читательское голосование

Нравится

Статью одобрили 11 читателей.

Для участия в голосовании зарегистрируйтесь и войдите на сайт с вашими логином и паролем.
 

Поделись с друзьями!

 

 

Связанные материалы

 

Схема на Датагоре. Новая статья Стекловолокно + эпоксидка. Изготовление лицевых панелей любой формы из стеклопластика... Приветствую жителей и гостей Датагории. Хочу поделиться своим опытом изготовления лицевых панелей...
Схема на Датагоре. Новая статья Итоги мартовской вылазки в Горячий Ключ из холодного Новокузнецка... Привет, други! В понедельник, 7 апреля, я вернулся на историческую родину из разведывательного...
Схема на Датагоре. Новая статья Ламповый усилитель для высокоомных наушников на 6Н6П... Приветствую жителей города Датагорска очередным воплощением своего желания иметь на рабочем столе...
Схема на Датагоре. Новая статья Итоги конкурса «Выбор читателей Datagor.ru 2015»... Дорогие друзья! Поздравляю всех сограждан и гостей нашего электронного города с Новым годом и...
Схема на Датагоре. Новая статья Нестабильное напряжение электросети как проблема любителя лампового звука... Так уж исторически сложилось, что многоквартирный дом, в котором я живу, с двумя лифтами, кучей...
Схема на Датагоре. Новая статья Конденсаторный микрофон с фантомным питанием для подзвучки Ирландской флейты... В звуковой практике нередко приходится запитывать «личинку» конденсаторного микрофона от имеющегося...
Схема на Датагоре. Новая статья Ассемблер для микроконтроллера с нуля. Часть 1. Начало пути... Приветствую всех сограждан и читателей журнала Датагор! Пользуясь кучей времени, предоставленной...
Схема на Датагоре. Новая статья Печать сферической АС на 3D-принтере... Приветствую читателей «Датагора»! Хочу рассказать вам о создании акустической системы с...
Схема на Датагоре. Новая статья Датагорскiя Ведомости №1 (2012)... Здравствуйте, уважаемые сограждане-датагорцы и гости нашего электронного города! Спешу рассказать...
Схема на Датагоре. Новая статья Бокс для небольших ВЧ и СЧ головок из подручных материалов... Приветствую! На радиорынках моего города доступны автомобильные шелковые твиттеры. Пара лежит, но...
Схема на Датагоре. Новая статья Приём цифрового ТВ стандарта DVB-T2. Охота на мультиплексы РТРС-1 и РТРС-2... С учетом того, что в России вещание в цифровом стандарте ведётся с 2012 г., статья запоздалая. Но с...
Схема на Датагоре. Новая статья Лето 2009, Питер, "Алиса"... Всем привет!!! Мне вот удалось побывать в Санкт-Петербурге! В связи с этим несколько фоток, и...
 

Комментарии, вопросы, ответы, дополнения, отзывы

 

<
Читатель Датагора

Maroc

<
Читатель Датагора

AYAN

Добавить комментарий, вопрос, отзыв 💬

Камрады, будьте дружелюбны, соблюдайте правила!

  • Смайлы и люди
    Животные и природа
    Еда и напитки
    Активность
    Путешествия и места
    Предметы
    Символы
    Флаги
 
 
В начало | Зарегистрироваться | Заказать наши киты почтой