众所周知的Arduino里的delay()
将程序暂停指定为毫秒数的参数。
millis()
另一方面,是一个返回自程序启动以来经过的毫秒数的函数。
乍一看,您可能会怀疑此功能的实用性。事实是,它在许多情况下非常有用,通常会完全“替换”delay()
。首先让我们看一下如何使用millis()
几乎完全像delay()
。
时序问题经常出现在编程中。
目录
使用像millis()这样的delay()
unsigned long time_now = 0;
void setup() {
Serial.begin(115200);
}
void loop() {
time_now = millis();
Serial.println("Hello");
while(millis() < time_now + period){
//wait approx. [period] ms
}
}
如果您希望代码在每次循环迭代结束时仅暂停1000 ms,则上面的代码有点愚蠢。您可以 delay(1000)
改用。上面的代码和delay(1000)
结尾的代码之间的唯一区别是,上面的代码中的循环每秒将非常准确地运行一次。代码中的循环delay(1000)
会减少运行的频率,因为它也需要一些时间执行Serial.println("Hello")
。
为什么使用millis()而不是delay()?
现在,我们将millis()
比较与相比的两个优势delay()
。
准确的时间
我们将讨论的第一个优点是准确的时间安排。在代码方面,我们在上一章中进行了介绍。有了millis()
我们,我们可以确保循环执行所需的次数,而与执行时间无关(显然,只要执行时间短于所需的时间,就可以执行)。随着delay()
这是不可能的,因为我们不知道循环执行的时间有多长。
当以一定频率采样或运行滤波器时,此类精确定时非常有用。
不阻塞
另一个好处millis()
是它不会阻止我们在“等待”时运行代码。
unsigned long time_now = 0;
void setup() {
Serial.begin(115200);
}
void loop() {
if(millis() > time_now + period){
time_now = millis();
Serial.println("Hello");
}
//Run other code
}
假设我们要每秒打印一次“ Hello”,同时还要做其他事情。这是不可能的,delay()
因为它会暂停整个代码。这是我们可以执行此操作的一种方法:
该代码块与第一个代码块非常相似,不同之处在于,当不通过串行打印时,它不会阻塞程序的其余部分。
示例:一个简单的调度程序
让我们写一个简单的示例,在该示例中,我们创建一个调度程序,该调度程序以不同的间隔打印某些文本位。
#define INTERVAL_MESSAGE2 7000
#define INTERVAL_MESSAGE3 11000
#define INTERVAL_MESSAGE4 13000
unsigned long time_1 = 0;
unsigned long time_2 = 0;
unsigned long time_3 = 0;
unsigned long time_4 = 0;
void print_time(unsigned long time_millis);
void setup() {
Serial.begin(115200);
}
void loop() {
if(millis() > time_1 + INTERVAL_MESSAGE1){
time_1 = millis();
print_time(time_1);
Serial.println("I'm message number one!");
}
if(millis() > time_2 + INTERVAL_MESSAGE2){
time_2 = millis();
print_time(time_2);
Serial.println("Hello, I'm the second message.");
}
if(millis() > time_3 + INTERVAL_MESSAGE3){
time_3 = millis();
print_time(time_3);
Serial.println("My name is Message the third.");
}
if(millis() > time_4 + INTERVAL_MESSAGE4){
time_4 = millis();
print_time(time_4);
Serial.println("Message four is in the house!");
}
}
void print_time(unsigned long time_millis){
Serial.print("Time: ");
Serial.print(time_millis/1000);
Serial.print("s - ");
}
这是串行监视器中前60秒的样子:
这是一种同步代码中执行的好方法。您也可以同时运行其他代码。
micros()和溢出
就像delay()
有一个微秒版本称为delayMicroseconds()
,millis()
具有micros()
。如果您需要更好的分辨率,micros()
则可以采用。
但是,要知道,micros()
会后溢出约70分钟,比millis()
的50天。这意味着函数的返回值将从零开始。
摘要
millis()
并且micros()
是非常方便的功能,具有定时任务处理时使用。如果您不了解这些内容,则可能最终只会使用delay()
,但这种方式可能不会总是那么好。
[…] 把LED腳位等等先設置好,再利用millis()的寫法來固定時間產生一組亂數,並將亂數產生的ledPin來點亮。 […]
[…] 這邊是看到網路上這篇文章”Arduino教程:使用millis()代替delay()” […]
感觉有些语句不够通顺
学习了,谢谢