1. 项目概述
在智能家居快速发展的今天,传统插座已经无法满足现代家庭对用电设备智能化管理的需求。作为一名嵌入式开发者,我最近基于STM32F103C8T6开发了一款具备电量计量和远程控制功能的智能插座。这个项目不仅实现了基本的远程开关控制,还能实时监测用电设备的电压、电流、功率和累计电量,为家庭用电管理提供了数据支持。
这个智能插座的核心功能包括:
- 通过HLW8012芯片实现高精度电量计量
- 通过ESP8266 WiFi模块实现远程控制
- 通过继电器模块安全控制220V市电通断
- 本地按键应急控制和状态指示灯
- 电量数据上传至服务器或手机APP
提示:本项目涉及220V市电操作,在实施过程中务必注意安全,建议有一定电子基础的开发者尝试。
2. 硬件设计与电路连接
2.1 硬件选型与原理
硬件部分我选择了性价比较高的方案:
- 主控芯片:STM32F103C8T6最小系统板(72MHz主频,64KB Flash,20KB RAM)
- 电量计量:HLW8012芯片(支持电压、电流、功率和电量计量)
- WiFi模块:ESP8266-01S(支持AT指令透传模式)
- 继电器:5V单路光耦隔离继电器(10A/250VAC负载能力)
- 电源:220V转5V AC-DC模块(为整个系统供电)
电路设计上主要考虑了几个关键点:
- 强电与弱电隔离:市电部分与低压控制电路完全隔离
- 信号抗干扰:所有数字信号线都加了滤波电容
- 安全防护:继电器输出端加了压敏电阻和保险丝
2.2 详细接线方案
经过多次调试优化,最终确定的接线方案如下:
| STM32引脚 | 外接器件 | 连接说明 |
|---|---|---|
| 5V | HLW8012 VCC | 供电 |
| GND | HLW8012 GND | 共地 |
| PA2 | HLW8012 TX | UART2 RX(接收电量数据) |
| PA3 | HLW8012 RX | UART2 TX(预留配置接口) |
| 3.3V | ESP8266 VCC | 供电(需串联100Ω电阻限流) |
| GND | ESP8266 GND | 共地 |
| PB10 | ESP8266 TX | UART3 RX(接收WiFi数据) |
| PB11 | ESP8266 RX | UART3 TX(发送WiFi数据) |
| PA0 | 继电器IN | 控制端(低电平吸合) |
| 5V | 继电器VCC | 线圈供电 |
| GND | 继电器GND | 共地 |
| PB0 | 按键1 | 上拉输入(接GND为按下) |
| PB1 | 按键2 | 上拉输入(接GND为按下) |
| PA1 | 绿灯 | 串220Ω电阻接GND |
| PA2 | 红灯 | 串220Ω电阻接GND |
2.3 关键电路设计要点
-
HLW8012采样电路:
- 电压采样:通过1MΩ和1kΩ电阻分压
- 电流采样:使用5mA/2mA的电流互感器
- 在VCC和GND之间加0.1μF去耦电容
-
ESP8266供电电路:
- 虽然模块支持3.3-3.6V供电,但实测3.3V供电时WiFi信号较弱
- 最终采用5V供电,通过100Ω电阻限流,并在模块端加3.3V LDO稳压
-
继电器驱动电路:
- 使用NPN三极管驱动继电器线圈
- 线圈两端并联续流二极管
- 输出端加装压敏电阻(07D471K)和10A保险丝
注意事项:市电部分接线必须确保断电操作,所有裸露导线必须做好绝缘处理,建议使用热缩管或绝缘胶带包裹。
3. 软件开发环境搭建
3.1 工具链准备
开发这个项目需要以下软件工具:
-
Keil MDK-ARM V5.29:STM32的主要开发环境
- 需要安装STM32F1的Device Family Pack
- 建议使用注册版(代码大小无限制)
-
STM32CubeMX 6.8.0:用于外设初始化和引脚分配
- 生成HAL库基础代码
- 可视化配置时钟树和外设
-
串口调试工具:
- 推荐使用SSCOM或SecureCRT
- 需要同时监控HLW8012和ESP8266的数据
-
ESP8266烧录工具:
- 官方Flash Download Tools
- 需要准备透传固件(如AT固件)
3.2 STM32CubeMX配置详解
在CubeMX中的关键配置步骤:
-
时钟配置:
- HSE时钟:8MHz外部晶振
- PLL倍频:9倍(8MHz×9=72MHz)
- 系统时钟:72MHz
- APB1分频:2(36MHz)
- APB2分频:1(72MHz)
-
UART配置:
-
UART2(HLW8012):
- 波特率:9600
- 数据位:8
- 停止位:1
- 无校验
- 开启接收中断
-
UART3(ESP8266):
- 波特率:115200
- 数据位:8
- 停止位:1
- 无校验
- 开启接收中断
-
-
GPIO配置:
- PA0:GPIO_Output(继电器控制)
- PA1:GPIO_Output(绿灯)
- PA2:GPIO_Output(红灯)
- PB0:GPIO_Input(按键1,上拉)
- PB1:GPIO_Input(按键2,上拉)
-
NVIC配置:
- 开启UART2全局中断
- 开启UART3全局中断
- 优先级设置:UART2 > UART3
生成代码时选择:
- Toolchain/IDE:MDK-ARM V5
- 勾选"Generate peripheral initialization as a pair of .c/.h files"
4. 核心代码实现
4.1 软件架构设计
采用模块化设计,主要分为以下几个驱动层:
- HLW8012驱动:处理电量计量数据
- ESP8266驱动:实现WiFi连接和数据透传
- 继电器驱动:控制插座通断
- 按键指示灯驱动:本地人机交互
code复制SmartSocket/
├── Core/
│ ├── Inc/
│ │ ├── main.h
│ │ ├── hal_wifi.h // WiFi驱动
│ │ ├── hal_energy.h // 电量计量驱动
│ │ ├── hal_relay.h // 继电器驱动
│ │ └── key_led.h // 按键和指示灯驱动
│ └── Src/
│ ├── main.c
│ ├── hal_wifi.c
│ ├── hal_energy.c
│ ├── hal_relay.c
│ └── key_led.c
└── MDK-ARM/
└── SmartSocket.uvprojx
4.2 电量计量模块实现
HLW8012驱动关键代码解析:
c复制// hal_energy.h
typedef struct {
float voltage; // 电压(V)
float current; // 电流(A)
float power; // 功率(W)
float energy; // 累计电量(kWh)
uint8_t status; // 数据有效标志
} HLW8012_DataDef;
void HLW8012_Init(void);
void HLW8012_ReadData(HLW8012_DataDef *data);
void HLW8012_UART_Callback(uint8_t *data, uint16_t len);
数据解析逻辑:
- HLW8012每秒通过UART发送10字节数据帧
- 帧格式:0xAA + 电压(2B) + 电流(2B) + 功率(2B) + 电量(2B) + 0x55
- 电压值 = (data[1]<<8 | data[2]) / 10.0
- 电流值 = (data[3]<<8 | data[4]) / 1000.0
- 功率值 = (data[5]<<8 | data[6]) / 10.0
- 电量值 = (data[7]<<8 | data[8]) / 1000.0
经验分享:实际测试发现HLW8012的电流采样在小电流时误差较大,建议在代码中加入校准系数,可以通过对比专业电表读数来调整校准值。
4.3 WiFi通信模块实现
ESP8266驱动关键功能:
c复制// hal_wifi.h
typedef enum {
WIFI_UNINIT = 0,
WIFI_CONNECTING,
WIFI_CONNECTED,
WIFI_DISCONNECTED
} WIFI_StatusDef;
void ESP8266_Init(void);
WIFI_StatusDef ESP8266_CheckStatus(void);
void ESP8266_SendData(uint8_t *data, uint16_t len);
void ESP8266_ReceiveData(uint8_t *data, uint16_t *len);
AT指令配置流程:
- AT\r\n - 测试模块是否正常
- AT+CWMODE=1\r\n - 设置为Station模式
- AT+CWJAP="SSID","PWD"\r\n - 连接WiFi
- AT+CIPMODE=1\r\n - 设置透传模式
- AT+CIPSEND\r\n - 进入透传模式
避坑指南:ESP8266-01S的RX引脚对电压很敏感,直接接5V TTL可能会损坏模块。建议采用以下任一方案:
- 使用电平转换芯片(如TXS0108E)
- 串联1kΩ电阻限流
- 使用STM32的3.3V供电(需确保信号质量)
4.4 主控制逻辑实现
main.c中的核心控制流程:
c复制while (1) {
// 1. 读取电量数据
HLW8012_ReadData(&energy_data);
// 2. 处理按键
Key_TypeDef key = Key_Scan();
if(key == KEY1_PRESS) {
Relay_SetStatus(!Relay_GetStatus());
}
// 3. 处理WiFi指令
ESP8266_ReceiveData(wifi_rx_buf, &wifi_rx_len);
if(wifi_rx_len > 0) {
SmartSocket_HandleWifiCmd();
}
// 4. 定时上报数据
if(HAL_GetTick() - tick > 1000) {
tick = HAL_GetTick();
SmartSocket_SendEnergyData();
}
HAL_Delay(10);
}
数据上报格式示例:
code复制VOL:220.5V,CUR:1.256A,POW:276.8W,ENE:0.345kWh
控制指令格式:
- 开启插座:RELAY_ON
- 关闭插座:RELAY_OFF
5. 系统调试与优化
5.1 本地功能测试
上电后的测试流程:
-
观察指示灯状态:
- 红灯常亮:系统正常启动,继电器断开
- 红灯闪烁:系统异常(需检查串口输出)
-
按键测试:
- 按键1:切换继电器状态(红灯/绿灯切换)
- 按键2:重置累计电量(调试用)
-
串口监控:
- UART2(9600):查看HLW8012原始数据
- UART3(115200):查看ESP8266通信日志
5.2 远程控制测试
WiFi连接测试步骤:
- 确保路由器后台能看到ESP8266分配的IP
- 使用网络调试工具连接该IP的TCP端口(默认8266)
- 发送控制指令:
- RELAY_ON:应收到RELAY_ON_OK回复
- RELAY_OFF:应收到RELAY_OFF_OK回复
- 每秒应自动收到电量数据
5.3 常见问题排查
-
WiFi连接不稳定:
- 检查天线是否完好
- 尝试降低UART波特率到9600
- 在AT+CWJAP指令后增加更长延时
-
电量数据异常:
- 检查HLW8012的VREF电压(正常2.5V)
- 确认电流互感器方向正确
- 检查UART接线(TX/RX是否交叉)
-
继电器不动作:
- 测量PA0引脚电平变化
- 检查继电器线圈两端电压
- 确认继电器模块逻辑(高/低电平触发)
6. 安全封装与扩展建议
6.1 安全封装要点
-
外壳选择:
- 使用阻燃ABS材质
- 确保足够的散热空间
- 固定孔位与电路板匹配
-
内部绝缘:
- 高压与低压区域物理隔离
- 使用绝缘隔板分隔
- 所有市电接头热缩管保护
-
安全标识:
- 外壳明显位置标注"高压危险"
- 标注最大负载功率(如2200W)
- 提供产品规格标签
6.2 功能扩展方向
-
云端平台接入:
- 阿里云IoT:使用MQTT协议接入
- 腾讯云IoT:通过AT+MQTT指令接入
- 私有服务器:自定义TCP协议
-
本地显示增强:
- 0.96寸OLED显示实时数据
- 增加数码管显示当前功率
- 添加触摸按键替代机械按键
-
安全功能升级:
- 过流保护(硬件比较器+软件双重保护)
- 漏电保护(通过电流差值检测)
- 定时自动断电功能
-
能源管理功能:
- 电量统计(日/月/年)
- 电费计算(根据费率设置)
- 用电异常报警
7. 项目总结与心得
通过这个项目的实践,我总结了以下几点经验:
-
硬件设计方面:
- 强电与弱电隔离至关重要,光耦隔离是最低要求
- PCB布局时,高压部分要留有足够爬电距离
- 所有接口考虑防反接和过压保护
-
软件开发方面:
- HAL库的中断回调机制大大简化了开发
- 模块化设计便于后期功能扩展
- 状态机模式适合处理异步通信
-
调试技巧:
- 使用逻辑分析仪抓取UART信号
- 分段测试(先低压后高压)
- 添加丰富的调试日志输出
这个项目的完整代码和原理图我已经开源在GitHub上,后续我计划增加手机APP控制界面和用电数据分析功能。对于想尝试类似项目的开发者,我的建议是从低压部分开始逐步验证,确保基础功能稳定后再接入市电,安全永远是第一位的。
