基于STM32的智能家居系统设计

一、系统概述与核心功能

1. 系统定位

基于STM32的智能家居系统以“环境感知-智能决策-设备控制-远程交互”为核心,实现家庭环境的实时监控、设备的自动化控制、安全预警及能源管理,支持本地按键/语音控制与手机APP/Web远程管理,适用于家庭、公寓、小型办公场所。

2. 核心功能模块

模块 功能描述
环境监测 温湿度、光照强度、空气质量(PM2.5/甲醛)、烟雾、燃气泄漏、人体感应
设备控制 灯光(开关/调光)、插座、窗帘(开合/调速)、风扇、空调(红外遥控)
安全预警 入侵检测(门磁+人体红外)、火灾(烟雾+温度)、燃气泄漏(MQ-2)报警
通信交互 手机APP(Android/iOS)、Web端、语音控制(本地/云端)、多设备组网(Zigbee)
能源管理 用电设备功率统计、节能模式(自动关断闲置设备)、电池供电设备监控
数据存储 历史环境数据、设备操作记录、报警日志(本地EEPROM+云端同步)

二、硬件设计方案

1. 核心硬件选型

模块 型号 关键参数 接口方式
主控MCU STM32F103C8T6 72MHz Cortex-M3,64KB Flash,20KB RAM,12位ADC,3个UART,2个I2C,2个SPI 核心控制器
传感器组 温湿度:DHT11/SHT30 DHT11(±2℃/±5%RH,单总线);SHT30(±0.3℃/±2%RH,I2C,高精度) 单总线/I2C
光照:BH1750 0-65535 lux,I2C接口,低功耗(0.12mA) I2C(PB6/PB7)
空气质量:MQ-135 检测甲醛/苯/CO₂,模拟输出(0-5V),加热电压5V ADC(PA0)
人体红外:HC-SR501 探测距离7m,延时0-300s可调,高电平触发 GPIO(PA1,外部中断)
烟雾/燃气:MQ-2 检测烟雾/天然气,模拟输出,加热电压5V ADC(PA2)
执行器 继电器模块(4路) 5V驱动,单路10A/250V AC,光耦隔离 GPIO(PB0-PB3)
窗帘电机:28BYJ-48+ULN2003 5V步进电机,减速比1:64,扭矩0.3N·m GPIO(PB4-PB7,ULN2003驱动)
LED调光:WS2812B 5050封装,RGB全彩,单线通信,20mA/颗 GPIO(PA3,PWM控制)
通信模块 Wi-Fi:ESP8266-12F 802.11 b/g/n,内置TCP/IP,UART接口,支持AT指令/透传模式 UART(PA9/PA10)
蓝牙:HC-05 蓝牙2.0+EDR,10m距离,UART接口,主从模式切换 UART(PA11/PA12)
显示模块 OLED 12864(I2C) 0.96寸,128×64像素,自发光,低功耗(<10mA) I2C(PB6/PB7复用)
存储模块 AT24C02(EEPROM) 2KB容量,I2C接口,擦写10万次 I2C(PB6/PB7复用)
电源模块 5V/2A适配器+AMS1117-3.3V 输入220V AC,输出5V/2A(给传感器/电机),3.3V给STM32/OLED 稳压供电

2. 硬件电路设计要点

2.1 STM32最小系统

  • 时钟电路:8MHz外部晶振(主时钟)+ 32.768kHz RTC晶振(低功耗计时)。
  • 复位电路:10kΩ上拉电阻+0.1μF电容(手动复位+上电复位)。
  • 调试接口:SWD(PA13/SWIO,PA14/SWCLK),支持ST-Link下载调试。

2.2 传感器接口电路

  • 模拟传感器(MQ-135/MQ-2):输出0-5V模拟信号,通过分压电阻(10kΩ+20kΩ)降至0-3.3V后接入STM32 ADC引脚(PA0/PA2)。
  • 数字传感器(DHT11/BH1750):DHT11单总线接PA4,BH1750 I2C接PB6(SCL)/PB7(SDA)。
  • 人体红外(HC-SR501):OUT引脚接PA1(外部中断),高电平触发中断。

2.3 执行器驱动电路

  • 继电器模块:STM32 GPIO(PB0-PB3)通过S8050三极管驱动继电器线圈(5V供电),继电器触点控制220V负载(灯光/插座)。
  • 窗帘电机(28BYJ-48):ULN2003驱动芯片接收STM32 GPIO(PB4-PB7)信号,控制步进电机正反转及转速(PWM调速)。

2.4 通信模块接口

  • ESP8266:TXD接STM32 RXD(PA10),RXD接STM32 TXD(PA9),VCC接5V(需独立供电避免STM32串口过载)。
  • HC-05:TXD接PA12,RXD接PA11,KEY引脚接PB8(AT指令模式切换)。

三、软件设计与核心代码

1. 系统架构(FreeRTOS多任务调度)

采用FreeRTOS实时操作系统,划分5个核心任务(优先级从高到低):

  1. 传感器采集任务(优先级3):周期性读取温湿度、光照、空气质量等传感器数据。
  2. 安全预警任务(优先级4):实时监测人体红外、烟雾、燃气传感器,触发报警。
  3. 设备控制任务(优先级2):执行灯光、窗帘、风扇的控制逻辑(本地/远程指令)。
  4. 通信任务(优先级1):处理ESP8266/Wi-Fi通信(MQTT协议对接云平台)、蓝牙指令解析。
  5. UI显示任务(优先级0):OLED显示实时数据、设备状态,响应按键输入。

2. 核心代码实现(基于HAL库)

2.1 主程序框架(FreeRTOS初始化)

#include "stm32f1xx_hal.h"
#include "FreeRTOS.h"
#include "task.h"
#include "sensor.h"
#include "actuator.h"
#include "communication.h"
#include "ui.h"

int main(void) {
  HAL_Init();                     // 初始化HAL库
  SystemClock_Config();           // 配置系统时钟(72MHz)
  MX_GPIO_Init();                 // GPIO初始化
  MX_ADC1_Init();                  // ADC初始化(MQ传感器)
  MX_I2C1_Init();                  // I2C初始化(OLED/BH1750/AT24C02)
  MX_USART1_Init();                // USART1初始化(ESP8266)
  MX_USART2_Init();                // USART2初始化(HC-05)
  
  // FreeRTOS任务创建
  xTaskCreate(Sensor_Task, "Sensor", 128, NULL, 3, NULL);       // 传感器采集
  xTaskCreate(Safety_Task, "Safety", 128, NULL, 4, NULL);       // 安全预警
  xTaskCreate(Control_Task, "Control", 256, NULL, 2, NULL);     // 设备控制
  xTaskCreate(Comm_Task, "Communication", 256, NULL, 1, NULL);   // 通信处理
  xTaskCreate(UI_Task, "UI", 128, NULL, 0, NULL);               // UI显示
  
  vTaskStartScheduler();           // 启动FreeRTOS调度器
  while (1);                       // 理论上不会执行到这里
}

2.2 传感器采集任务(多传感器数据读取)

// 传感器数据结构体
typedef struct {
  float temp;       // 温度(℃)
  float humi;       // 湿度(%RH)
  uint16_t light;   // 光照强度(lux)
  uint16_t air_quality; // 空气质量(ADC值)
  uint16_t smoke;   // 烟雾浓度(ADC值)
  uint8_t motion;   // 人体感应(0/1)
} SensorData_t;

SensorData_t sensor_data;

void Sensor_Task(void *pvParameters) {
  TickType_t xLastWakeTime = xTaskGetTickCount();
  const TickType_t xFrequency = pdMS_TO_TICKS(1000);  // 1秒采集一次
  
  while (1) {
    // 读取温湿度(DHT11)
    DHT11_Read(&sensor_data.temp, &sensor_data.humi);
    
    // 读取光照(BH1750)
    sensor_data.light = BH1750_ReadLight();
    
    // 读取空气质量(MQ-135,ADC采集)
    sensor_data.air_quality = MQ135_ReadADC();
    
    // 读取烟雾浓度(MQ-2,ADC采集)
    sensor_data.smoke = MQ2_ReadADC();
    
    // 读取人体红外(HC-SR501,GPIO读取)
    sensor_data.motion = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1);
    
    // 发送数据到消息队列(供控制任务和UI任务使用)
    xQueueSend(sensor_queue, &sensor_data, 0);
    
    vTaskDelayUntil(&xLastWakeTime, xFrequency);  // 周期性执行
  }
}

2.3 设备控制任务(灯光/窗帘/风扇联动)

// 设备控制结构体(本地/远程指令)
typedef struct {
  uint8_t light_switch;    // 灯光开关(0关/1开)
  uint8_t light_brightness;// 灯光亮度(0-100)
  uint8_t curtain_pos;     // 窗帘位置(0全关/100全开)
  uint8_t fan_speed;       // 风扇转速(0-3档)
} ControlCmd_t;

void Control_Task(void *pvParameters) {
  ControlCmd_t cmd;
  
  while (1) {
    // 从消息队列接收控制指令(本地按键/远程APP)
    if (xQueueReceive(control_queue, &cmd, portMAX_DELAY) == pdPASS) {
      // 灯光控制(WS2812B调光)
      WS2812_SetBrightness(cmd.light_brightness);
      HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, cmd.light_switch ? GPIO_PIN_SET : GPIO_PIN_RESET);
      
      // 窗帘控制(步进电机驱动)
      if (cmd.curtain_pos > current_curtain_pos) {
        Curtain_Open(cmd.curtain_pos - current_curtain_pos);  // 正转开窗帘
      } else if (cmd.curtain_pos < current_curtain_pos) {
        Curtain_Close(current_curtain_pos - cmd.curtain_pos); // 反转关窗帘
      }
      
      // 风扇控制(继电器+PWM调速)
      HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, cmd.fan_speed > 0 ? GPIO_PIN_SET : GPIO_PIN_RESET);
      TIM_SetCompare1(TIM3, cmd.fan_speed * 341);  // PWM占空比调速(0-1023)
      
      current_curtain_pos = cmd.curtain_pos;  // 更新当前窗帘位置
    }
    
    // 自动化场景逻辑(示例:光照低于50lux自动开灯)
    if (sensor_data.light < 50 && !cmd.light_switch) {
      ControlCmd_t auto_cmd = {.light_switch = 1, .light_brightness = 80};
      xQueueSend(control_queue, &auto_cmd, 0);  // 发送自动开灯指令
    }
    
    vTaskDelay(pdMS_TO_TICKS(100));  // 100ms周期检查指令
  }
}

2.4 Wi-Fi通信任务(MQTT协议对接云平台)

// MQTT客户端初始化(ESP8266透传模式)
void MQTT_Client_Init(void) {
  ESP8266_SendATCmd("AT+CWMODE=1\r\n", "OK", 1000);       // 设为STA模式
  ESP8266_SendATCmd("AT+CWJAP=\"WiFi_SSID\",\"PASSWORD\"\r\n", "OK", 5000); // 连接WiFi
  ESP8266_SendATCmd("AT+CIPSTART=\"TCP\",\"mqtt.eclipseprojects.io\",1883\r\n", "OK", 3000); // 连接MQTT服务器
}

// MQTT消息发布(上传传感器数据)
void MQTT_Publish_SensorData(SensorData_t *data) {
  char payload[128];
  sprintf(payload, "{\"temp\":%.1f,\"humi\":%.1f,\"light\":%d,\"motion\":%d}", 
          data->temp, data->humi, data->light, data->motion);
  ESP8266_SendATCmd("AT+MQTTPUB=0,\"home/sensor\",\"%s\",1,0\r\n", payload, 1000); // 发布主题home/sensor
}

void Comm_Task(void *pvParameters) {
  MQTT_Client_Init();  // 初始化MQTT客户端
  
  while (1) {
    // 从传感器队列获取数据并上传
    SensorData_t data;
    if (xQueuePeek(sensor_queue, &data, 0) == pdPASS) {
      MQTT_Publish_SensorData(&data);  // 上传传感器数据到云平台
    }
    
    // 接收云平台指令(如远程控制灯光)
    char rx_buf[64];
    if (ESP8266_Receive(rx_buf, sizeof(rx_buf), 100) > 0) {
      if (strstr(rx_buf, "\"cmd\":\"light_on\"")) {
        ControlCmd_t cmd = {.light_switch = 1, .light_brightness = 100};
        xQueueSend(control_queue, &cmd, 0);  // 转发指令到控制任务
      }
    }
    
    vTaskDelay(pdMS_TO_TICKS(5000));  // 5秒上传一次数据
  }
}

2.5 OLED显示任务(实时数据可视化)

void UI_Task(void *pvParameters) {
  OLED_Init();  // 初始化OLED
  
  while (1) {
    SensorData_t data;
    ControlCmd_t cmd;
    
    // 从队列获取数据
    xQueuePeek(sensor_queue, &data, 0);
    xQueuePeek(control_queue, &cmd, 0);
    
    // 清屏并显示数据
    OLED_Clear();
    OLED_ShowString(0, 0, "Smart Home", 16);
    char buf[32];
    sprintf(buf, "Temp:%.1fC Humi:%.1f%%", data.temp, data.humi);
    OLED_ShowString(0, 2, buf, 16);
    sprintf(buf, "Light:%dlux Motion:%d", data.light, data.motion);
    OLED_ShowString(0, 4, buf, 16);
    sprintf(buf, "Light:%s Bright:%d%%", cmd.light_switch ? "ON" : "OFF", cmd.light_brightness);
    OLED_ShowString(0, 6, buf, 16);
    
    OLED_Refresh();  // 刷新屏幕
    vTaskDelay(pdMS_TO_TICKS(500));  // 500ms刷新一次
  }
}

参考代码 基于STM32的智能家居设计 www.youwenfan.com/contentcnt/133726.html

四、手机APP设计(Android示例)

1. APP功能模块

  • 设备管理:灯光、窗帘、风扇等设备的开关、调光、调速控制。
  • 环境监测:实时显示温湿度、光照、空气质量数据及历史曲线。
  • 场景模式:预设“回家模式”(开灯+开窗帘+开空调)、“离家模式”(关所有设备+布防)。
  • 报警推送:烟雾/燃气泄漏、入侵检测时推送短信/APP通知。

2. 通信协议(MQTT)

  • 上行(设备→APP):传感器数据({"temp":25.5,"humi":60,"light":300,"motion":1})。
  • 下行(APP→设备):控制指令({"cmd":"light_ctrl","switch":1,"brightness":80})。

3. 核心代码示例(Android MQTT客户端)

// MQTT连接与订阅
MqttAndroidClient client = new MqttAndroidClient(context, "tcp://mqtt.eclipseprojects.io:1883", "android_client");
client.setCallback(new MqttCallback() {
    @Override
    public void messageArrived(String topic, MqttMessage message) throws Exception {
        String payload = new String(message.getPayload());
        JSONObject json = new JSONObject(payload);
        // 解析传感器数据并更新UI
        runOnUiThread(() -> {
            tvTemp.setText(json.getDouble("temp") + "℃");
            tvHumi.setText(json.getDouble("humi") + "%");
        });
    }
});

// 订阅传感器主题
client.subscribe("home/sensor", 1);

// 发送控制指令(如开灯)
JSONObject cmd = new JSONObject();
cmd.put("cmd", "light_ctrl");
cmd.put("switch", 1);
cmd.put("brightness", 80);
client.publish("home/control", new MqttMessage(cmd.toString().getBytes()));

五、系统调试与优化

1. 调试步骤

阶段 操作 工具
硬件调试 测量电源电压(5V/3.3V)、传感器输出信号 万用表、示波器
传感器校准 对比标准温湿度计校准DHT11/SHT30 标准仪表、串口打印ADC原始值
通信测试 用串口助手发送AT指令测试ESP8266/H-C05 串口调试助手(SSCOM)
联调 APP发送指令控制设备,观察执行结果 Android Studio调试、逻辑分析仪

2. 常见问题解决

问题 原因 解决方案
传感器数据跳变 电源干扰/ADC采样不稳定 增加滤波电容(0.1μF),软件滑动平均滤波
ESP8266连接失败 WiFi密码错误/信号弱 检查密码,缩短模块与路由器距离
窗帘电机堵转 机械阻力过大/驱动电流不足 减小步进电机转速(增大PWM周期)
APP控制延迟高 MQTT服务器响应慢/网络不稳定 更换MQTT服务器(如阿里云IoT),优化网络

六、扩展功能与进阶设计

1. 语音控制集成

  • 本地语音识别:添加LD3320语音模块(SPI接口),支持“打开灯光”“关闭窗帘”等指令。
  • 云端语音助手:对接天猫精灵/小爱同学,通过Wi-Fi接收语音指令并转发给STM32。

2. 视频监控扩展

  • 摄像头模块:添加OV2640摄像头(DCMI接口),实现实时视频监控(MJPEG流传输)。
  • 移动侦测:通过STM32分析摄像头图像,检测到移动物体时触发报警并截图上传云端。

3. 能源管理系统

  • 用电统计:添加电流互感器(ACS712)采集设备电流,计算功率及用电量(kWh)。
  • 节能算法:基于历史数据预测用电高峰,自动关闭非必要设备(如无人时关灯)。

4. 低功耗优化

  • STM32低功耗模式:空闲时进入STOP模式(关闭外设时钟,保留RTC),按键/传感器中断唤醒。
  • 传感器间歇工作:温湿度传感器每小时唤醒1次采集数据,其余时间断电。

七、总结

基于STM32的智能家居系统通过多传感器融合FreeRTOS多任务调度Wi-Fi/蓝牙双通信手机APP交互,实现了家庭环境的智能化管理与控制。系统具备高扩展性(支持添加摄像头、语音模块)、高可靠性(多重安全预警)及低功耗特性(STOP模式续航≥72小时),可作为智能家居原型开发或小型项目落地的基础框架。

posted @ 2026-04-21 16:48  chen_yig  阅读(37)  评论(0)    收藏  举报