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

Генерация кода для Arduino (Мигающий светодиод на конечных автоматах)

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

Введение

Библиотека конечных автоматов Engee служит полезным и эффективным инструментом разработки алгоритмов управления, в том числе для целевых платформ. Представление алгоритма в виде графа с несколькими определенными состояниями и условными переходами между ними делает его более наглядным и удобным для отладки и модернизации. Таким образом повышается скорость разработки управляющей программы и снижается вероятность ошибки.

Цель этого примера - показать процесс создания алгоритма управления мигающим светодиодом для Arduino-совместимых платформ с использованием библиотеки конечных автоматов. Пример является, по сути, вариантом демонстрационного примера arduino_blink и включает в себя описание и демонстрацию работы модели blink_chart. В этой модели состояние светодиода (включен/выключен) и величина задержки переключения определяются блоком chart.

Аппаратное обеспечение

Для проверки работы алгоритма можно воспользоваться любой Arduino-совместимой платформой. Мультиплатформенность моделей engee обусловлена тем, что генерируемый Си-код импортируется в виде подключаемых файлов Си, а конфигурация аппаратной части происходит в стороннем ПО.

В данном примере мы используем отладочную плату Iskra Neo от Amperka. Она подключается к ПК по кабелю USB - USB-micro. Для компиляции пользовательской программы и загрузки в контроллер используется Arduino IDE, а также необходим драйвер интерфейсного чипа. Для демонстрации работы программы на "железе" используется портативный цифровой осциллограф DSO Quad Alloy Black от Seeed Studio.

hardware.png

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

Модель управления встроенным светодиодом платы Arduino состоит из одного блока Chart, воспроизводящего управляющий алгоритм, и двух выходных контактов Outport: out_LED_BUILTIN и Сhart. Первый сигнал в качестве переменной связан в скетче Arduino с выходным контактом (GPIO) под номером 13, который также является контактом управления встроенным светодиодом. Второй сигнал выводит состояние внутреннего счетчика блока Chart. Оба сигнала также используются для логгирования в модели.

ModelScreeen.JPG

В блоке chart используются два выходных сигнала: out, начальное значение - "true" и cnt

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

Диаграмма состояний (содержимое блока Chart) имеет 4 состояния:

  1. init - начальное состояние алгоритма, устанавливается начальное значение счетчика при входе в состояние cnt = 0;.

  2. increment - основное состояние алгоритма, здесь происходит сравнение значения счетчика с условиями перехода (переходы под номерами 1, 2, 3) и увеличение значения счетчика при входе в состояние cnt = cnt + 1;. Увеличение значения счетчика на "1" соответствует в действительности его увеличению на 1 мс, так как расчет алгоритма будет происходить через 1 мс, что будет определено далее в коде скетча Arduino.

  3. ON - состояние, при котором происходит увеличение счетчика в случае, если его величина меньше 499 мс. При выполнении этого условия выходной сигнал, управляющий светодиодом, устанавливается в значение "true".

  4. OFF - состояние, при котором происходит увеличение счетчика в случае, если его величина больше или равна 499 мс. При выполнении этого условия выходной сигнал, управляющий светодиодом, устанавливается в значение "false".

При достижении счетчиком величины большей или равной 998 мс, диаграмма переходит в состояние init. Счетчик ограничен величиной 998 мс ввиду того, что на расчет состояния init, которое напрямую не управляет светодиодом, затрачивается еще два цикла длительностью 2 мс. Таким образом, общая длительность периода мерцания светодиода составляет 1000 мс.

image.png

Еще один важный момент, который необходимо учитывать при разработке модели - это порядок исполнения переходов. Именно в таком порядке будут прописаны условия перехода из состояния в условной конструкции if(){} elseif(){} …​ else{} сгенерированного файла Си. К примеру, в данной модели условие окончание периода [cnt >= 998] проверяется первым, хотя, если бы его порядок был 3, то успешное выполнение условия [cnt >= 499] препятствовало бы его проверке и счетчик периода не сбросился. С другой стороны, проверка условия окончания периода в каждом цикле расчета не эффективна, и данному переходу следует присвоить порядок 3 и изменить условие перехода в состояние OFF на [(cnt >= 499) && (cnt < 998)]

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

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

if "blink_chart" in [m.name for m in engee.get_all_models()]
    m = engee.open( "blink_chart" );
else
    m = engee.load( "$(@__DIR__)/blink_chart.engee" );
end

data = engee.run(m);

Из полученных данных модели построим график изменения значения счетчика:

using Plots
plot(data["Cnt"].time, data["Cnt"].value,
    label="Cnt", size=(900,300), lw=2)
xlims!(0.0,3.0)

interactive-scripts/images/codegen_arduino_blink_chart/76c33ebac15fe21ee364e87b64c531402ab8427e

Как видно, величина счетчика изменяется в пределах 0 - 1000, с периодичностью 1000 мс. Теперь построим график сигнала out_LED_BUILTIN, который и управляет встроенным светодиодом Arduino.

plot(data["out_LED_BUILTIN"].time, data["out_LED_BUILTIN"].value,
    label="out_LED_BUILTIN", size=(900,300), lw=2)
xlims!(0.0,3.0)

interactive-scripts/images/codegen_arduino_blink_chart/84711c4b0d0ead123b4e0a90bf849e39cca20345

Мы получили периодический прямоугольный сигнал с периодом 1000 мс и коэффициентом заполнения 50%.

Выполнение алгоритма на Arduino

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

engee.generate_code( "$(@__DIR__)/blink_chart.engee",
                     "$(@__DIR__)/sketch_blink_chart_custom/blink_chart_code" )
"Created directory - /user/start/examples/codegen/arduino_blink_chart/sketch_blink_chart_custom/blink_chart_code"

В указанной директории сгенерировались подключаемые файлы. Также в директории sketch_blink_chart_custom выложен заранее написанный скетч Arduino с именем этой директории sketch_blink_chart_custom.ino. В нем подключается заголовочный файл, полученный при генерации кода, инициализируется периферия микроконтроллера, вызываются функции для управления светодиодом. Подробное описание скетча дано в комментариях его кода. Для выполнения кода на Arduino необходимо скачать директорию sketch_blink_chart_custom и загрузить скетч sketch_blink_chart_custom.ino из Arduino IDE в целевое устройство. В нашем случае, как говорилось ранее, это - Iskra Neo от Amperka. После компиляции скетча выводится сообщение об успешности операции и размере выходного файла:

Compilation.JPG

Снятие сигналов с платы Arduino

После загрузки кода в Arduino на отладочной плате можно наблюдать мигающий светодиод. Для наглядности в описании примера подключим измерительный контакт осциллографа к пину 13 на отладочной плате и снимем осциллограмму.

FirstOscillogramma.jpg

Как видно из снятой осциллограммы, на контакте 13 отладочной платы формируется периодический прямоугольный сигнал с временем заполнения 500 мс и периодом 1000 мс.

Вывод

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