Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/arduino/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Time 比较可能溢出的时间_Time_Arduino_Overflow - Fatal编程技术网

Time 比较可能溢出的时间

Time 比较可能溢出的时间,time,arduino,overflow,Time,Arduino,Overflow,我需要检测无符号long的溢出 此变量保存设备运行后的毫秒数(它是Arduino)。通过执行sizeof(unsigned long),我发现它确实是一个32位的数字。现在,由于它每毫秒递增一次,这意味着在这个值溢出之前,设备将运行大约49天 因为这是一个家庭系统,它不是真正可取的。现在我用这个数字来比较当前时间是否大于前一个时间加上去抖动量 if(timeChanged + amountOfMs < currentTime){ ... } if(timeChanged+amountOf

我需要检测
无符号long
的溢出

此变量保存设备运行后的毫秒数(它是Arduino)。通过执行sizeof(unsigned long),我发现它确实是一个32位的数字。现在,由于它每毫秒递增一次,这意味着在这个值溢出之前,设备将运行大约49天

因为这是一个家庭系统,它不是真正可取的。现在我用这个数字来比较当前时间是否大于前一个时间加上去抖动量

if(timeChanged + amountOfMs < currentTime){ ... }
if(timeChanged+amountOfMs

不用说,一旦发生溢出,这将不再起作用。解决这个问题的有效方法是什么?我也曾考虑过使用第二个计时器来检查毫秒是否溢出,但最终我会遇到同样的问题。

您可以创建一个新的if循环来检查条件:if(currentTime==0xfffffe)

如果是这种情况,下一毫秒将使变量溢出。所以在这一点上,你可以手动将它重置为零,然后转到从零开始的循环


这可能对你的情况有帮助,也可能没有帮助。我不能肯定,因为你还没有分享关于你的代码的更多细节

定义两个变量,我将它们称为'now'和'lastNow'

unsigned long now;
unsigned long lastNow = 0;
在循环中,您现在可以执行以下操作:

now = millis();
if (now < lastNow) {
    // rollover!
}
lastNow = now;
now=millis();
如果(现在

无论你循环的频率有多高(或不经常),都很好而且可靠。

似乎你已经得到了两个非常糟糕的答案

正确的答案是,只要计算正确,就不必担心millis()翻转

这很糟糕:

if(timeChanged+amountOfMs
这很好(翻车安全):

if(currentTime-timeChanged>amountOfMs){…}
它工作的原因是具有无符号整数的算术(在您的例子中是无符号长的)可靠地工作于模max+1(
ULONG_max+1
is 2^32)。因此,
currentTime
timeChanged
,它们的差值总是有正确的值,模2^32。只要您每49天(很可能)多次测试按钮,差异将在
无符号长
范围内,您的测试将是正确的


换一种说法:如果millis()在
timeChanged
currentTime
之间滚动,那么
currentTime-timeChanged
之间的差值将为负值。但由于差分实际上是用无符号数字计算的,因此它将下溢并滚动到正确的结果。不过,我不喜欢这种解释,因为它听起来像是一个补偿另一个错误的错误。事实是:如果你用模算术来看待无符号数,那么任何地方都不会有错误。

这是一个非常常见的错误(也是我自己犯的错误),以至于Arduino游乐场有一个很好的、彻底的、正确的答案。请参见

我想一个选项确实应该是,一旦数字足够高,可以将所有值和计时器重置为最大去抖动时间,就进行检查。谢谢这将是不可靠的,因为您依赖于当时正在运行的代码,而这可能不是。答案根本不正确,请参阅我的答案,以了解检测翻滚的可靠方法。好的,很抱歉,这是一个错误,因为我打字很匆忙。而不是使用if(currentTime==0xFFFFFE);您应该使用if(currentTime>=0xFFFFFFFE)。现在我看不出@phil的答案和我的答案有什么区别。还是失败了。一旦当前时间过去,它将大大低于您建议的值,不是吗?我们的答案差别很大。就像我真的用过我的一样,它是有效的,而你显然没有用过你的,因为如果你用过,你就会知道它不起作用。让我们举一个实际的例子:你问
millis()
并得到(0xFFFFFFFE)存储在
timeChanged
,然后你再问
millis()
并得到(0xFFFFFFFF)。如果amountOfMs是10(例如),前一个测试给出:
If(8<0xffffff)
,它将错误地执行。后一个测试给出:
if(1>10)
就可以了。然后,假设你第二次问
millis()
,得到
0x1
。前一个测试给出:
if(8<1)
所以它是正确的,第二个测试给出:
if(3<10)
所以它也是正确的。用实际数字更容易理解