Arduino

Arduino 全面指南

1. Arduino 简介

1.1 什么是 Arduino?

Arduino 是一个开源电子原型平台,包含:

  • 硬件:各种微控制器板
  • 软件:基于 Processing 语言的集成开发环境(IDE)
  • 社区:全球开源社区支持

1.2 核心特点

  • 开源:硬件和软件完全开源
  • 易用:不需要专业电子知识
  • 低成本:开发板价格亲民
  • 跨平台:支持 Windows、macOS、Linux
  • 丰富库:大量现成的库可以使用

2. Arduino 硬件家族

2.1 主流开发板

// Arduino UNO R3(最常用)
// ATmega328P 微控制器
// 14个数字I/O引脚(6个PWM)
// 6个模拟输入引脚
// 16MHz 时钟,32KB Flash,2KB SRAM

// Arduino Mega 2560
// ATmega2560 微控制器
// 54个数字I/O引脚(15个PWM)
// 16个模拟输入引脚
// 256KB Flash,8KB SRAM

// Arduino Nano
// 小型化版本,适合嵌入式项目
// 功能与UNO相似,体积更小

// Arduino Due
// 基于ARM Cortex-M3
// 32位,84MHz,512KB Flash
// 54个数字I/O引脚(12个PWM)

// Arduino MKR系列
// 低功耗,物联网专用
// 集成WiFi、蓝牙、LoRa等模块

2.2 扩展板(Shields)

// 以太网扩展板:网络连接
// WiFi扩展板:无线连接
// 电机驱动扩展板:控制电机
// LCD扩展板:显示屏
// GPS扩展板:定位功能
// SD卡扩展板:数据存储

3. Arduino 编程基础

3.1 程序结构

// Arduino程序基本结构
void setup() {
  // 初始化代码,只运行一次
  Serial.begin(9600);        // 初始化串口通信
  pinMode(LED_BUILTIN, OUTPUT); // 设置引脚模式
}

void loop() {
  // 主循环代码,重复执行
  digitalWrite(LED_BUILTIN, HIGH); // 打开LED
  delay(1000);                     // 等待1秒
  digitalWrite(LED_BUILTIN, LOW);  // 关闭LED
  delay(1000);                     // 等待1秒
}

3.2 常用函数

// 引脚控制
pinMode(pin, mode);          // 设置引脚模式
digitalWrite(pin, value);    // 数字输出
digitalRead(pin);            // 数字输入
analogRead(pin);             // 模拟输入(0-1023)
analogWrite(pin, value);     // PWM输出(0-255)

// 时间控制
delay(ms);                   // 毫秒延迟
delayMicroseconds(us);       // 微秒延迟
millis();                    // 获取运行时间(毫秒)
micros();                    // 获取运行时间(微秒)

// 串口通信
Serial.begin(speed);         // 初始化串口
Serial.print(data);          // 发送数据
Serial.println(data);        // 发送数据并换行
Serial.read();               // 读取数据
Serial.available();          // 检查可用数据

3.3 变量与数据类型

// 基本数据类型
boolean flag = true;         // 布尔值
byte b = 255;                // 0-255
char c = 'A';                // 字符
int num = 1234;              // 整数(-32,768 to 32,767)
unsigned int ui = 65535;     // 无符号整数
long l = 123456L;            // 长整数
float f = 3.14;              // 浮点数
double d = 3.141592;         // 双精度浮点

// 数组
int numbers[5] = {1, 2, 3, 4, 5};
String text = "Hello Arduino"; // 字符串对象

// 常量
const float PI = 3.14159;
#define LED_PIN 13          // 宏定义

4. 传感器与控制实例

4.1 LED 控制

// PWM控制LED亮度
const int LED_PIN = 9;

void setup() {
  pinMode(LED_PIN, OUTPUT);
}

void loop() {
  // 呼吸灯效果
  for (int brightness = 0; brightness <= 255; brightness++) {
    analogWrite(LED_PIN, brightness);
    delay(10);
  }
  
  for (int brightness = 255; brightness >= 0; brightness--) {
    analogWrite(LED_PIN, brightness);
    delay(10);
  }
}

4.2 按钮控制

// 按钮控制LED
const int BUTTON_PIN = 2;
const int LED_PIN = 13;

int buttonState = 0;

void setup() {
  pinMode(LED_PIN, OUTPUT);
  pinMode(BUTTON_PIN, INPUT_PULLUP); // 使用内部上拉电阻
}

void loop() {
  buttonState = digitalRead(BUTTON_PIN);
  
  if (buttonState == LOW) { // 按钮按下(使用上拉电阻时低电平有效)
    digitalWrite(LED_PIN, HIGH);
  } else {
    digitalWrite(LED_PIN, LOW);
  }
}

4.3 温度传感器(DS18B20)

#include <OneWire.h>
#include <DallasTemperature.h>

#define ONE_WIRE_BUS 2

OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

void setup() {
  Serial.begin(9600);
  sensors.begin();
}

void loop() {
  sensors.requestTemperatures();
  float tempC = sensors.getTempCByIndex(0);
  
  Serial.print("Temperature: ");
  Serial.print(tempC);
  Serial.println(" °C");
  
  delay(1000);
}

4.4 超声波测距

// HC-SR04超声波传感器
const int TRIG_PIN = 9;
const int ECHO_PIN = 10;

void setup() {
  Serial.begin(9600);
  pinMode(TRIG_PIN, OUTPUT);
  pinMode(ECHO_PIN, INPUT);
}

void loop() {
  // 发送10微秒的高电平触发信号
  digitalWrite(TRIG_PIN, LOW);
  delayMicroseconds(2);
  digitalWrite(TRIG_PIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIG_PIN, LOW);
  
  // 读取回波时间
  long duration = pulseIn(ECHO_PIN, HIGH);
  
  // 计算距离(声速340m/s)
  float distance = duration * 0.034 / 2;
  
  Serial.print("Distance: ");
  Serial.print(distance);
  Serial.println(" cm");
  
  delay(100);
}

4.5 舵机控制

#include <Servo.h>

Servo myServo;
int pos = 0;

void setup() {
  myServo.attach(9); // 舵机信号线接引脚9
}

void loop() {
  // 0到180度往复运动
  for (pos = 0; pos <= 180; pos += 1) {
    myServo.write(pos);
    delay(15);
  }
  for (pos = 180; pos >= 0; pos -= 1) {
    myServo.write(pos);
    delay(15);
  }
}

5. 通信协议

5.1 I2C通信

// I2C LCD1602显示屏
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

// 设置LCD地址(通常是0x27或0x3F)
LiquidCrystal_I2C lcd(0x27, 16, 2);

void setup() {
  lcd.init();           // 初始化LCD
  lcd.backlight();      // 打开背光
  lcd.setCursor(0, 0);  // 设置光标位置
  lcd.print("Hello World!");
  lcd.setCursor(0, 1);
  lcd.print("Arduino I2C LCD");
}

void loop() {
  // 可以显示动态内容
}

5.2 SPI通信

// SPI OLED显示屏
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define OLED_MOSI  11
#define OLED_CLK   13
#define OLED_DC    9
#define OLED_CS    10
#define OLED_RESET 8

Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);

void setup() {
  display.begin(SSD1306_SWITCHCAPVCC);
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0,0);
  display.println("Hello SPI!");
  display.display();
}

void loop() {
  // 显示内容
}

5.3 串口通信

// 与电脑通信
void setup() {
  Serial.begin(115200);
  Serial.println("Arduino Ready!");
}

void loop() {
  // 接收电脑发送的数据
  if (Serial.available() > 0) {
    String command = Serial.readStringUntil('\n');
    Serial.print("Received: ");
    Serial.println(command);
    
    // 处理命令
    if (command == "LED_ON") {
      digitalWrite(LED_BUILTIN, HIGH);
      Serial.println("LED turned ON");
    } else if (command == "LED_OFF") {
      digitalWrite(LED_BUILTIN, LOW);
      Serial.println("LED turned OFF");
    }
  }
  
  // 发送传感器数据
  int sensorValue = analogRead(A0);
  Serial.print("Sensor Value: ");
  Serial.println(sensorValue);
  
  delay(1000);
}

6. 物联网项目示例

6.1 WiFi连接(ESP8266/ESP32)

// 使用ESP8266连接WiFi
#include <ESP8266WiFi.h>

const char* ssid = "YourWiFiSSID";
const char* password = "YourWiFiPassword";

void setup() {
  Serial.begin(115200);
  delay(10);
  
  // 连接WiFi
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  
  WiFi.begin(ssid, password);
  
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

void loop() {
  // 发送HTTP请求
  if (WiFi.status() == WL_CONNECTED) {
    WiFiClient client;
    const int httpPort = 80;
    const char* host = "api.thingspeak.com";
    
    if (client.connect(host, httpPort)) {
      // 发送GET请求
      String url = "/update?api_key=YOUR_API_KEY&field1=" + String(analogRead(A0));
      client.print(String("GET ") + url + " HTTP/1.1\r\n" +
                   "Host: " + host + "\r\n" +
                   "Connection: close\r\n\r\n");
    }
    client.stop();
  }
  
  delay(15000); // 每15秒发送一次
}

6.2 MQTT协议

// 使用PubSubClient进行MQTT通信
#include <ESP8266WiFi.h>
#include <PubSubClient.h>

WiFiClient espClient;
PubSubClient client(espClient);

void setup_wifi() {
  delay(10);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
  }
}

void reconnect() {
  while (!client.connected()) {
    if (client.connect("arduinoClient")) {
      client.publish("arduino/status", "online");
      client.subscribe("arduino/led");
    } else {
      delay(5000);
    }
  }
}

void callback(char* topic, byte* payload, unsigned int length) {
  // 处理接收到的消息
  String message;
  for (int i = 0; i < length; i++) {
    message += (char)payload[i];
  }
  
  if (String(topic) == "arduino/led") {
    if (message == "ON") {
      digitalWrite(LED_BUILTIN, LOW);
    } else {
      digitalWrite(LED_BUILTIN, HIGH);
    }
  }
}

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
}

void loop() {
  if (!client.connected()) {
    reconnect();
  }
  client.loop();
  
  // 发布传感器数据
  int sensorValue = analogRead(A0);
  String payload = String(sensorValue);
  client.publish("arduino/sensor", payload.c_str());
  
  delay(2000);
}

7. 高级应用

7.1 中断处理

// 外部中断
const int INTERRUPT_PIN = 2;
volatile int interruptCounter = 0;

void setup() {
  Serial.begin(9600);
  pinMode(INTERRUPT_PIN, INPUT_PULLUP);
  
  // 设置中断:引脚2,下降沿触发,中断处理函数handleInterrupt
  attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), handleInterrupt, FALLING);
}

void loop() {
  if (interruptCounter > 0) {
    // 关闭中断保护
    noInterrupts();
    int counter = interruptCounter;
    interruptCounter = 0;
    interrupts(); // 重新开启中断
    
    Serial.print("Interrupts: ");
    Serial.println(counter);
  }
}

// 中断处理函数(必须简短)
void handleInterrupt() {
  interruptCounter++;
}

7.2 低功耗模式

// 睡眠模式
#include <avr/sleep.h>
#include <avr/power.h>

void setup() {
  Serial.begin(9600);
  
  // 设置睡眠模式
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  
  // 启用睡眠
  sleep_enable();
  
  Serial.println("Going to sleep...");
  delay(100);
  
  // 进入睡眠
  sleep_cpu();
  
  // 唤醒后继续执行
  Serial.println("Awake!");
}

void loop() {
  // 主循环
  delay(1000);
  Serial.println("Running...");
  
  if (Serial.available()) {
    // 收到串口数据时进入睡眠
    Serial.read();
    sleep_enable();
    sleep_cpu();
  }
}

7.3 多任务处理

// 使用millis()实现多任务
unsigned long previousMillisLED = 0;
unsigned long previousMillisSensor = 0;
const long intervalLED = 500;   // LED闪烁间隔
const long intervalSensor = 2000; // 传感器读取间隔

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  unsigned long currentMillis = millis();
  
  // 任务1: LED闪烁
  if (currentMillis - previousMillisLED >= intervalLED) {
    previousMillisLED = currentMillis;
    
    static bool ledState = false;
    digitalWrite(LED_BUILTIN, ledState);
    ledState = !ledState;
  }
  
  // 任务2: 读取传感器
  if (currentMillis - previousMillisSensor >= intervalSensor) {
    previousMillisSensor = currentMillis;
    
    int sensorValue = analogRead(A0);
    Serial.print("Sensor: ");
    Serial.println(sensorValue);
  }
  
  // 任务3: 检查按钮
  // 可以继续添加更多非阻塞任务
}

8. 项目案例

8.1 智能家居控制系统

#include <DHT.h>
#include <WiFi.h>
#include <PubSubClient.h>

#define DHTPIN 4
#define DHTTYPE DHT11
#define LIGHT_PIN 5
#define FAN_PIN 6

DHT dht(DHTPIN, DHTTYPE);
WiFiClient espClient;
PubSubClient client(espClient);

void setup() {
  Serial.begin(115200);
  dht.begin();
  pinMode(LIGHT_PIN, OUTPUT);
  pinMode(FAN_PIN, OUTPUT);
  
  setupWiFi();
  setupMQTT();
}

void loop() {
  if (!client.connected()) {
    reconnectMQTT();
  }
  client.loop();
  
  // 读取温湿度
  float temperature = dht.readTemperature();
  float humidity = dht.readHumidity();
  
  // 发布到MQTT
  if (!isnan(temperature) && !isnan(humidity)) {
    String payload = "{\"temp\":" + String(temperature) + 
                     ",\"hum\":" + String(humidity) + "}";
    client.publish("home/sensor", payload.c_str());
  }
  
  delay(5000);
}

// 自动控制逻辑
void autoControl(float temp) {
  if (temp > 28) {
    digitalWrite(FAN_PIN, HIGH);
  } else {
    digitalWrite(FAN_PIN, LOW);
  }
}

8.2 机器人小车

// 电机驱动控制
#define ENA 5
#define IN1 6
#define IN2 7
#define IN3 8
#define IN4 9
#define ENB 10

void setup() {
  pinMode(ENA, OUTPUT);
  pinMode(IN1, OUTPUT);
  pinMode(IN2, OUTPUT);
  pinMode(IN3, OUTPUT);
  pinMode(IN4, OUTPUT);
  pinMode(ENB, OUTPUT);
  
  // 初始化停止状态
  stop();
}

void loop() {
  // 超声波避障
  long distance = measureDistance();
  
  if (distance > 30) {
    forward();
  } else {
    stop();
    delay(500);
    turnRight();
    delay(300);
  }
  
  delay(100);
}

void forward() {
  digitalWrite(IN1, HIGH);
  digitalWrite(IN2, LOW);
  digitalWrite(IN3, HIGH);
  digitalWrite(IN4, LOW);
  analogWrite(ENA, 150);
  analogWrite(ENB, 150);
}

void backward() {
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, HIGH);
  digitalWrite(IN3, LOW);
  digitalWrite(IN4, HIGH);
  analogWrite(ENA, 150);
  analogWrite(ENB, 150);
}

void turnLeft() {
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, HIGH);
  digitalWrite(IN3, HIGH);
  digitalWrite(IN4, LOW);
  analogWrite(ENA, 150);
  analogWrite(ENB, 150);
}

void turnRight() {
  digitalWrite(IN1, HIGH);
  digitalWrite(IN2, LOW);
  digitalWrite(IN3, LOW);
  digitalWrite(IN4, HIGH);
  analogWrite(ENA, 150);
  analogWrite(ENB, 150);
}

void stop() {
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, LOW);
  digitalWrite(IN3, LOW);
  digitalWrite(IN4, LOW);
}

9. 开发工具与技巧

9.1 调试技巧

// 串口调试技巧
void debugPrint(String label, int value) {
  Serial.print(label);
  Serial.print(": ");
  Serial.println(value);
}

// 内存使用检查
extern int __heap_start, *__brkval;
int freeMemory() {
  int v;
  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
}

// 性能测试
void benchmark() {
  unsigned long start = micros();
  // 测试代码
  for(int i = 0; i < 1000; i++) {
    digitalRead(A0);
  }
  unsigned long end = micros();
  Serial.print("Time: ");
  Serial.print(end - start);
  Serial.println(" us");
}

9.2 常用库推荐

1. 传感器库:
   - DHT sensor library(温湿度)
   - Adafruit_Sensor(通用传感器)
   - Adafruit_BME280(温湿度气压)

2. 显示库:
   - LiquidCrystal(LCD1602)
   - Adafruit_GFX(图形库)
   - U8g2(OLED显示屏)

3. 通信库:
   - PubSubClient(MQTT)
   - WiFiManager(WiFi配置)
   - WebSockets(WebSocket)

4. 电机控制:
   - Servo(舵机)
   - AccelStepper(步进电机)
   - AFMotor(电机驱动)

5. 工具库:
   - ArduinoJson(JSON处理)
   - TaskScheduler(任务调度)
   - TimerOne(定时器)

10. 学习资源

10.1 官方资源

10.2 学习路径建议

  1. 入门阶段:LED控制、按钮、蜂鸣器
  2. 传感器阶段:温湿度、光敏、超声波
  3. 输出设备:LCD、OLED、舵机、电机
  4. 通信协议:串口、I2C、SPI
  5. 物联网:WiFi、蓝牙、MQTT
  6. 高级应用:中断、低功耗、多任务

10.3 项目实践建议

// 项目开发步骤
1. 明确项目需求
2. 绘制电路图(推荐使用Fritzing)
3. 准备元器件清单
4. 分模块编写和测试代码
5. 集成测试
6. 优化和调试
7. 制作外壳(3D打印或激光切割)
8. 编写文档

总结

Arduino是电子爱好者和创客的绝佳平台,它的优势在于:

  • 快速原型:几分钟就能搭建一个功能原型
  • 丰富生态:海量的传感器和扩展模块
  • 社区支持:全球开发者分享的代码和教程
  • 教育价值:非常适合STEM教育

无论你是初学者还是专业开发者,Arduino都能为你打开物联网和嵌入式开发的大门。从简单的LED闪烁开始,逐步挑战更复杂的项目,你会发现硬件编程的无限乐趣!

posted @ 2026-01-02 16:54  ukyo--碳水化合物  阅读(4)  评论(0)    收藏  举报