exs_bh1750 扩展库
作者:沈园园 | 最后修改:2026-08-26
一、概述
exs_bh1750 是 ROHM BH1750 数字环境光传感器的 LuatOS 扩展库。 BH1750 内部集成光电二极管阵列和 16 位 ADC,通过 I2C 总线直接输出环境光照度 lux 值, 广泛应用于手机屏幕亮度调节、智能家居、路灯控制、温室补光等场景。
BH1750 提供 1~65535 lux 的照度测量范围,支持 H(1 lux)/ H2(0.5 lux)/ L(4 lux) 三种分辨率,支持连续测量和单次测量两种模式,并可通过测量时间寄存器(MTreg)调整测量时间与灵敏度。
1.1 主要特性
-
测量范围 1~65535 lux,16 位 ADC 输出
-
三种分辨率可选:H 分辨率(1 lux,120ms)、H2 分辨率(0.5 lux,120ms)、L 分辨率(4 lux,16ms)
-
连续测量与单次测量两种模式(单次测量完成后自动断电,适合低功耗场景)
-
测量时间寄存器 MTreg 可调(31~254,默认 69),值越大测量时间越长、灵敏度越高
-
内置 50Hz/60Hz 光噪声抑制电路,抗交流光源干扰
-
光谱响应峰值 560nm,与人眼明视觉函数(V(λ))匹配
-
I2C 接口最高支持 400kHz(本库默认 i2c.FAST)
-
断电模式功耗极低,适合电池供电产品
-
工作电压 2.4V~3.6V(GY-302 模块内置 3.3V 稳压,可直接接 3V3~5V)
-
工作温度 -40℃~+85℃
1.2 加载方式
-- 扩展库需要 require 加载后才能调用
local exs_bh1750 = require "exs_bh1750"
1.3 注意事项
-
I2C 接线:BH1750 通过 I2C 总线与主控通信,SCL/SDA 需正确连接(Air780EHV I2C1:67=SCL、66=SDA,i2c_id=1)
-
I2C 地址:由 ADDR 引脚决定——ADDR 接地时地址为 0x23,ADDR 接 VCC 时为 0x5C;GY-302 模块默认 ADDR 接地(0x23),本库配套 demo 按 0x23 使用
-
模块供电:GY-302 模块已集成 4.7kΩ I2C 上拉电阻和 3.3V 稳压电路,VCC 可直接接 3V3(也可接 5V,模块内部稳压)
-
I2C 速率:BH1750 最高支持 400kHz,本库 init 默认使用 i2c.FAST(400kHz)
-
单次测量自动断电:单次测量模式(MODE_ONCE_*)下,每次测量完成后传感器自动进入断电状态;本库 get_lux() 已自动处理"触发测量→等待→读取"流程
-
MTreg 与测量时间:测量时间与 MTreg 成正比,MTreg=254 时 H 模式测量时间约 442ms,读取前需等待足够时间(本库已自动计算等待时间)
-
传感器安装:应安装在能接收环境光的位置,避免被外壳遮挡;深色玻璃下方安装时光照衰减明显
1.4 硬件连接
┌──────────────┐ ┌──────────────────┐
│ 主控 │ │ GY-302 BH1750 │
│ (Air7xxx) │ │ 光强传感器模块 │
│ │ │ │
│ PIN67/SCL ───┼────────────────────┼──→ SCL │
│ │ │ │
│ PIN66/SDA ───┼────────────────────┼──→ SDA │
│ │ │ │
│ 3V3 ────┼────────────────────┼──→ VCC(模块供电)│
│ │ │ │
│ GND ────┼────────────────────┼──→ GND(共地) │
│ │ │ │
│ GND ────┼────────────────────┼──→ ADDR(地址 0x23)
└──────────────┘ └──────────────────┘
1.5 指令集
| 指令 | 值 | 功能说明 |
|---|---|---|
| 断电(Power Down) | 0x00 | 进入低功耗状态 |
| 上电(Power On) | 0x01 | 退出断电状态 |
| 复位(Reset) | 0x02 | 复位,恢复默认配置(MTreg=69) |
| 连续 H 分辨率 | 0x03 | 连续测量,1 lux 分辨率,120ms |
| 连续 H 分辨率2 | 0x04 | 连续测量,0.5 lux 分辨率,120ms |
| 连续 L 分辨率 | 0x05 | 连续测量,4 lux 分辨率,16ms |
| 单次 H 分辨率 | 0x10 | 单次测量,1 lux 分辨率,120ms |
| 单次 H 分辨率2 | 0x11 | 单次测量,0.5 lux 分辨率,120ms |
| 单次 L 分辨率 | 0x13 | 单次测量,4 lux 分辨率,16ms |
| MTreg 高 3 位 | 0x40~0x47 | 设置测量时间高 3 位:0x40 | (mtreg >> 5) |
| MTreg 低 5 位 | 0x60~0x7F | 设置测量时间低 5 位:0x60 | (mtreg & 0x1F) |
测量模式说明:
连续测量:发送指令后传感器持续测量,读取时返回最新测量结果
单次测量:发送指令后测量一次,测量完成后自动进入断电状态(低功耗)
H2 分辨率:lux 计算时原始值除以 2.4(即 0.5 lux 步进),适合低照度精细测量
MTreg 说明(默认 69,范围 31~254):
MTreg 越小 → 测量时间越短、灵敏度越低(31 时约为默认的 0.45 倍)
MTreg 越大 → 测量时间越长、灵敏度越高(254 时约为默认的 3.68 倍)
测量时间 = 典型值 × (MTreg / 69),H 模式典型 120ms,L 模式典型 16ms
1.6 I2C 通信协议
BH1750 通过 I2C 总线通信,从机地址由 ADDR 引脚决定(0x23 / 0x5C),通信帧格式如下:
| 操作 | 帧格式 |
|---|---|
| 写指令 | START → 从机地址(写) → 指令字节 → STOP |
| 读数据 | START → 从机地址(读) → 数据高字节 → 数据低字节 → STOP |
从机地址格式:
0x23(ADDR 接地)或0x5C(ADDR 接 VCC)I2C 速率:标准 100kHz / 快速 400kHz,本库默认 400kHz(i2c.FAST)
数据输出:16 位测量结果,高字节在前,通过 2 字节读操作获取
lux 计算公式(MTreg=69 时):
H 模式: lux = raw / 1.2
H2 模式: lux = raw / 2.4
L 模式: lux = raw / 1.2(原始值低 2 位为 0,步进 4 lux)
MTreg 调整后:lux = raw / 1.2 × (69 / MTreg)(H/L 模式)
lux = raw / 2.4 × (69 / MTreg)(H2 模式)
二、核心示例
-
核心示例是指:使用本库文件提供的核心 API,开发的基础业务逻辑的演示代码
-
核心示例的作用是:帮助开发者快速理解如何使用本库,所以核心示例的逻辑都比较简单
-
更加完整和详细的 demo,请参考 LuatOS 仓库 中各个产品目录下的 demo/sensor/BH1750(Air780EHV + GY-302 BH1750 模块演示)
2.1 连续测量示例
-- 加载扩展库
local exs_bh1750 = require "exs_bh1750"
-- 应用主函数
local function bh1750_continuous_demo()
-- 初始化 BH1750(I2C1、地址 0x23、连续 H 分辨率模式)
local result = exs_bh1750.init()
if not result then
log.error("exs_bh1750", "BH1750 初始化失败")
return
end
log.info("exs_bh1750", "BH1750 初始化成功")
-- 每秒读取一次照度,共 5 次
for i = 1, 5 do
local lux = exs_bh1750.get_lux()
if lux then
log.info("exs_bh1750", string.format("照度: %.1f lux", lux))
end
sys.wait(1000)
end
end
-- 启动任务
sys.taskInit(bh1750_continuous_demo)
2.2 单次测量示例
-- 加载扩展库
local exs_bh1750 = require "exs_bh1750"
-- 应用主函数
local function bh1750_once_demo()
-- 初始化 BH1750(单次测量模式,测量完成后自动断电,适合低功耗场景)
local result = exs_bh1750.init(1, 0x23, exs_bh1750.MODE_ONCE_H)
if not result then
log.error("exs_bh1750", "BH1750 初始化失败")
return
end
-- 每次读取自动完成:发送测量指令 → 等待测量完成 → 读取数据
for i = 1, 3 do
local lux = exs_bh1750.get_lux()
if lux then
log.info("exs_bh1750", string.format("照度: %.1f lux", lux))
end
sys.wait(500)
end
end
sys.taskInit(bh1750_once_demo)
2.3 分辨率切换与 MTreg 调整示例
-- 加载扩展库
local exs_bh1750 = require "exs_bh1750"
-- 应用主函数
local function bh1750_resolution_demo()
-- 初始化 BH1750(默认连续 H 分辨率模式)
local result = exs_bh1750.init()
if not result then
log.error("exs_bh1750", "BH1750 初始化失败")
return
end
-- 切换到 H2 分辨率(0.5 lux,最高精度)
exs_bh1750.set_mode(exs_bh1750.MODE_CONT_H2)
sys.wait(200)
local lux_h2 = exs_bh1750.get_lux()
log.info("exs_bh1750", "H2 分辨率照度: ", lux_h2 and string.format("%.1f", lux_h2) or "读取失败")
-- 增大 MTreg 提高灵敏度(MTreg=254,测量时间约 442ms)
exs_bh1750.set_mtreg(254)
exs_bh1750.set_mode(exs_bh1750.MODE_CONT_H)
sys.wait(500)
local lux_high = exs_bh1750.get_lux()
log.info("exs_bh1750", "高灵敏度照度: ", lux_high and string.format("%.1f", lux_high) or "读取失败")
-- 恢复默认 MTreg
exs_bh1750.set_mtreg(69)
exs_bh1750.set_mode(exs_bh1750.MODE_CONT_H)
end
sys.taskInit(bh1750_resolution_demo)
三、常量解释
扩展库常量,顾名思义是由合宙 LuatOS 扩展库中定义的、不可重新赋值或修改的固定值,在脚本代码中不需要声明,可直接调用。
本扩展库提供 6 个测量模式常量,用于 init 和 set_mode 的参数:
| 常量 | 值 | 功能说明 |
|---|---|---|
| exs_bh1750.MODE_CONT_H | 0x03 | 连续 H 分辨率(1 lux,120ms) |
| exs_bh1750.MODE_CONT_H2 | 0x04 | 连续 H2 分辨率(0.5 lux,120ms) |
| exs_bh1750.MODE_CONT_L | 0x05 | 连续 L 分辨率(4 lux,16ms) |
| exs_bh1750.MODE_ONCE_H | 0x10 | 单次 H 分辨率(1 lux,120ms) |
| exs_bh1750.MODE_ONCE_H2 | 0x11 | 单次 H2 分辨率(0.5 lux,120ms) |
| exs_bh1750.MODE_ONCE_L | 0x13 | 单次 L 分辨率(4 lux,16ms) |
四、函数详解
4.1 初始化与控制
4.1.1 exs_bh1750.init(i2c_id, slave_address, mode)
功能
初始化 BH1750,配置 I2C 通信参数(400kHz 快速模式),复位芯片恢复默认配置, 并启动指定测量模式
参数
i2c_id
参数含义:主机使用的 I2C 总线 ID,用来控制 BH1750
数据类型:number
取值范围:平台有效的 I2C 总线编号(如 0 或 1)
是否必选:否
注意事项:可选,默认 1
参数示例:1
slave_address
参数含义:BH1750 从机地址(由 ADDR 引脚决定)
数据类型:number
取值范围:0x23(ADDR 接地)或 0x5C(ADDR 接 VCC)
是否必选:否
注意事项:可选,默认 0x23;GY-302 模块默认 ADDR 接地,地址为 0x23
参数示例:0x23
mode
参数含义:测量模式常量(exs_bh1750.MODE_CONT_H / MODE_ONCE_H 等 6 种)
数据类型:number
取值范围:0x03 / 0x04 / 0x05(连续)/ 0x10 / 0x11 / 0x13(单次)
是否必选:否
注意事项:可选,默认 exs_bh1750.MODE_CONT_H(连续 H 分辨率模式)
参数示例:exs_bh1750.MODE_ONCE_H
返回值
local init_result = exs_bh1750.init(i2c_id, slave_address, mode)
init_result
含义说明:初始化是否成功
数据类型:boolean
取值范围:true(成功), false(失败)
注意事项:初始化失败时请检查接线、供电和地址配置(ADDR 引脚与代码地址是否一致)
返回示例:true
示例
-- 基础初始化(I2C1、地址 0x23、连续 H 分辨率模式)
local result = exs_bh1750.init()
-- 自定义地址(ADDR 接 VCC,地址 0x5C)
local result = exs_bh1750.init(1, 0x5C)
-- 单次测量模式初始化
local result = exs_bh1750.init(1, 0x23, exs_bh1750.MODE_ONCE_H)
4.1.2 exs_bh1750.deinit()
功能
关闭 BH1750 通信,释放 I2C 总线资源。关闭前先发送断电指令使传感器进入低功耗状态
参数
无
返回值
local result = exs_bh1750.deinit()
result
含义说明:释放是否成功
数据类型:boolean
取值范围:true(成功), false(失败)
注意事项:释放后传感器进入断电状态,如需使用需重新 init
返回示例:true
示例
exs_bh1750.deinit()
4.2 数据读取
4.2.1 exs_bh1750.get_lux()
功能
读取环境光照度 lux 值。连续测量模式直接读取最新测量数据; 单次测量模式自动完成"发送测量指令 → 等待测量完成 → 读取数据"完整流程。
注意:本接口内部会执行系统延时(sys.wait),必须在任务协程中调用
参数
无
返回值
local lux = exs_bh1750.get_lux()
lux
含义说明:环境光照度 lux 值
数据类型:number(浮点数)
取值范围:0 ~ 65535(实际按模式分辨率换算)
注意事项:读取失败返回 nil;单次模式下每次调用都会触发一次新测量
返回示例:3071.7
示例
-- 连续测量模式读取照度
local lux = exs_bh1750.get_lux()
if lux then
log.info("exs_bh1750", string.format("照度: %.1f lux", lux))
end
4.2.2 exs_bh1750.get_raw()
功能
读取 BH1750 输出的 16 位原始测量数据(高字节在前)。
注意:本接口仅读取原始数据,不触发测量。单次测量模式下需先调用 get_lux() 或手动触发测量后再读取
参数
无
返回值
local raw = exs_bh1750.get_raw()
raw
含义说明:16 位原始测量值
数据类型:number
取值范围:0 ~ 65535
注意事项:读取失败返回 nil;单次测量模式下需先触发测量
返回示例:3686
示例
-- 读取原始数据
local raw = exs_bh1750.get_raw()
if raw then
log.info("exs_bh1750", "原始值: ", raw)
end
4.3 测量配置
4.3.1 exs_bh1750.set_mode(mode)
功能
设置测量模式(连续/单次 × H/H2/L 分辨率),切换后立即生效。
内部自动先发送上电指令(若处于断电状态),再发送测量模式指令
参数
mode
参数含义:测量模式常量(exs_bh1750.MODE_CONT_H / MODE_ONCE_H 等 6 种)
数据类型:number
取值范围:0x03 / 0x04 / 0x05(连续)/ 0x10 / 0x11 / 0x13(单次)
是否必选:是
注意事项:传入无效值返回 false
参数示例:exs_bh1750.MODE_CONT_H2
返回值
local result = exs_bh1750.set_mode(mode)
result
含义说明:设置是否成功
数据类型:boolean
取值范围:true(成功), false(失败)
注意事项:切换模式后建议等待相应测量时间后再读取数据
返回示例:true
示例
-- 切换到单次 H 分辨率模式(低功耗)
exs_bh1750.set_mode(exs_bh1750.MODE_ONCE_H)
-- 切换到连续 H2 分辨率模式(最高精度)
exs_bh1750.set_mode(exs_bh1750.MODE_CONT_H2)
4.3.2 exs_bh1750.set_mtreg(mtreg)
功能
设置测量时间寄存器 MTreg(31~254,默认 69)。MTreg 越大测量时间越长、灵敏度越高, lux 计算时已自动按 (69 / MTreg) 修正
参数
mtreg
参数含义:测量时间寄存器值
数据类型:number
取值范围:31 ~ 254
是否必选:是
注意事项:超出范围返回 false;设置后需重新发送测量模式指令(set_mode)确保按新测量时间测量
参数示例:254
返回值
local result = exs_bh1750.set_mtreg(mtreg)
result
含义说明:设置是否成功
数据类型:boolean
取值范围:true(成功), false(失败)
注意事项:MTreg 改变后测量时间随之变化,读取前需等待足够时间
返回示例:true
示例
-- 提高灵敏度(MTreg=254,测量时间约 442ms)
exs_bh1750.set_mtreg(254)
exs_bh1750.set_mode(exs_bh1750.MODE_CONT_H)
-- 恢复默认(MTreg=69)
exs_bh1750.set_mtreg(69)
exs_bh1750.set_mode(exs_bh1750.MODE_CONT_H)
4.4 电源管理
4.4.1 exs_bh1750.power_down()
功能
发送断电指令,使 BH1750 进入低功耗状态(断电模式下电流消耗极小)。 断电后测量停止,需上电并重新发送测量模式指令才能恢复测量
参数
无
返回值
local result = exs_bh1750.power_down()
result
含义说明:断电是否成功
数据类型:boolean
取值范围:true(成功), false(失败)
注意事项:断电后 get_lux 读取会失败(返回 nil),属正常现象
返回示例:true
示例
-- 测量完成后断电,进入低功耗
exs_bh1750.power_down()
4.4.2 exs_bh1750.power_on()
功能
发送上电指令,使 BH1750 退出断电状态。上电后需重新发送测量模式指令(set_mode)才能恢复测量
参数
无
返回值
local result = exs_bh1750.power_on()
result
含义说明:上电是否成功
数据类型:boolean
取值范围:true(成功), false(失败)
注意事项:上电后需调用 set_mode 重新启动测量
返回示例:true
示例
-- 上电并恢复连续测量
exs_bh1750.power_on()
exs_bh1750.set_mode(exs_bh1750.MODE_CONT_H)
4.4.3 exs_bh1750.reset()
功能
发送复位指令,恢复默认配置(MTreg 恢复为 69)。复位后需重新发送测量模式指令才能恢复测量
参数
无
返回值
local result = exs_bh1750.reset()
result
含义说明:复位是否成功
数据类型:boolean
取值范围:true(成功), false(失败)
注意事项:复位后 MTreg 恢复为默认值 69,需重新 set_mode 启动测量
返回示例:true
示例
-- 复位并恢复连续测量
exs_bh1750.reset()
exs_bh1750.set_mode(exs_bh1750.MODE_CONT_H)
4.5 其他
4.5.1 exs_bh1750.version()
功能
获取扩展库版本号
参数
无
返回值
local version = exs_bh1750.version()
version
含义说明:扩展库版本号(时间戳格式)
数据类型:string
取值范围:8 位数字,如 202608262000
注意事项:无
返回示例:"202608262000"
示例
log.info("exs_bh1750", "版本号: ", exs_bh1750.version())