目录
3、meter.h / meter.c —— 采样与电参数计算
4、relay.h / relay.c —— 过载保护继电器
6、display.h / display.c —— OLED 显示模块
难度定位:★★★☆☆(中等实用型)|适合:想做一个「民生实用 + 数据可视化充分 + 论文好写」选题、基础中等的同学|预估周期:3~4 周
一、这个毕设是干什么的?
一句话:做一套能实时监测家里用电情况、统计每天每月用电量、发现过载自动断电、还能在网页上看见用电曲线的家庭能耗监测系统。
再展开说:系统用一个 ESP32 主控,接上电压、电流传感器,串在家庭的用电回路里,实时采集电压、电流、功率,算出这一刻用了多少瓦;把数据上传到云平台,网页上能看当前功率、今日用电量、本月用电量,还有历史曲线;当功率超过设定阈值(比如接了太多大功率电器),系统自动断开继电器保护线路;它还会统计每天、每月的电费估算,帮你找出「哪些电器最费电」,为节能提供依据。
二、它解决什么问题?
不知道自己家用了多少电 → 实时显示功率、日/月用电量,用电情况一目了然;
电费账单看不懂、不知道怎么省 → 统计用电曲线与峰谷,找出高耗时段,有据可省;
大功率电器同时运行有安全隐患 → 超过阈值自动断电保护,避免跳闸/过载起火;
传统电表只能看总量、无数据 → 物联网方案能分时统计、远程查看、生成报表,让用电「可视化、可分析」。
本质是:把「机械电表只能看一个读数」升级成「实时采集 + 云端可视化 + 过载保护 + 能耗分析」的家庭能源管理系统,这正是「智慧能源 / 家庭节能」的典型落地。
三、核心功能?
| 功能 | 说明 |
|---|---|
| 实时功率采集 | 电压 + 电流传感器实时采样,计算瞬时功率 |
| 日/月用电量统计 | 功率对时间积分累计,得到 kWh,按日/月汇总 |
| 过载断电保护 | 功率超阈值自动断开继电器,保护线路 |
| 云端可视化 | WiFi 上传云平台,网页看实时数据与曲线 |
| 用电数据分析 | 峰谷时段、每日对比、电费估算 |
| 本地显示 | OLED 显示电压、电流、功率、用电量 |
| 历史记录 | 云平台存储历史数据,可查趋势 |
| 阈值可配置 | 过载阈值、上报间隔可调 |
四、用到哪些技术?
| 类别 | 具体 | 作用 |
|---|---|---|
| 主控 | ESP32 | 采样、计算、上传、控制 |
| 电压采集 | ZMPT101B 电压互感器模块 | 采集交流电压,隔离安全 |
| 电流采集 | SCT-013 钳形电流互感器(或 ACS712) | 采集交流电流,隔离安全 |
| 执行 | 继电器模块 | 过载时断开负载 |
| 通信 | ESP32 内置 WiFi + MQTT | 上传数据到云平台 |
| 显示 | SSD1306 OLED(I2C) | 本地显示实时数据 |
| 平台 | 云平台(如 OneNET / 阿里云 IoT / 自建 MQTT + 网页) | 数据存储与可视化 |
| 计算 | 有效值(RMS)计算 + 功率积分 | 把采样变成功率与电量 |
| 开发 | Arduino IDE + C 语言 | 编写烧录程序 |
安全提醒:本系统要接触 220V 交流电,采样必须用互感器隔离(ZMPT101B / SCT-013 都带隔离),不能把 220V 直接进主控。接线、测试务必断电操作,带电部分做好绝缘,切勿徒手触碰。
五、系统是怎么工作的?
家庭用电回路(220V) ↓ 经互感器隔离采样 ZMPT101B(电压) + SCT-013(电流) ↓ 模拟信号 ESP32 主控(ADC 采样 → RMS 算电压电流 → 功率 = U*I) ↓ ↓ OLED 本地显示 过载判断(P > 阈值 → 断继电器) ↓ WiFi + MQTT 上传云平台 ↓ 网页可视化:实时功率 / 日电量 / 月电量 / 曲线 / 电费估算
一句话串起来:互感器隔离采样 → ESP32 计算电压电流功率 → 本地显示 + 过载保护 → 经 WiFi/MQTT 上传云端 → 网页可视化与能耗分析。
这套「隔离采样 + 有效值计算 + 功率积分 + 云端可视化」的架构,是所有电参数监测、能耗管理类毕设的通用骨架,也可扩展成多回路、工商业用电监测。
六、大概怎么做?
买齐硬件(ESP32 + ZMPT101B + SCT-013 + 继电器 + OLED);
先做安全准备:所有接线断电进行,互感器只做隔离采样,220V 部分做好绝缘;
分别调通传感器:用万用表对比,确认 ADC 采样能反映电压电流变化;
写采样与计算:定时采样 → 计算有效值(RMS)→ 求瞬时功率 → 对时间积分算电量;
加过载保护:功率超阈值 → 断开继电器;
接 WiFi + MQTT,上传数据到云平台(OneNET/阿里云,或自建);
云平台建数据流/看板:实时功率、日电量、月电量曲线;
联调:接一个电吹风,网页功率明显上升;超阈值自动断电;曲线与累计电量正确,链路跑通即完成。
核心难点是「交流信号的 RMS 计算 + 功率积分算电量 + 过载判断」,其余是通信与显示。下面逐步展开。
七、硬件清单与接线
1、硬件清单
| 器件 | 型号/规格 | 数量 |
|---|---|---|
| 主控板 | ESP32 DevKitC | 1 |
| 电压传感器 | ZMPT101B 电压互感器模块 | 1 |
| 电流传感器 | SCT-013-000 钳形互感器(配采样电阻)或 ACS712-30A | 1 |
| 继电器模块 | 5V 单路/多路(带光耦隔离) | 1 |
| OLED 显示屏 | SSD1306 128×64(I2C) | 1 |
| 负载 | 台灯/电吹风/小功率电器 | 若干 |
| 电源 | 5V 适配器(给主控与模块) | 1 |
| 安全件 | 绝缘胶带、接线端子、保险丝 | 若干 |
| 面包板 + 杜邦线 | — | 若干 |
2、接线表(低压侧,220V 侧务必断电操作)
| ESP32 引脚 | 连接器件 | 说明 |
|---|---|---|
| GPIO34 | ZMPT101B OUT | ADC 读取电压信号(0~4095) |
| GPIO35 | SCT-013 采样输出 | ADC 读取电流信号 |
| GPIO26 | 继电器 IN | 过载时控制断开 |
| GPIO21 | OLED SDA | I2C 数据线 |
| GPIO22 | OLED SCL | I2C 时钟线 |
| 3.3V/5V | 传感器/继电器 VCC | 按模块要求供电 |
| GND | 所有器件地线 | 必须共地 |
安全要点:ZMPT101B 与 SCT-013 都通过电磁感应隔离,采样端与 220V 强电不直接相连;接 220V 回路的线必须断电、做好绝缘、用接线端子固定,测试时人不要触碰任何裸露导线。
八、核心器件原理简述
1、ZMPT101B 电压互感器
通过线圈感应把 220V 交流电压按比例缩小成安全的低电压信号,输出与输入隔离;
模块上一般有电位器可调零点/幅值,输出为叠加直流的交流波形,接 ADC 采样后可算有效值;
优点:安全隔离、成本低,是交流电压采集的常用方案。
2、SCT-013 钳形电流互感器
直接「钳」在导线外,通过磁场感应测量导线电流,无需断开电路,安全方便;
输出是小电流信号,通常需接一个采样电阻(负载电阻)转换成电压再进 ADC;
量程选型要匹配家庭用电(如 30A/100A),过小量程易饱和。
3、有效值(RMS)与功率计算
交流信号是正弦波,不能用瞬时值当有效值,要在一个周期内多次采样,按下式算:
有效值 = √( (1/N) × Σ(x_i²) )
功率 P = U_rms × I_rms(近似,忽略相位差;若用功率专用芯片可算真实功率);
电量 E(kWh) = Σ(P × Δt) / 3600,即把每次功率乘以时间间隔累加。
九、云端与协议设计
1、MQTT 主题与数据点
| 主题/数据流 | 含义 |
|---|---|
home/energy/voltage | 实时电压(V) |
home/energy/current | 实时电流(A) |
home/energy/power | 实时功率(W) |
home/energy/today | 今日用电量(kWh) |
home/energy/month | 本月用电量(kWh) |
home/energy/overload | 过载告警事件 |
2、上报 JSON 示例
{"voltage":226.5,"current":2.31,"power":523.2,
"today":1.28,"month":36.4,"overload":0,"ts":1762300800}
平台选择:OneNET / 阿里云 IoT / 腾讯云 IoT 都有免费额度与可视化看板;也可用 EMQX + InfluxDB + Grafana 自建,答辩展示曲线更专业。
十、开发环境搭建
安装 Arduino IDE(2.x);
添加 ESP32 板卡(开发板管理器搜索
esp32安装);安装库:
PubSubClient(MQTT)、ArduinoJson(JSON 组包)、Adafruit SSD1306、Adafruit GFX;选择开发板
ESP32 Dev Module,烧录失败按住 BOOT 键重试。
十一、软件设计(.h / .c 多文件工程)
代码按功能拆分:头文件(.h)只放宏、结构体、函数声明,源文件(.c)放具体实现,职责清晰、符合正式工程规范。
1、工程文件结构
esp32_energy_meter/ ├── config.h // 全局配置:引脚、校准系数、阈值、WiFi/MQTT ├── meter.h // 采样与电参数计算声明 ├── meter.c // ADC 采样、RMS、功率、电量实现 ├── relay.h // 继电器(过载保护)声明 ├── relay.c // 继电器控制实现 ├── cloud.h // 云端上传模块声明 ├── cloud.c // WiFi + MQTT + JSON 上报实现 ├── display.h // OLED 显示模块声明 ├── display.c // OLED 显示实现 └── main.c // 主程序:setup() / loop()
2、config.h —— 全局配置
#ifndef CONFIG_H
#define CONFIG_H
/* ADC 采样引脚 */
#define PIN_VOLT 34 /* 电压互感器输出 */
#define PIN_CURR 35 /* 电流互感器采样输出 */
/* 继电器(过载保护) */
#define PIN_RELAY 26 /* 低电平触发 */
/* OLED (I2C) */
#define PIN_SDA 21
#define PIN_SCL 22
/* 校准系数(用标准电压/电流实测标定) */
#define CAL_V 0.32f /* 电压 ADC→实际电压 系数 */
#define CAL_I 0.011f /* 电流 ADC→实际电流 系数 */
/* 过载阈值(W):超过即断开 */
#define POWER_LIMIT 3000.0f
/* 采样参数 */
#define SAMPLE_N 200 /* 每周期采样点数 */
#define SAMPLE_DT 0.0005f /* 采样间隔 0.5ms */
/* WiFi / MQTT(换成自己的) */
#define WIFI_SSID "your_wifi"
#define WIFI_PASS "your_pass"
#define MQTT_HOST "broker.emqx.io"
#define MQTT_PORT 1883
#define MQTT_TOPIC "home/energy/data"
#endif
3、meter.h / meter.c —— 采样与电参数计算
meter.h(声明):
#ifndef METER_H
#define METER_H
#include <stdbool.h>
typedef struct {
float voltage; /* 电压 V */
float current; /* 电流 A */
float power; /* 功率 W */
float energy; /* 累计电量 kWh */
bool valid; /* 数据是否有效 */
} meter_data_t;
void meter_init(void); /* 初始化 ADC */
meter_data_t meter_measure(void); /* 采样一次并计算各项 */
#endif
meter.c(实现,核心算法):
#include "meter.h"
#include "config.h"
static float totalEnergy = 0.0f; /* 累计电量 kWh */
void meter_init(void) {
analogReadResolution(12); /* 12 位 ADC:0~4095 */
pinMode(PIN_VOLT, INPUT);
pinMode(PIN_CURR, INPUT);
}
/* 计算一段采样数据的有效值 */
static float calcRMS(int pin, float cal) {
float sum = 0.0f;
for (int i = 0; i < SAMPLE_N; i++) {
float v = analogRead(pin) - 2048; /* 去直流偏置(约中点) */
sum += v * v;
delayMicroseconds(SAMPLE_DT * 1000);
}
float rms = sqrt(sum / SAMPLE_N);
return rms * cal;
}
meter_data_t meter_measure(void) {
meter_data_t d;
d.voltage = calcRMS(PIN_VOLT, CAL_V);
d.current = calcRMS(PIN_CURR, CAL_I);
d.power = d.voltage * d.current; /* 近似功率 */
d.valid = (d.voltage > 50.0f); /* 电压太低视为无效 */
/* 电量累计:P(瓦) × 采样时长(时) */
float dt_hour = (SAMPLE_N * SAMPLE_DT) / 3600.0f;
if (d.valid) totalEnergy += (d.power * dt_hour);
d.energy = totalEnergy;
return d;
}
4、relay.h / relay.c —— 过载保护继电器
relay.h(声明):
#ifndef RELAY_H
#define RELAY_H
#include <stdbool.h>
void relay_init(void); /* 初始化,默认闭合(通电) */
void relay_cut(void); /* 断开负载 */
void relay_restore(void); /* 恢复供电 */
bool relay_is_cut(void); /* 是否已断开 */
#endif
relay.c(实现):
#include "relay.h"
#include "config.h"
static bool cut = false;
void relay_init(void) {
pinMode(PIN_RELAY, OUTPUT);
relay_restore(); /* 上电默认闭合通电 */
}
void relay_cut(void) {
digitalWrite(PIN_RELAY, HIGH); /* 低电平触发,断开时给高电平 */
cut = true;
}
void relay_restore(void) {
digitalWrite(PIN_RELAY, LOW);
cut = false;
}
bool relay_is_cut(void) { return cut; }
5、cloud.h / cloud.c —— 云端上传模块
cloud.h(声明):
#ifndef CLOUD_H
#define CLOUD_H
#include "meter.h"
#include <stdbool.h>
bool cloud_init(void); /* 连 WiFi 与 MQTT */
bool cloud_upload(const meter_data_t *d, bool overload); /* 上报一次 */
#endif
cloud.c(实现,关键逻辑):
#include "cloud.h"
#include "config.h"
#include <WiFi.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>
static WiFiClient espClient;
static PubSubClient mqtt(espClient);
bool cloud_init(void) {
WiFi.begin(WIFI_SSID, WIFI_PASS);
while (WiFi.status() != WL_CONNECTED) delay(500);
mqtt.setServer(MQTT_HOST, MQTT_PORT);
return mqtt.connect("energy-meter-01");
}
bool cloud_upload(const meter_data_t *d, bool overload) {
if (!mqtt.connected()) mqtt.connect("energy-meter-01");
StaticJsonDocument<200> doc;
doc["voltage"] = round(d->voltage * 10) / 10.0f;
doc["current"] = round(d->current * 100) / 100.0f;
doc["power"] = d->power;
doc["energy"] = d->energy;
doc["overload"] = overload ? 1 : 0;
char buf[160];
serializeJson(doc, buf, sizeof(buf));
return mqtt.publish(MQTT_TOPIC, buf);
}
6、display.h / display.c —— OLED 显示模块
display.h(声明):
#ifndef DISPLAY_H
#define DISPLAY_H
#include "meter.h"
void display_init(void);
void display_show(const meter_data_t *d, bool cut);
#endif
display.c(实现):
#include "display.h"
#include "config.h"
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
static Adafruit_SSD1306 oled(128, 64, &Wire, -1);
void display_init(void) {
Wire.begin(PIN_SDA, PIN_SCL);
oled.begin(SSD1306_SWITCHCAPVCC, 0x3C);
oled.clearDisplay();
oled.setTextColor(SSD1306_WHITE);
}
void display_show(const meter_data_t *d, bool cut) {
oled.clearDisplay();
oled.setCursor(0, 0);
oled.print("V:"); oled.print(d->voltage); oled.println("V");
oled.print("I:"); oled.print(d->current); oled.println("A");
oled.print("P:"); oled.print(d->power); oled.println("W");
oled.print("E:"); oled.print(d->energy); oled.println("kWh");
oled.println(cut ? "OVERLOAD CUT!" : "Normal");
oled.display();
}
7、main.c —— 主程序
#include "config.h"
#include "meter.h"
#include "relay.h"
#include "cloud.h"
#include "display.h"
static bool overloaded = false;
void setup() {
meter_init();
relay_init();
display_init();
cloud_init();
}
void loop() {
/* ① 采样与计算 */
meter_data_t d = meter_measure();
if (!d.valid) return; /* 数据无效跳过 */
/* ② 过载保护:超过阈值断电,恢复正常后自动恢复 */
if (d.power > POWER_LIMIT) {
relay_cut();
overloaded = true;
} else if (overloaded && d.power < POWER_LIMIT * 0.7f) {
relay_restore(); /* 回落到 70% 以下才恢复,防抖 */
overloaded = false;
}
/* ③ 本地显示 + 云端上报 */
display_show(&d, relay_is_cut());
cloud_upload(&d, overloaded);
delay(1000); /* 每秒一轮 */
}
以上为核心模块代码。需要时可继续扩展:新增
cost.c电费估算、history.c本地存历史曲线、多回路采集等,主程序只调用接口,逻辑一目了然。
十二、代码要点讲解
.h/.c分离:.h只放宏、结构体、函数声明,.c放实现隐藏细节,模块独立便于扩展,是论文「模块化设计」的要点;
config.h集中配置:引脚、校准系数、阈值、WiFi/MQTT 都收在一个文件,改参数不用翻代码;
calcRMS有效值算法:一个周期内多次采样、平方求和再开方,是交流电参数测量的核心;
CAL_V / CAL_I标定系数:ADC 读数不是真实值,必须实测标定,否则功率不准;电量积分:
totalEnergy += P × dt,把瞬时功率按时间累加,得到 kWh,是电表的核心逻辑;过载保护防抖:超过阈值立即断,回落到 70% 以下才恢复,避免临界状态反复通断;
JSON 上报:一次上报电压、电流、功率、电量、告警,平台端一次解码全部展示;
互感器隔离:采样端与 220V 强电隔离,这是安全底线。
十三、功能测试与验收
| 功能 | 实现方式 | 测试方法 |
|---|---|---|
| 电压采集 | calcRMS(PIN_VOLT) | 对比万用表电压,误差在可接受范围 |
| 电流采集 | calcRMS(PIN_CURR) | 用万用表钳表对比,接入不同负载验证 |
| 功率显示 | U×I | 接台灯,功率明显小于电吹风,符合常识 |
| 用电量累计 | totalEnergy += P×dt | 运行一段时间,与理论计算值对比 |
| 过载保护 | P > POWER_LIMIT → relay_cut | 同时开多个大功率电器,超过阈值自动断电 |
| 云端上传 | MQTT JSON | 平台看板实时收到数据、曲线与实际相符 |
| 本地显示 | OLED | 电压/电流/功率/电量/状态正常刷新 |
分步验收清单:
上电 OLED 显示电压、电流、功率 → 显示层 OK;
接入台灯,功率读数合理上升 → 采样与计算 OK;
换电吹风,功率明显增大 → 功率测量 OK;
运行一段时间,电量累计增加 → 电量积分 OK;
加多个负载超过阈值,继电器断开 → 过载保护 OK;
云平台看到实时数据与曲线 → 云端可视化 OK。
十四、能给你什么启发?
选题优势:民生实用方向,贴近生活、好讲解;数据可视化模块充足(实时功率 + 日电量 + 月电量 + 曲线),论文「数据分析」部分好写、篇幅充足;硬件成本低(互感器便宜)、逻辑清晰,答辩演示直观(接电器看功率变化很直观)。
想冲更高分数,随便往这几个方向扩:
电费估算:按阶梯电价/峰谷电价算电费,给出节省建议;
分回路监测:多路互感器分别监测空调、热水器等,找出「电老虎」;
加开关控制:远程/定时断开某路,实现节能管理;
异常用电告警:功率突增、夜间异常耗电推送告警;
数据分析报表:日/周/月报表、峰谷分析,接口更丰富;
加太阳能/储能:监测自发自用,拓展到家庭微电网。
十五、开题报告 & 答辩要点
1、开题报告可直接改用的表述
1. 选题依据(背景):随着家庭用电设备增多,用户对用电情况的了解仍停留在「月末看电表」层面,缺乏实时、分时、可视化的用电数据,难以发现高耗电器与安全隐患。物联网技术使家庭用电的实时采集、云端可视化与过载保护成为可能,构建家庭能源消耗监测系统对节能减排与用电安全具有现实意义。
2. 研究意义:本课题将电压电流传感、有效值计算、功率积分、无线通信与可视化技术相结合,一方面让用户实时掌握家庭用电、发现节能空间、保障用电安全;另一方面完整覆盖模拟信号采集、电参数计算、数据上传与可视化等物联网关键技术,对巩固专业知识、锻炼软硬件综合开发能力有重要意义。
3. 系统功能概述:系统以 ESP32 为主控,通过 ZMPT101B 电压互感器与 SCT-013 电流互感器隔离采集家庭用电的电压、电流,计算有效值与瞬时功率,累计得到日/月用电量;功率超过阈值时自动断开继电器保护线路;数据经 WiFi/MQTT 上传云平台,在网页端进行实时显示、历史曲线与能耗分析。
4. 创新点(按实际情况选取):
采用互感器隔离采样,安全可靠,可测真实交流电参数;
实现实时采集 + 过载保护 + 云端可视化一体化;
提供日/月用电量统计与能耗分析,具备节能指导价值。
5. 技术难点:
交流信号的有效值(RMS)计算与传感器标定;
功率对时间的积分与电量累计精度;
过载判断与保护动作的可靠性(防误动/防抖)。
2、答辩常见问题(参考回答要点)
| 可能被问 | 回答要点 |
|---|---|
| 怎么测交流电压电流? | 用 ZMPT101B 电压互感器、SCT-013 电流互感器隔离采样,进 ADC |
| 为什么不用直接分压采样? | 直接接触 220V 不安全,互感器隔离采样安全可靠 |
| 有效值怎么算? | 一个周期多次采样,平方求和开方得 RMS,再乘标定系数 |
| 电量怎么累计? | 功率对时间积分,E += P×dt,累加得到 kWh |
| 过载怎么保护? | 功率超阈值断开继电器,回落到 70% 才恢复,防抖 |
| 数据怎么上云? | WiFi + MQTT,JSON 打包上报,平台看板可视化 |
| 精度怎么保证? | 用标准表实测标定系数,采样周期覆盖完整工频周期 |
| 系统有哪些改进空间? | 电费估算、分回路监测、异常告警、报表、储能监测等 |
转载自 CSDN-专业IT技术社区
原文链接:https://blog.csdn.net/x1649545783/article/details/170145937




