采集光敏模块的AD数值
313.8、采集光敏模块的 AD 数值
void setup() { // 定义初始化函数;Arduino Uno 上电或复位后执行一次
pinMode(A0, INPUT); // 将 A0 明确设为高阻输入;保留视频最终上传代码中的写法
Serial.begin(115200); // 以 115200 bit/s 初始化串口,串口监视器必须选择相同波特率
} // setup() 初始化结束
void loop() { // 定义主循环;本函数结束后会从开头继续执行
int adc = analogRead(A0); // 对 A0 上的模拟电压进行一次 ADC 转换,并把 0~1023 的结果保存到 adc
Serial.println(adc); // 以十进制打印本次 ADC 结果,并在末尾发送换行符
delay(1500); // 阻塞等待 1500 ms,因此下一次采样约在 1.5 秒后进行
} // 本轮采样结束,随后再次进入 loop()
一、光敏电阻的使用
本节先用一只光敏电阻模块完成最小采样实验:模块的模拟输出 AO 接入 Arduino Uno 的 A0,程序每隔约 1.5 秒读取一次 ADC 转换结果并发送到串口监视器。视频实测表明,遮住光敏电阻后数值升高,用外部光源近距离照射后数值明显降低。
视频前端圆片状、带蛇形感光图案和两根引脚的器件才是光敏电阻本体。它是无正负极的两端无源电阻;蓝色电路板则是完整的光敏模块,在光敏电阻之外还集成了分压电阻、LM393 比较器、电位器和指示灯,因此模块排针具有 4 个引脚,并且 VCC、GND 不能接反。不要把“光敏电阻本体的两脚”和“模块的四针接口”混为一谈。
页首源码来自视频中最终编译、上传并实际运行的草图。课件预置代码曾写成 analogRead(right),但本节并没有定义 right;教师在 Arduino IDE 中实际输入和上传的是 analogRead(A0),因此不能把课件中的占位名称当成本节最终源码。
需要先区分两个外形很相近的名称:
AO中最后一个字符是字母 O,表示模块的 Analog Output(模拟输出)。A0中最后一个字符是数字 0,表示 Arduino Uno 的第 0 路模拟输入。- 信号路径是
光照 → 光敏电阻阻值 → AO 电压 → A0 → Uno 内部 ADC → 0~1023 的数字结果。AO端本身不会把模拟量转换成数字量,真正完成转换的是 Uno 内部 ADC。
1.1 代码编写
1.1.1 初始化部分
pinMode(A0, INPUT) 把 A0 明确设置为高阻输入。视频把 Uno 上的引脚模式概括为输入、输出和上拉输入;对本节使用的 AVR Uno 而言,对应常量是 INPUT、OUTPUT 和 INPUT_PULLUP。
不过,analogRead(A0) 并不依赖这句显式配置才能工作:Uno 复位后引脚默认为输入,Arduino 官方的 Analog Read Serial 示例也直接调用 analogRead(A0)。本节仍按视频原样保留 pinMode(A0, INPUT),它能表达“这一路只用于采样”的意图。不要改成 INPUT_PULLUP,否则内部上拉电阻会参与传感器分压并改变读数。
Serial.begin(115200) 设置串口传输速率。这里的 115200 是每秒传输的比特数(bit/s),串口监视器右下角也必须选择 115200 baud。原始笔记中的 125200 是识别错误,视频代码和监视器画面均为 115200。
1.1.2 循环采样与打印
程序在每一轮 loop() 中依次完成三件事:
analogRead(A0)启动一次模数转换,返回 A0 当前电压对应的 ADC 码。- 局部变量
adc保存结果;Uno 上的int足以容纳 0~1023。 Serial.println(adc)打印十进制数并换行,随后delay(1500)等待 1500 ms。
因此,串口监视器会逐行显示一个新数值。采样周期是“ADC 转换、串口发送等执行时间 + 1500 ms”,所以严格来说会略大于 1.5 秒,而不是精确的 1.500 秒。delay() 期间处理器不会继续执行本草图的其他循环业务;本节只有单路观察任务,这种阻塞写法足够演示,不能据此提前补写后续四路追光逻辑。
1.1.3 Uno 的模拟输入与 10 位 ADC
Arduino Uno R3 引出的模拟输入是 A0~A5,共 6 路,不是视频口述的“五路”。后续项目需要四只光敏模块,可以占用其中四路;本节只连接和读取 A0。
Uno 所用 ATmega328P 的 ADC 分辨率为 10 位,因此共有:
$ 2^{10}=1024\text{ 个量化码} $
这些码从 0 开始编号,所以 analogRead() 的返回范围是:
$ 0\sim 1023 $
“1024 个可能值”不等于“最大值为 1024”。原视频课件和口述中的“0~1024”以及后段误说的“$2^{14}$”都应修正:本板是 10 位 ADC、1024 个码、最大码 1023。
默认参考电压下,Uno 把接近 0 V 的输入转换为接近 0,把接近参考电压的输入转换为接近 1023。若以标称 5 V 为参考,一位最低有效位对应的理想电压步长约为:
$ \Delta V=\frac{V_{REF}}{1024}=\frac{5\text{ V}}{1024}\approx4.88\text{ mV} $
这只是 ADC 输入电压的量化结果,不是光照的 lux 值,也不是光敏电阻的欧姆值。供电与参考电压偏差、模块个体差异、安装角度和环境杂散光都会影响读数;追光项目更关心四个方向之间的相对差值。
1.1.4 AO、DO 和蓝色电位器
视频中的四针模块具有 VCC、GND、DO、AO:
| 引脚 | 信号类型 | 本节是否连接 | 作用 |
|---|---|---|---|
VCC | 电源 | 是,接 5V | 给分压电路、比较器和指示灯供电 |
GND | 电源参考 | 是,接 GND | 为电源和 AO 信号提供共同的零电位参考 |
AO | 连续模拟电压 | 是,接 A0 | 随光敏分压变化,由 Uno 的 ADC 采样 |
DO | 数字比较结果 | 否 | 只表示 AO 位于可调阈值的哪一侧,结果为高/低电平 |
蓝色电位器主要用于产生 LM393 比较器的参考电压,从而调节 DO 的翻转阈值,也就是“多亮时数字输出才改变”。它不会改变光敏电阻本身,也不是本节 AO → A0 采样链路的增益旋钮。换句话说,转动它通常会改变 DO 和状态指示灯在何时翻转,却不会按比例放大或缩小 analogRead(A0) 的连续数值。
模块上通常有两只指示灯:
- 电源指示灯在 VCC、GND 正确供电后保持点亮。
- 比较器状态灯跟随
DO的状态。视频所用模块在环境较亮时状态灯亮,遮挡光敏电阻后熄灭;其翻转点受电位器位置影响。其他版型若比较器输入或 LED 接法不同,亮灭极性也可能不同,应以对应原理图或实测为准。
1.2 接线教学
1.2.1 本节实际接线
本节只需三根线,DO 保持不接:
光敏电阻模块 Arduino Uno
┌────────────┐
│ VCC ├───────────────────── 5V
│ GND ├───────────────────── GND
│ AO ├───────────────────── A0
│ DO ├──── 本节悬空,不接
└────────────┘
建议断电后按照模块丝印逐根核对,不要只凭杜邦线颜色判断。GND 不只是“负极线”,还是 AO 与 A0 共同的电压参考;没有共地,A0 读数就不可靠。AO 只能接到允许的输入电压范围内,本实验由同一 5 V 系统供电,不要再把外部高于 5 V 或负电压直接送入 A0。
视频使用的是课程方加焊了多组 5V、GND 的 Uno 扩展排针。它们只是把同一电源网络复制到多个插口,便于后续连接四只模块,并不会生成彼此隔离的新电源,也不会提高 USB 或开发板能够提供的总电流。
1.2.2 为什么亮时数值反而更小
光敏电阻(LDR)通常表现为光越强、阻值越小;光越弱、阻值越大。结合本模块接法和视频实测,AO 所在的分压链路可简化为:
5V ── 固定电阻 ──┬── AO ──> Arduino A0
│
光敏电阻
│
GND
设固定电阻为 $R_F$、光敏电阻为 $R_{LDR}$,则:
$ V_{AO}=V_{CC}\times\frac{R_{LDR}}{R_F+R_{LDR}} $
由公式可直接得到本节观察到的关系:
| 环境变化 | $R_{LDR}$ | $V_{AO}$ | analogRead(A0) |
|---|---|---|---|
| 光线增强 | 变小 | 下降 | 数值减小 |
| 光线减弱或被遮挡 | 变大 | 上升 | 数值增大 |
这个方向来自本节模块的实际分压接法,并不是“所有光敏模块都必然亮时数值小”。如果另一款模块把光敏电阻和固定电阻上下互换,AO 的变化方向就会反过来;换模块后应先做遮挡和照射实验再编写判断逻辑。
1.2.3 上传与串口监视器
视频中的完整操作顺序为:
- 把模块 AO、GND、VCC 分别接到 Uno 的 A0、GND、5V。
- 用 USB 数据线连接电脑,在 Arduino IDE 中选择本机实际出现的 Uno 串口。
- 编译并上传页首草图。
- 打开串口监视器,把波特率设为
115200 baud。 - 先记录正常环境光读数,再遮住光敏电阻,最后用外部光源近距离照射,比较三种状态。
如果监视器出现乱码,应先检查监视器与 Serial.begin(115200) 是否一致;如果始终没有新行,应检查端口、上传状态和串口监视器连接;如果数值固定为 0 或 1023,则应检查 AO 是否误接 GND/5V、三根线是否插错,以及模块与 Uno 是否共地。
1.2.4 视频实测结果
视频画面可读到的代表性数据如下;这些是演示样机的现场读数,不是所有模块都必须达到的标准值:
| 测试状态 | 视频中的代表性 ADC 读数 | 现象 |
|---|---|---|
| 普通环境光 | 320、298、293、304,随后约 312~331 | AO 处于中间电压区间 |
| 用手遮挡 | 566、553、547、558 | 光线变弱,读数升高;状态灯熄灭 |
| 外部光源逐渐靠近 | 290、296、193、37、26 | 光线增强,读数显著降低 |
数值变化只能说明该模块在当前供电和安装条件下的相对明暗变化。它没有经过照度标定,不能把“26”直接写成 26 lux,也不能把“558”理解为光敏电阻是 558 Ω。
1.2.5 面向后续四路追光的注意点
- 本节只验证一路 A0;四路传感器的引脚定义、差值比较和舵机动作会在后续课程中编写,不能补入本节页首源码。
- 安装前应依次遮挡或照射每只模块,在串口中确认实际接线对应的上、下、左、右,不能只相信线色或标签。
- 四只模块存在个体偏差。即使受到相同光照,读数也可能不同;后续阈值应结合实物测试,而不是把本节的 300、500 或 26 当作固定标准。
- 做相对追光时,传感器之间应尽量采用相同供电、相近安装角度和一致遮光结构,否则比较结果会混入结构误差。
- 状态灯是否点亮来自
DO比较结果;本项目后续比较的是四路AO的 ADC 数值,两者不能混为一条控制信号。
核对依据
- 本地
videos/313.8、采集光敏模块的AD数值.mp4:逐帧核对最终上传代码、A0/5V/GND 三线连接、115200 baud串口设置、1.5 秒延时,以及环境光、遮挡和外部强光下的实际 ADC 数值与状态灯变化。 - 本地
transcripts/313.8、采集光敏模块的AD数值.txt与.srt:核对讲解顺序、四路传感器的项目用途和现场操作;结合视频画面纠正“五路”“0~1024”“$2^{14}$”“125200”等转录或口述错误。 - 本地配套
太阳能追光路灯.pptx、接线图.jpg与最终6.ino:只用于交叉核对模块四针定义、项目实际使用 AO 以及后续四路接口;本节源码仍严格以本节视频最终上传版本为准,没有提前补入追光程序。 - Arduino Uno R3 官方页面:核对 Uno R3 具有 6 路模拟输入。
- Arduino 官方 Analog Read Serial 示例:核对
analogRead(A0)的用法、0~1023 返回范围、默认 0~5 V 输入关系,以及官方示例无需先调用pinMode(A0, INPUT)。 - Microchip ATmega328P 官方资料:核对 Uno 主控 ADC 的 10 位分辨率。
- TI LM393 官方资料:核对模块所用比较器的开集电极输出性质;电位器、DO 与状态灯的具体连接仍以课程模块电路及本节实测为准。