Arduino - 控制语句
Arduino - 现代控制流
Section titled “Arduino - 现代控制流”为了创建交互式和智能的项目,您的程序需要做出决策。控制语句是基本的构建块,它允许您根据特定条件来决定程序执行的流程。这使得您的 Arduino 能够对传感器输入、用户命令和内部状态变化做出反应。
现代 C++(Arduino 使用的语言)提供了一套强大的控制结构。让我们通过实际的现实世界示例来探索其中最核心的部分。
1. 条件语句:if、else if、else
Section titled “1. 条件语句:if、else if、else”这是最常见的决策工具。它只在特定条件为 true(真)时执行一段代码。
if:检查一个条件。如果条件为真,花括号{}里的代码就会运行。else if:如果第一个if条件为假,则检查第二个条件。else:如果所有之前的if和else if条件都为假,则else代码块中的代码会运行。
实践示例:智能灯
Section titled “实践示例:智能灯”让我们制作一个仅在按下按钮时才点亮的 LED。这展示了一个基本的输入到输出的反应。
// 最佳实践:对引脚号使用 'const int' 或 'constexpr'。// 这可以防止意外修改,并使代码更具可读性。constexpr int LED_PIN = 13; // 大多数 Arduino 板载的 LEDconstexpr int BUTTON_PIN = 2; // 将一个按钮连接到引脚 2
void setup() { // 初始化引脚,使其用于指定目的 pinMode(LED_PIN, OUTPUT); // 使用 INPUT_PULLUP 启用内部上拉电阻。 // 这意味着当按钮未按下时引脚读数为 HIGH,按下时读数为 LOW。 pinMode(BUTTON_PIN, INPUT_PULLUP);
// 启动串口通信,用于调试 Serial.begin(9600);}
void loop() { // 读取按钮状态 int buttonState = digitalRead(BUTTON_PIN);
// 由于使用了 INPUT_PULLUP,逻辑是反转的:LOW 表示按钮被按下。 if (buttonState == LOW) { // 如果按钮被按下,打开 LED。 digitalWrite(LED_PIN, HIGH); Serial.println("Button is pressed. LED ON."); } else { // 如果按钮未按下,关闭 LED。 // 此处无需打印,否则会刷屏串口监视器。 digitalWrite(LED_PIN, LOW); }
delay(50); // 一个小延迟,用于消除抖动并防止串口刷屏}2. switch...case 语句
Section titled “2. switch...case 语句”当您有一个变量需要对照多个可能的值进行检查时,switch 语句通常比一长串 if-else if 语句更简洁、更高效。
实践示例:多模式设备
Section titled “实践示例:多模式设备”想象一个具有三种模式(例如,常亮、闪烁、渐变)的设备,通过串口监视器发送命令来选择模式。
constexpr int LED_PIN = 9; // 使用一个 PWM 引脚进行渐变(例如 Uno 上的 3, 5, 6, 9, 10, 11)char deviceMode = 's'; // 's' 代表常亮,'b' 代表闪烁,'f' 代表渐变
void setup() { pinMode(LED_PIN, OUTPUT); Serial.begin(9600); Serial.println("Enter a mode: 's' (solid), 'b' (blink), 'f' (fade)");}
void loop() { // 检查串口是否有可用数据可读 if (Serial.available() > 0) { char input = Serial.read(); if (input == 's' || input == 'b' || input == 'f') { deviceMode = input; } }
// 使用 switch 语句处理当前模式 switch (deviceMode) { case 's': // 常亮模式:LED 始终开启 digitalWrite(LED_PIN, HIGH); break; // **关键**:'break' 用于退出 switch 语句。如果没有它,程序将继续执行下一个 case 块!
case 'b': // 闪烁模式 digitalWrite(LED_PIN, HIGH); delay(500); digitalWrite(LED_PIN, LOW); delay(500); break;
case 'f': // 渐变模式(使用 for 循环,见下一节) for (int i = 0; i <= 255; i++) { analogWrite(LED_PIN, i); delay(5); } for (int i = 255; i >= 0; i--) { analogWrite(LED_PIN, i); delay(5); } break;
default: // 最佳实践:始终包含一个 default 情况,以处理意外值。 // 在这种情况下,什么也不做。 break; }}常见陷阱:缺失的 break
Section titled “常见陷阱:缺失的 break”忘记 break 语句是一个非常常见的错误。如果您省略它,程序将继续执行下一个 case 块中的代码,导致意想不到的行为。
3. 迭代:for 循环和 while 循环
Section titled “3. 迭代:for 循环和 while 循环”循环用于重复执行一段代码块。这对于诸如 LED 闪烁、多次读取传感器或处理数据等任务至关重要。
for 循环
Section titled “for 循环”当您确切知道要重复某个动作多少次时,for 循环是完美的选择。switch 语句中的 LED 渐变示例就使用了 for 循环。
while 循环
Section titled “while 循环”当您希望循环在条件为真时持续执行,但不知道何时会停止时,while 循环是理想的选择。
// 实践示例:等待传感器准备就绪// (这是一个概念性示例)
#include <Wire.h>#include <Adafruit_Sensor.h>// #include <Some_Sensor_Library.h> // 一个假想的传感器库
// SomeSensor sensor;
void setup() { Serial.begin(9600); while (!Serial) { ; // 等待串口连接。原生 USB 端口板需要此操作。 }
Serial.println("等待传感器初始化...");
// while 循环非常适合等待条件满足 // while (!sensor.isReady()) { // Serial.print("."); // delay(100); // }
Serial.println("\n传感器已准备就绪!");}
void loop() { // 主程序逻辑从这里开始}4. 三元运算符 (? :)
Section titled “4. 三元运算符 (? :)”这是一种紧凑的、单行的简写形式,用于简单的 if-else 语句。它非常适合根据条件为变量赋值。
语法:condition ? value_if_true : value_if_false
Section titled “语法:condition ? value_if_true : value_if_false”// 之前(使用 if-else):int x = 10;int y;if (x > 5) { y = 100;} else { y = 0;}
// 之后(使用三元运算符):int x = 10;int y = (x > 5) ? 100 : 0; // y 将为 100
// 另一个示例int lightLevel = analogRead(A0);String message = (lightLevel < 500) ? "It's dark" : "It's bright";Serial.println(message);迷你项目:交通灯系统
Section titled “迷你项目:交通灯系统”综合您所学到的知识!创建一个简单的交通灯系统,包含红、黄、绿三色 LED。使用 digitalWrite() 控制 LED,使用 delay() 控制序列时间。使用 if-else 或 switch 语句来构建您的逻辑,使其在以下状态之间循环:绿灯 -> 黄灯 -> 红灯 -> 绿灯…