Arduino延迟功能,以及为什么不应该使用它

当您第一次开始学习如何开发时,您可能会开发出一种类似这样的产品:

连接到Arduino的将是一个LED灯。这将每隔一秒钟左右关闭一次,并将持续到Arduino关闭为止。这是Arduino的“ Hello World"程序,完美地说明了几行代码如何创建有形的东西。

我也敢打赌,您使用了 delay() 函数定义灯打开和关闭之间的间隔。但这就是问题:虽然延迟对于Arduino工作原理的基本演示很方便,但您实际上不应该在现实世界中使用它。这就是原因-以及应该使用的方式。

delay()函数的工作方式非常简单。它接受单个整数(或数字)参数。这个数字代表程序在进入下一行代码之前应等待的时间(以毫秒为单位)。

但是问题是, delay()函数不是这是使程序等待的一种好方法,因为这就是所谓的“阻止"功能。

为说明阻止功能为何不好的原因,我想让您想象一下厨房里有两个不同的厨师: > Henry Blocking 和 Eduardo NonBlocking 。两者都做同样的工作,但是方式却大相径庭。

亨利做早餐时,首先将两轮面包放进烤面包机。当它最终时,面包冒出金黄色,亨利将其放在盘子上,然后将两个鸡蛋裂成一个煎锅。再次,他在油爆裂时待命,白色开始变硬。完成后,他将它们包起来,开始炸两小块培根。当它们足够酥脆后,他将其从煎锅上取下,放在盘子上,然后开始食用。

Eduardo的工作方式略有不同。在烤面包时,他已经开始煎鸡蛋和培根。他没有同时等待一项完成烹饪,而是转到另一项。最终结果是爱德华多做早餐的时间比亨利少-到亨利·布洛克完成时,吐司和鸡蛋已经变冷了。

这是一个愚蠢的比喻,但它说明了这一点。

阻止功能可以阻止程序在完成特定任务之前执行任何其他操作。如果您希望同时发生多个 action ,则根本无法使用 delay()

尤其是如果您的应用程序要求您执行以下操作:不断从连接的传感器获取数据,您应避免使用 delay()函数,因为它会绝对暂停所有内容

幸运的是,< em> delay()不是让程序在为Arduino编码时等待的唯一方法。

millis()函数执行单个任务。调用时,它返回(作为 long 数据类型)自程序首次启动以来经过的毫秒数。那么,为什么这样做有用呢?

由于使用了一些简单的数学运算,您可以轻松地“计时"程序的各个方面而不会影响程序的工作方式。以下是millis()工作原理的基本演示。如您所见,程序将LED灯点亮1000毫秒(一秒钟),然后将其关闭。但是至关重要的是,它以一种非阻塞的方式实现了它。

现在让我们看看它如何与Arduino一起工作。

该程序-很大程度上基于Arduino官方文档-通过从当前时间中减去先前记录的时间来工作。如果剩余时间(即自上次记录时间以来经过的时间)大于间隔(在这种情况下为1000毫秒),则程序会将 previousTime 变量更新为当前时间,并且

并且由于它是非阻塞的,因此位于第一个 if语句之外的任何代码都应正常工作。

值只是意味着它永远不会是负面的;我们这样做是为了使我们可以存储的最大数量更大。默认情况下,数字变量是带符号的,这意味着该变量的一个“位"内存用于存储值是正数还是负数。通过将其指定为正数,我们可以多玩一点。

中断

到目前为止,我们已经了解了一种在Arduino程序中计时的方法,该方法比 delay()更好。但是还有另一种更好但更复杂的方法:中断。这些优点是允许您精确地计时Arduino程序,并以异步的方式快速响应外部输入。

这意味着它可以与主程序,不断等待事件发生,而不会中断代码流。这可以帮助您有效地响应事件,而不会影响Arduino处理器的性能。

触发中断时,它要么停止程序,要么调用一个函数,通常称为 Interrupt Handler。 中断服务程序。一旦结束,程序便返回到原来的状态。

为Arduino提供动力的AVR芯片仅支持硬件中断。当输入引脚从高到低或由Arduino的内置计时器触发时,就会发生这种情况。

听起来有些神秘。甚至令人困惑。但事实并非如此。要了解它们的工作原理并查看它们在现实世界中的使用示例,请访问Arduino文档。

使用 millis()确实需要一些额外的工作与使用 delay()相比。但是请相信我,您的程序将对此表示感谢,没有它,您将无法在Arduino上执行多任务处理。

如果您想查看 millis()的示例用于现实的Arduino项目中,请查看James Bruce的Arduino夜灯和日出警报。

发现了我们应该警惕的其他任何阻止功能吗?在下面的评论中让我知道,我们将聊天。

图片来源:Arduino(Daniel Spiess),首席(Ollie Svenson)

标签: Arduino 编程