Документация Engee
Notebook

Генерация кода для Arduino (Светофор на конечных автоматах)

В этом примере мы разработаем модель в Engee для управления трехсекционным светофором для Arduino-совместимых плат с использованием библиотеки Конечных автоматов.

Введение

Цель этого примера - разработать модель управления трехсекционным светофором согласно временной диаграмме. Управляющий алгоритм будет реализован при помощи блока Chart, а снятие входных и формирование выходных сигналов - блоками C-Function.

Для комплексной демонстрации возможностей библиотеки Конечных автоматов Engee, в том числе при последующей генерации кода, в алгоритме управления светофором будет организована работа двух режимов - рабочего (попеременно включаются секции) и дежурного (включается и выключается секция желтого света). Переключение режимов будет осуществляться по входному дискретному сигналу от целевого устройства.

Аппаратная часть

В этом демонстрационном примере используется контроллер у Iskra Neo от Amperka. Управляемая схема собрана из радиокомпонентов - светодиодов, кнопочного контакта, резисторов и соединительных проводов на беспаячной макетной плате, как это показано на компоновочной схеме ниже.

plate_2.JPG

Входной сигнал на включение/выключение дежурного режима подается кнопочным контактом на цифровой контакт 4 платы Arduino. Выходные сигналы включения секций светофора выдаются цифровыми контактами 10 - 12 на светодиоды соответствующих цветов. Для корректной работы схемы также используются токоограничивающие (330 Ом) и стягивающий (10 кОм) резисторы. Питание схема получает от самой платы Arduino.

Временная диаграмма

Реализуемый алгоритм будет воспроизводить работу светофора по следующей временной диаграмме.

В начале цикла рабочего режима загорается на 10 секунд красная секция светофора. В последние 3 секунды ее работы параллельно загорается желтая секция. По истечению этого времени загорается на 10 секунд зеленая секция. После зеленая секция мигает в течение 5 секунд, при этом периоды её включения и выключения продолжаются по 1 секунде. После окончания мигания загорается на 3 секунды желтая секция. После этого цикл рабочего режима начинается заново.

Для наглядности описанная диаграмма представлена на рисунке ниже.

worktimediagram_2.png

Цикл дежурного режима описывается двумя состояниями светофора:

  • включена желтая секция в течение 1 секунды,
  • выключены все секции в течение 1 секунды.

Описание модели

Модель этого демонстрационного примера состоит из пяти блоков, как это показано на скриншоте модели ниже.

image.png

Управляющий алгоритм, как говорилось ранее, воспроизводится блоком Chart. У этого блока один вход mode для сигнала переключения режима работы и два выхода cnt и light для вывода сигнала счетчика светофора и кода загорающихся секций соответственно. Периферия контроллера инициализируется и управляется при помощи блоков C Function: Digital Input - для передачи в модель состояния цифрового входа контроллера, Digital Output - для вывода состояния секций на цифровые выходы контроллера, To Serial - для вывода данных через последовательный порт контроллера. Подробное описание принципов работы этих блоков дано в комментариях их кода.

Для успешной генерации кода блока Digital Input необходима передача в него входного сигнала. В примере для этого используется блок Constant.

Диаграмма состояний

В диаграмме состояний блока Chart содержатся шесть состояний: пять для рабочего режима (Red, RedAndYellow, Green, Blink, Yellow) и одно для служебного (BlinkOn).

image_2.png

В каждом состоянии происходит декрементирование счетчика cnt и установка состояния секций светофора light. Установка счетчика и проверка условий для изменения состояния секций светофора происходит в переходах между состояниями Chart.

Ниже представлена таблица сигналов блока Chart.

image.png

Переменная light передает двоичное состояние выходных контактов целевого устройства. Бит под номером 0 в этой переменной соответствует зеленой секции светофора, бит под номером 1 - желтой, а бит под номером 2 - красной. Например: при light = 4 = 0b0110, где биты под номерами 1 и 2 принимают значение "1", на светофоре будут включены красная и желтая секции.

Изменение режима работы светофора происходит между состояниями Red и BlinkOn в зависимости от значения входной переменной mode.

Переменная service является локальной для блока Chart и служит для переключения состояния BlinkOn

Результаты моделирования

Загрузим описанную модель:

In [ ]:
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:

In [ ]:
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)
Out[0]:

На выведенном графике видно изменение переменных. Период расчета в модели установлен равным 1 секунде. Изменение переменной состояния секций светофора light по значению и длительности соответствует временной диаграмме.

Загрузка кода в Arduino

Для переноса разработанной модели на целевое устройство сгенерируем Си-код:

In [ ]:
engee.generate_code( "$(@__DIR__)/arduino_traffic_lights.engee",
                     "$(@__DIR__)/arduino_traffic_lights_code" )
[ Info: Generated code and artifacts: /user/start/examples/codegen/arduino_traffic_lights/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.

image.png

Видно, что в последовательный порт выводятся прописанные в блоке To Serial сообщения в требуемом формате с периодичностью 1 секунда.

При нажатии на кнопочный контакт при горящем красном светодиоде светофор переходит в дежурный режим, а в последовательный порт выводятся следующие сообщения:

image.png

В последовательный порт выводится требуемое сообщение с периодичностью 1 секунда. Следовательно, работа светофора в дежурном режиме также корректна, что подтверждает работоспособность модели и кода.

Вывод

В этом демонстрационном примере была разработана модель трехсекционного светофора для Arduino-совместимых платформ. Алгоритм управления воссоздан при помощи библиотеки конечных автоматов. Модель воспроизводит работу светофора в двух режимах, при этом обеспечивается не только переключение секций, но и их мигание. Работоспособность алгоритма была проверена на целевом устройстве, результирующий код не только управляет светодиодными секциями, но и передает в последовательный порт сообщения о текущем режиме, зажженных секциях и оставшемся времени работы секции.

Блоки, использованные в примере