Engee 文档
Notebook

Arduino的代码生成(有限状态机上的交通灯)

在这个例子中,我们将在Engee中开发一个模型,用于使用库有限自动机控制Arduino兼容板的三段交通灯。

导言

本例的目的是根据时间图开发三段红绿灯的控制模型。 控制算法将使用块实现 Chart,以及输入的去除和输出信号的产生-以块为单位 C-Function.

为了全面展示图书馆的能力工程师有限自动机,包括在随后的代码生成期间,将在交通灯控制算法中以两种模式运行-工作模式(部分交替打开)和工作模式(黄灯部分打开和关闭)。 这些模式将根据来自目标设备的离散输入信号进行切换。

硬件部分

本演示使用Amperka的Iskra Neo控制器。 控制电路由无线电元件组装而成-Led,按钮触点,电阻和无焊面包板上的连接线,如下面的布局图所示。

plate_2.JPG

打开/关闭待机模式的输入信号由按钮触点提供给Arduino板的数字引脚4。 用于接通交通灯区段的输出信号由数字触点10-12提供给适当颜色的Led。 限流(330欧姆)和张紧器(10kOhm)电阻也用于电路的正确操作。 该电路从Arduino板本身接收电源。

时间图

所实现的算法将根据以下时间图再现红绿灯的操作。

在运行模式周期开始时,红绿灯的红色部分亮起10秒。 在其操作的最后3秒中,黄色部分平行亮起。 在此时间之后,绿色部分亮起10秒。 之后,绿色部分闪烁5秒,而其开和关周期持续1秒。 闪烁结束后,黄色部分亮起3秒。 之后,操作模式的循环重新开始。

为了清楚起见,所描述的图示于下图中。

WorkTimeDiagram_2.png

待机周期由两个红绿灯状态描述:
-黄色部分开启1秒,
-所有部分关闭1秒。

模型描述

这个演示的模型由五个块组成,如下面的模型截图所示。

image.png

控制算法,如前所述,由块再现 Chart. 这个街区有一个入口 mode 为工作模式切换信号和两个输出 cntlight 以分别输出红绿灯计数器的信号和被照明路段的代码。 控制器的外围设备使用块进行初始化和控制 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",红色和黄色部分将在红绿灯处打开。

状态之间的红绿灯操作模式变化 RedBlinkOn 取决于输入变量的值 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

要将开发的模型传输到目标设备,我们将生成一个C代码。:

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上的代码执行

在成功编译并将草图上传到目标设备后,调试板的数字输出端将产生信号,以打开交通灯部分(面包板上的Led)。 为了确保模型正常工作,请在Arduino IDE中打开串行端口监视器。

image.png

可以看出,块中指定的数据输出到串行端口。 To Serial 所需格式的消息,频率为1秒。

当您按下按钮接触红色LED打开时,红绿灯切换到待机模式,并将以下消息输出到串行端口:

image.png

所需的消息以1秒的频率输出到串口。 因此,红绿灯在待机模式下的操作也是正确的,这证实了模型和代码的可操作性。

结论

在本演示中,为Arduino兼容平台开发了一个三段交通灯模型。 使用有限自动机库重新创建控制算法。 该模型以两种模式再现了交通灯的操作,同时不仅确保了部分的切换,还确保了它们的闪烁。 该算法已经在目标设备上进行了测试,得到的代码不仅控制LED部分,而且还将有关当前模式,点亮部分和部分剩余运行时间的消息传输到串行端口。

示例中使用的块