光照传感器 BH1750 自动调光系统:智能节能照明实战

为什么需要自动调光?

你有没有过这样的经历:晚上躺在床上玩手机,屏幕亮度太高刺得眼睛疼;或者白天在办公室里,显示器亮度太低看不清?

固定亮度的照明设备其实很不人性化。环境光变化时,我们需要手动调节——但大多数人根本懒得这么做。结果就是:要么太亮费电又刺眼,要么太暗伤眼睛。

今天我们要做的,就是一个能”看懂”环境亮度的智能调光系统。它使用 BH1750 数字光照传感器,实时检测周围光线强度,自动调节 LED 或屏幕亮度。

这个项目适合用在:

  • 智能台灯

  • 显示器自动背光调节

  • 手机/平板环境光适配

  • 智能家居照明系统

BH1750 传感器简介

BH1750 是一款数字型光照传感器,来自罗姆半导体(ROHM)。相比模拟光敏电阻,它有这些优势:

特性BH1750光敏电阻
输出类型数字 I2C模拟电压
测量范围1-65535 Lux依赖电路设计
精度±20%较差
波长响应接近人眼不一致
校准出厂校准需要手动校准
价格约 3-5 元约 0.5-1 元

BH1750 的测量范围是 1-65535 Lux,覆盖了从黑暗室内(约 100 Lux)到晴朗户外(约 50000 Lux)的场景。

关键参数:

  • 工作电压:3.0-3.6V(部分模块带稳压,可接 5V)

  • 接口:I2C(默认地址 0x23,可切换到 0x5C)

  • 分辨率:16 位

  • 响应时间:最快 120ms

硬件清单

组件型号数量单价总价
光照传感器BH1750FVI 模块1¥4.5¥4.5
主控板Arduino Nano1¥12¥12
LED 灯珠5mm 白光 LED3¥0.3¥0.9
限流电阻220Ω3¥0.1¥0.3
面包板400 孔1¥5¥5
杜邦线公对公 20cm10¥0.2¥2
合计¥24.7

购买建议:淘宝搜索”BH1750 模块”,选择带稳压和上拉电阻的版本,接线更简单。

电路连接

BH1750 使用 I2C 接口,只需要 4 根线:

BH1750Arduino Nano
VCC5V(模块带稳压)
GNDGND
SCLA5(I2C 时钟)
SDAA4(I2C 数据)

LED 连接(以 3 颗 LED 为例):

  • LED 正极 → 数字引脚 D9(PWM)→ 220Ω电阻 → LED 负极 → GND

接线图说明:

BH1750          Arduino Nano
┌────────┐      ┌────────────┐
│   VCC  │──────│   5V       │
│   GND  │──────│   GND      │
│   SCL  │──────│   A5       │
│   SDA  │──────│   A4       │
└────────┘      └────────────┘

LED (通过 220Ω电阻)
┌────────┐      ┌────────────┐
│   +    │──────│   D9 (PWM) │
│   -    │──────│   GND      │
└────────┘      └────────────┘

代码实现

1. 安装依赖库

使用 Adafruit_BH1750 库,它比原始 I2C 读写更方便:

# Arduino IDE 中搜索 "BH1750" 安装
# 或手动下载:https://github.com/claws/BH1750

2. 完整代码

#include 
#include **

// 定义引脚
#define LED_PIN 9

// 创建传感器对象
BH1750 lightSensor;

// 调光参数
const int MIN_LUX = 50;      // 最低光照阈值(暗环境)
const int MAX_LUX = 1000;    // 最高光照阈值(亮环境)
const int PWM_MIN = 30;      // 最低亮度(避免完全熄灭)
const int PWM_MAX = 255;     // 最高亮度

// 平滑滤波
float smoothedLux = 0;
const float ALPHA = 0.3;     // 滤波系数(0.1-0.5,越小越平滑)

void setup() {
  Serial.begin(9600);

  // 初始化 LED
  pinMode(LED_PIN, OUTPUT);

  // 初始化传感器
  if (lightSensor.begin(BH1750::CONTINUOUS_HIGH_RES_MODE, 0x23)) {
    Serial.println(F("BH1750 初始化成功"));
  } else {
    Serial.println(F("BH1750 初始化失败,检查接线!"));
    while (1);
  }

  // 设置测量时间(68ms 默认,可调整)
  lightSensor.setMeasurementTime(BH1750::MT_69MS);
}

void loop() {
  // 读取光照值
  if (lightSensor.hasValue()) {
    float lux = lightSensor.readLightLevel();

    // 指数移动平均滤波
    smoothedLux = ALPHA * lux + (1 - ALPHA) * smoothedLux;

    // 计算 PWM 值(映射到亮度范围)
    int pwmValue = calculatePWM(smoothedLux);

    // 输出到 LED
    analogWrite(LED_PIN, pwmValue);

    // 串口调试输出
    Serial.print("光照:");
    Serial.print(smoothedLux);
    Serial.print(" Lux | PWM: ");
    Serial.println(pwmValue);
  }

  delay(200);  // 200ms 采样间隔
}

// 根据光照计算 PWM 值
int calculatePWM(float lux) {
  // 限制在有效范围内
  lux = constrain(lux, MIN_LUX, MAX_LUX);

  // 线性映射:光照越强,LED 越亮
  // 注意:人眼对亮度感知是对数的,这里用线性简化
  int pwm = map(lux, MIN_LUX, MAX_LUX, PWM_MIN, PWM_MAX);

  return constrain(pwm, PWM_MIN, PWM_MAX);
}

3. 代码解析

关键部分说明:**

  1. $1

  2. $1

  3. $1

常见问题排查

问题 1:传感器返回 0 或固定值

可能原因:

  • 接线错误(SCL/SDA 接反)

  • I2C 地址不对(尝试 0x5C)

  • 上拉电阻缺失(模块应自带)

解决方法:

// I2C 扫描代码,查找传感器地址
#include 

void setup() {
  Serial.begin(9600);
  Wire.begin();

  Serial.println("I2C 扫描中...");
  for (byte addr = 1; addr 
#include 

void publishLux(float lux) {
  char payload[10];
  dtostrf(lux, 4, 1, payload);
  mqttClient.publish("home/sensor/lux", payload);
}

实际应用场景

场景 1:智能台灯

  • 白天自动调亮,晚上自动调暗

  • 深夜保持最低亮度(30%),避免完全熄灭

场景 2:显示器背光

  • 配合电脑使用,根据房间亮度调整

  • 减少眼睛疲劳,节能 30-50%

场景 3:植物生长灯

  • 根据自然光补充光照

  • 保持植物接收恒定光照强度

场景 4:汽车仪表照明

  • 隧道进出自动调整

  • 避免突然变亮/变暗影响驾驶

成本与节能分析

成本: 硬件总成本约 25 元,量产可降至 15 元以内。

节能效果: 相比固定亮度照明,自动调光可节能 30-60%。以 10W LED 灯为例:

  • 固定亮度:10W × 8 小时 = 80Wh/天

  • 自动调光:平均 5W × 8 小时 = 40Wh/天

  • 年节省:(80-40) × 365 = 14.6 kWh

按电费 0.6 元/kWh 计算,单灯年节省约 8.8 元。大规模部署(如办公室 100 盏灯)年节省近 900 元。

总结

BH1750 自动调光系统是一个实用且低成本的项目。它解决了固定亮度照明的痛点,既能提升舒适度,又能节能。

核心要点回顾:

  1. $1

  2. $1

  3. $1

  4. $1

动手试试吧,让你的照明设备真正”看懂”环境!

希望这篇博客文章对您有所帮助!