Генерация кода для Arduino (Светофор на конечных автоматах)¶
В этом примере мы разработаем модель в Engee для управления трехсекционным светофором для Arduino-совместимых плат с использованием библиотеки Конечных автоматов.
Введение¶
Цель этого примера - разработать модель управления трехсекционным светофором согласно временной диаграмме. Управляющий алгоритм будет реализован при помощи блока Chart
, а снятие входных и формирование выходных сигналов - блоками C-Function
.
Для комплексной демонстрации возможностей библиотеки Конечных автоматов Engee, в том числе при последующей генерации кода, в алгоритме управления светофором будет организована работа двух режимов - рабочего (попеременно включаются секции) и дежурного (включается и выключается секция желтого света). Переключение режимов будет осуществляться по входному дискретному сигналу от целевого устройства.
Аппаратная часть¶
В этом демонстрационном примере используется контроллер у Iskra Neo от Amperka. Управляемая схема собрана из радиокомпонентов - светодиодов, кнопочного контакта, резисторов и соединительных проводов на беспаячной макетной плате, как это показано на компоновочной схеме ниже.
Входной сигнал на включение/выключение дежурного режима подается кнопочным контактом на цифровой контакт 4 платы Arduino. Выходные сигналы включения секций светофора выдаются цифровыми контактами 10 - 12 на светодиоды соответствующих цветов. Для корректной работы схемы также используются токоограничивающие (330 Ом) и стягивающий (10 кОм) резисторы. Питание схема получает от самой платы Arduino.
Временная диаграмма¶
Реализуемый алгоритм будет воспроизводить работу светофора по следующей временной диаграмме.
В начале цикла рабочего режима загорается на 10 секунд красная секция светофора. В последние 3 секунды ее работы параллельно загорается желтая секция. По истечению этого времени загорается на 10 секунд зеленая секция. После зеленая секция мигает в течение 5 секунд, при этом периоды её включения и выключения продолжаются по 1 секунде. После окончания мигания загорается на 3 секунды желтая секция. После этого цикл рабочего режима начинается заново.
Для наглядности описанная диаграмма представлена на рисунке ниже.
Цикл дежурного режима описывается двумя состояниями светофора:
- включена желтая секция в течение 1 секунды,
- выключены все секции в течение 1 секунды.
Описание модели¶
Модель этого демонстрационного примера состоит из пяти блоков, как это показано на скриншоте модели ниже.
Управляющий алгоритм, как говорилось ранее, воспроизводится блоком Chart
. У этого блока один вход mode
для сигнала переключения режима работы и два выхода cnt
и light
для вывода сигнала счетчика светофора и кода загорающихся секций соответственно. Периферия контроллера инициализируется и управляется при помощи блоков C Function
: Digital Input
- для передачи в модель состояния цифрового входа контроллера, Digital Output
- для вывода состояния секций на цифровые выходы контроллера, To Serial
- для вывода данных через последовательный порт контроллера. Подробное описание принципов работы этих блоков дано в комментариях их кода.
Для успешной генерации кода блока Digital Input
необходима передача в него входного сигнала. В примере для этого используется блок Constant
.
Диаграмма состояний¶
В диаграмме состояний блока Chart
содержатся шесть состояний: пять для рабочего режима (Red
, RedAndYellow
, Green
, Blink
, Yellow
) и одно для служебного (BlinkOn
).
В каждом состоянии происходит декрементирование счетчика cnt
и установка состояния секций светофора light
. Установка счетчика и проверка условий для изменения состояния секций светофора происходит в переходах между состояниями Chart
.
Ниже представлена таблица сигналов блока Chart
.
Переменная light
передает двоичное состояние выходных контактов целевого устройства. Бит под номером 0 в этой переменной соответствует зеленой секции светофора, бит под номером 1 - желтой, а бит под номером 2 - красной. Например: при light = 4 = 0b0110
, где биты под номерами 1 и 2 принимают значение "1", на светофоре будут включены красная и желтая секции.
Изменение режима работы светофора происходит между состояниями Red
и BlinkOn
в зависимости от значения входной переменной mode
.
Переменная service
является локальной для блока Chart
и служит для переключения состояния BlinkOn
Результаты моделирования¶
Загрузим описанную модель:
if "arduino_traffic_lights" in [m.name for m in engee.get_all_models()]
m = engee.open( "arduino_traffic_lights" );
else
m = engee.load( "$(@__DIR__)/arduino_traffic_lights.engee" );
end
data = engee.run(m);
Из полученных данных модели построим графики переменных счетчика cnt
и кода состояния секций светофора light
:
using Plots
plotlyjs();
plot(data["Chart.cnt"].time, data["Chart.cnt"].value,
label="Counter", size=(900,300), lw=2, st=:step)
plot!(data["Chart.light"].time, data["Chart.light"].value,
label="Light", size=(900,300), lw=2, st=:step)
xlims!(0.0,40.0)
На выведенном графике видно изменение переменных. Период расчета в модели установлен равным 1 секунде. Изменение переменной состояния секций светофора light
по значению и длительности соответствует временной диаграмме.
Загрузка кода в Arduino¶
Для переноса разработанной модели на целевое устройство сгенерируем Си-код:
engee.generate_code( "$(@__DIR__)/arduino_traffic_lights.engee",
"$(@__DIR__)/arduino_traffic_lights_code" )
В указанной директории arduino_traffic_lights_code
сгенерировались подключаемые файлы. Также в директории демонстрационного примера arduino_traffic_lights
выложен заранее написанный скетч Arduino с именем этой директории arduino_traffic_lights.ino
. В нем подключается заголовочный файл, полученный при генерации кода, инициализируются глобальные переменные, определяется цикл расчета модели, а также вызываются функции расчета модели. Подробное описание скетча дано в комментариях его кода.
Для выполнения кода на Arduino необходимо скачать директорию arduino_traffic_lights
и загрузить скетч arduino_traffic_lights.ino
из Arduino IDE в целевое устройство.
Выполнение кода на Arduino¶
После успешной компиляции и загрузки скетча в целевое устройство на цифровых выходах отладочной платы будут формироваться сигналы на включение секций светофора (светодиодов на макетной плате). Для того чтобы убедиться в правильности работы модели откроем монитор последовательного порта в Arduino IDE.
Видно, что в последовательный порт выводятся прописанные в блоке To Serial
сообщения в требуемом формате с периодичностью 1 секунда.
При нажатии на кнопочный контакт при горящем красном светодиоде светофор переходит в дежурный режим, а в последовательный порт выводятся следующие сообщения:
В последовательный порт выводится требуемое сообщение с периодичностью 1 секунда. Следовательно, работа светофора в дежурном режиме также корректна, что подтверждает работоспособность модели и кода.
Вывод¶
В этом демонстрационном примере была разработана модель трехсекционного светофора для Arduino-совместимых платформ. Алгоритм управления воссоздан при помощи библиотеки конечных автоматов. Модель воспроизводит работу светофора в двух режимах, при этом обеспечивается не только переключение секций, но и их мигание. Работоспособность алгоритма была проверена на целевом устройстве, результирующий код не только управляет светодиодными секциями, но и передает в последовательный порт сообщения о текущем режиме, зажженных секциях и оставшемся времени работы секции.