一、项目概述
本项目旨在通过软硬件结合的方式,设计并实现一个基于STM32的智能台灯系统。该系统主要用于提供个性化、智能化的照明解决方案,实现自动调光、色温调节、情景模式等功能,广泛应用于家庭学习、办公照明、阅读休闲等领域。
技术栈关键词
-
硬件:STM32单片机、BH1750光照传感器、HC-SR501人体感应、WS2812B RGB灯珠、OLED显示屏、语音识别模块
-
软件:C语言、PWM调光算法、传感器数据处理、通信协议
-
控制方式:自动调光、情景模式、语音控制、手机APP控制
-
核心功能:环境光自适应、人体感应、色温调节、健康照明
二、系统架构
系统架构设计
本系统的硬件架构主要包括STM32单片机作为控制核心,光照传感器用于环境光检测,人体感应传感器用于人员检测,RGB灯珠用于照明,OLED显示屏用于状态显示。系统采用I2C、SPI和PWM接口进行各组件之间的数据传输。
系统架构图:
二、系统架构设计
┌─────────────────┐ ┌──────────────────┐
│ 手机APP控制 │◄──►│ 语音控制模块 │
│ /微信小程序 │ │ (语音识别) │
└─────────────────┘ └──────────────────┘
│ │
│ 蓝牙/UART │ UART
▼ ▼
┌─────────────────────────────────────────────┐
│ STM32主控制器 │
│ ┌─────────────┬─────────────┬────────────┐ │
│ │ 照明控制 │ 传感器模块 │ 显示模块 │ │
│ │ (PWM) │ (I2C/ADC) │ (I2C/SPI) │ │
│ └─────────────┴─────────────┴────────────┘ │
└─────────────────────────────────────────────┘
│ │ │
┌────┴─────┐ ┌────┴─────┐ ┌────┴────┐
│ RGB灯珠 │ │光照/人体 │ │ OLED │
│ WS2812B │ │ 传感器 │ │ 显示屏 │
└──────────┘ └──────────┘ └─────────┘
组件选择
-
STM32单片机:选择STM32F103C8T6,性能稳定,PWM输出丰富,适合照明控制
-
光照传感器:BH1750数字光强传感器,高精度,支持I2C通信
-
人体感应传感器:HC-SR501红外热释电传感器,灵敏度可调
-
RGB灯珠:WS2812B智能LED,集成驱动IC,可编程控制
-
OLED显示屏:0.96寸OLED显示屏,I2C接口,低功耗
-
语音模块:LD3320语音识别模块,支持中文指令识别
-
蓝牙模块:HC-05蓝牙模块,支持手机APP通信
三、环境搭建
硬件连接:
- BH1750光照传感器 → STM32 I2C接口(PB6-PB7),HC-SR501人体感应 → STM32 GPIO引脚(PA0),WS2812B RGB灯珠 → STM32 PWM引脚(PA8),OLED显示屏 → STM32 I2C接口(PB8-PB9),语音模块 → STM32 UART接口(PA9-PA10),蓝牙模块 → STM32 UART接口(PA2-PA3)
软件环境:
- 开发环境使用Keil uVision或STM32CubeIDE,安装必要的库文件,如STM32的HAL库、WS2812B驱动库、OLED显示库,配置系统时钟,确保PWM频率稳定
四、代码实现过程
基于STM32的智能台灯系统中各个模块的代码实现过程,包括传感器数据采集、PWM调光控制、自动调光算法、情景模式控制等。每个模块的代码示例将配以详细的代码说明,以确保逻辑清晰、易于理解和维护。
1. 系统初始化模块
系统初始化主要完成各硬件模块的初始化和系统参数的设置。系统状态结构体 :定义系统运行状态的结构体,包含亮度、色温、工作模式等参数,外设初始化 :依次初始化GPIO、I2C、PWM、UART等外设接口,传感器初始化 :初始化光照传感器、OLED显示屏、RGB灯珠等外设,初始状态设置:设置默认的亮度和色温参数
cs
#include "stm32f1xx_hal.h"
#include "bh1750.h"
#include "ws2812b.h"
#include "oled.h"
#include "stdio.h"
// 系统状态结构体
typedef struct {
uint8_t brightness; // 亮度 0-100%
uint16_t color_temp; // 色温 2700-6500K
uint8_t mode; // 工作模式
uint8_t auto_mode; // 自动模式开关
uint32_t light_level; // 环境光照强度
uint8_t presence; // 人体存在状态
} SystemStatus;
SystemStatus sys_status = {
.brightness = 70,
.color_temp = 4000,
.mode = 0,
.auto_mode = 1,
.light_level = 0,
.presence = 0
};
// 系统初始化函数
void System_Init(void) {
// HAL库初始化
HAL_Init();
// 系统时钟配置
SystemClock_Config();
// GPIO初始化
MX_GPIO_Init();
// I2C初始化(光照传感器和OLED)
MX_I2C1_Init();
// PWM初始化(RGB调光)
MX_TIM1_Init();
// UART初始化(语音和蓝牙)
MX_USART1_UART_Init();
MX_USART2_UART_Init();
// 外设初始化
BH1750_Init(); // 光照传感器
OLED_Init(); // OLED显示屏
WS2812B_Init(); // RGB灯珠初始化
// 初始状态设置
Set_Brightness(sys_status.brightness);
Set_Color_Temperature(sys_status.color_temp);
printf("智能台灯系统初始化完成\r\n");
}
2. 光照传感器模块
光照传感器模块负责采集环境光照强度数据,测量模式选择 :使用一次高分辨率模式,测量精度较高,数据滤波 :采用一阶低通滤波消除噪声干扰,环境光评估:根据光照强度将环境分为不同等级,用于后续调光决策
cs
// BH1750光照传感器读取函数
uint32_t Read_Light_Level(void) {
uint8_t data[2];
uint32_t lux = 0;
// 发送测量命令(一次高分辨率模式)
uint8_t cmd = BH1750_ONE_TIME_HIGH_RES_MODE;
HAL_I2C_Master_Transmit(&hi2c1, BH1750_ADDR, &cmd, 1, 100);
// 等待测量完成
HAL_Delay(180);
// 读取测量结果
if (HAL_I2C_Master_Receive(&hi2c1, BH1750_ADDR, data, 2, 100) == HAL_OK) {
lux = ((data[0] << 8) | data[1]) / 1.2;
}
// 低通滤波处理
static uint32_t filtered_lux = 0;
const float alpha = 0.3; // 滤波系数
filtered_lux = alpha * lux + (1 - alpha) * filtered_lux;
sys_status.light_level = filtered_lux;
return filtered_lux;
}
// 环境光评估函数
uint8_t Evaluate_Ambient_Light(uint32_t lux) {
if (lux < 50) {
return LIGHT_LEVEL_DARK; // 很暗
} else if (lux < 200) {
return LIGHT_LEVEL_LOW; // 较暗
} else if (lux < 500) {
return LIGHT_LEVEL_MEDIUM; // 适中
} else if (lux < 1000) {
return LIGHT_LEVEL_BRIGHT; // 较亮
} else {
return LIGHT_LEVEL_VERY_BRIGHT; // 很亮
}
}
3. 自动调光算法模块
自动调光算法根据环境光照和用户习惯自动调节台灯亮度,光照-亮度映射 :建立环境光照与目标亮度的对应关系,人体感应影响 :检测到无人时自动降低亮度节能,平滑过渡 :采用渐进式调整避免亮度突变,时间因素考虑:根据一天中的不同时间调节色温,符合人体生物钟
cs
// 自动调光算法
uint8_t Auto_Brightness_Adjust(uint32_t ambient_lux) {
uint8_t target_brightness = sys_status.brightness;
// 根据环境光照计算目标亮度
if (ambient_lux < 50) {
// 环境很暗:需要较高亮度
target_brightness = 80;
} else if (ambient_lux < 200) {
// 环境较暗:中等亮度
target_brightness = 60;
} else if (ambient_lux < 500) {
// 环境适中:较低亮度
target_brightness = 40;
} else if (ambient_lux < 1000) {
// 环境较亮:很低亮度
target_brightness = 20;
} else {
// 环境很亮:最低亮度
target_brightness = 10;
}
// 考虑人体存在状态
if (sys_status.presence == 0) {
// 无人时自动降低亮度或关闭
target_brightness = target_brightness / 2;
}
// 平滑过渡(避免亮度突变)
static uint8_t current_brightness = 70;
if (abs(target_brightness - current_brightness) > 5) {
// 每次调整不超过5%
if (target_brightness > current_brightness) {
current_brightness += 5;
} else {
current_brightness -= 5;
}
}
return current_brightness;
}
// 色温自适应调节
uint16_t Auto_Color_Temperature_Adjust(uint32_t ambient_lux, uint8_t time_hour) {
uint16_t target_temp = 4000; // 默认4000K
// 根据时间调节色温
if (time_hour >= 6 && time_hour <= 9) {
// 早晨:较高色温提神
target_temp = 5000 + (time_hour - 6) * 100;
} else if (time_hour > 9 && time_hour <= 18) {
// 白天:自然白光
target_temp = 5500;
} else if (time_hour > 18 && time_hour <= 21) {
// 傍晚:逐渐变暖
target_temp = 4000 - (time_hour - 18) * 200;
} else {
// 夜晚:低色温助眠
target_temp = 3000 - (time_hour - 21) * 100;
if (target_temp < 2700) target_temp = 2700;
}
// 根据环境光照微调
if (ambient_lux < 100) {
// 环境暗时偏暖色
target_temp -= 300;
} else if (ambient_lux > 800) {
// 环境亮时偏冷色
target_temp += 200;
}
return target_temp;
}
4. PWM调光控制模块
PWM调光控制模块负责控制LED的亮度和颜色。PWM控制 :通过调整PWM占空比控制LED亮,色温-RGB映射 :将色温值转换为RGB颜色值,平滑过渡:实现亮度渐变的视觉效果,提升用户体验
cs
// 设置亮度函数
void Set_Brightness(uint8_t brightness) {
// 限制范围
if (brightness > 100) brightness = 100;
// 计算PWM占空比
uint16_t duty_cycle = (brightness * PWM_PERIOD) / 100;
// 设置PWM输出
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, duty_cycle);
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_2, duty_cycle);
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_3, duty_cycle);
// 更新系统状态
sys_status.brightness = brightness;
printf("亮度设置为: %d%%\r\n", brightness);
}
// 设置色温函数
void Set_Color_Temperature(uint16_t color_temp) {
// 限制色温范围
if (color_temp < 2700) color_temp = 2700;
if (color_temp > 6500) color_temp = 6500;
// 计算RGB值(简化算法)
float ratio = (color_temp - 2700.0f) / (6500.0f - 2700.0f);
uint8_t red, green, blue;
// 冷白光 -> 暖白光过渡
red = 255;
green = 255 - (uint8_t)(ratio * 80);
blue = 255 - (uint8_t)(ratio * 150);
// 设置RGB颜色
Set_RGB_Color(red, green, blue);
// 更新系统状态
sys_status.color_temp = color_temp;
printf("色温设置为: %dK\r\n", color_temp);
}
// 平滑调光过渡
void Smooth_Brightness_Transition(uint8_t target_brightness, uint16_t duration_ms) {
uint8_t current = sys_status.brightness;
uint8_t steps = 50; // 过渡步数
uint16_t delay_time = duration_ms / steps;
if (target_brightness > current) {
// 渐亮
for (uint8_t i = current; i <= target_brightness; i++) {
Set_Brightness(i);
HAL_Delay(delay_time);
}
} else {
// 渐暗
for (uint8_t i = current; i >= target_brightness; i--) {
Set_Brightness(i);
HAL_Delay(delay_time);
}
}
}
5. 情景模式控制模块
情景模式控制模块提供多种预设的照明模式,模式定义 :定义多种实用的照明场景模式,参数预设 :每个模式都有预设的亮度和色温参数,自动选择:根据时间和环境自动选择合适的情景模式
cs
// 情景模式定义
typedef enum {
MODE_READING = 0, // 阅读模式
MODE_WORKING, // 工作模式
MODE_RELAX, // 休闲模式
MODE_SLEEP, // 睡眠模式
MODE_MOVIE, // 观影模式
MODE_CUSTOM // 自定义模式
} SceneMode;
// 设置情景模式
void Set_Scene_Mode(SceneMode mode) {
switch (mode) {
case MODE_READING:
// 阅读模式:高亮度,中性色温
Set_Brightness(90);
Set_Color_Temperature(5000);
printf("已切换到阅读模式\r\n");
break;
case MODE_WORKING:
// 工作模式:适中亮度,偏冷色温
Set_Brightness(80);
Set_Color_Temperature(5500);
printf("已切换到工作模式\r\n");
break;
case MODE_RELAX:
// 休闲模式:较低亮度,暖色温
Set_Brightness(50);
Set_Color_Temperature(3500);
printf("已切换到休闲模式\r\n");
break;
case MODE_SLEEP:
// 睡眠模式:渐暗过程,暖色温
Smooth_Brightness_Transition(10, 3000);
Set_Color_Temperature(2700);
printf("已切换到睡眠模式\r\n");
break;
case MODE_MOVIE:
// 观影模式:低亮度,避免反光
Set_Brightness(20);
Set_RGB_Color(20, 20, 30); // 微弱的蓝光
printf("已切换到观影模式\r\n");
break;
case MODE_CUSTOM:
// 自定义模式:保持当前设置
printf("自定义模式\r\n");
break;
}
sys_status.mode = mode;
}
// 自动情景模式选择
void Auto_Scene_Selection(uint8_t time_hour, uint32_t ambient_lux) {
if (time_hour >= 22 || time_hour < 6) {
// 夜间时段:睡眠模式
Set_Scene_Mode(MODE_SLEEP);
} else if (time_hour >= 8 && time_hour <= 17) {
// 工作时间段:根据环境选择
if (ambient_lux < 300) {
Set_Scene_Mode(MODE_WORKING);
} else {
Set_Brightness(40); // 环境较亮时降低亮度
}
} else {
// 其他时段:休闲模式
Set_Scene_Mode(MODE_RELAX);
}
}
6. 人体感应控制模块
人体感应控制模块检测人员存在状态,实现智能开关控制。状态检测 :实时检测人体存在状态,延时判断 :采用延时判断避免误触发,智能控制 :根据人员状态自动调节照明,节能设计:无人时自动降低亮度或关闭
cs
// 人体感应检测
uint8_t Detect_Human_Presence(void) {
static uint32_t last_detection_time = 0;
static uint8_t presence_state = 0;
// 读取人体感应传感器状态
uint8_t current_state = HAL_GPIO_ReadPin(PIR_GPIO_Port, PIR_Pin);
if (current_state == 1) {
// 检测到人体
last_detection_time = HAL_GetTick();
if (presence_state == 0) {
presence_state = 1;
printf("检测到人员进入\r\n");
}
} else {
// 未检测到人体
uint32_t current_time = HAL_GetTick();
if (presence_state == 1 && (current_time - last_detection_time > 30000)) {
// 超过30秒未检测到人体,认为人员离开
presence_state = 0;
printf("人员已离开\r\n");
}
}
sys_status.presence = presence_state;
return presence_state;
}
// 基于人体感应的智能控制
void Human_Presence_Control(void) {
if (sys_status.presence == 1) {
// 有人时:根据环境光自动调节
if (sys_status.auto_mode) {
uint8_t target_brightness = Auto_Brightness_Adjust(sys_status.light_level);
if (abs(target_brightness - sys_status.brightness) > 10) {
Smooth_Brightness_Transition(target_brightness, 1000);
}
}
} else {
// 无人时:逐渐降低亮度
static uint32_t last_presence_time = 0;
uint32_t current_time = HAL_GetTick();
if (sys_status.brightness > 0) {
if (current_time - last_presence_time > 60000) { // 1分钟后
Smooth_Brightness_Transition(0, 2000); // 2秒内关闭
last_presence_time = current_time;
printf("无人状态,自动关闭台灯\r\n");
} else if (current_time - last_presence_time > 30000) { // 30秒后
Set_Brightness(sys_status.brightness / 2); // 降低一半亮度
}
}
}
}
7. 用户交互模块
用户交互模块提供多种控制方式,包括触摸按键、语音控制和手机APP控制。多方式控制 :支持触摸、语音、蓝牙APP多种控制方式,防抖处理 :按键检测添加防抖处理,命令解析 :语音和蓝牙命令的解析与执行,状态反馈:向APP发送当前系统状态
cs
// 触摸按键处理
void Touch_Key_Handler(void) {
static uint8_t last_key_state[4] = {0};
uint8_t current_key_state[4];
// 读取触摸按键状态
current_key_state[0] = HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin);
current_key_state[1] = HAL_GPIO_ReadPin(KEY2_GPIO_Port, KEY2_Pin);
current_key_state[2] = HAL_GPIO_ReadPin(KEY3_GPIO_Port, KEY3_Pin);
current_key_state[3] = HAL_GPIO_ReadPin(KEY4_GPIO_Port, KEY4_Pin);
// 检测按键按下事件
for (int i = 0; i < 4; i++) {
if (current_key_state[i] == 0 && last_key_state[i] == 1) {
// 按键按下
Process_Key_Press(i);
}
last_key_state[i] = current_key_state[i];
}
}
// 处理按键按下事件
void Process_Key_Press(uint8_t key_index) {
switch (key_index) {
case 0: // 开关/模式切换
if (sys_status.brightness > 0) {
Smooth_Brightness_Transition(0, 500);
} else {
Smooth_Brightness_Transition(70, 500);
}
break;
case 1: // 亮度增加
if (sys_status.brightness < 100) {
Set_Brightness(sys_status.brightness + 10);
}
break;
case 2: // 亮度减少
if (sys_status.brightness > 10) {
Set_Brightness(sys_status.brightness - 10);
}
break;
case 3: // 情景模式切换
sys_status.mode = (sys_status.mode + 1) % 5;
Set_Scene_Mode(sys_status.mode);
break;
}
}
// 语音控制处理
void Voice_Control_Handler(void) {
uint8_t voice_command = 0;
// 读取语音模块数据
if (HAL_UART_Receive(&huart1, &voice_command, 1, 10) == HAL_OK) {
switch (voice_command) {
case VOICE_CMD_ON:
Smooth_Brightness_Transition(70, 500);
printf("语音命令:开灯\r\n");
break;
case VOICE_CMD_OFF:
Smooth_Brightness_Transition(0, 500);
printf("语音命令:关灯\r\n");
break;
case VOICE_CMD_BRIGHT_UP:
if (sys_status.brightness < 90) {
Set_Brightness(sys_status.brightness + 10);
}
printf("语音命令:调亮\r\n");
break;
case VOICE_CMD_BRIGHT_DOWN:
if (sys_status.brightness > 10) {
Set_Brightness(sys_status.brightness - 10);
}
printf("语音命令:调暗\r\n");
break;
case VOICE_CMD_READING_MODE:
Set_Scene_Mode(MODE_READING);
printf("语音命令:阅读模式\r\n");
break;
}
}
}
// 蓝牙APP控制处理
void Bluetooth_Control_Handler(void) {
uint8_t bluetooth_buffer[32];
uint8_t data_length = 0;
// 检查蓝牙数据
if (HAL_UART_Receive(&huart2, bluetooth_buffer, 32, 10) > 0) {
// 解析控制命令
if (bluetooth_buffer[0] == 0xAA) { // 帧头
uint8_t command = bluetooth_buffer[1];
uint8_t param1 = bluetooth_buffer[2];
uint8_t param2 = bluetooth_buffer[3];
switch (command) {
case BT_CMD_SET_BRIGHTNESS:
Set_Brightness(param1);
break;
case BT_CMD_SET_COLOR_TEMP:
Set_Color_Temperature(param1 * 100);
break;
case BT_CMD_SET_MODE:
Set_Scene_Mode(param1);
break;
case BT_CMD_GET_STATUS:
Send_Status_To_App();
break;
}
}
}
}
五、项目总结与未来展望
本项目成功设计并实现了一个基于STM32的智能台灯系统,通过软硬件结合的方式,展示了嵌入式系统在智能照明领域的实际应用。系统的主要目标是提供智能化、个性化、健康化的照明解决方案,具备良好的实用性和扩展性。
未来展望
本项目不仅实现了智能台灯的基本功能,还在用户体验、健康保护、节能环保等方面进行了深入设计,具有良好的市场前景和社会价值。
-
增加Wi-Fi模块:实现远程控制和云服务
-
集成摄像头:实现人脸识别和坐姿检测
-
增加环境传感器:CO₂、PM2.5等环境监测
-
机器学习算法:用户习惯的深度学习优化
-
太阳能供电:增加太阳能充电功能
-
组网功能:多台灯组网和协同控制