雷竞技注册
项目

Arduino Multitasking!如何在Arduino代码中使用Milli

2017年10月11日通过瑞安琼斯

延迟陈述很棒,尤其是他们的简单性,但在尝试多次arduino时,他们可以真正对东西的阻碍。忘记延迟并跳上米兰()火车!

延迟陈述很棒,尤其是他们的简单性,但在尝试多次arduino时,他们可以真正对东西的阻碍。忘记延迟并跳上米兰()火车!

物料清单:

为什么?

只要您需要微控制器即可短暂地暂停延迟声明,它就会很容易抛出,但是当您尝试做其他事情时,它是一个真正的虚拟,如监视按钮推动。随着我的arduino技能有所改善,我认为是时候放弃延迟并学会能够多任务我的arduino。是的,它确实为您的程序添加了更多代码,但反过来,它会使您成为一个更熟练的程序员,并增加您的Arduino的潜力。为此,我们需要学习如何使用“millis()”命令。

如何?

您看,延迟暂停您的Arduino的程序,使其无法在此时间段内做任何其他事情。我们将学习,而不是暂停我们的整个程序,而不是暂停我们的整个程序在完成一个动作之前所经过的时间。当然,这是通过我们的好朋友“millis()”和一些用于存储数据的变量来完成的。为了简单起见,我们从每个人的第一个草图开始,《眨眼》但我们改为《毫不延迟的眨眼》

首先是像任何其他程序一样,声明任何必要的引脚或变量,例如引脚13上的LED。我们还需要一个整数来存储LED的当前状态。随着初始LED状态关闭,这将设置为低。然后声明“unsigned long”类型的变量“上一个梅里斯”。而不是使用“int,”无符号长变量是32位,对于其中值可能变得非常大的变量,我们可能想要等待在采取动作之前的潜在的时间。

“以前的媒体”将用于存储最后一次我们的LED闪烁。“const long”也是32位,但永远不会改变,或者是不变。我们将将其设置为1000并将其用作暂停时间,以毫秒为单位(因为我们)总是想要暂停1000ms。然后,当然,请记住像往常一样宣布您的LED的Pinmode。

//常量不会改变。这里用于设置引脚编号:const int ledPin = 13;// LED引脚的数量//变量会改变:int ledState = LOW;//通常,你应该对保存时间的变量使用"unsigned long" //值会很快变得太大,对于int型存储unsigned long previoussmillis = 0;const long interval = 1000; // const long interval = 1000;// interval at which to blink(毫秒)void setup(){//设置数字pin为输出:pinMode(ledPin, output);}

然后我们进入循环!记住,我们不需要延迟,而是要计算从上一次眨眼到现在已经过去了多少时间,在我们的例子中是1000毫秒。如果规定的时间通过了,是时候改变了状态我们的LED,要么反之亦然,反之亦然。

首先,我们将设置unsigned long“currentmillis”等于“Millis()”当前的米兰的时间数。这将有助于我们确定是否有区别当前的时间和以前的时间超过了1000毫秒。为了做到这一点,我们说,如果当前时间-前一段时间我们的LED眨了眨眼大于或等于我们指定的价值1000ms,将最近一次眨眼的时间存储为之前的smillis。这将有助于我们记住自上次遍布循环的最后一次眨眼之间的时间。

如果LED状态为LOW,则设置为HIGH,否则设置为LOW。然后根据之前的状态数字写LED的HIGH或LOW。

Void loop(){//这里是你放置代码需要一直运行。//查看是否到了闪烁LED的时候;也就是说,如果//当前时间与上次闪烁时间之间的差异// LED大于您想要的间隔时间//闪烁LED。unsigned long currentMillis = millis();if (currentMillis - previousMillis >= interval){//保存上次闪烁的LED previousMillis = currentMillis;//如果LED是关闭的,则打开它,反之亦然:if (ledState == LOW) {ledState = HIGH;} else {ledState = LOW;} //用变量ledState设置LED: digitalWrite(ledPin, ledState);}}

请记住拍摄它缓慢并将代码分解为您可以更容易理解的较小部分。如果你还没有得到它,那没关系 - 它需要一些练习。如果您确实了解并获得工作,请尝试在第二个LED中添加混合并以不同的速率闪烁。有关此主题的更多信息,可以在Adafruit Industries网站上找到,Bill Earl提供了一系列用于多任务您的Arduino-op甚至添加电机和可寻址LED的三部分系列一探究竟!再次感谢您的跟进!

其他麻省理工学院 - 我创新:

为自己提供这个项目!BOM。

4评论
  • W
    沃伦冬天 2017年11月04

    祝贺你转换成milli 's(),但是在推荐给读者的代码中仍然有一些问题需要纠正。

    该陈述效率低下:
    if (currentMillis - previousMillis >= interval)

    这种低效率是由这句话引起的:
    以前的米尔= currentmillis;

    你可以编码这一点:
    time_to_do_work = currentmillis +间隔;
    - 这在“间隔”期间只有一次数学工作。

    然后,测试将是:
    if (currentMillis >= Time_To_Do_Work)
    - 没有数学工作,在每个循环期间都会保存几个周期。虽然对这种微不足道的任务来说不是一个重要的考虑,但您正在尝试展示读者他们应该如何编写自己的代码。

    ___
    下一个问题更为严重。

    此语句中再次出现错误:
    以前的米尔= currentmillis;

    由于编码如此,您的应用程序的时间准确性将漂移。

    代码如下所示更准确:
    time_to_do_work = time_to_do_work +间隔;

    此编码将允许应用程序在达到时间“间隔”或过期时尽快采取行动。

    这是一个更准确的方式来编码计划重复事件的时间。对于随机发生的事件,这是安排下一个所需时间的准确方法:
    time_to_do_work = currentmillis +间隔;

    因此,编写代码的最佳方式取决于应用程序的时间管理要求。

    当事情变得忙碌时,每循环节省一些循环可能会派上用场。

    ___
    您推荐的编码方法也错过了将读者介绍给子例程的机会。

    这些可以大大增加代码的可读性,并在维护任务期间减少错误。

    考虑这种方法:
    if (currentMillis >= Time_To_Do_Work)
    {
    Update_LED_Status ();
    }

    我通常会在单行上代码一个简单的语句,其中各种测试彼此对齐(因此您可以轻松查看差异)。

    我还会对齐各种操作(子例程调用),以便您可以看到代码可以执行的各种操作。

    ___
    最后,您可以建议读者使用“有限状态机”方法研究编码。
    -https://en.m.wikipedia.org/wiki/Finite-state_machine

    喜欢。 回复
    • F
      fabelizer 2017年11月18日
      正如我所理解的那样,随着减法操作,添加操作不会调整定时器溢出。这就是为什么在Arduino工作中的减法方法是首选。但是,我肯定不是一个中小企业。可以通过仔细选择当您的工作定时器复位发生时进行调整定时器蠕变,但是当包括功能时,由于执行的不同时间,它可能非常难以准确调整。
      喜欢。 回复
  • R
    Raju17133 2018年12月16日

    大家好,我是raju ahmmed,来自孟加拉国,我需要一些帮助,请我有麻烦的编码编码arduino线追随者车,请给我代码电子邮件:.(必须启用JavaScript才能查看此电子邮件地址)
    请帮我
    谢谢

    喜欢。 回复