3. 视觉基础
做亮度测量,第一步就是选对传感器。我这些年用过不少环境光传感器,从最早的分立式光敏电阻,到后来的数字集成传感器,体验差别非常大。今天咱们重点聊两款经典芯片——BH1750 和 TSL2561,顺便把 I²C 通信协议的基础捋一遍。
3.1 为什么选数字环境光传感器?
早些年做项目,很多人用光敏电阻加 ADC 的方案。说实话,那玩意儿精度差、一致性差,还得自己做校准曲线。后来我接触到数字环境光传感器,才发现什么叫「省心」。数字传感器内部集成了光电二极管、放大器和 ADC,直接输出 lux 值,你通过 I²C 或 SMBus 读寄存器就行。
核心优势: 数字输出、无需校准、低功耗、小封装、光谱响应接近人眼。
3.2 BH1750:入门首选
BH1750 是罗姆半导体(ROHM)的产品。我个人习惯把它叫做「傻瓜式传感器」——为什么?因为它太容易用了。
主要参数
| 参数 | 值 |
|---|---|
| 测量范围 | 1 ~ 65535 lux |
| 分辨率 | 1 lux(高分辨率模式下可达 0.5 lux) |
| 接口 | I²C(地址 0x23 或 0x5C) |
| 工作电压 | 2.4V ~ 3.6V |
| 功耗 | 典型 0.12 mA |
BH1750 内部有 16 位 ADC,直接输出数字光照强度。你想想看,不用算公式、不用查表,读两个字节就完事了。我在一个智能台灯项目里用过它,效果非常稳定。
典型电路连接
BH1750 MCU (如 ESP32/Arduino)
VCC → 3.3V
GND → GND
SCL → GPIO22 (SCL)
SDA → GPIO21 (SDA)
ADDR → GND (地址 0x23) 或 VCC (地址 0x5C)
小技巧: ADDR 引脚接地时 I²C 地址为 0x23,接 VCC 时为 0x5C。如果你需要挂多个传感器,这个功能很实用。
3.3 TSL2561:更灵活的选择
TSL2561 是艾迈斯半导体(ams)的产品。它比 BH1750 多了一个红外通道,能帮你做更精细的光谱补偿。我记得有一次在户外光照监测项目里,BH1750 在强阳光下偶尔会饱和,换成 TSL2561 后问题就解决了。
主要参数
| 参数 | 值 |
|---|---|
| 测量范围 | 0.1 ~ 40000 lux(可配置增益) |
| 通道 | 宽带通道 + 红外通道 |
| 接口 | I²C / SMBus(地址 0x29, 0x39, 0x49) |
| 工作电压 | 2.7V ~ 3.6V |
| 功耗 | 典型 0.24 mA |
TSL2561 的灵活性体现在哪里?你可以通过寄存器配置积分时间、增益倍数,甚至让它工作在掉电模式来省电。不过代价是——你得自己写 lux 转换公式。嗯,这里要注意,官方手册里给的公式是基于特定光源的,如果你用的光源类型不同,最好自己做一次校准。
BH1750 vs TSL2561 对比
| 对比项 | BH1750 | TSL2561 |
|---|---|---|
| 输出方式 | 直接 lux 值 | 原始 ADC 值,需转换 |
| 红外补偿 | 无 | 有(红外通道) |
| 配置灵活性 | 低(固定模式) | 高(可编程) |
| 使用难度 | ★☆☆☆☆ | ★★★☆☆ |
| 适用场景 | 室内照明、台灯 | 户外、多光源环境 |
3.4 I²C 通信协议基础
这两个传感器都用 I²C 通信。I²C 是飞利浦(现 NXP)在 80 年代发明的两线制串行总线。说白了,就两根线:SCL(时钟)和 SDA(数据)。
I²C 的核心概念
- 主设备与从设备: MCU 是主设备,传感器是从设备。主设备发起通信,从设备响应。
- 地址: 每个从设备有唯一 7 位地址。比如 BH1750 的地址是 0x23(7 位)或 0x46(8 位)。
- 起始条件与停止条件: SCL 高电平时,SDA 从高变低是起始;SDA 从低变高是停止。
- 应答(ACK): 每发送一个字节后,接收方必须拉低 SDA 表示收到。
I²C 读写流程
以 BH1750 为例,读光照值的流程是这样的:
- 主设备发送起始条件
- 主设备发送从设备地址 + 写位(0x46)
- BH1750 应答
- 主设备发送测量指令(如 0x10 表示连续高分辨率模式)
- BH1750 应答
- 主设备发送停止条件
- 等待 120ms(测量时间)
- 主设备发送起始条件
- 主设备发送从设备地址 + 读位(0x47)
- BH1750 应答
- 主设备读取 2 字节数据(高字节 + 低字节)
- 主设备发送停止条件
// 伪代码示例:读取 BH1750
i2c_start();
i2c_write(0x46); // 地址 + 写
i2c_write(0x10); // 连续高分辨率模式
i2c_stop();
delay_ms(120);
i2c_start();
i2c_write(0x47); // 地址 + 读
high_byte = i2c_read(ACK);
low_byte = i2c_read(NACK);
i2c_stop();
lux = (high_byte << 8) | low_byte;
lux = lux / 1.2; // BH1750 转换公式
我曾经踩过的坑: 第一次用 BH1750 时,忘了等 120ms 就去读数据,结果读回来全是 0xFF。后来查手册才发现,传感器测量需要时间。另外,I²C 上拉电阻也很关键——4.7kΩ 是常用值,但总线长度超过 20cm 时建议换成 2.2kΩ。
3.5 知识结构图
下面这张图帮你理清本章的核心脉络:
3.6 选型建议
到底选 BH1750 还是 TSL2561?我个人的经验是这样的:
- 如果你做室内产品(智能台灯、屏幕亮度调节、办公照明),BH1750 完全够用。它简单、稳定、代码量少。
- 如果你做户外或复杂光照环境(汽车仪表、户外显示屏、农业大棚),TSL2561 更合适。它的红外补偿能帮你排除红外干扰,测量更准。
- 如果你对功耗有极致要求,TSL2561 的掉电模式可以做到微安级,BH1750 则没有这个功能。
一个小建议: 初学者可以先从 BH1750 入手,把 I²C 通信调通,再换 TSL2561 体验更复杂的配置。我当年就是这么过来的——先跑通简单的,再挑战复杂的,心里有底。