第一章 所选主题和项目介绍
1.1 项目主题
可配置智能光调节系统——基于环境光照检测的闭环LED亮度控制系统
1.2 项目背景与意义
在日常生活和工业生产中,环境光照的稳定性对视觉舒适度和工作效率有着重要影响。传统照明系统采用固定亮度输出,无法根据外界环境光强变化自动调节,导致在环境光较强时LED照明浪费能源,而在环境光较暗时照明又显得不足。
本系统针对上述问题,切合任务智能家居的智能照明主题,设计了一套可配置的智能光调节系统。系统以光强传感器实时采集环境光照数据为核心,通过微控制器运行闭环控制算法,动态调节LED驱动器的PWM占空比,使照明区域的光强稳定在用户预设的目标值附近。该系统特别适用于台灯、展柜照明、阅读灯等场景,实现了"恒定舒适光照+节能"的双重目标。
1.3 主要功能指标
功能项 | 指标要求 |
环境光检测 | 0~200 lux可调目标值 |
LED输出控制 | 5串暖光LED,0~100%占空比可调 |
控制模式 | 自动模式(闭环调节)+手动模式(独立占空比控制) |
刷新频率 | 传感器100ms采样,控制周期50ms |
人机界面 | 240×240彩屏显示,4按键操作 |
PWM频率 | 20KHz(无可见频闪) |
第二章 硬件介绍
2.1 主控平台——十二指神针开发板

带屏版的12指神探,配备了一块240*240分辨率的LCD彩屏以及两个可程控按键和一个拨轮,丰富了人机交互功能,方便信息观察、界面切换等使用方式。此外还配备了白色外壳,精心设计的包装不仅使板卡日常使用时更加美观也便于板卡的站立以及使用安全。还配备配备了丰富的对外接口。
2.2 光强传感器——LTR-329
LTR-329ALS-01是Lite-On公司生产的环境光照传感器,采用I2C接口通信,默认地址为0x29(7-bit)。
关键特性:
- 光谱响应范围:可见光+近红外(400~700nm)
- 两路独立光敏二极管:CH0(可见光+IR)、CH1(仅IR)
- I2C接口,兼容标准I2C协议
- 内置ADC,支持多种量程和积分时间
- 工作电压:2.4V~3.6V
引脚定义:
引脚 | 功能 |
SCL | I2C时钟线 |
SDA | I2C数据线 |
INT | 中断输出(可选) |
ADD | I2C地址选择(接GND为0x29) |
2.3 LED驱动器——AP5724WG
AP5724WG是一款高效率升压型LED驱动器,专为串联LED灯串设计:
核心参数:
参数 | 数值 |
输入电压范围 | 2.7V~5.5V |
输出电压范围 | 最高30V |
最大输出电流 | 1A |
开关频率 | 1MHz |
PWM调光频率 | 可达100KHz |
效率 | 最高92% |
调光原理: AP5724WG内置PWM调光引脚(DIM),通过在该引脚输入PWM信号,以PWM占空比控制输出电流大小,从而实现LED亮度调节。当PWM占空比为100%时输出全电流,0%时关闭输出。
2.6 硬件架构总览

第三章 方案框图和项目设计思路
3.1 系统整体框图

3.2 设计思路
3.2.1 闭环控制原理
本系统的核心设计基于负反馈闭环控制原理:
- 采样阶段:LTR-329传感器周期性采样环境光照值(100ms间隔)
- 比较阶段:将实测光照值与用户设定的目标光照进行比较,得到偏差值
- 调节阶段:根据偏差方向和大小,通过简单比例控制算法调节PWM占空比
- 执行阶段:PWM信号输入AP5724WG的DIM引脚,控制LED电流实现亮度调节
3.2.2 控制算法选择
考虑到光照变化响应速度和稳定性要求,本系统采用增量式比例控制(P控制):
PWM(n) = PWM(n-1) + Kp × diff (当 |diff| > 阈值)
其中:
- diff = Target_Lux - Actual_Lux
- Kp = 0.5(比例系数)
- 阈值 = 5 lux(避免频繁调节)
该算法优点:
- 实现简单,计算资源占用低
- 响应速度快,无超调
- 参数少,易调谐
3.2.3 双模式设计
为满足不同使用场景需求,系统设计两种工作模式:
模式 | 说明 | 适用场景 |
自动模式(AUTO) | 闭环控制,根据环境光自动调节LED亮度 | 日常使用,恒定光照 |
手动模式(MANUAL) | 用户直接设定PWM占空比 | 特殊照明需求、调试 |
3.3 关键设计考量
3.3.1 PWM频率设计(20KHz)
选择20KHz PWM频率的原因:
- 规避可闻频闪:人类听觉范围约20Hz~20KHz,高于20KHz的PWM不会产生噪音
- AP5724WG兼容性:该芯片支持最高100KHz PWM调光,20KHz完全满足要求
- 微控制器资源平衡:在保证无频闪的前提下,选择较低的20KHz可减少开关损耗和发热
3.3.2 I2C地址确定
通过分析Adafruit LTR329/LTR303驱动程序,确认LTR-329的I2C地址为0x29(7-bit格式)。这一地址在驱动程序的宏定义中明确给出:
#define LTR329_I2CADDR_DEFAULT 0x29
3.3.3 LTR-329数据寄存器布局
根据官方datasheet,LTR-329数据寄存器布局如下:
寄存器地址 | 功能 | 数据长度 |
0x88 | CH1低字节 | 1字节 |
0x89 | CH1高字节 | 1字节 |
0x8A | CH0低字节 | 1字节 |
0x8B | CH0高字节 | 1字节 |
I2C读取时,从0x88起始连续读取4字节,顺序为:CH1_LOW, CH1_HIGH, CH0_LOW, CH0_HIGH。
第四章 原理图和PCB设计
LED驱动板

原理图
PCB
3D效果图
第五章 软件设计
主程序流程图

关键代码分析
LTR-329驱动程序
class LTR329:
def __init__(self, i2c, addr=LTR329_ADDR):
self.i2c = i2c
self.addr = addr
self._last_lux = 0
def begin(self):
self.i2c.writeto(self.addr, bytes([LTR329_ALS_CTRL, 0x01]))
utime.sleep_ms(10)
self.i2c.writeto(self.addr, bytes([LTR329_MEAS_RATE, 0x02]))
utime.sleep_ms(10)
return True
def read_als(self):
data = self.i2c.readfrom_mem(self.addr, LTR329_CH1DATA, 4)
ch0 = data[2] | (data[3] << 8) # 可见光+IR通道
ch1 = data[0] | (data[1] << 8) # 仅IR通道
if ch0 == 0 or ch1 == 0:
return self._last_lux # 无效数据返回缓存值
self._last_lux = self._calc_lux(ch0, ch1)
return self._last_lux
def _calc_lux(self, ch0, ch1):
"""根据两通道数据计算光照度"""
ratio = ch1 / (ch0 + ch1)
if ratio < 0.45:
return int(1.1423 * ch0 - 0.2248 * ch1)
elif ratio < 0.64:
return int(0.6818 * ch0 - 0.1333 * ch1)
else:
return int(0.3869 * ch0 + 0.0429 * ch1)
代码解析:
- _last_lux 缓存机制解决了I2C读取瞬间返回0的问题,避免显示跳变
- 0x88寄存器连续4字节读取,按小端序解析CH1和CH0
- 三段式lux计算公式对应不同光比区间
按键扫描(带软件去抖)
def read_buttons():
def check_btn(pin, last):
curr = pin.value()
if curr != last:
last = curr
return (curr == 0, last) # 按下瞬间返回True
return (False, last)
c, btn_confirm_last = check_btn(confirm_btn, btn_confirm_last)
r, btn_return_last = check_btn(return_btn, btn_return_last)
u, btn_up_last = check_btn(up_btn, btn_up_last)
d, btn_down_last = check_btn(down_btn, btn_down_last)
m, btn_center_last = check_btn(center_btn, btn_center_last)
return c, r, u, d, m
去抖原理: 仅在电平变化瞬间(按下或释放)返回按键事件,之后保持稳定。这种方式自然实现了软件去抖,无需延时等待。
自动调光算法
def auto_adjust_light():
global CURRENT_BRIGHTNESS
if not AUTO_MODE:
return
lux = als_sensor.read_als()
diff = TARGET_LUX - lux
if abs(diff) > 5: # 阈值5 lux,避免频繁调节
if diff > 0:
new_brightness = min(100, CURRENT_BRIGHTNESS + 5)
else:
new_brightness = max(0, CURRENT_BRIGHTNESS - 5)
set_brightness(new_brightness)
def set_brightness(value):
duty = int(value * 65535 / 100) # 16位PWM
pwm.duty_u16(duty)
CURRENT_BRIGHTNESS = value
算法特点:
- 阈值控制:|diff|>5才调节,避免小幅震荡
- 增量调节:每次±5%,避免调节过快
- 边界限制:0~100%占空比限制
差量显示刷新
_cache = {
'lux': None,
'target_lux': None,
'brightness': None,
'mode': None,
}
def update_run_display():
lux = als_sensor.read_als()
brightness = int(pwm.duty_u16() * 100 / 65535)
if _cache['lux'] != lux:
display.fill_rect(100, 50, 120, 18, COLOR_BG)
display.text(font1, "%d lux" % lux, 100, 52, COLOR_WHITE)
_cache['lux'] = lux
# ... 类似处理其他字段
优化效果: 仅当数值实际变化时才更新显示区域,减少屏幕刷新次数,降低闪烁。
第六章 硬件功能展示
系统组装实物图

自动调节效果测试

页面效果:

第七章 设计中的难题与解决方法
LTR-329数据跳变问题
问题现象:
环境光强数值在0和其他数值之间反复跳变,无法稳定显示。
问题分析:
- 传感器内部数据更新需要时间
- 直接读取可能导致读取到无效中间值
- 当通道数据为0时返回0lux,但下次可能读到正常值
解决方案:
- 添加 _last_lux 缓存机制
- 当通道数据为0时返回缓存的上次有效值
- 移除不可靠的 new_data_available() 检查
if ch0 == 0 or ch1 == 0:
return self._last_lux # 无效数据返回缓存值
第八章 心得体会
本次可配置智能光调节系统的设计,从需求分析到方案制定,从硬件连接到软件实现,我们完成了从概念到原型的完整开发流程。系统的核心价值在于:通过实时检测环境光照并闭环调节LED输出,实现了"恒定舒适光照+节能"的双重目标。 自动模式下,系统能够自动适应环境光变化,维持稳定的阅读或工作光照;手动模式下,用户可完全自定义照明效果。在实现过程中,我们遇到了I2C地址错误、数据跳变、按键去抖等典型问题,通过查阅官方文档、参考开源驱动代码、不断调试优化,最终解决了所有技术难点。这些经验将为后续嵌入式项目开发打下坚实基础。