Arduino 延时函数
在Arduino编程中,时间控制是一个非常重要的概念。延时函数允许我们在程序中暂停执行一段时间,这对于控制LED闪烁、传感器读取间隔、电机运行时间等场景非常有用。本文将详细介绍Arduino中的两种主要延时函数:delay()
和millis()
,并通过实际案例展示它们的应用。
1. delay()
函数
delay()
是Arduino中最常用的延时函数。它的作用是暂停程序的执行一段指定的时间(以毫秒为单位)。例如,delay(1000)
会让程序暂停1秒钟。
代码示例
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()
不会暂停程序的执行,因此可以在延时期间执行其他任务。
代码示例
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()
来实现这个功能。
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()
来实现去抖动功能。
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
或其他时间管理方法。