在Arduino中使用功能时有最大延迟时间(延迟)

时间:2015-12-30 16:06:30

标签: c++ c arduino

{
    digitalWrite(13, HIGH);   // turn the LED on (HIGH is the voltage level)
    delay(1000);              // wait for a second
    digitalWrite(13, LOW);    // turn the LED off by making the voltage LOW
    delay(1000);              // wait for a second
}

我正在尝试将延迟设置为60,000但是在1分钟后将其输出到Arduino时,指示灯不会亮起。

4 个答案:

答案 0 :(得分:3)

arduino reference page for delay 延迟的参数是 unsigned long

无符号长整数on the arduino可以从0到4,294,967,295。

这个数字很可能会被传递到'延迟'被解释为int。这意味着延迟限制在最大32,767。

您应该将延迟值明确声明为无符号长like the solution in this post

unsigned long seconds = 1000L; //Notice the L 
unsigned long minutes = seconds * 60;

delay(minutes); //for 60,000 milliseconds

答案 1 :(得分:1)

给出此链接:https://www.arduino.cc/en/Reference/DelayMicroseconds

目前,产生准确延迟的最大值是16383.这可能会在未来的Arduino版本中发生变化。对于超过几千微秒的延迟,您应该使用delay()代替。

所有这些似乎表明该功能只关注较低的14位。

因此即使在较长的延迟函数中:delay()也可能只使用较低的14位。

答案 2 :(得分:0)

为什么不使用诸如10000(10秒)之类的特定延迟并将虚拟变量增加1,然后在虚拟变量达到所需的延迟时间时执行操作。就像虚拟变量一样,1是10秒,当20是20x10 = 200秒,依此类推。这可以走很长的路。

答案 3 :(得分:0)

是的...有人在其他地方引用了此线程,这是正确的解释:

delay()采用无符号长(0到2 ^ 32-1之间的32位数字,约42亿)。并且delay(60000)可以正常工作。 尝试传递大于眨眼中使用的数字但小于42亿的数字可能会遇到两种麻烦 delay()

首先,如果您在现场通过将数字相乘生成数字,例如delay(60 * 1000);

这两个数字都将默认为int(从-32768到32767的16位带符号整数),因此乘法将溢出该值……如果我的数学为我服务,则剩下-5536……然后,该值将转换为无符号很长,剩下2 ^ 32-5536,或者说大约42亿。

解决方案很简单-通过将UL放在数字之一后(明确地告诉编译器,您打算将该文字设置为无符号长整数(另一个将自动提升为无符号长整数来匹配):

延迟(60UL * 1000);

arduino用户在此处遇到麻烦的另一种方式(确实是同样的方式,只是通过不同的途径)是,如果他们将延迟分配给了不适合它的数据类型,例如:

int time = 60000; //这也以-5536结尾...

...

延迟(时间); //相同的结果!

解决方案也非常简单-只需将时间声明为无符号长整数即可,而不是整数。

请注意,第一种情况(但不是第二种情况)会在常量表达式生成溢出的情况下实际生成编译器警告…。除非arduino默认关闭编译器警告。您可以在文件->首选项中将其重新打开。有时候,它会警告一些没问题的东西,但是当您看到警告,并且没有按照您的意愿去做时,警告是开始查找的好地方。

delayMicroseconds()的背景

delayMicroseconds()的最大长度为16383,这是无关紧要的-该限制是因为delayMicroseconds在幕后实现的方式与delay()完全不同。 delay()基于micros()和millis计时器系统(在调用setup()之前配置了硬件计时器,溢出中断会增加毫秒的全局计数; millis()使用该计数,而micros使用该计数)加上计时器上的当前计数)。然而,delayMicroseconds需要比该方法所能达到的精度高得多(micros需要大约7-8us的时间才能返回,并且分辨率为4us,因为所涉及的计时器以/ 64预分频运行于16MHz时钟)。它是通过计算时钟周期来实现的。首先需要一个无符号的int(16位)而不是无符号的long。它将请求的延迟乘以4(至少对于16MHz时钟),然后将其转换为用内联汇编器编写的循环的迭代数,该循环每次迭代需要4个时钟周期。因此,这就是明显的14位限制的来源:4个周期的循环数必须适合16位,因此微秒数是其的1/4(假设16 MHz系统时钟-因此,一个8 MHz pro mini,例如,您可以为delayMicroseconds()!指定两倍的延迟时间。在一个(极为罕见的)20 MHz时钟上,最长的延迟将在13000((2 ^ 16-1)/(20/4 = 5))左右,不过,在此之前,最好还是做一会儿循环检查micros()...