用STM32F103和ESP8266做个智能插座:手机远程监控功率,还能自动断电(附完整代码)

📅 2026/7/6 13:02:40 👁️ 阅读次数 📝 编程学习
用STM32F103和ESP8266做个智能插座:手机远程监控功率,还能自动断电(附完整代码)

用STM32F103和ESP8266打造高精度智能插座:从硬件设计到云端控制全解析

家里热水器忘关导致电费飙升?电脑长时间待机浪费能源?今天我们就用STM32F103和ESP8266这两个性价比极高的硬件平台,打造一个能手机远程监控、自动断电的智能插座解决方案。这个项目不仅实用,还能让你深入理解交流电检测、WiFi通信和继电器控制的完整技术链条。

1. 项目整体架构设计

智能插座的核心功能可以分解为三个模块:交流电参数检测、主控逻辑处理和无线通信。我们选用STM32F103作为主控芯片,它不仅具备足够的ADC通道和计算能力,还有丰富的社区资源支持。ESP8266则负责WiFi连接,将数据上传到手机端。

系统工作流程

  1. 电压/电流互感器实时采集交流电参数
  2. STM32进行ADC采样和功率计算
  3. 通过串口将数据发送给ESP8266模块
  4. WiFi模块将数据推送到手机APP
  5. 用户可以通过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端备注
TXPA9RX需电平匹配
RXPA10TX需电平匹配
GNDGNDGND必须共地
VCC3.3V3.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 智能控制逻辑扩展

除了基本的过载保护,可以增加更多实用功能:

  1. 定时开关:设置特定时段自动断电

    # 示例伪代码 if current_time in schedule_off_period: turn_off_relay()
  2. 用电统计:按日/周/月分析用电习惯

    // 存储每日用电量 struct { uint16_t day; float energy; } energy_log[31];
  3. 场景联动:与其他智能设备配合,如"离开家时自动关闭所有插座"

  4. 异常报警:检测到持续过载或电压异常时推送通知

5. 校准与调试技巧

任何电力测量设备都需要校准才能保证精度。你需要一个已知功率的负载(如白炽灯泡)作为参考。

校准步骤:

  1. 接入纯阻性负载(如100W灯泡)
  2. 测量实际电压和电流(用万用表)
  3. 调整代码中的校准系数
    // 校准后的计算公式 realVoltage = rawADC * 0.87f; // 调整这个系数

常见问题排查:

  • 数据跳动大:增加软件滤波,如移动平均或卡尔曼滤波
  • WiFi频繁断开:检查电源稳定性,添加看门狗
  • 继电器误动作:调整过载判断的延时时间

这个项目最有趣的部分是你可以不断扩展功能,比如加入温度传感器监测设备发热,或者用机器学习算法识别电器类型。我曾用类似方案帮朋友解决了鱼缸加热器故障导致的电费异常问题,通过历史用电数据分析,准确锁定了故障发生的时间点。