Генерация кода для Arduino (Перекресток)¶
В этом примере мы разработаем модель в Engee для управления двумя автомобильными и одним пешеходным светофорами на одном перекрестке на базе Arduino-совместимой платы с использованием библиотеки Конечных автоматов.
Введение¶
Цель этого примера - разработать модель управления перекрестком, состоящим из двух автомобильных и одного пешеходного потоков, которые управляются двумя трёхсекционными и одним двухсекционным светофорами соответственно. Алгоритм переключения секций будет определяться согласно временной диаграмме. Управляющий алгоритм будет реализован при помощи нескольких блоков Chart
, а снятие входных и формирование выходных сигналов - блоками C-Function
.
В алгоритме программы управления возможен выбор режима - рабочего или дежурного, переключение режимов будет осуществляться по входному дискретному сигналу от целевого устройства.
Данный пример является развитием демонстрационного примера "Генерация кода для Arduino (Светофор на конечных автоматах)". Особенностями данного примера в сравнении с предыдущим являются: моделирование и генерация кода нескольких, связанных друг с другом блоков Chart
и вывод массива данных в периферию.
Аппаратная часть¶
В этом демонстрационном примере используется контроллер у Iskra Neo от Amperka. Управляемая схема собрана из радиокомпонентов - светодиодов, кнопочного контакта, резисторов и соединительных проводов на беспаячной макетной плате, как это показано на компоновочной схеме ниже. Схема имитирует работу светофоров: двух автомобильных трёхсекционных и одного пешеходного двухсекционного.
Входной сигнал на включение/выключение дежурного режима подается кнопочным контактом на цифровой контакт 4 платы Arduino. Выходные сигналы включения секций автомобильных светофоров выдаются цифровыми контактами 8 - 13 на светодиоды соответствующих цветов. Выходные сигналы включения секций пешеходных светофоров выдаются цифровыми контактами 6, 7. Для корректной работы схемы также используются токоограничивающие (330 Ом) и стягивающий (10 кОм) резисторы. Питание схема получает от самой платы Arduino.
Временная диаграмма¶
Реализуемый алгоритм будет воспроизводить работу светофоров на перекрестке по представленной ниже временной диаграмме.
Три потока - два автомобильных и один пешеходный управляются асинхронно. При этом разрешение на движение (зелёный свет) одновременно формируется только для одного потока и длится 10 секунд. После окончания разрешения на движение автомобильного потока включается мигание зелёной секцией. Переход светофора из разрешающего сигнала в запрещающий (красный свет) сопровождается включением жёлтой секции на 5 секунд, обратный переход - одновременным включением красной и жёлтой секций на 5 секунд.
Цикл дежурного режима описывается двумя состояниями светофоров:
- в течение 1 секунды включены жёлтые секции автомобильных светофоров, секции пешеходного светофора выключены;
- в течение 1 секунды выключены все секции автомобильных и пешеходного светофоров.
Описание модели¶
Модель этого демонстрационного примера представлена на рисунке ниже.
Управляющий алгоритм разделен на функциональные части - работа счётчика воспроизводится в блоке Common_Counter
, формирование управляющего сигнала light
для автомобильных светофоров - в блоке Traffic_Lights
, формирование управляющего сигнала cross
для пешеходного светофора - в блоке Crosswalk
.
Для передачи в модель сигнала выбора режима используется блок Digital Input
, для вывода сообщений в последовательный порт Arduino - блок To Serial
, а для вывода на цифровые пины Arduino кодов автомобильных и пешеходного светофора - блоки Digital_Output_1
и Digital_Output_2
соответственно.
Для структурированного вывода данных в последовательный порт используется блок формирования вектора DataMux
.
Диаграммы состояний¶
В диаграмме состояний блока Common_Counter
при помощи состояния Counter
и переходов 2
и 3
воспроизводится работа инкрементирующего счётчика со сбросом после 54 секунд. Состояние Service
и переход 1
используются для сброса счётчика в значение "-1" при установке дежурного режима для перекрестка.
В зависимости от величины переменной счётчика cntr
в диаграмме состояний блока Traffic_Lights
происходит выбор величины переменной lights
, кодирующей состояния секций автомобильных светофоров. При этом состояния все состояния, кроме ninth
и tenth
воспроизводят последовательность переключения секций в рабочем режиме.
Диаграмма состояний блока Traffic_Lights
представлена на рисунке ниже.
В свою очередь, в зависимости от значения переменной lights
в блоке Crosswalk
происходи выбор значения переменной cross
, кодирующей состояния пешеходного светофора.
Диаграмма состояний блока Crosswalk
представлена на рисунке ниже.
В настройках каждой диаграммы состояний блоков Chart
определены таблицы сигналов. Начальные значения выходных переменных:
- блок
Common_Counter
, переменнаяmode = 0
; - блок
Traffic_Lights
, переменнаяlight = 33
; - блок
Crosswalk
, переменнаяcross = 2
.
Результаты моделирования¶
Загрузим описанную модель:
if "arduino_crossroad" in [m.name for m in engee.get_all_models()]
m = engee.open( "arduino_crossroad" );
else
m = engee.load( "$(@__DIR__)/arduino_crossroad.engee" );
end
data = engee.run(m);
Из полученных данных модели построим графики переменных счётчика counter
, закодированных состояния секций автомобильных светофоров traffic_lights
и пешеходного светофора crosswalk_lights
.
using Plots
plotlyjs()
plot(data["counter"].time, data["counter"].value,
label="Счётчик", size=(900,300), lw=2, st=:step)
plot!(data["traffic_lights"].time, data["traffic_lights"].value,
label="Код светофоров", size=(900,300), lw=2, st=:step,
legend=:topleft)
xlabel!("Время, сек")
ylabel!("Значения")
plot(data["crosswalk_lights"].time, data["crosswalk_lights"].value,
label="Код пешеходный светофор", size=(900,300), lw=2, st=:step, color=:green,
ylims = (0,3), xticks=:none, legend=:topleft )
xlabel!("Время, сек")
ylabel!("Значения")
На выведенном графике видно изменение переменных. Период расчета в модели установлен равным 1 секунде. Изменение переменных состояния секций автомобильных и пешеходного светофоров traffic_lights
и crosswalk_lights
по значениям и длительности соответствуют временной диаграмме
Загрузка кода в Arduino¶
Для переноса разработанной модели на целевое устройство сгенерируем Си-код:
engee.generate_code( "$(@__DIR__)/arduino_crossroad.engee",
"$(@__DIR__)/arduino_crossroad_code" )
В указанной директории arduino_crossroad_code
сгенерировались подключаемые файлы. Также в директории демонстрационного примера arduino_crossroad
выложен заранее написанный скетч Arduino с именем этой директории arduino_crossroad.ino
. В нем подключается заголовочный файл, полученный при генерации кода, инициализируются глобальные переменные, определяется цикл расчета модели, а также вызываются функции расчета модели. Подробное описание скетча дано в комментариях его кода.
Для выполнения кода на Arduino необходимо скачать директорию arduino_crossroad
и загрузить скетч arduino_crossroad.ino
из Arduino IDE в целевое устройство.
Выполнение кода на Arduino¶
После успешной компиляции и загрузки скетча в целевое устройство на цифровых выходах отладочной платы будут формироваться сигналы на включение секций светофоров (светодиодов на макетной плате). Для того чтобы убедиться в правильности работы модели откроем монитор последовательного порта в Arduino IDE.
Видно, что в последовательный порт выводятся прописанные в блоке To Serial
сообщения в требуемом формате с периодичностью 1 секунда.
При нажатии на кнопочный контакт светофоры перекрестка переходят в дежурный режим, а в последовательный порт выводятся следующие сообщения: