Arduino程序的基石setup()
和loop()
函数构成了整个开发体系的核心逻辑。这两个函数的设计哲学体现了嵌入式系统开发的两个关键维度:
setup()
):执行单次配置任务loop()
):持续执行主控逻辑setup()
函数的进阶应用尽管setup()
仅执行一次,但其功能远不止于简单的引脚配置。现代开发实践中,setup()
承担着多项重要职责:
cpp
void setup() {
// 基础配置
pinMode(13, OUTPUT); // 配置数字引脚13为输出模式
pinMode(A0, INPUT_PULLUP); // 配置模拟引脚A0为上拉输入
analogReference(DEFAULT); // 设置参考电压为默认值
// 通信初始化
Serial.begin(115200); // 高速串口通信
Wire.begin(); // I2C总线初始化
SPI.begin(); // SPI总线初始化
// 外设初始化
if (!SD.begin(4)) { // SD卡初始化
Serial.println("SD卡初始化失败");
return;
}
// 中断配置
attachInterrupt(digitalPinToInterrupt(2), handleInterrupt, RISING); // 配置外部中断
// 外部库初始化
if (!bme.begin(0x76)) { // BME280传感器初始化
Serial.println("传感器初始化失败");
while (1); // 永久等待
}
}
loop()
函数的优化策略loop()
函数的执行效率直接影响系统响应速度。优化方法包括:
delay()
,改用时间戳计算cpp
unsigned long previousMillis = 0;
const long interval = 1000;
void loop() {
unsigned long currentMillis = millis();
// 非阻塞延时
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
toggleLED(); // 执行状态切换
}
// 传感器数据采集
if (millis() - lastSensorRead > 500) {
readSensors();
}
// 通信任务
if (Serial.available()) {
processSerialInput();
}
}
大型项目建议采用模块化架构:
cpp
// 主程序文件:main.ino
#include "ledControl.h"
#include "sensorManager.h"
#include "wifiHandler.h"
void setup() {
initLEDs();
initSensors();
connectToWiFi();
}
void loop() {
checkLEDStatus();
readSensorData();
handleWiFiTasks();
}
Arduino支持硬件串口和软件串口:
cpp
#include
SoftwareSerial mySerial(10, 11); // RX, TX
void setup() {
Serial.begin(9600);
mySerial.begin(19200);
}
void loop() {
// 硬件串口通信
if (Serial.available()) {
char c = Serial.read();
mySerial.write(c);
}
// 软件串口通信
if (mySerial.available()) {
Serial.write(mySerial.read());
}
}
cpp
#define START_BYTE 0xA5
#define END_BYTE 0x5A
void sendPacket(byte cmd, byte data) {
Serial.write(START_BYTE);
Serial.write(cmd);
Serial.write(data);
Serial.write(END_BYTE);
}
bool receivePacket(byte *cmd, byte *data) {
if (Serial.available() >= 4) {
byte start = Serial.read();
if (start == START_BYTE) {
*cmd = Serial.read();
*data = Serial.read();
byte end = Serial.read();
if (end == END_BYTE) return true;
}
}
return false;
}
cpp
#include
#include
BLEServer* pServer;
BLEService* pService;
BLECharacteristic* pCharacteristic;
void setup() {
BLEDevice::init("MyESP32");
pServer = BLEDevice::createServer();
pService = pServer->createService(BLEUUID("0000110A-0000-1000-8000-00805F9B34FB"));
pCharacteristic = pService->createCharacteristic(
BLEUUID("0000110B-0000-1000-8000-00805F9B34FB"),
BLECharacteristic::PROPERTY_READ |
BLECharacteristic::PROPERTY_WRITE
);
pCharacteristic->setValue("Hello World");
pService->start();
pServer->getAdvertising()->start();
}
void loop() {
if (pCharacteristic->getValue().length() > 0) {
String value = pCharacteristic->getValue().c_str();
pCharacteristic->setValue(""); // 清空缓冲区
}
}
cpp
#include
void setup() {
Serial.begin(9600);
while (!Serial);
if (!LoRa.begin(915E6)) {
Serial.println("LoRa初始化失败");
while (1);
}
}
void loop() {
int packetSize = LoRa.parsePacket();
if (packetSize) {
while (LoRa.available()) {
String data = LoRa.readString();
Serial.println("收到数据: " + data);
}
} else {
LoRa.beginPacket();
LoRa.print("Hello LoRa");
LoRa.endPacket();
delay(1000);
}
}
cpp
#include
#include
#include
Adafruit_BME280 bme;
DHT dht(A0, DHT11);
void setup() {
Serial.begin(115200);
if (!bme.begin(0x76)) {
Serial.println("BME280未检测到");
while (1);
}
dht.begin();
}
void loop() {
float temp = bme.readTemperature();
float hum = bme.readHumidity();
float dhtTemp = dht.readTemperature();
float dhtHum = dht.readHumidity();
Serial.print("BME280 - 温度: ");
Serial.print(temp);
Serial.print(" °C, 湿度: ");
Serial.print(hum);
Serial.println(" %");
Serial.print("DHT11 - 温度: ");
Serial.print(dhtTemp);
Serial.print(" °C, 湿度: ");
Serial.print(dhtHum);
Serial.println(" %");
delay(2000);
}
cpp
#include
AccelStepper stepper(AccelStepper::DRIVER, 2, 3); // DIR, STEP
void setup() {
stepper.setMaxSpeed(1000);
stepper.setAcceleration(500);
}
void loop() {
if (stepper.distanceToGo() == 0) {
stepper.moveTo(stepper.currentPosition() + 200); // 移动200步
}
stepper.run();
}
cpp
#include
Servo esc;
void setup() {
esc.attach(9); // 连接到PWM引脚9
esc.write(3); // 最小信号(停止)
delay(2000);
esc.write(7); // 启动信号
}
void loop() {
for (int speed=3; speed<=7; speed++) {
esc.write(speed);
delay(1000);
}
for (int speed=7; speed>=3; speed--) {
esc.write(speed);
delay(1000);
}
}
cpp
#include
#include
char ssid[] = "YOUR_SSID";
char pass[] = "YOUR_PASSWORD";
unsigned long myChannelNumber = YOUR_CHANNEL_NUMBER;
const char * myWriteAPIKey = "YOUR_API_KEY";
WiFiClient client;
void setup() {
Serial.begin(9600);
while (!Serial);
if (WiFi.status() != WL_CONNECTED) {
WiFi.begin(ssid, pass);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
}
ThingSpeak.begin(client);
}
void loop() {
float temperature = getTemperature(); // 自定义传感器读取函数
ThingSpeak.writeField(myChannelNumber, 1, temperature, myWriteAPIKey);
delay(20000); // 20秒间隔
}
cpp
#include
#include
const char* ssid = "YOUR_SSID";
const char* password = "YOUR_PASSWORD";
const char* mqtt_server = "broker.hivemq.com";
const int mqtt_port = 1883;
const char* mqtt_user = "";
const char* mqtt_password = "";
WiFiClient espClient;
PubSubClient client(espClient);
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");
for (int i=0; i
特性 | Arduino UNO | ESP32 | Raspberry Pi Pico |
---|---|---|---|
处理器 | ATmega328P (16MHz) | Xtensa LX6 (240MHz) | ARM Cortex-M0+ (133MHz) |
内存 | 2KB SRAM, 32KB Flash | 520KB SRAM, 4MB Flash | 264KB SRAM, 2MB Flash |
无线功能 | 无 | Wi-Fi/蓝牙 | 无(需外接模块) |
编程语言 | C/C++ | C++/MicroPython | C++/MicroPython |
价格(约) | 2−2−5 | 5−5−15 | 4−4−6 |
功耗 | 低 | 中 | 低 |
开发环境 | Arduino IDE | Arduino IDE/ESP-IDF | Arduino IDE/Thonny |
项目需求 | 推荐开发板 | 理由 |
---|---|---|
初学者教学 | Arduino UNO | 简单易用,社区资源丰富 |
物联网应用 | ESP32 | 内置Wi-Fi/蓝牙,处理能力强 |
多任务处理 | Raspberry Pi Pico | 双核处理器,高性能 |
低功耗设备 | Arduino UNO | 低功耗设计,适合电池供电 |
工业控制 | Arduino Mega | 更多I/O引脚和内存 |
音频处理 | Teensy 4.1 | 高速音频处理能力 |
cpp
volatile bool interruptFlag = false;
void handleInterrupt() {
interruptFlag = true;
}
void setup() {
pinMode(2, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(2), handleInterrupt, FALLING);
}
void loop() {
if (interruptFlag) {
interruptFlag = false;
// 执行中断处理逻辑
}
// 主循环逻辑
}
malloc()
/free()
时注意内存碎片cpp
// 不推荐方式
String data = "Start";
for (int i=0; i<100; i++) {
data += String(i);
}
// 推荐方式
char buffer[100];
snprintf(buffer, sizeof(buffer), "Start 0-99");
const
限定不可变数据cpp
#define LED_PIN 13
void setup() {
DDRB |= (1 << LED_PIN); // 设置为输出
}
void loop() {
PORTB ^= (1 << LED_PIN); // 切换LED状态
delay(500);
}
cpp
#include
#include
const char* ssid = "YOUR_SSID";
const char* password = "YOUR_PASSWORD";
WebServer server(80);
void handleRoot() {
String html = "";
html += "智能家居控制
";
html += "开灯
";
html += "关灯";
html += "";
server.send(200, "text/html", html);
}
void handleLightOn() {
digitalWrite(LED_BUILTIN, HIGH);
server.sendHeader("Location", "/");
server.send(303);
}
void handleLightOff() {
digitalWrite(LED_BUILTIN, LOW);
server.sendHeader("Location", "/");
server.send(303);
}
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
}
server.on("/", handleRoot);
server.on("/light/on", handleLightOn);
server.on("/light/off", handleLightOff);
server.begin();
}
void loop() {
server.handleClient();
}
cpp
#include
#include
#include
#include
Adafruit_BME280 bme;
char ssid[] = "YOUR_SSID";
char pass[] = "YOUR_PASSWORD";
unsigned long channelID = YOUR_CHANNEL_ID;
const char * apiKey = "YOUR_API_KEY";
WiFiClient client;
void setup() {
Serial.begin(9600);
while (!Serial);
if (!bme.begin(0x76)) {
Serial.println("BME280未检测到");
while (1);
}
WiFi.begin(ssid, pass);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
ThingSpeak.begin(client);
}
void loop() {
float temp = bme.readTemperature();
float hum = bme.readHumidity();
float pres = bme.readPressure() / 100.0F;
ThingSpeak.writeFields(channelID, apiKey, temp, hum, pres);
delay(20000); // 20秒间隔
}
micros()
测量函数执行时间__heap_cap
检查内存使用sleep()
函数)问题现象 | 可能原因 | 解决方案 |
---|---|---|
串口无法通信 | 波特率不匹配 | 检查Serial.begin() 参数 |
传感器数据异常 | 电源不稳定 | 增加电容滤波 |
电机运行抖动 | PWM频率过低 | 使用analogWriteFrequency() 调整 |
Wi-Fi连接失败 | SSID/PASSWORD错误 | 检查WiFi凭据 |
程序卡死 | 内存泄漏 | 检查动态内存分配 |
随着RISC-V架构在嵌入式领域的普及,未来Arduino生态系统可能会出现基于RISC-V的开发板,提供更灵活的指令集定制能力和更高的性能。
结合TensorFlow Lite等机器学习框架,Arduino设备将具备本地AI推理能力,实现更智能的边缘计算应用。
随着LoRaWAN、NB-IoT等低功耗广域网技术的成熟,Arduino设备将在智慧城市、农业监测等领域发挥更大作用。