Engee 文档
Notebook

Arduino的代码生成(PWM信号生成)

在这个例子中,我们将展示如何在Engee中生成Arduino平台上PWM生成的软件代码。

导言

有许多方法可以创建脉宽调制信号(PWM)。 我们正在实现一个与演示示例尽可能相似的基本组件模型。 arduino_blink. 也就是说,我们必须管理打开和关闭LED的事件之间的时间延迟。

您可以使用的其他方式:

*将平滑变化的模拟信号与锯齿信号进行比较,并在相交时刻切换二极管
*使用内置的Arduino功能之一

平台准备

对于这个例子,我们将需要一个Arduino兼容的平台(Uno,Leonardo,Iskra等)和合适的USB电缆。 您还需要在计算机上安装[Arduino IDE]环境(https://www.arduino.cc/en/software ),查找和供应[附加драйверы](http://wiki.amperka.ru/articles:driver-ch340#установка_драйвера )(如有必要)并通过USB端口连接现有板。

image_2.png

模型描述

在这个例子中,我们将从模型中生成代码。 pwm.engee.

模型的接口与示例中的接口相同 arduino_blink. 在计算的每一步,她:

  1. 使用输出切换LED状态 out_LED_BUILTIN (最初等于1,它随着每个周期变为"相反"),
  2. 使用输出返回Arduino时间延迟值 param_WAIT_MS (以毫秒为单位的值)。
image_2.png

钻孔将随着块中设置的频率沿正弦曲线变化。 Sine. 最大值被设置为同一块的幅度,并且在那里设置的偏移量允许延迟值永远不会小于0,这将在Arduino平台上导致错误并停止程序执行。

它是通过使用值 param_WAIT_MS 我们将通过使用不同长度的脉冲打开和关闭Arduino平台的"板载"LED来控制脉冲频率。

PWM信号的特征在于,在固定周期 它改变状态 1 和条件 0,其持续时间总计等于 ,但使用参数更改其比率 (钻孔)。

image.png

我们将使用此信号在Arduino平台上模拟平滑的LED亮度控制。

数据类型转换

基本上,Engee模型的块直接反映在Arduino的代码中。 并非所有平台都使用相同的C/C++语言标准。 当然,在创建代码时,您总是必须考虑低级实现细节。

在这个例子中,我们在Engee中克服的问题是自动类型转换。 在Arduino平台上:

*将布尔型数据类型与数值型数据类型相加时,输出为布尔型数据类型
*使用无符号整数添加double数据类型时,输出为无符号整数(如果不指定特殊数据类型,则正弦波的操作结果是不正确的)

数据类型的问题在哪里?

image_3.png

因此,我们需要预测数据类型在C代码中的工作方式,并相应地调整模型块(用绿色复选标记标记):

*街区 Constant 必须返回数据类型 Float32
*座 Compare To Zero 不得返回 bool,而 uint8

所有这些设置都设置在适当的块中。 有时这些问题可以使用块来解决。 Data Type Conversion 这些转换也会进入生成的源代码。

测试模型

半自然建模的过程
涉及在模拟环境中运行模型以进行调试和优化,随后在硬件平台上监视相同算法的运行。

在我们的例子中,值得考虑的是Arduino以自己的时钟频率运行,并且可以在不同数量的周期内执行不同的命令。 要依赖于实时物理时间,最好创建一个基于实时系统的代码生成模板。

尽管如此,我们已经可以展示我们的解决方案将如何工作。

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

data = engee.run(m);

让我们绘制切换LED的延迟时间(传递到的参数) delay()).

In [ ]:
using Plots
plot( data["param_WAIT_MS"].time, data["param_WAIT_MS"].value,
      label="param_WAIT_MS", st=:step, size=(900,300))

# Подкрасим переменное время задержки (LED вкл/выкл)
plot!( data["param_WAIT_MS"].time, [iseven(i) ? d : NaN for (i,d) in enumerate(data["param_WAIT_MS"].value)],
      label="задержка при выключенном LED", st=:step, size=(900,300), c=:black, lw=2)
plot!( data["param_WAIT_MS"].time, [isodd(i) ? d : NaN for (i,d) in enumerate(data["param_WAIT_MS"].value)],
      label="задержка при включенном LED", st=:step, size=(900,300), c=:red, lw=2)
Out[0]:

我们在这里看到了什么? 时间延迟 param_WAIT_MS 它随时间而变化,以便每两个相邻值总是加起来大约10毫秒。 调制该过程的规律由正弦波设定。


如果我们正确地组合两个输出信号,我们将看到确切的PWM信号,控制提供给LED连接的输出的电流的开关。

In [ ]:
plot( cumsum(data["param_WAIT_MS"].value),
             data["out_LED_BUILTIN"].value,
      st=:step, size=(900,200))
Out[0]:

该模型没有以模拟操作的实时方式配置,因此您可能会注意到模型时间(2秒是模拟的持续时间)不等于处理器时间(根据时间表–大约1秒,然后具有大的 要确保此属性,您需要以稍微不同的方式构建模型。

代码生成

在本演示中,我们建议使用以下命令生成代码:

In [ ]:
engee.generate_code( "$(@__DIR__)/pwm.engee",
                     "$(@__DIR__)/sketch_pwm_custom/pwm_code" )
Out[0]:
"Created directory - /user/start/examples/codegen/arduino_pwm/sketch_pwm_custom/pwm_code"

其结果是,在目录 sketch_pwm_custom 文件夹将打开 pwm_code 我们发现 .c.h 文件与我们的模型的代码。

项目文件

我们的项目中只有一个模型。 在生成的文件中,我们只需要带有此模型代码的文件:源代码 pwm.c 和头文件 pwm.h.

值得关注的是项目文件和目录的结构。:

image_2.png

*档案 sketch_pwm_custom.ino 包含接口模型的描述-Arduino,
*级别目录 sketch_pwm_custom 它应该与文件命名相同。 *.ino (Arduino IDE要求),
*目录 pwm_code 它包含带有生成代码的文件,我们将包含在文件中。 *.ino.

将模型转移到Arduino

要将项目转移到Arduino,标准步骤如下:

  1. 下载目录 sketch_pwm_custom 从文件浏览器中,解压缩存档
  2. 打开文件 sketch_pwm_custom.ino 并点击按钮 Upload

结果应该如下(LED闪烁平稳):

20240127_042956~2.GIF

结论

我们创建了一个比闪烁LED稍微复杂的模型。 这种创建PWM信号的方法将允许您控制简单的设备,如Led或伺服电机。

我们必须考虑到数据类型转换在目标平台上的工作方式。 尽管如此,我们已经看到Engee平台可以通过生成代码来模拟可以在硬件平台上几乎无缝运行的组件。