跳到主要内容

Arduino 延时函数

在Arduino编程中,时间控制是一个非常重要的概念。延时函数允许我们在程序中暂停执行一段时间,这对于控制LED闪烁、传感器读取间隔、电机运行时间等场景非常有用。本文将详细介绍Arduino中的两种主要延时函数:delay()millis(),并通过实际案例展示它们的应用。

1. delay() 函数

delay() 是Arduino中最常用的延时函数。它的作用是暂停程序的执行一段指定的时间(以毫秒为单位)。例如,delay(1000) 会让程序暂停1秒钟。

代码示例

cpp
void setup() {
pinMode(LED_BUILTIN, OUTPUT); // 设置内置LED引脚为输出模式
}

void loop() {
digitalWrite(LED_BUILTIN, HIGH); // 打开LED
delay(1000); // 暂停1秒
digitalWrite(LED_BUILTIN, LOW); // 关闭LED
delay(1000); // 暂停1秒
}

在这个例子中,LED会每隔1秒钟闪烁一次。

备注

delay() 函数会阻塞程序的执行,这意味着在延时期间,Arduino无法执行其他任务。因此,delay() 适用于简单的任务,但在需要同时处理多个任务时,可能会限制程序的灵活性。

2. millis() 函数

millis() 是一个非阻塞的延时函数,它返回自Arduino启动以来的毫秒数。与delay()不同,millis()不会暂停程序的执行,因此可以在延时期间执行其他任务。

代码示例

cpp
unsigned long previousMillis = 0; // 存储上一次LED状态改变的时间
const long interval = 1000; // 间隔时间(1秒)
bool ledState = LOW; // LED的初始状态

void setup() {
pinMode(LED_BUILTIN, OUTPUT); // 设置内置LED引脚为输出模式
}

void loop() {
unsigned long currentMillis = millis(); // 获取当前时间

if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis; // 更新上一次状态改变的时间

// 切换LED状态
if (ledState == LOW) {
ledState = HIGH;
} else {
ledState = LOW;
}

digitalWrite(LED_BUILTIN, ledState); // 设置LED状态
}
}

在这个例子中,LED仍然会每隔1秒钟闪烁一次,但程序在等待期间可以执行其他任务。

提示

millis() 非常适合用于需要同时处理多个任务的场景,例如在控制LED的同时读取传感器数据或响应按钮按下事件。

3. 实际应用案例

案例1:交通信号灯模拟

假设我们要模拟一个简单的交通信号灯系统,红灯亮5秒,黄灯亮2秒,绿灯亮5秒。我们可以使用millis()来实现这个功能。

cpp
unsigned long previousMillis = 0;
const long redInterval = 5000; // 红灯亮5秒
const long yellowInterval = 2000; // 黄灯亮2秒
const long greenInterval = 5000; // 绿灯亮5秒
int state = 0; // 0: 红灯, 1: 黄灯, 2: 绿灯

void setup() {
pinMode(8, OUTPUT); // 红灯引脚
pinMode(9, OUTPUT); // 黄灯引脚
pinMode(10, OUTPUT); // 绿灯引脚
}

void loop() {
unsigned long currentMillis = millis();

switch (state) {
case 0: // 红灯
digitalWrite(8, HIGH);
digitalWrite(9, LOW);
digitalWrite(10, LOW);
if (currentMillis - previousMillis >= redInterval) {
previousMillis = currentMillis;
state = 1; // 切换到黄灯
}
break;

case 1: // 黄灯
digitalWrite(8, LOW);
digitalWrite(9, HIGH);
digitalWrite(10, LOW);
if (currentMillis - previousMillis >= yellowInterval) {
previousMillis = currentMillis;
state = 2; // 切换到绿灯
}
break;

case 2: // 绿灯
digitalWrite(8, LOW);
digitalWrite(9, LOW);
digitalWrite(10, HIGH);
if (currentMillis - previousMillis >= greenInterval) {
previousMillis = currentMillis;
state = 0; // 切换回红灯
}
break;
}
}

案例2:按钮去抖动

在读取按钮输入时,通常会遇到抖动问题。我们可以使用millis()来实现去抖动功能。

cpp
unsigned long lastDebounceTime = 0;
const long debounceDelay = 50; // 去抖动时间
int buttonState = LOW;
int lastButtonState = LOW;

void setup() {
pinMode(2, INPUT); // 按钮引脚
pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
int reading = digitalRead(2);

if (reading != lastButtonState) {
lastDebounceTime = millis(); // 重置去抖动计时器
}

if ((millis() - lastDebounceTime) > debounceDelay) {
if (reading != buttonState) {
buttonState = reading;

if (buttonState == HIGH) {
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN)); // 切换LED状态
}
}
}

lastButtonState = reading;
}

4. 总结

在Arduino编程中,delay()millis() 是两种常用的时间控制函数。delay() 简单易用,但会阻塞程序的执行;millis() 则更加灵活,适合需要同时处理多个任务的场景。通过合理使用这两种函数,可以实现各种复杂的时间控制功能。

5. 附加资源与练习

  • 练习1:修改交通信号灯模拟程序,增加一个行人按钮,按下按钮后绿灯立即变为黄灯,然后变为红灯。
  • 练习2:使用millis()实现一个简单的计时器,显示从程序启动到当前的时间。
警告

在使用millis()时,注意unsigned long类型的变量会在约49天后溢出。如果你的程序需要运行超过这个时间,请考虑使用unsigned long long或其他时间管理方法。