项目简介
本项目使用ESP32C6微控制器开发了一个智能光照补光系统,能够根据环境光强度自动调节补光灯的亮度。系统采用GY-302(BH1750)光照传感器实时监测环境光照,通过WS2812B可编程LED灯珠进行智能补光,并在0.96英寸OLED屏幕上实时显示光照数据。
主要功能:
实时监测环境光照强度
根据光照值智能调节补光(光线越暗,点亮LED越多)
OLED屏幕显示实时光照数据和LED状态
全自动运行,无需人工干预
应用场景:
植物补光系统
工作台智能照明
摄影补光装置
智能家居照明控制
硬件清单
核心组件
| 组件名称 | 规格说明 | 数量 |
|---------|---------|------|
| ESP32C6-WROOM-1 | 主控开发板 | 1 |
| GY-302模块 | BH1750光照传感器 | 1 |
| WS2812B灯珠 | 可编程RGB LED | 4颗 |
| 0.96" OLED | SSD1306驱动,I2C接口 | 1 |
| 面包板/PCB | 连接电路 | 1 |
| 杜邦线 | 若干 | - |硬件特点介绍
1.ESP32C6-WROOM-1:
基于RISC-V架构
内置Wi-Fi 6和蓝牙5.3
低功耗设计
丰富的外设接口

2.GY-302(BH1750):
数字光照传感器
I2C通信接口
测量范围:1-65535 lux
高精度、低功耗

3.WS2812B:
可单独控制的RGB LED
内置智能控制芯片
支持级联控制
色彩丰富,亮度可调

接线说明
引脚连接表
- GY-302
GY-302光照传感器
```
GY-302 → ESP32C6
VCC → 3.3V
GND → GND
SCL → GPIO7
SDA → GPIO6
ADDR → GND(或悬空)
```- WS2812B LED
WS2812B LED灯带
```
WS2812B → ESP32C6
DIN → GPIO8
VCC → 5V
GND → GND
```- 0.96OLED(IIC)
0.96" OLED显示屏
```
OLED → ESP32C6
VCC → 3.3V
GND → GND
SCL → GPIO7(与GY-302共用I2C总线)
SDA → GPIO6(与GY-302共用I2C总线)
```接线注意事项
1. I2C总线共享:GY-302和OLED都使用I2C通信,可以共用SCL和SDA引脚
2. 电压注意:OLED和GY-302使用3.3V供电,WS2812B使用5V供电
3. 地线共地:所有模块的GND必须连接在一起
4. 引脚可调:代码中的引脚定义可根据实际接线修改
软件环境配置
Arduino IDE设置
1. 安装ESP32开发板支持
打开Arduino IDE
文件 → 首选项
在"附加开发板管理器网址"中添加:
https://espressif.github.io/arduino-esp32/package_esp32_index.json工具 → 开发板 → 开发板管理器
搜索"esp32"并安装
2. 选择开发板
工具 → 开发板 → ESP32C6 Dev Module
安装必需库文件
在Arduino IDE的库管理器中(工具 → 管理库)安装以下库:
1. BH1750*by Christopher Laws - 光照传感器驱动库
2. Adafruit NeoPixel - WS2812B LED控制库
3. Adafruit SSD1306 - OLED显示屏驱动库
4. Adafruit GFX Library - 图形绘制基础库
完整代码
#include <Wire.h>
#include <BH1750.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_NeoPixel.h>
// OLED显示屏配置
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
#define SCREEN_ADDRESS 0x3C
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// WS2812B LED配置
#define LED_PIN 8 // WS2812B数据引脚,可根据实际接线修改
#define LED_COUNT 4 // 4颗LED灯珠
Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
// BH1750光照传感器
BH1750 lightMeter;
// I2C引脚定义 (ESP32C6默认引脚)
#define SDA_PIN 6
#define SCL_PIN 7
// 光强阈值设置(单位:lux)
#define THRESHOLD_1 50 // 点亮1颗LED
#define THRESHOLD_2 100 // 点亮2颗LED
#define THRESHOLD_3 200 // 点亮3颗LED
#define THRESHOLD_4 400 // 点亮4颗LED
void setup() {
Serial.begin(115200);
Serial.println("iCEasy Light Control System");
// 初始化I2C
Wire.begin(SDA_PIN, SCL_PIN);
// 初始化OLED显示屏
if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
Serial.println(F("SSD1306初始化失败"));
for(;;);
}
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println("iCEasy");
display.display();
delay(1000);
// 初始化BH1750光照传感器
if (lightMeter.begin(BH1750::CONTINUOUS_HIGH_RES_MODE)) {
Serial.println(F("BH1750初始化成功"));
} else {
Serial.println(F("BH1750初始化失败"));
}
// 初始化WS2812B LED
strip.begin();
strip.setBrightness(50); // 设置亮度 (0-255)
strip.show(); // 初始化所有LED为关闭状态
Serial.println("系统初始化完成");
}
void loop() {
// 读取光照强度
float lux = lightMeter.readLightLevel();
// 串口输出
Serial.print("光照强度: ");
Serial.print(lux);
Serial.println(" lux");
// 根据光照强度决定点亮LED数量(光线越暗,点亮越多)
int ledsToLight = 0;
if (lux < THRESHOLD_1) {
ledsToLight = 4; // 非常暗,点亮所有LED
} else if (lux < THRESHOLD_2) {
ledsToLight = 3; // 较暗,点亮3颗LED
} else if (lux < THRESHOLD_3) {
ledsToLight = 2; // 一般,点亮2颗LED
} else if (lux < THRESHOLD_4) {
ledsToLight = 1; // 较亮,点亮1颗LED
} else {
ledsToLight = 0; // 足够亮,关闭所有LED
}
// 控制LED灯
updateLEDs(ledsToLight);
// 更新OLED显示
updateDisplay(lux, ledsToLight);
// 延迟一段时间再读取
delay(500);
}
// 更新LED灯状态
void updateLEDs(int count) {
strip.clear();
for(int i = 0; i < count; i++) {
// 设置为白色补光,可根据需要调整颜色
strip.setPixelColor(i, strip.Color(255, 255, 255));
}
strip.show();
}
// 更新OLED显示
void updateDisplay(float lux, int ledsOn) {
display.clearDisplay();
// 第一行显示iCEasy
display.setTextSize(1);
display.setCursor(0, 0);
display.println("iCEasy");
// 显示分隔线
display.drawLine(0, 10, SCREEN_WIDTH, 10, SSD1306_WHITE);
// 显示光照强度
display.setTextSize(1);
display.setCursor(0, 15);
display.print("Light: ");
display.print(lux, 1);
display.println(" lux");
// 显示LED状态
display.setCursor(0, 28);
display.print("LEDs ON: ");
display.print(ledsOn);
display.print("/4");
// 显示LED状态图形
display.setCursor(0, 42);
display.print("Status: ");
for(int i = 0; i < LED_COUNT; i++) {
if(i < ledsOn) {
display.print("[*]");
} else {
display.print("[ ]");
}
}
display.display();
}
代码详解
核心逻辑说明
1. 光照强度分级策略
系统采用四级阈值设计,实现智能补光:
| 光照范围(lux) | 点亮LED数量 | 环境描述 |
|----------------|------------|---------|
| < 50 | 4颗 | 非常暗 |
| 50-100 | 3颗 | 较暗 |
| 100-200 | 2颗 | 一般 |
| 200-400 | 1颗 | 较亮 |
| > 400 | 0颗 | 足够亮 |设计思路:光线越暗,补光需求越大,点亮更多LED;光线充足时自动关闭补光,节能环保。
2. I2C总线多设备共享
```cpp
Wire.begin(SDA_PIN, SCL_PIN);GY-302和OLED都使用I2C通信,通过不同的I2C地址(0x23和0x3C)实现同一总线上的多设备通信。
3. WS2812B控制原理
```cpp
strip.setPixelColor(i, strip.Color(255, 255, 255));
strip.show();`setPixelColor()` 设置单个LED的颜色(RGB值)
`show()` 将设置应用到硬件
白色补光使用RGB(255, 255, 255)
4. OLED显示布局
第1行:显示项目标识"iCEasy"
第2行:分隔线
第3行:实时光照强度数值
第4行:当前点亮的LED数量
第5行:LED状态可视化([*]表示亮,[ ]表示灭)
使用说明
上传代码
1. 连接ESP32C6到电脑USB口
2. 在Arduino IDE中选择正确的端口
3. 点击"上传"按钮
4. 等待编译和上传完成
扩展功能建议
1. Wi-Fi远程监控
利用ESP32C6的Wi-Fi功能,可以实现:
手机APP远程查看光照数据
云端数据记录和分析
远程控制补光开关
2. 颜色温度调节
修改LED颜色实现不同色温:
```cpp
// 暖白光
strip.setPixelColor(i, strip.Color(255, 200, 150));
// 冷白光
strip.setPixelColor(i, strip.Color(200, 220, 255));3. 定时功能
添加RTC模块,实现:
定时开关补光
夜间自动补光
数据记录时间戳
4. 更多LED数量
增加LED数量以提供更强补光:
```cpp
#define LED_COUNT 12 // 更改为12颗LED5. PWM调光
实现LED亮度渐变调节:
```cpp
strip.setBrightness(map(lux, 0, 400, 255, 0));项目总结
本项目展示了如何使用ESP32C6构建一个完整的智能光照控制系统,涵盖了:
✅ 传感器数据采集:BH1750高精度光照检测
✅ 智能控制逻辑:基于光照强度的自动补光
✅ 可视化显示:OLED实时数据展示
✅ 硬件驱动:WS2812B可编程LED控制
✅ I2C通信:多设备总线共享
这个项目不仅具有实用价值,还是学习嵌入式开发的优秀案例,适合初学者入门和进阶玩家扩展。
参考资料
[ESP32C6官方文档](https://docs.espressif.com/projects/esp-idf/en/latest/esp32c6/)
[BH1750传感器手册](https://www.mouser.com/datasheet/2/348/bh1750fvi-e-186247.pdf)
[WS2812B技术规格](https://cdn-shop.adafruit.com/datasheets/WS2812B.pdf)
[Adafruit NeoPixel库文档](https://adafruit.github.io/Adafruit_NeoPixel/html/class_adafruit___neo_pixel.html)

