用STM32F103和ESP8266做个智能插座:手机远程监控功率,还能自动断电(附完整代码)
用STM32F103和ESP8266打造高精度智能插座:从硬件设计到云端控制全解析
家里热水器忘关导致电费飙升?电脑长时间待机浪费能源?今天我们就用STM32F103和ESP8266这两个性价比极高的硬件平台,打造一个能手机远程监控、自动断电的智能插座解决方案。这个项目不仅实用,还能让你深入理解交流电检测、WiFi通信和继电器控制的完整技术链条。
1. 项目整体架构设计
智能插座的核心功能可以分解为三个模块:交流电参数检测、主控逻辑处理和无线通信。我们选用STM32F103作为主控芯片,它不仅具备足够的ADC通道和计算能力,还有丰富的社区资源支持。ESP8266则负责WiFi连接,将数据上传到手机端。
系统工作流程:
- 电压/电流互感器实时采集交流电参数
- STM32进行ADC采样和功率计算
- 通过串口将数据发送给ESP8266模块
- WiFi模块将数据推送到手机APP
- 用户可以通过APP远程控制继电器状态
硬件选型上,TV1005M电压互感器和TA1005M电流互感器是性价比很高的选择,它们都能提供2000V的隔离电压,确保使用安全。继电器模块建议选用固态继电器,相比机械式继电器具有更长的使用寿命和更快的响应速度。
2. 硬件电路设计与安全注意事项
2.1 交流电检测电路
电压检测采用TV1005M互感器,其变比为1000:1,意味着220V交流电经过互感器后输出约为0.22V。我们需要通过运放电路将这个信号放大到适合STM32 ADC输入的0-3.3V范围。
典型的分压电路设计:
// 电压检测电路计算公式 实际电压 = ADC值 × (3.3/4096) × (R1+R2)/R2 × 变比倒数电流检测使用TA1005M互感器,需要在次级并联一个精密采样电阻。这里有个关键点:当没有电流通过时,互感器输出不是零,而是一个很小的偏移电压,需要在代码中进行软件校准。
警告:直接测量市电存在触电风险!所有高压侧电路必须做好绝缘处理,建议使用3D打印外壳或购买现成的绝缘插座改装。
2.2 STM32与ESP8266的接口设计
两个模块通过串口通信,连接时需要注意:
| 引脚 | STM32端 | ESP8266端 | 备注 |
|---|---|---|---|
| TX | PA9 | RX | 需电平匹配 |
| RX | PA10 | TX | 需电平匹配 |
| GND | GND | GND | 必须共地 |
| VCC | 3.3V | 3.3V | 切勿接5V |
ESP8266的供电要特别注意,上电瞬间电流可能达到500mA,建议单独使用一个LDO稳压器而不是直接从STM32取电。
3. 软件实现与关键代码解析
3.1 ADC采样与数据处理
STM32的ADC需要配置为连续扫描模式,对电压和电流通道交替采样。为了抑制50Hz工频干扰,每个周期采样至少20个点(即1ms采样一次),然后取一个周期的平均值。
// ADC初始化关键代码 void Adc_Init(void) { ADC_InitTypeDef ADC_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; ADC_InitStructure.ADC_ScanConvMode = ENABLE; ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfChannel = 2; ADC_Init(ADC1, &ADC_InitStructure); ADC_Cmd(ADC1, ENABLE); ADC_ResetCalibration(ADC1); while(ADC_GetResetCalibrationStatus(ADC1)); ADC_StartCalibration(ADC1); while(ADC_GetCalibrationStatus(ADC1)); }功率计算需要考虑功率因数,简单的做法是电压和电流的瞬时值相乘后积分:
// 实时功率计算 for(int i=0; i<SAMPLING_POINTS; i++){ instantPower = voltageSamples[i] * currentSamples[i]; totalPower += instantPower; } realPower = totalPower / SAMPLING_POINTS;3.2 WiFi通信协议设计
ESP8266配置为TCP服务器,手机APP作为客户端连接。数据格式采用紧凑的字符串协议,例如:
V:230A:01234P:1234567Q:1234.56T:1234R:1字段说明:
- V:电压(单位V)
- A:电流(单位mA)
- P:功率(单位mW)
- Q:累计电量(单位Wh)
- T:运行时间(单位秒)
- R:继电器状态(1接通,0断开)
在STM32端,使用sprintf生成数据包:
char packet[50]; sprintf(packet,"V:%03dA:%05dP:%07luQ:%06.2fT:%04dR:%d", voltage, current, power, energy, uptime, relayState);4. 手机APP交互与高级功能实现
4.1 基础数据显示
APP界面应清晰展示实时数据:
- 电压、电流波形图
- 实时功率数字显示
- 累计用电量统计
- 继电器状态指示
建议使用MQTT协议而非原始TCP连接,这样可以实现断线自动重连和消息队列。流行的IoT平台如Blynk或Node-RED都可以快速搭建监控界面。
4.2 智能控制逻辑扩展
除了基本的过载保护,可以增加更多实用功能:
定时开关:设置特定时段自动断电
# 示例伪代码 if current_time in schedule_off_period: turn_off_relay()用电统计:按日/周/月分析用电习惯
// 存储每日用电量 struct { uint16_t day; float energy; } energy_log[31];场景联动:与其他智能设备配合,如"离开家时自动关闭所有插座"
异常报警:检测到持续过载或电压异常时推送通知
5. 校准与调试技巧
任何电力测量设备都需要校准才能保证精度。你需要一个已知功率的负载(如白炽灯泡)作为参考。
校准步骤:
- 接入纯阻性负载(如100W灯泡)
- 测量实际电压和电流(用万用表)
- 调整代码中的校准系数
// 校准后的计算公式 realVoltage = rawADC * 0.87f; // 调整这个系数
常见问题排查:
- 数据跳动大:增加软件滤波,如移动平均或卡尔曼滤波
- WiFi频繁断开:检查电源稳定性,添加看门狗
- 继电器误动作:调整过载判断的延时时间
这个项目最有趣的部分是你可以不断扩展功能,比如加入温度传感器监测设备发热,或者用机器学习算法识别电器类型。我曾用类似方案帮朋友解决了鱼缸加热器故障导致的电费异常问题,通过历史用电数据分析,准确锁定了故障发生的时间点。
