Skip to content

1. 光的强度(光照度)怎么表示?

Lux 是一个完整的英文单词,中文译为“勒克斯”。 它是国际单位制(SI)中光照度(Illuminance)的单位。

1.1 光照度的详细解释:

  1. Lux (lx) 衡量的是表面接收到的光通量密度。简单来说,就是有多少光“照射”在某个物体表面上。
  2. 定义:1 lux 等于 1 流明(lumen)的光通量均匀分布在 1 平方米(square meter)的面积上。即 $1 \text{ lx} = 1 \text{ lm/m}^2$。

1.2 区分“光照度”与“光强度”:

  1. 光照度 (Illuminance):单位是 Lux (lx)。指的是被照面接收到的光的多少。例如:你的书桌桌面有多亮。BH1750 传感器测量的就是这个值。
  2. 发光强度 (Luminous Intensity):单位是 坎德拉 (Candela, cd)。指的是光源本身在特定方向上发光的强弱。例如:手电筒灯泡有多亮。

1.3 词源:

  1. “Lux” 在拉丁语中直接意为“光”。

1.4 Lux(光照度)常见场景参考:

  1. 0.0001 lux:无月光的夜晚
  2. 2.50 lux:家庭浴室或走廊的照明
  3. 00 - 500 lux:办公室或教室的标准照明
  4. 10,000 - 25,000 lux:晴朗白天的室外(非直射阳光)
  5. 100,000 lux:正午直射阳光

2. BH1750 数据手册结构化摘要

2.1 典型应用与目标设备

  • 智能手机、平板电脑:自动调节屏幕亮度
  • LCD 电视、显示屏:背光控制
  • 笔记本电脑:键盘背光控制
  • 数码相机:曝光控制
  • 智能家居:灯光自动调节
  • 便携设备:GPS、PDA

2.2 核心参数

参数规格
型号BH1750FVI
制造商ROHM Semiconductor
功能数字环境光传感器(16位串行输出)
测量范围1 ~ 65535 lx(高分辨率模式)
供电电压 (VCC)2.4V ~ 3.6V(建议 3.0V)
I2C 接口标准/快速模式 (f/s Mode)
功耗测量时 120µA(典型值),断电模式 0.01µA
封装WSOF6I (2.0mm × 2.5mm × 0.75mm)

2.3 BH1750原理图怎么看?

  1. ADDR 连接了一个下拉电阻(R5),电阻阻值为 4.7kΩ。
  2. 另外,DVI 上接了一个上拉电阻(R1),阻值为 1kΩ(1000 欧姆)。 觉醒系列_module_BH1750BH1750 原理图

如果无法预览,请点击 此处下载 BH1750FVI 数据手册 PDF 文件

2.4 引脚定义 (6引脚封装)

引脚号名称功能
1VCC电源输入 (2.4V ~ 3.6V)
2ADDRI2C 地址选择
接 GND → 地址 0x23
接 VCC → 地址 0x5C
3GND接地
4SDAI2C 数据线
5DVI复位 & I2C 参考电压
上电后需至少 1µs 的低电平复位。
6SCLI2C 时钟线

BH1750模块的引脚对应:

  • 5脚模块,DVI未引出。
  • 硬件上,ADDR已通过 R5 (4.7kΩ) 下拉到 GND → 地址固定为 0x23

BH1750背视图BH1750背视图

BH1750光照度传感器模块引脚丝印BH1750光照度传感器模块引脚丝印

BH1750接线图BH1750接线图


2.5 I2C 地址

ADDR 引脚状态7位地址写地址读地址
接 GND (你模块的默认状态)0x23 (0100011)0x460x47
接 VCC0x5C (1011100)0xB80xB9

2.6 命令表 (Opcode)

命令代码 (Hex)说明
Power Down0x00进入低功耗模式
Power On0x01从低功耗唤醒,等待测量
Reset0x07重置数据寄存器(清空之前的结果)
Continuously H-Resolution0x10连续测量,1 lx 精度,120ms
Continuously H-Resolution 20x11连续测量,0.5 lx 精度,120ms
Continuously L-Resolution0x13连续测量,4 lx 精度,16ms
One Time H-Resolution0x20单次测量,1 lx 精度,120ms,测量后自动进入 Power Down
One Time H-Resolution 20x21单次测量,0.5 lx 精度,120ms,测量后自动进入 Power Down
One Time L-Resolution0x23单次测量,4 lx 精度,16ms,测量后自动进入 Power Down

2.7 电气特性 (VCC = 3.0V, Ta = 25°C)

参数最小值典型值最大值单位
工作电压 (VCC)2.43.03.6V
测量电流 (Icc)-120190µA
掉电电流 (Icc2)-0.011.0µA
测量精度 (S/A)0.961.21.44times
测量时间 (H-Res)-120180ms
分辨率 (H-Res)-1-lx
I2C 时钟频率--400kHz

2.8 计算公式

C
uint16_t raw_data = (high_byte << 8) | low_byte;
float lux = raw_data / 1.2f;

注意:高分辨率模式2 (0.5 lx) 时,计算公式为 lux = raw_data / 1.2f / 2

2.9 关于 DVI 引脚的特别说明

虽然你的模块未引出 DVI 引脚,但根据数据手册:

  1. 引脚 5 (DVI) 是异步复位端:上电后,需让 DVI 保持至少 1µs 的低电平,才能完成内部寄存器复位。
  2. 手头上的模块设计:通过 R1 (1kΩ) 将 DVI 上拉到 VCC。这意味着硬件复位时序无法满足。
  3. 解决方案(软件复位):在初始化时发送 Reset 命令 (0x07) 来模拟硬件复位。这已包含在上述提供的驱动代码中。

3. ESP32-S3的BH1750驱动代码(基于ESP-IDF)

3.1 ESP-IDF 编写 ESP32-S3 驱动 BH1750 获取光照度数据流程图

ESP-IDF 编写 BH1750 驱动代码

3.2 ESP-IDF 的 BH1750 驱动代码

C

#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/i2c_master.h"
#include "esp_log.h"

static const char *TAG = "BH1750";

// =============================================
// 引脚与参数定义
// =============================================
#define I2C_MASTER_SCL_IO          GPIO_NUM_16
#define I2C_MASTER_SDA_IO          GPIO_NUM_17
#define I2C_MASTER_FREQ_HZ         100000
#define I2C_PORT                   I2C_NUM_0

// BH1750 地址(ADDR 接地)
#define BH1750_ADDR                0x23        // 7位地址
#define BH1750_WRITE_ADDR          0x46        // 写地址 (0x23 << 1)
#define BH1750_READ_ADDR           0x47        // 读地址 (0x23 << 1) | 1

// =============================================
// BH1750 命令定义
// =============================================
#define BH1750_CMD_POWER_ON        0x01        // 上电
#define BH1750_CMD_RESET           0x07        // 软复位
#define BH1750_CMD_ONE_TIME_H_RES  0x20        // 单次高分辨率模式 (1 lx, 120ms)

// =============================================
// 全局句柄
// =============================================
static i2c_master_bus_handle_t bus_handle;
static i2c_master_dev_handle_t dev_handle;

// =============================================
// I2C 初始化 & 设备探测
// =============================================
esp_err_t bh1750_init(void) {
    // 1. 创建 I2C 总线
    i2c_master_bus_config_t bus_cfg = {
        .clk_source = I2C_CLK_SRC_DEFAULT,
        .i2c_port = I2C_PORT,
        .scl_io_num = I2C_MASTER_SCL_IO,
        .sda_io_num = I2C_MASTER_SDA_IO,
        .glitch_ignore_cnt = 7,
        .flags.enable_internal_pullup = true,
    };
    ESP_ERROR_CHECK(i2c_new_master_bus(&bus_cfg, &bus_handle));

    // 2. 探测设备是否在线
    esp_err_t ret = i2c_master_probe(bus_handle, BH1750_ADDR, 1000 / portTICK_PERIOD_MS);
    if (ret != ESP_OK) {
        ESP_LOGE(TAG, "BH1750 未找到 (地址 0x%02X)", BH1750_ADDR);
        return ret;
    }
    ESP_LOGI(TAG, "BH1750 已找到 (地址 0x%02X)", BH1750_ADDR);

    // 3. 添加设备到总线
    i2c_device_config_t dev_cfg = {
        .dev_addr_length = I2C_ADDR_BIT_LEN_7,
        .device_address = BH1750_ADDR,
        .scl_speed_hz = I2C_MASTER_FREQ_HZ,
    };
    ESP_ERROR_CHECK(i2c_master_bus_add_device(bus_handle, &dev_cfg, &dev_handle));

    // 4. 软件复位(解决 DVI 上拉带来的复位问题)
    uint8_t cmd = BH1750_CMD_RESET;
    ret = i2c_master_transmit(dev_handle, &cmd, 1, 1000 / portTICK_PERIOD_MS);
    if (ret != ESP_OK) {
        ESP_LOGE(TAG, "复位命令失败");
        return ret;
    }
    vTaskDelay(pdMS_TO_TICKS(5));

    // 5. 上电唤醒
    cmd = BH1750_CMD_POWER_ON;
    ret = i2c_master_transmit(dev_handle, &cmd, 1, 1000 / portTICK_PERIOD_MS);
    if (ret != ESP_OK) {
        ESP_LOGE(TAG, "Power On 命令失败");
        return ret;
    }

    return ESP_OK;
}

// =============================================
// 单次测量(高分辨率模式)
// =============================================
esp_err_t bh1750_measure_once(float *lux) {
    // 1. 发送测量命令
    uint8_t cmd = BH1750_CMD_ONE_TIME_H_RES;
    esp_err_t ret = i2c_master_transmit(dev_handle, &cmd, 1, 1000 / portTICK_PERIOD_MS);
    if (ret != ESP_OK) {
        ESP_LOGE(TAG, "测量命令发送失败");
        return ret;
    }

    // 2. 等待测量完成 (高分辨率模式需要 120-180ms)
    vTaskDelay(pdMS_TO_TICKS(180));

    // 3. 读取 2 字节数据
    uint8_t data[2];
    ret = i2c_master_receive(dev_handle, data, 2, 1000 / portTICK_PERIOD_MS);
    if (ret != ESP_OK) {
        ESP_LOGE(TAG, "数据读取失败");
        return ret;
    }

    // 4. 计算光照强度
    uint16_t raw_data = (data[0] << 8) | data[1];
    *lux = (float)raw_data / 1.2f;

    return ESP_OK;
}

// =============================================
// 主程序
// =============================================
void app_main(void) {
    ESP_LOGI(TAG, "BH1750 测试程序启动");

    // 初始化 BH1750
    if (bh1750_init() != ESP_OK) {
        ESP_LOGE(TAG, "初始化失败,程序退出");
        return;
    }

    // 主循环测量
    while (1) {
        float lux;
        if (bh1750_measure_once(&lux) == ESP_OK) {
            ESP_LOGI(TAG, "光照强度: %.2f lx", lux);
        } else {
            ESP_LOGE(TAG, "测量失败");
        }
        vTaskDelay(pdMS_TO_TICKS(2000)); // 每2秒测量一次
    }
}

觉醒,然后燎原。 © 2026 门主引擎