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 为例,读光照值的流程是这样的:

  1. 主设备发送起始条件
  2. 主设备发送从设备地址 + 写位(0x46)
  3. BH1750 应答
  4. 主设备发送测量指令(如 0x10 表示连续高分辨率模式)
  5. BH1750 应答
  6. 主设备发送停止条件
  7. 等待 120ms(测量时间)
  8. 主设备发送起始条件
  9. 主设备发送从设备地址 + 读位(0x47)
  10. BH1750 应答
  11. 主设备读取 2 字节数据(高字节 + 低字节)
  12. 主设备发送停止条件
// 伪代码示例:读取 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 知识结构图

下面这张图帮你理清本章的核心脉络:

环境光传感器与 I²C 通信知识结构 环境光传感器 BH1750 TSL2561 直接 lux 输出 I²C 接口 红外补偿 可编程增益 I²C 协议:SCL + SDA,地址,起始/停止,应答 应用:智能照明 / 屏幕亮度调节 / 户外监测 💡 选型建议 室内固定光源 → BH1750 户外/多光源 → TSL2561

3.6 选型建议

到底选 BH1750 还是 TSL2561?我个人的经验是这样的:

  • 如果你做室内产品(智能台灯、屏幕亮度调节、办公照明),BH1750 完全够用。它简单、稳定、代码量少。
  • 如果你做户外或复杂光照环境(汽车仪表、户外显示屏、农业大棚),TSL2561 更合适。它的红外补偿能帮你排除红外干扰,测量更准。
  • 如果你对功耗有极致要求,TSL2561 的掉电模式可以做到微安级,BH1750 则没有这个功能。

一个小建议: 初学者可以先从 BH1750 入手,把 I²C 通信调通,再换 TSL2561 体验更复杂的配置。我当年就是这么过来的——先跑通简单的,再挑战复杂的,心里有底。