Engee 文档
Notebook

Arduino的代码生成(十字路口)

在这个例子中,我们将在Engee中开发一个模型,用于使用库有限自动机基于Arduino兼容板控制同一个路口的两个汽车和一个行人交通灯。

导言

本例的目的是开发一种用于控制由两个汽车和一个行人流组成的交叉路口的模型,该交叉路口分别由两个三段和一个两段红绿灯控制。 段切换算法将根据时间图确定。 控制算法将使用几个块来实现。 Chart,以及输入的去除和输出信号的产生-以块为单位 C-Function.

在控制程序的算法中,可以选择模式-工作或待机,切换模式将通过来自目标设备的离散输入信号进行。

此示例是演示示例"Code generation for Arduino(Traffic light on)"的开发automata)"。本例与前一例相比的特点是:几个相互连接的块的建模和代码生成 Chart 并将数据阵列输出到外设。

硬件部分

本演示使用Amperka的Iskra Neo控制器。 控制电路由无线电元件组装而成-Led,按钮触点,电阻和无焊面包板上的连接线,如下面的布局图所示。 该方案模拟红绿灯的运行:两个汽车三段和一个行人两段。

image.png

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

时间图

实现的算法将根据下面的时间图再现路口红绿灯的操作。

三个交通流,两辆汽车和一个行人,是异步控制的. 在这种情况下,一次仅为一个流生成交通许可(绿灯)并持续10秒。 交通许可结束后,绿色路段的闪烁开启。 红绿灯从启用信号到禁止信号(红灯)的过渡伴随着包含黄色部分5秒,反向过渡伴随着同时包含红色和黄色部分5秒。

image_3.png

占空比由两个红绿灯状态描述:
*黄色路段汽车红绿灯亮1秒,行人红绿灯路段熄灭;
*汽车和行人交通灯的所有部分在1秒内关闭。

模型描述

该演示的模型如下图所示。

image_2.png

控制算法分为功能部分-计数器的操作在块中再现 Common_Counter、控制信号生成 light 对于汽车交通灯-在块 Traffic_Lights、控制信号生成 cross 行人交通灯-在街区 Crosswalk.

以将模式选择信号传送到模型,该块用于 Digital Input 要将消息输出到Arduino块的串行端口 To Serial,并且用于将汽车和行人交通灯代码输出到数字Arduino引脚,有块 Digital_Output_1Digital_Output_2 相应地。

向量生成单元,用于结构化数据输出到串口。 DataMux.

状态图

在方块状态图中 Common_Counter 使用状态 Counter 和过渡 23 递增计数器的操作在54秒后用复位再现。 条件 Service 和过渡 1 它们用于在设置交叉点的待机模式时将计数器重置为值"-1"。

image_2.png

取决于计数器变量的值 cntr 在方块状态图中 Traffic_Lights 变量值被选中 lights,对汽车交通信号灯的路段状态进行编码。 在这种情况下,除 ninthtenth 操作模式中的切换部分的序列被再现。
方块状态图 Traffic_Lights 如下图所示。

image_2.png

反过来,取决于变量的值 lights 在街区里 Crosswalk 变量值被选中 cross,编码行人红绿灯的状态。
方块状态图 Crosswalk 如下图所示。

image.png

在每个块状态图的设置 Chart 信号表进行定义。 输出变量的初始值:
*座 Common_Counter,一个变量 mode = 0;
*座 Traffic_Lights,一个变量 light = 33;
*座 Crosswalk,一个变量 cross = 2.

模拟结果

让我们加载描述的模型:

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

In [ ]:
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!("Значения")
Out[0]:
In [ ]:
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!("Значения")
Out[0]:

显示的图形显示变量的变化。 模型中的计算周期设置为1秒。 改变汽车和行人交通信号灯路段的状态变量 traffic_lightscrosswalk_lights 值和持续时间对应于时间图

将代码上传到Arduino

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

In [ ]:
engee.generate_code( "$(@__DIR__)/arduino_crossroad.engee",
                     "$(@__DIR__)/arduino_crossroad_code" )
[ Info: Generated code and artifacts: /user/start/examples/codegen/arduino_crossroad/arduino_crossroad_code

在指定的目录中 arduino_crossroad_code 生成了插件文件。 同样在演示示例的目录中 arduino_crossroad 已经发布了带有此目录名称的预先编写的Arduino草图。 arduino_crossroad.ino. 它连接代码生成时得到的头文件,初始化全局变量,定义模型计算周期,调用模型计算函数。 草图的详细描述在其代码的注释中给出。

要在Arduino上执行代码,您需要下载目录 arduino_crossroad 并上传草图 arduino_crossroad.ino 从Arduino IDE到目标设备。

Arduino上的代码执行

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

image_4.png

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

当按下按钮触点时,路口红绿灯切换到待机模式,并将以下消息输出到串口:

image_2.png

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

结论

在这个演示中,开发了一个用于Arduino兼容平台的具有两个三段汽车和一个两段行人交通灯的交叉路口模型。 使用有限自动机库重新创建控制算法。 该模型以两种模式再现了红绿灯的操作,同时不仅确保了路段的切换,还确保了它们的闪烁。 该算法的性能在目标设备上进行了测试,由此产生的代码不仅控制LED部分,而且还将有关当前模式,三个红绿灯的点亮部分和当前运行时间的消息传输

示例中使用的块