Engee 文档
Notebook

Arduino的代码生成(有限状态机上的PWM)

在这个例子中,我们将在Engee中开发最简单的模型,用于使用库有限自动机在Arduino兼容板的输出端进行脉冲宽度调制,用于构建算法和块 C Function 以与目标设备的外围设备交互。

导言

此示例的目的是展示使用有限自动机库为Arduino兼容平台开发PWM接触控制算法的过程。 在此示例中,与演示示例相反 arduino_blink_chart 算法的所有可能状态都减少到单个状态,并且输出变量的变化发生在条件转换中。 这使得可以减少上传到目标设备的编译文件的体积,尽管略有减少。 此外,该示例演示了如何使用该块 C Function 访问控制器的外围设备和Arduino开发环境的功能。


此示例中的硬件使用与示例中相同 arduino_blink_chart.

模型描述

在Arduino板的PWM触点控制模型中,块 Сhart 直接再现控制算法,其输出触点 cntout 它们用于输出和保存相应的变量。 座 C Function 它用于通过Arduino IDE中使用的功能与控制器的外围设备进行交互。 座 Outport 模型中的("Cnt")对于成功的代码生成是必要的。

image_2.png

到"in"块输入 C Function 接收PWM脉冲持续时间的值,然后将其传输到Arduino板的PWM引脚(~13)。

状态图

方块状态图 Chart 如前所述,在这个例子中它由单个状态表示 - Counter. 从下图中可以看到,除了检查转换条件之外,此状态不会重现任何操作。 在模型计算的每个步骤中,按照指定的顺序检查过渡条件,直到满足其中一个条件。 当条件满足时,条件体被执行并且发生到初始状态的转换,之后循环重复。

image.png

在条件的主体中,分配变量的6个可能值中的一个。 out PWM脉冲和计数器变量的持续时间递增 cnt. 执行其中一个转换的条件是在指定范围之一中找到计数器变量。 当变量达到 cnt 最大值为"1000",计数器复位(cnt = 0;),PWM脉冲持续时间被设置为"0"。


因此,我们得到输出 Out 街区 Chart PWM脉冲持续时间的逐步变化。

image.png

输出变量的初始值为"0",从状态图中的信号设置菜单中可以看出。

C Function

C Function 它在考虑的模型中仅用于代码生成。 因此,对于Engee模型的成功编译和验证,用户代码被划分为部分 C Function 包含在条件编译指令中 #ifdef ... #endif. 代码中写了什么 C Function 只有在附加头文件时才满足编译条件。 Arduino.h,这在从Arduino IDE编译时自动发生,而在Engee仿真环境中编译时不会发生。


部分 StartCode 该块用于初始化控制器的外围设备,并将在Arduino IDE中在函数中调用一次 setup().

image.png

部分 OutputCode 块用于改变PWM脉冲的持续时间并将该值输出到串行端口。 它将在函数中每1毫秒调用一次 loop().

image_3.png

每个过程的详细描述在评论部分给出。 C Function.

模拟结果

让我们加载描述的模型:

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

data = engee.run(m);

从获得的模型数据中,我们将绘制计数器值的变化和PWM脉冲的持续时间。:

In [ ]:
using Plots
plotlyjs();
plot(data["Chart.cnt"].time, data["Chart.cnt"].value,
    label="Cnt", size=(900,300), lw=2)
plot!(data["Chart.out"].time, data["Chart.out"].value,
    label="Out", size=(900,300), lw=2)
xlims!(0.0,3.0)
Out[0]:

从仿真结果可以看出,接收到的计数器信号 Cnt 从"0"到"1000"每1毫秒以"1"的增量增加1秒。 PWM脉冲持续时间信号 Out 根据值的不同,计数器值随值逐步增加: "51", "102", "153", "204", "255".


现在,在确保算法和模型正常工作后,您可以继续代码生成并在目标设备上播放模型。

将代码上传到Arduino

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

In [ ]:
engee.generate_code( "$(@__DIR__)/pwm_chart.engee",
                     "$(@__DIR__)/pwm_chart_code" )
Out[0]:
"Created directory - /user/start/examples/codegen/arduino_pwm_chart/pwm_chart_code"

在指定目录中 pwm_chart_code 生成了插件文件。 同样在演示示例的目录中 arduino_pwm_chart 已经发布了带有此目录名称的预先编写的Arduino草图。 arduino_pwm_chart.ino. 它连接代码生成时得到的头文件,初始化和调用模型计算时间变量,还调用模型计算函数。 与此同时,模型计算功能现在不仅用于计算控制算法,还用于控制控制器的外围设备。 草图的详细描述在其代码的注释中给出。


要在Arduino上执行代码,您需要下载目录 arduino_pwm_chart 并上传草图 arduino_pwm_chart.ino 从Arduino IDE到目标设备。 在我们的例子中,如前所述,这是来自Amperka的Iskra Neo。


成功编译并将可执行代码下载到目标设备后,Arduino IDE诊断窗口会显示有关操作成功和输出文件大小的消息。:

image.png

Arduino上的代码执行

如在块 C Function 我们使用PWM周期持续时间的值不仅控制PWM通道,还将计算值输出到计算机的串行端口,转到Arduino IDE工具并通过串行连接运行绘图仪。 连接绘图仪上将显示变量更改。 out 在计算的每一步。

gif.gif
image.png

从绘图仪上所示的曲线图可以看出,PWM脉冲持续时间的变化周期为200毫秒,持续时间值具有先前指定的值。 此外,在Arduino板上可以观察到内置LED亮度的逐渐增加,周期为1秒,因为板的LED和引脚13都连接到控制器的同一通道。

从Arduino板移除信号

在目标设备上测试模型结束时,我们将从Arduino板的引脚13执行所需信号的示波器。

IMAG098.png

所呈现的波形示出了PWM脉冲持续时间的逐渐增加,持续时间的变化周期为-200毫秒,持续时间的增加周期的总持续时间为1秒。

结论

在考虑的演示示例中,开发了基于有限自动机库的Arduino兼容平台的PWM控制算法模型。 还特别注意考虑通过块与目标设备的外围设备一起工作 C Function. 由于它是从微控制器获得的数据和从调试板获得的波形中建立的,因此从Engee模型生成的C代码准确地再现了嵌入式算法并与仿真结果相对应。

示例中使用的块