Arduino教程:使用millis()代替delay()

释放双眼,带上耳机,听听看~!

众所周知的Arduino里的delay()将程序暂停指定为毫秒数的参数。

millis()另一方面,是一个返回自程序启动以来经过的毫秒数的函数。

乍一看,您可能会怀疑此功能的实用性。事实是,它在许多情况下非常有用,通常会完全“替换”delay() 。首先让我们看一下如何使用millis()几乎完全像delay()

Arduino教程:使用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秒的样子:

 

Arduino教程:使用millis()代替delay()

 

这是一种同步代码中执行的好方法。您也可以同时运行其他代码。

micros()和溢出

就像delay()有一个微秒版本称为delayMicroseconds()millis()具有micros()。如果您需要更好的分辨率,micros()则可以采用。

但是,要知道,micros()会后溢出约70分钟,比millis()50天。这意味着函数的返回值将从零开始。

摘要

millis()并且micros()是非常方便的功能,具有定时任务处理时使用。如果您不了解这些内容,则可能最终只会使用delay(),但这种方式可能不会总是那么好。

给TA打赏
共{{data.count}}人
人已打赏
免费项目

面部跟踪和微笑检测万圣节机器人

2019-11-7 21:38:29

免费项目

Arduino教程——如何正确使用外部中断?

2019-11-17 22:47:58

3 条回复 A文章作者 M管理员
  1. […] 把LED腳位等等先設置好,再利用millis()的寫法來固定時間產生一組亂數,並將亂數產生的ledPin來點亮。 […]

  2. […] 這邊是看到網路上這篇文章”Arduino教程:使用millis()代替delay()” […]

  3. 感觉有些语句不够通顺

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索
'); })();