树莓派Pico光敏电阻应用:从ADC读取到智能光控实战

发布时间:2026/8/19 7:07:49

树莓派Pico光敏电阻应用:从ADC读取到智能光控实战
1. 项目缘起为什么用Pico玩LDR如果你手头有一块树莓派Pico又恰好对光线敏感的应用感兴趣比如想做个自动小夜灯、植物光照监测仪或者一个简单的光控开关那么用光敏电阻LDR来入门模拟信号采集绝对是个经典又实用的选择。我最近在整理工作室的传感器模块时翻出了几个LDR正好手边有闲置的Pico就顺手搭了个电路把整个从硬件连接到软件编程再到数据校准和实际应用的过程重新走了一遍。这个过程看似简单但里面有不少细节比如如何正确读取那个“飘忽不定”的模拟值、怎么处理环境光的非线性变化以及如何让代码既稳定又高效都是新手容易踩坑的地方。这篇文章我就以一个老电子爱好者的视角带你从头到尾、扎扎实实地实现一个基于树莓派Pico的LDR传感器系统并分享一些我实测中总结出来的、数据手册上不会写的经验。LDR或者说光敏电阻它的核心特性是电阻值会随着光照强度的增强而降低。在Pico的世界里我们无法直接测量电阻但可以通过一个简单的分压电路将这个变化的电阻转化为Pico的ADC模数转换器可以读取的电压变化。Pico内置的ADC分辨率是12位意味着它能把0到3.3V的电压分成4096个等级0-4095这个精度对于很多光照相关的应用来说已经绰绰有余。整个项目的核心逻辑就是搭建电路 - 编程读取ADC值 - 将ADC值映射为有实际意义的光照强度或状态 - 触发相应的控制逻辑。下面我们就从硬件准备开始一步步拆解。2. 硬件搭建分压电路与引脚选择硬件连接是整个项目的地基连接方式直接决定了数据的稳定性和准确性。对于LDR最经典、最可靠的电路就是串联一个固定电阻构成分压电路。2.1 元器件清单与电路原理你需要准备的东西很简单树莓派Pico一块任何版本均可Pico W同样适用。光敏电阻LDR一个。固定电阻一个阻值我强烈推荐使用10kΩ。这是经过多次测试后平衡灵敏度与量程的最佳选择。面包板、杜邦线若干。为什么是10kΩ这需要一点计算。LDR的阻值范围很宽在完全黑暗下可能高达1MΩ甚至更高在强光下可能只有几百欧姆。如果我们选择一个太大的固定电阻比如100kΩ在光线稍强时LDR电阻变得很小分压点电压会接近0VADC读数会很小导致在明亮环境下分辨率不足。如果选择一个太小的固定电阻比如1kΩ在黑暗时LDR电阻很大分压点电压会接近3.3VADC读数会很大但在黑暗区的变化就不明显了。10kΩ是一个折中的选择它能让LDR在常见室内光照范围几百勒克斯到几千勒克斯内其分压点电压大致落在ADC量程的中间区域从而获得最佳的测量分辨率和动态范围。电路连接如下图所示文字描述将Pico的3V3(OUT)引脚连接到面包板的正极电源轨。将Pico的GND引脚连接到面包板的负极电源轨。将LDR的一端连接到正极电源轨3.3V。将LDR的另一端连接到固定电阻10kΩ的一端。这个连接点就是我们关键的信号测量点。将固定电阻10kΩ的另一端连接到负极电源轨GND。最后从那个信号测量点LDR和10kΩ电阻的连接处引出一根线连接到Pico的任何一个ADC引脚。Pico的GP26、GP27、GP28引脚都连接到了ADC我习惯使用GP26它对应着ADC0。注意务必确保LDR和固定电阻的连接顺序是“3.3V - LDR - 测量点 - 10kΩ电阻 - GND”。如果接反了逻辑会完全颠倒越亮读数越小虽然可以通过软件修正但按标准接法更直观。2.2 引脚选择与ADC通道确认树莓派Pico有3个专用的ADC引脚GP26、GP27、GP28分别对应ADC0、ADC1、ADC2。还有一个ADC通道ADC3连接内部温度传感器ADC4连接VSYS。对于我们这个项目使用GP26ADC0就足够了。在软件中我们需要初始化的就是这个ADC通道。硬件连接完成后建议先用万用表测量一下“信号测量点”对地的电压用手遮挡LDR看看电压是否在0~3.3V之间变化用手电筒照射时电压是否显著下降。这个简单的验证可以排除硬件连接错误后续调试软件时会省去很多麻烦。3. 软件编程从读取原始值到数据平滑硬件就绪后我们进入软件部分。我将使用MicroPython进行编程因为它对新手友好交互性强。确保你的Pico已经刷入了最新的MicroPython固件。3.1 基础代码读取原始ADC值首先我们写一个最简单的程序每秒打印一次ADC的原始读数。from machine import ADC, Pin import time # 初始化ADC引脚连接在GP26 (ADC0) ldr ADC(Pin(26)) # 循环读取并打印 while True: # 读取原始ADC值范围0-65535这里有个坑 raw_value ldr.read_u16() print(Raw ADC Value:, raw_value) time.sleep(1)把这段代码保存为main.py上传到Pico运行你会看到一串数字在跳动。但是你可能会立刻发现一个问题为什么读数范围是0-65535不是说好的12位ADC0-4095吗这是一个非常关键的细节在MicroPython的ADC类中read_u16()方法返回的是一个16位无符号整数但它并不是直接把12位的ADC结果左移4位。为了提供更好的兼容性和分辨率感觉MicroPython的底层驱动默认将ADC读数缩放到了0-65535的范围。也就是说即使ADC硬件只有12位read_u16()返回的值也会在0到65535之间变化。这一点务必牢记它是我们后续所有计算的基础。如果你用read_u16()读取3.3V得到的值会非常接近65535。3.2 数据平滑对抗噪声与抖动直接打印原始值你会发现即使光线稳定数值也在一定范围内上下跳动这是电子电路固有的噪声和ADC的量化误差。为了得到更稳定、可用的数据我们必须对数据进行平滑处理。最常用且有效的方法是移动平均滤波。from machine import ADC, Pin import time ldr ADC(Pin(26)) # 定义采样窗口大小 window_size 10 readings [] while True: # 采集一个瞬时值 current_reading ldr.read_u16() # 将新值加入列表 readings.append(current_reading) # 保持列表长度不超过窗口大小 if len(readings) window_size: readings.pop(0) # 移除最旧的一个值 # 计算窗口内平均值 smoothed_value sum(readings) / len(readings) print(Raw: {:5d} | Smoothed: {:8.2f}.format(current_reading, smoothed_value)) time.sleep(0.1) # 加快采样频率以平滑这段代码维护了一个固定长度例如10的读数列表。每次循环它加入一个新的读数并去掉最旧的一个然后计算列表的平均值。这个smoothed_value就比单个原始值稳定得多。window_size可以根据需要调整越大越平滑但响应速度越慢通常5-20之间是个不错的选择。3.3 电压换算与光照状态判断有了平滑后的ADC值我们可以把它换算成实际的电压这对于调试和理解电路状态非常有帮助。换算公式基于read_u16()的0-65535对应0-3.3V。# 在循环内计算平滑值之后 voltage (smoothed_value / 65535) * 3.3 print(Voltage: {:.2f} V.format(voltage))更常见的是我们不需要精确的照度值那需要经过严格校准的照度计而是判断一个相对的光照状态比如“黑暗”、“昏暗”、“正常”、“明亮”。我们可以通过实验设定几个阈值。# 定义阈值基于read_u16()的值需要根据实际环境调整 DARK_THRESHOLD 15000 # 低于此值认为黑暗 DIM_THRESHOLD 30000 # 低于此值认为昏暗 BRIGHT_THRESHOLD 50000 # 高于此值认为明亮 while True: # ... 计算 smoothed_value ... if smoothed_value DARK_THRESHOLD: light_state Dark elif smoothed_value DIM_THRESHOLD: light_state Dim elif smoothed_value BRIGHT_THRESHOLD: light_state Normal else: light_state Bright print(State: {:7s} | Value: {:8.2f}.format(light_state, smoothed_value)) time.sleep(0.5)如何确定这些阈值这就是需要动手实验的地方。在目标环境下分别记录LDR在完全遮盖黑暗、夜晚室内昏暗、白天室内正常、台灯直射明亮时的平滑ADC值取一个中间范围作为阈值。记住这些阈值是和你使用的特定LDR、固定电阻值以及环境息息相关的。4. 进阶应用实现一个智能光控夜灯掌握了基础读取和判断后我们可以做一个有趣的应用一个智能光控夜灯。当环境光变暗时自动打开Pico板载的LEDGP25当环境光变亮时自动关闭。4.1 完整代码实现这里我们引入一个“迟滞”比较防止光线在阈值附近波动时LED频繁开关。from machine import ADC, Pin import time # 初始化 ldr ADC(Pin(26)) led Pin(25, Pin.OUT) # Pico板载LED window_size 10 readings [] # 阈值与迟滞 LIGHT_THRESHOLD 20000 # 判断暗的阈值 HYSTERESIS 3000 # 迟滞范围 led_state False # 当前LED状态默认关闭 def get_smoothed_adc(): 获取平滑后的ADC值 global readings current ldr.read_u16() readings.append(current) if len(readings) window_size: readings.pop(0) if len(readings) 0: return current return sum(readings) / len(readings) while True: avg_adc get_smoothed_adc() # 带迟滞的逻辑判断 if not led_state and avg_adc LIGHT_THRESHOLD: # 当前LED关且光线变暗低于阈值则开灯 led.value(1) led_state True print(Light ON - ADC: {:.0f}.format(avg_adc)) elif led_state and avg_adc (LIGHT_THRESHOLD HYSTERESIS): # 当前LED开且光线变亮高于阈值迟滞则关灯 led.value(0) led_state False print(Light OFF - ADC: {:.0f}.format(avg_adc)) time.sleep(0.2) # 主循环延迟迟滞Hysteresis是关键。它创建了一个“关灯阈值”LIGHT_THRESHOLD HYSTERESIS比“开灯阈值”LIGHT_THRESHOLD更高。这意味着从亮变暗时需要低于20000才开灯而从暗变亮时需要高于23000才关灯。中间的3000就是缓冲区域有效避免了阈值附近的抖动。4.2 优化与扩展PWM调光你可以不让LED只是简单的开关而是使用PWM脉宽调制让LED的亮度随着环境光变暗的程度而平滑增加。这需要将LED引脚初始化为PWM并根据ADC值计算PWM占空比。from machine import PWM pwm_led PWM(Pin(25)) pwm_led.freq(1000) # 设置PWM频率为1kHz # 在循环中将ADC值映射到PWM范围例如0-20000 brightness int((65535 - avg_adc) / 65535 * 20000) # 光线越暗亮度值越大 brightness max(0, min(20000, brightness)) # 限制在0-20000范围内 pwm_led.duty_u16(brightness)网络功能Pico W如果你用的是Pico W可以将光照状态通过Wi-Fi发送到服务器如MQTT broker或Web页面实现远程监控。甚至可以接收网络指令手动覆盖自动控制。数据记录将ADC值和时间戳写入Pico的存储空间用于长期记录光照变化分析日照规律。5. 实测中的陷阱与深度优化前面走通了基本流程但要想做出稳定可靠的项目还得聊聊我踩过的坑和总结的优化技巧。5.1 ADC参考电压的波动Pico的ADC参考电压默认是供电电压VSYS通过内部LDO降压到3.3V给ADC_REF。如果你的Pico是通过USB供电且USB电源质量一般或者板上其他电路耗电变化大这个3.3V可能会轻微波动导致ADC读数不准。解决方案是使用Pico内部相对稳定的参考源。虽然MicroPython没有直接提供切换ADC参考电压的API但我们可以通过测量一个已知稳定的电压例如通过一个分压电阻从3.3V分出的一个固定电压来反向校准。更根本的办法是对于精度要求高的场合考虑使用外部基准电压源芯片。5.2 LDR的响应速度与非线性LDR的响应速度较慢尤其是从亮到暗的恢复过程。这意味着它不适合检测快速的光线变化比如脉冲光。它的阻值与照度关系也呈非线性通常近似于对数关系。这意味着在低照度区ADC值变化很敏感在高照度区ADC值变化很迟钝。如果你需要近似线性的输出可以在软件里做一个简单的映射表或者使用指数/对数函数进行补偿。# 一个简单的线性化尝试示例需根据实际传感器特性校准 def linearize_adc(raw_adc): # 假设我们通过实验得到几个点(dark_adc, dark_lux), (bright_adc, bright_lux) # 这里进行线性插值 dark_adc, dark_lux 5000, 10 bright_adc, bright_lux 60000, 1000 # 防止超出范围 raw_adc max(dark_adc, min(bright_adc, raw_adc)) # 线性映射 estimated_lux dark_lux (bright_lux - dark_lux) * ((raw_adc - dark_adc) / (bright_adc - dark_adc)) return estimated_lux5.3 电源噪声与滤波电容在面包板搭建的电路中电源线和信号线很容易引入噪声。一个立竿见影的改善措施是在LDR分压电路的信号测量点GP26引脚到地GND之间并联一个0.1uF104的陶瓷电容。这个电容可以吸收高频噪声使ADC读取的电压更稳定。你会立刻看到原始ADC值的跳动范围显著减小。5.4 代码效率与低功耗优化如果你的项目是电池供电那么功耗就至关重要。我们的主循环中使用了time.sleep(0.2)这期间CPU仍在运行消耗能量。更优的做法是使用machine.lightsleep()或machine.deepsleep()并在GP26上配置中断唤醒但ADC引脚唤醒支持有限需查手册。降低ADC采样频率。对于光照变化这种慢速信号每秒采样1-2次都足够了。关闭不必要的外设如Pico W的Wi-Fi。一个简单的低功耗模式示例非深度睡眠import machine import time ldr machine.ADC(26) led machine.Pin(25, machine.Pin.OUT) # 主循环间隔延长到5秒 while True: value ldr.read_u16() if value 20000: led.on() else: led.off() # 长时间休眠大幅降低平均功耗 time.sleep(5)6. 从LDR到“Sensor Fusion”的遐想虽然本项目只用了LDR一个传感器但关键词里提到了“sensor fusion ros2”这指向了一个更宏大的概念传感器融合。即使不用ROS2我们也可以在Pico上实践简单的融合思想。例如结合一个DHT11温湿度传感器。设想一个智能花园小系统LDR监测光照DHT11监测温湿度。单独的判断可能是“光线不足需要补光”或“温度太高需要报警”。但融合判断可以更智能规则1如果光照充足但温度过低可能是晴朗的夜晚植物有冻伤风险需启动加热器。规则2如果光照不足且湿度过高可能是连续的阴雨天需要额外补光并提醒减少浇水。在Pico上实现这样的多传感器逻辑无非是初始化多个传感器在循环中读取各自的数据然后在一个集中的决策函数里编写这些if-elif规则。代码结构会变得更有条理将数据采集、数据处理、逻辑决策分层。# 伪代码结构示意 class GardenMonitor: def __init__(self): self.ldr ADC(Pin(26)) self.dht DHT11(Pin(15)) self.light_state None self.temp None self.humidity None def read_sensors(self): self.light_state self._get_light_state() self.temp, self.humidity self.dht.read() def _get_light_state(self): # ... 平滑和判断光照状态的逻辑 ... pass def make_decision(self): if self.light_state Bright and self.temp 15: return RISK: Sunny but cold, watch for frost. elif self.light_state Dark and self.humidity 80: return ACTION: Low light high humidity, reduce watering. else: return Status Normal def run(self): while True: self.read_sensors() decision self.make_decision() print(decision) time.sleep(10)通过这个例子你会发现即便是一个简单的LDR项目其思维模式可以很自然地扩展到更复杂的物联网应用中。硬件连接是筋骨数据采集是血液而逻辑与算法才是赋予项目智能的灵魂。从读取一个跳动的数字到让它成为自动控制系统的可靠“眼睛”这个过程里对硬件特性的理解、对软件稳定性的追求、对实际应用场景的思考才是嵌入式开发中最有魅力的部分。

相关新闻

3步让Mac读写NTFS硬盘:免费工具Nigate实战通关指南

3步让Mac读写NTFS硬盘:免费工具Nigate实战通关指南

2026/8/19 7:07:49

3步让Mac读写NTFS硬盘:免费工具Nigate实战通关指南 【免费下载链接】Free-NTFS-for-Mac Nigate: An open-source NTFS utility for Mac. It supports all Mac models (Intel and Apple Silicon), providing full read-write access, mounting, and management for N…

TEL 3M80-003864-13 PCB 板组件

TEL 3M80-003864-13 PCB 板组件

2026/8/19 6:57:49

TEL 3M80-003864-13 PCB 板组件 产品简介TEL 3M80-003864-13 是东京电子(TEL)半导体设备专用的PCB板组件,作为设备内部电路系统的关键组成单元,主要用于信号连接、电源分配及模块间的电气互联。产品参数产品型号:TEL 3…

PHOTON G29386-4021-002 驱动器模拟板

PHOTON G29386-4021-002 驱动器模拟板

2026/8/19 6:57:49

PHOTON G29386-4021-002 驱动器模拟板 产品简介PHOTON G29386-4021-002 是光子(PHOTON)公司推出的一款驱动器模拟板,主要用于工业驱动系统中的模拟信号处理与驱动控制,实现控制系统与执行单元之间的信号转换与精确驱动。产品参数产…

多智能体协同避障:基于到达时间分离与安全滤波的分布式解决方案

多智能体协同避障:基于到达时间分离与安全滤波的分布式解决方案

2026/8/19 7:47:51

1. 项目概述:多智能体协同中的“安全、公平与效率”三角难题 在机器人、自动驾驶、无人机集群、工业自动化等前沿领域,多智能体协同正从实验室走向现实应用。然而,当多个自主系统在同一物理空间内运行时,一个核心的、令人头疼的矛…

从HC-SR04到实时状态显示:超声波测距仪的系统设计与实现

从HC-SR04到实时状态显示:超声波测距仪的系统设计与实现

2026/8/19 7:47:51

1. 项目概述:超声波测距仪与实时状态显示 如果你玩过Arduino,大概率会接触过超声波传感器,它几乎是所有入门项目的“标配”元件之一。但大多数教程止步于串口打印一个距离数值,这离一个真正“可用”的设备还差得远。今天我想分享的…

基于LLM的智能SZZ算法:AgentSZZ框架实现Bug引入提交精准定位

基于LLM的智能SZZ算法:AgentSZZ框架实现Bug引入提交精准定位

2026/8/19 7:47:51

1. 项目概述:当LLM化身代码侦探在软件开发的日常里,定位一个Bug的引入点,也就是找到那行“罪魁祸首”的代码变更,是件既关键又头疼的事。传统的git blame命令能告诉你某行代码最后一次被谁修改,但它无法区分这次修改是…

MDA方法:用结构化推理流程让中等大模型媲美顶级模型

MDA方法:用结构化推理流程让中等大模型媲美顶级模型

2026/8/19 7:47:51

1. 先搞清楚 MDA 到底是什么,以及它为什么能“追平”顶级模型看到“MDA让LLM提假设,8次实验追平Opus 4.7”这个标题,很多人的第一反应可能是:这又是一个新的、更强大的开源模型吗?或者是一个全新的训练框架&#xff1f…

华为eNSP安装配置全攻略:从零搭建稳定网络实验环境

华为eNSP安装配置全攻略:从零搭建稳定网络实验环境

2026/8/19 7:47:51

很多网络工程师和在校学生在学习华为网络技术时,都会遇到一个共同的“拦路虎”——eNSP的安装与配置。从官网下载困难、安装包不完整,到各种驱动报错、设备启动失败,每一步都可能让人耗费数小时甚至几天。网上资料虽然多,但往往零…

基于Arduino与步进电机的迪斯科球自动贩卖机设计与实现

基于Arduino与步进电机的迪斯科球自动贩卖机设计与实现

2026/8/19 7:37:51

1. 项目概述:当迪斯科球遇上自动贩卖机如果你和我一样,是个喜欢在家里搞点小派对,或者对复古、创意小玩意儿情有独钟的人,那你肯定对迪斯科球不陌生。那个在灯光下旋转、反射出无数光斑的小球,几乎是七八十年代派对氛围…

【文章复现】非线性值迭代自适应动态规划(ADP):离散时间非线性系统的策略迭代自适应动态规划算法研究附Matlab代码

【文章复现】非线性值迭代自适应动态规划(ADP):离散时间非线性系统的策略迭代自适应动态规划算法研究附Matlab代码

2026/8/19 3:36:59

✅作者简介:热爱科研的Matlab仿真开发者,擅长毕业设计辅导、数学建模、数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。🍎 往期回顾关注个人主页:Matlab科研工作室👇 关注我领取海量matlab电子书和…

【双层规划,节点出清价,绿证交易,CVaR方法】两级电力市场环境下计及风险的省间交易商最优购电模型附Matlab代码

【双层规划,节点出清价,绿证交易,CVaR方法】两级电力市场环境下计及风险的省间交易商最优购电模型附Matlab代码

2026/8/18 1:03:22

✅作者简介:热爱科研的Matlab仿真开发者,擅长毕业设计辅导、数学建模、数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。🍎 往期回顾关注个人主页:Matlab科研工作室👇 关注我领取海量matlab电子书和…

隐式mpc+自适应mpc+时变mpc,线性时变模型预测控制附Simulink仿真

隐式mpc+自适应mpc+时变mpc,线性时变模型预测控制附Simulink仿真

2026/8/17 8:40:51

✅作者简介:热爱科研的Matlab仿真开发者,擅长毕业设计辅导、数学建模、数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。🍎 往期回顾关注个人主页:Matlab科研工作室👇 关注我领取海量matlab电子书和…

SQL 调优 [ 2 ]

SQL 调优 [ 2 ]

2026/8/19 0:07:32

type列详解EXPLAIN输出的type列描述了表是如何连接的,性能从最好到最差的排序如下:systemconsteq_refreffulltextref_or_nullindex_mergeunique_subqueryindex_subqueryrangeindexALL接下来我们对 type列 做详细讲解。我们都知道,想要评估一条…

正式评优怎么选投票工具?人人微投票审计级防刷能力实测

正式评优怎么选投票工具?人人微投票审计级防刷能力实测

2026/8/19 0:07:32

在线上投票工具遍地开花的今天,选择一个合适的平台,本质上是在做一道关于场景与需求的匹配题。人人微投票是一个很典型的案例——它的产品逻辑、技术架构和商业模式,都围绕着“正式评选”这个细分场景深度扎根,也因此形成了自己鲜…

15 天 3 连发:DeepSeek 的「机枪」节奏,到底在下什么棋?

15 天 3 连发:DeepSeek 的「机枪」节奏,到底在下什么棋?

2026/8/19 0:07:32

15 天 3 连发:DeepSeek 的「机枪」节奏,到底在下什么棋?回看 2026 年 8 月这半个月,DeepSeek 的动作密度堪称疯狂:月初端出便宜快速的 V4-Flash,8 月 13 日同一天甩出 V4-Pro 正式版 开源 Harness 框架&am…

摆脱论文困扰!盘点2026年全网爆红的的AI论文写作工具

摆脱论文困扰!盘点2026年全网爆红的的AI论文写作工具

2026/8/17 12:00:53

一天写完毕业论文在2026年已不再是天方夜谭。2026年最炸裂、实测能大幅提速的AI论文写作工具,覆盖选题构思、文献整理、内容生成、格式排版等核心场景,真正帮你高效搞定论文难题。 一、全流程王者:一站式搞定论文全链路(一天定稿首…

导师推荐!2026最新AI论文工具测评与实用推荐

导师推荐!2026最新AI论文工具测评与实用推荐

2026/8/15 10:10:27

2026年真正好用的AI论文工具,核心看生成的论文质量、低AI味、格式正确、学术适配四大指标。综合实测,千笔AI、ThouPen、豆包、DeepSeek、Grammarly 是当前最值得推荐的梯队,覆盖从免费到付费、从中文到英文、从文科到理工的全场景需求。 一、…

告别游戏崩溃:XCOM 2模组管理器的智能革命

告别游戏崩溃:XCOM 2模组管理器的智能革命

2026/8/18 12:20:24

告别游戏崩溃:XCOM 2模组管理器的智能革命 【免费下载链接】xcom2-launcher The Alternative Mod Launcher (AML) is a replacement for the default game launchers from XCOM 2 and XCOM Chimera Squad. 项目地址: https://gitcode.com/gh_mirrors/xc/xcom2-lau…