嵌入式开发 Arduino 入门实战:光敏电阻检测 + 串口控制舵机
刚拿到一块 Arduino UNO,最想知道的大概就是两件事:怎么让板子读取外界信号(传感器输入),以及怎么让板子驱动外部设备(执行器输出)。
这篇教程用两个经典入门项目,把这两件事一次讲清楚:
- 光敏电阻检测:读取模拟信号,通过串口监视器实时观察光照变化
- 串口控制舵机:在串口监视器里输入角度数字,舵机转到对应位置
做完这两个实验,你会对 Arduino 的数字 I/O、模拟输入、串口通信、PWM 输出、库的使用有一个直观的认识。
一、你需要准备的硬件
两个项目可以共用大部分硬件,一次性备齐:
| 元件 | 数量 | 说明 |
|---|---|---|
| Arduino UNO(或兼容板) | 1 | 带 USB 数据线 |
| 面包板 | 1 | 830 孔或 400 孔均可 |
| 光敏电阻 | 1 | 也叫光敏电阻模块,裸片或模块均可 |
| 普通电阻 | 若干 | 1KΩ / 4.7KΩ / 10KΩ,用作分压 |
| 舵机(Servo) | 1 | SG90 或 MG996R 均可 |
| 跳线 | 若干 | 公对公、公对母各准备一些 |
| LED(可选) | 1 | 板载 D13 已有,可不加 |
小贴士:如果你是纯新手,建议直接买”Arduino 入门套件”,上述元件基本都会包含。
二、项目一:光敏电阻检测
2.1 什么是光敏电阻?
光敏电阻(Photoresistor / LDR, Light Dependent Resistor)是一种电阻值随光照强度变化的元件:
- 光照越强 → 电阻越小
- 光照越弱 → 电阻越大
光敏电阻没有正负极之分,可以直接替换接入电路。但需要注意,如果你想获得更大的数值变化范围,输入 5V 比输入 3.3V 效果更好。
如果是光敏二极管(Photodiode),则具有二极管的单向导通特性,有正负极之分,可用万用表测量区分。
2.2 接线方法
核心思路:光敏电阻与一个固定电阻串联组成分压电路,中间节点接到 Arduino 的模拟输入引脚 A5。
5V
│
├── 固定电阻 (10KΩ)
│
├──────────── A5 (模拟输入)
│
├── 光敏电阻
│
GND
具体接线:
| 元件引脚 | 连接到 |
|---|---|
| 光敏电阻一端 | 5V |
| 光敏电阻另一端 | A5 + 固定电阻一端 |
| 固定电阻另一端 | GND |
固定电阻的作用是与光敏电阻形成分压。电阻值不同,ADC 读数的变化范围也不同——可以用 1KΩ、4.7KΩ、10KΩ 分别试试,观察哪种效果最好。
2.3 程序代码
#define AD5 A5 // 定义模拟口 A5
#define LED 13 // 定义数字口 13(板载 LED)
int Intensity = 0; // 光照度数值
void setup() // 程序初始化
{
pinMode(LED, OUTPUT); // 设置 LED 为输出模式
Serial.begin(9600); // 设置串口波特率 9600
}
void loop() // 程序主体循环
{
Intensity = analogRead(AD5); // 读取模拟口 A5 的 ADC 值(0~1023)
Serial.print("Intensity = ");
Serial.println(Intensity); // 串口输出数值,并换行
delay(500); // 延时 500ms
}
2.4 观察串口监视器
上传程序后,打开 Arduino IDE 的串口监视器(快捷键 Ctrl+Shift+M),波特率选 9600。
你会看到类似这样的输出:
Intensity = 720
Intensity = 715
Intensity = 312
Intensity = 298
Intensity = 680
- 用电筒照射光敏电阻 → 数值变大(或变小,取决于接线方式)
- 用手遮住光敏电阻 → 数值反向变化
analogRead() 返回的是 01023 之间的整数,对应 05V 的电压。这就是 Arduino 的 10 位 ADC(模拟数字转换器)。
三、项目二:串口控制舵机
3.1 什么是舵机?
舵机(Servo)是一种可以精确控制转角的电机。和普通直流电机不同,舵机内置了减速齿轮和反馈电路,可以转到指定角度并保持住。
常见规格:
| 类型 | 角度范围 | 典型型号 |
|---|---|---|
| 普通舵机 | 0° ~ 180° | SG90, MG90S |
| 数字舵机 | 0° ~ 180° | MG996R |
| 连续旋转舵机 | 360° 连续旋转 | 改装版 SG90 |
3.2 舵机引脚说明
舵机通常有三条线:
| 线色 | 功能 | 连接到 |
|---|---|---|
| 棕色 / 黑色 | 地线(GND) | Arduino GND |
| 红色 | 电源(VCC) | Arduino 5V |
| 橙色 / 白色 | 信号线(IN) | Arduino D9(PWM 引脚) |
注意:Arduino UNO 上标有
~符号的数字引脚才支持 PWM(脉冲宽度调制)。舵机的信号线必须接在 PWM 引脚上(D9 或 D10)。
3.3 接线方法
Arduino UNO
┌──────────┐
│ │
│ D9 ────┼──── 舵机信号线(橙色)
│ 5V ────┼──── 舵机电源线(红色)
│ GND ────┼──── 舵机地线(棕色)
│ │
└──────────┘
供电提醒:SG90 小舵机可以直接用 Arduino 的 5V 供电。但如果是 MG996R 等大电流舵机,建议单独供电,否则可能烧坏板子或导致重启。
3.4 程序代码
#include <Servo.h> // 引入舵机库
Servo myservo; // 创建舵机对象
char inByte = 0; // 串口接收的单个字符
int angle = 0; // 角度值
String temp = ""; // 临时字符串缓存
void setup()
{
myservo.attach(9); // 舵机信号线接 D9 引脚
Serial.begin(9600); // 设置串口波特率 9600
}
void loop()
{
// 判断串口是否有数据到达
while (Serial.available() > 0)
{
inByte = Serial.read(); // 一次读取一个字符
temp += inByte; // 拼接到临时字符串
}
if (temp != "") // 如果缓存不为空
{
angle = temp.toInt(); // 字符串转整数
Serial.print("角度: ");
Serial.println(angle); // 回显到串口,方便观察
}
temp = ""; // 清空缓存
myservo.write(angle); // 控制舵机转到指定角度
delay(100); // 延时 100ms,等待舵机到位
}
3.5 使用方法
- 上传程序后,打开串口监视器(波特率 9600)
- 输入一个 0 到 180 之间的数字,例如
90 - 点击发送
- 舵机会立即转到对应的角度
舵机的有效角度范围是 0° ~ 180°。超出范围的值可能被忽略或导致舵机抖动。
3.6 程序思路解析
这个程序的核心逻辑并不复杂:
- 引入库:
#include <Servo.h>—— Arduino 内置的舵机控制库 - 创建对象:
Servo myservo;—— 声明一个舵机实例 - 绑定引脚:
myservo.attach(9);—— 将舵机信号线绑定到 D9 - 读取串口:逐字符读取输入,拼成完整字符串
- 转换角度:
temp.toInt()将字符串转为整数 - 执行控制:
myservo.write(angle)让舵机转到目标角度
四、两个项目的知识点对比
| 知识点 | 项目一:光敏电阻 | 项目二:舵机控制 |
|---|---|---|
| 信号方向 | 输入(传感器 → Arduino) | 输出(Arduino → 执行器) |
| 引脚类型 | 模拟输入(A5) | 数字 PWM 输出(D9) |
| 核心函数 | analogRead() | myservo.write() |
| 通信方式 | 串口输出(调试观察) | 串口输入(控制指令) |
| 库的使用 | 无需额外库 | 需要 #include <Servo.h> |
做完这两个实验,你会发现 Arduino 编程的基本模式就是:读传感器 → 处理数据 → 驱动执行器。无论后面做更复杂的项目——智能小车、气象站、机械臂——底层逻辑都是一致的。
五、常见问题
Q:光敏电阻读数不变化? 检查分压电阻是否接好,确认光敏电阻没有短路。换一个阻值(1KΩ / 10KΩ)试试。
Q:舵机乱抖、不归位? 供电不足是最常见的原因。大舵机请单独供电,并注意共地。
Q:串口监视器乱码?
确认 Serial.begin() 的波特率与串口监视器设置一致(都是 9600)。
Q:舵机只能转到 0° 和 180°,中间角度不动? 检查是否输入了有效范围内的数字。某些廉价舵机的精度较差,小角度变化不明显。
六、下一步学什么?
完成这两个入门项目后,可以继续尝试:
- 把光敏电阻的读数映射到舵机角度(
map()函数),实现”光照越强,舵机转得越大” - 加一个 LCD 屏幕,把传感器数值显示出来
- 尝试 DHT11 温湿度传感器,学习单总线协议
- 学习 I2C / SPI 协议,接入更多高级传感器
Arduino 的世界很大,但入门的门槛确实不高。一块板子、几根线、几十行代码——你就能让硬件动起来。