基于ESP32与PZEM-004T的智能电能表DIY:从硬件选型到数据可视化

智能电能表ESP32PZEM-004T
于 2026-05-28 13:22:54 修改
·本内容遵循CC 4.0 BY-SA版权协议

1. 项目概述:从研究需求到DIY智能电表的诞生

几年前,我在大学里做一项关于家庭节能策略的研究时,遇到了一个非常具体且棘手的问题:我需要长时间、连续地监测并记录一个普通插座的实时用电数据,用于后续在Excel或Python中进行能耗模式分析。市面上的商用电能监测仪要么价格昂贵,要么功能封闭,无法导出我需要的原始时序数据;而网络上能找到的DIY方案,要么过于简陋仅能显示瞬时数值,要么代码复杂、集成度低,难以稳定运行。正是在这种“求而不得”的困境下,我决定自己动手,打造一个集实时显示、数据记录和可视化于一体的智能电能表。这个项目的核心目标很明确:低成本、高灵活性、数据可导出。最终,我选择了PZEM-004T作为测量核心,ESP32-C3作为大脑,再配上一块带SD卡槽的TFT触摸屏,构成了今天要分享的这个系统。它不仅完美解决了我的论文数据采集问题,后来更被我用于长期监测家中冰箱、电脑等设备的待机功耗,成为了一个实用的能耗管理工具。无论你是电子爱好者、物联网开发者,还是像我当初一样需要可靠数据支撑的研究人员,这个项目都能为你提供一个从硬件到软件、从原理到实操的完整参考。

2. 核心硬件选型与设计思路解析

一套稳定可靠的监测系统,硬件是基石。我的选型原则是:在满足精度和功能需求的前提下,尽可能采用成熟、易得的模块化组件,以降低开发难度和风险。

2.1 测量核心:为何是PZEM-004T?

在电流/功率测量领域,方案很多,从简单的ACS712霍尔传感器搭配分压电路自建,到使用成品电能计量芯片如ATT7022EU。我最终选择PZEM-004T模块,是基于以下几点核心考量:

  1. 集成化与高精度:PZEM-004T内部集成了精密采样电阻、信号调理电路和专用的电能计量芯片。它直接输出校准好的数字量(电压、电流、功率、电能),省去了我们自己设计放大电路、进行ADC采样、并编写复杂校准算法的巨大工作量。其标称测量精度(电压、电流、功率)可达0.5%,对于非计量级的DIY应用完全足够。
  2. 通信接口简单:它采用工业标准的Modbus-RTU协议 over UART(串口)进行通信。对于微控制器而言,只需通过一个串口发送固定的指令帧,即可读取所有参数,编程模型非常清晰简单,远比自己处理模拟信号稳定。
  3. 安全隔离:模块的输入侧(接交流电)和输出侧(接单片机)之间通常有光耦或磁耦隔离,这为低压侧的微控制器提供了重要的安全屏障,是DIY涉电项目必须重视的一点。

注意:PZEM-004T有交流(AC)和直流(DC)版本,务必根据你的测量对象选择。本项目针对家庭用电,使用的是AC版本。

2.2 主控单元:ESP32-C3的胜任力分析

主控的选择经历了从Arduino Uno到ESP32的演变。最初用Uno,但很快发现两个瓶颈:一是只有一个硬件串口(Serial),被PZEM占用后就无法连接电脑进行调试打印,非常不便;二是处理TFT图形界面和文件系统操作时,内存和速度略显吃力。

ESP32-C3 Supermini成为了我的最终选择,理由如下:

  • 多硬件串口:ESP32-C3有多个UART外设。我可以分配一个专用UART与PZEM通信,同时保留主串口(Serial0)用于程序调试和输出日志,互不干扰。
  • 足够的性能与内存:比传统AVR单片机更强的处理能力和更大的SRAM,能够流畅驱动SPI接口的TFT屏进行图形绘制,并处理SD卡的文件读写操作。
  • 成本与体积:ESP32-C3系列性价比高,“Supermini”封装尺寸小巧,非常适合集成到紧凑的自制PCB中。
  • 未来可扩展性:虽然本项目未使用,但其内置的Wi-Fi能力为未来升级为物联网电表、数据远程上传留下了可能。

2.3 人机交互与存储:TFT屏与SD卡组合的价值

数据显示和记录是本项目的两大核心输出功能。

  • TFT触摸屏(ILI9341驱动):选择带触摸功能的2.4寸屏,是为了创造一个完整的嵌入式产品体验,而不仅仅是“开发板堆叠”。实时数据(电压、电流、功率)的直观显示,能让用户立刻感知设备状态。更重要的是,我通过编程实现了多个时间维度的历史功率曲线图(日、周、月、年),这需要屏幕有足够的分辨率和色彩表现力来绘制清晰的图表。
  • SD卡模块:数据记录是刚需。SD卡以文件形式存储数据,容量大(通常16GB-32GB足够记录数年数据),且生成的CSV文件可以直接在电脑上用Excel、WPS或数据分析软件打开,无缝衔接后续处理流程。我选择了集成在TFT屏板载的SD卡槽,节省空间和布线。

2.4 时间基准:DS1307 RTC模块的必要性

你可能想问,ESP32本身有RTC(实时时钟),为什么还要外加一个DS1307模块?原因在于数据记录的时间戳可靠性。ESP32的RTC在断电后依靠纽扣电池维持,但时间精度一般,且长时间断电后时间会丢失。而DS1307是专用的时钟芯片,计时精度高,耗电极低,一颗普通的CR2032纽扣电池可以维持运行数年。对于需要按准确时间序列分析能耗的数据记录系统,一个独立、可靠的时间源是至关重要的。它为每一条记录的CSV数据行提供了准确的“年-月-日 时:分:秒”信息。

3. 电路设计与PCB布局实战要点

将面包板上的原型转化为一块可靠的PCB,是项目产品化的关键一步。我的设计思路是功能分区、走线清晰、兼顾安全与可制造性。

3.1 核心电路连接解析

系统的连接可以归纳为三条主要的通信总线:

  1. SPI总线(共享):这是最繁忙的一条总线。TFT显示屏的驱动芯片(ILI9341)、触摸屏控制器(XPT2046)以及SD卡,三者共用一组SPI引脚(MOSI, MISO, SCK)。它们通过不同的“片选(CS)”引脚被主控单独寻址。例如,当需要向屏幕写数据时,拉低TFT_CS引脚;当需要读写SD卡时,则拉低SD_CS引脚。这种共享总线的方式极大地节省了主控的IO口资源。
  2. I2C总线:仅连接DS1307 RTC模块。I2C是双线制(SDA数据线,SCL时钟线),支持多设备挂载,布线简单。这里只接一个设备,为未来扩展其他I2C传感器(如温湿度)留出了余地。
  3. UART串口:专用于连接PZEM-004T。连接非常简单,就是交叉连接:ESP32-C3的TX脚接PZEM的RX,ESP32-C3的RX脚接PZEM的TX,再加上共地(GND)。注意,PZEM模块本身需要供电,其VCC接5V或3.3V需参照具体模块手册。

3.2 PCB设计中的经验与妥协

由于我想尝试使用低成本的单层板制作,在布线时遇到了挑战。单层板意味着所有走线不能交叉,必须在一面完成。最终,有两根线实在无法绕开(一根是地线GND,一根是SPI时钟线SCK),我选择了在PCB上预留两个“跳线点”的解决方案。

  • 跳线点的处理:在PCB布局时,我将这两根无法布通的线断开,在断点两端放置了两个焊盘。PCB制作出来后,用一小段导线手工焊接连接这两个焊盘,相当于一根“空中飞线”。
  • 为什么不用双层板? 对于个人DIY或小批量制作,单层板的价格通常远低于双层板。这次妥协是在成本和工艺复杂性之间取得平衡。在实际焊接时,需要用细导线(如电阻剪下的引脚)仔细连接,并确保焊接牢固、不与其他线路短路。

3.3 安全隔离与布局警告

这是重中之重! PCB上有交流高压(220V)部分(PZEM的输入端子)和直流低压部分(单片机、屏幕等)。在布局时,我刻意将这两部分严格分开在PCB的两端,并留出了足够的“电气间隙”(Creepage Distance)。即使如此,在最终组装完成后,务必用绝缘材料(如亚克力板、3D打印外壳)将整个PCB背面完全覆盖封装。因为即使在PCB正面你看不到裸露的铜线,背面的走线也可能因为焊接或其他原因而暴露,存在触电风险。永远记住:安全是DIY涉电项目的第一原则

4. 软件架构与关键代码实现

软件部分是整个系统的灵魂,负责协调所有硬件、处理数据、更新界面和记录文件。我的代码结构围绕“状态机”和“非阻塞式”设计展开,以确保系统响应流畅,数据不丢失。

4.1 库管理与开发环境搭建

我强烈推荐使用 PlatformIO 而非传统的Arduino IDE进行开发。PlatformIO对库的依赖管理、多环境配置和代码跳转支持要好得多。

核心库及其作用如下表所示:

库名称 用途 关键说明
PZEM-004T-v30 与PZEM模块通信,读取电参数 封装了Modbus-RTU协议,提供readVoltage(), readPower()等易用函数。
RTClib 与DS1307 RTC通信,获取时间 提供now()函数返回DateTime对象,方便进行时间格式化。
Adafruit_GFX 图形底层库 提供画点、线、圆、文本等基本绘图函数,是显示库的基础。
Adafruit_ILI9341 驱动特定型号的TFT屏 基于GFX库,初始化屏幕并实现底层像素写入。务必确认你的屏幕驱动芯片型号
XPT2046_Touchscreen 读取触摸屏坐标 将SPI传来的原始ADC值转换为屏幕坐标。需要校准。
SD (Arduino内置) SD卡文件系统操作 用于创建、打开、读写CSV文件。

platformio.ini中正确配置这些依赖后,编译和上传将变得非常顺畅。

4.2 主程序逻辑与状态机设计

系统的主循环(loop()函数)必须高效且不能阻塞。以下是其核心逻辑的伪代码阐述:

CPP
void loop() {
unsigned long currentMillis = millis(); // 获取当前时间戳
 
// 1. 定时读取传感器(例如每500ms)
if (currentMillis - lastSensorReadTime >= SENSOR_READ_INTERVAL) {
readPowerDataFromPZEM(); // 读取电压、电流、功率、电能
lastSensorReadTime = currentMillis;
}
 
// 2. 定时记录数据(例如每5秒)
if (currentMillis - lastLogTime >= LOG_INTERVAL) {
DateTime now = rtc.now(); // 从RTC获取时间
logDataToCSV(now, voltage, current, power, energy); // 写入SD卡
updateGraphBuffers(now, power); // 更新用于绘图的数据缓冲区
lastLogTime = currentMillis;
}
 
// 3. 实时处理触摸(无延迟)
processTouchInput(); // 检测触摸,切换页面
 
// 4. 刷新显示(根据当前页面)
switch (currentPage) {
case PAGE_REALTIME:
drawRealtimePage(voltage, current, power, energy);
break;
case PAGE_DAILY_GRAPH:
drawGraphPage(dailyPowerData);
break;
// ... 其他页面
}
}

这种“非阻塞”模式确保了无论数据记录(可能涉及较慢的SD卡写入)耗时多久,触摸检测和界面刷新都能得到及时响应,不会出现屏幕卡死的情况。

4.3 CSV数据记录的实现细节

数据记录的核心目标是生成一个结构清晰、可用性强的CSV文件。

  • 文件命名与管理:我采用按日期创建新文件的策略。例如,20240415.csv。每次系统启动时,程序会检查SD卡根目录下是否存在当天的文件,如果没有则创建,并在文件首行写入表头:Date,Time,Voltage(V),Current(A),Power(W),Energy(kWh)
  • 数据写入格式:每一条记录都是一行,包含时间戳和所有电参数。例如:2024-04-15,14:30:05,221.5,0.85,188.3,1.245。这里的关键是使用RTC提供的时间,而不是单片机开机后的运行时间。
  • 写入优化与错误处理:SD卡写入相对较慢,且可能因卡松动、损坏导致失败。我的策略是:
    1. 打开文件(追加模式)。
    2. 格式化数据字符串。
    3. 写入一行并立即关闭文件(file.close())。虽然频繁打开关闭会增加一点开销,但能极大降低因程序意外崩溃或断电导致整个文件损坏的风险。同时,每次写入都应检查返回值,如果失败,可以在屏幕角落显示一个错误图标,提示用户检查SD卡。

4.4 多级图形界面的绘制策略

绘制历史功率曲线是界面部分最复杂的任务。屏幕分辨率有限(如320x240),不可能显示每秒一个点。我的策略是“数据聚合”:

  1. 数据缓冲区:在内存中为“日视图”、“周视图”等分别开辟数组作为缓冲区。例如,日视图缓冲区有24个元素,对应一天24小时。
  2. 数据聚合:当新的功率值到来时,根据当前时间,将其累加到对应的小时(日视图)或对应天(周视图)的“桶”中。同时记录该时间段内的采样次数。
  3. 绘图时计算平均值:当需要绘制日曲线时,从缓冲区中取出每个小时的总功率,除以采样次数,得到该小时的平均功率,再用这个平均值来绘制柱状图或折线图。这样,无论采样频率多高,最终显示的都是一段时间内的趋势,既节省了显示空间,又反映了真实用电模式。
  4. 图形元素绘制:使用Adafruit_GFX库的函数,先清屏,然后画坐标轴、刻度线、标签,最后根据聚合后的数据绘制图形。为了视觉清晰,我选择用填充的柱状图表示功率,比细折线更直观。

5. 系统集成、调试与故障排查实录

将硬件组装好,代码烧录进去,只是第一步。让整个系统稳定可靠地运行起来,需要细致的调试和问题排查。

5.1 硬件组装与上电检查

按照PCB或接线图焊接、连接好所有模块后,切勿直接接入220V交流电。请按以下顺序检查:

  1. 低压部分上电:首先只给单片机、屏幕、RTC等低压部分提供5V或3.3V电源(通过USB或直流电源)。观察:
    • ESP32-C3是否正常启动(指示灯闪烁)。
    • TFT屏幕是否点亮并显示初始化界面(如欢迎页或错误提示)。
    • 如果屏幕白屏或花屏,首先检查TFT_CSRESET等控制引脚连接是否正确,以及Adafruit_ILI9341库中初始化的引脚号是否与你的实际接线一致。
  2. 检查串口通信:打开串口监视器(波特率115200),查看程序输出的调试信息。理想情况下,你应该能看到程序初始化SD卡、RTC成功的日志,以及尝试读取PZEM但可能超时的错误(因为此时PZEM未供电)。
  3. 单独测试PZEM:将PZEM模块通过其自带的端子接上一个安全的负载(如台灯),并为其提供工作电压(注意是模块的VCC引脚,不是测量输入端)。用USB转TTL串口工具连接PZEM的TX/RX,使用串口调试助手发送Modbus查询指令(如01 04 00 00 00 0A CRC),看是否能收到正确的数据回复。这可以单独验证PZEM模块本身是否工作正常。

5.2 软件调试与常见问题

即使硬件连接正确,软件层面的问题也可能导致系统异常。以下是我在开发中遇到的几个典型问题及解决方法:

问题现象 可能原因 排查步骤与解决方案
屏幕显示乱码或全白 1. SPI时钟速率过高。
2. 屏幕驱动芯片型号不匹配。
3. 电源功率不足。
1. 在begin()函数中尝试降低SPI时钟频率,如从SPI_CLOCK_DIV2改为SPI_CLOCK_DIV4
2. 确认屏幕驱动芯片(ILI9341/ST7789/ST7735),并包含正确的库。有时需要尝试不同的初始化参数序列。
3. 使用万用表测量屏幕VCC引脚电压,确保在4.5V-5.5V之间。尝试单独为屏幕供电。
触摸屏坐标不准或反向 触摸屏未校准或坐标映射错误。 XPT2046库通常提供getRaw()函数获取原始ADC值。你需要记录屏幕四个角触摸时的原始值,然后在代码中实现一个映射函数,将原始值转换为屏幕像素坐标。这是一个必须进行的步骤。
读取PZEM数据始终为0或NaN 1. UART引脚接反(TX/RX)。
2. 波特率不匹配。
3. PZEM模块地址错误。
1. 确认ESP32的TX接PZEM的RX,RX接TX。
2. PZEM-004T-v30模块默认波特率是9600,检查代码中PZEM004Tv30对象的初始化波特率设置。
3. 默认地址是0xF8或0x01(不同固件版本可能不同)。尝试使用库提供的setAddress()函数或扫描地址。
SD卡无法初始化或文件写入失败 1. SD卡格式不是FAT16/FAT32。
2. SPI引脚冲突或CS引脚错误。
3. 卡槽接触不良或卡损坏。
1. 在电脑上将SD卡格式化为FAT32格式(分配单元大小默认即可)。
2. 确认SD_CS引脚定义正确,且与其他SPI设备的CS引脚不同。
3. 用读卡器检查SD卡是否正常。尝试更换一张卡。在代码中加入更详细的错误日志,打印SD.begin()的返回值。
RTC时间读取错误或不变 1. I2C地址错误。
2. RTC模块电池没电。
3. I2C上拉电阻未接。
1. DS1307的I2C地址通常是0x68。使用I2C扫描程序确认。
2. 测量RTC模块背面电池电压,应高于2.5V。
3. ESP32-C3内部有上拉电阻,但若线较长或干扰大,建议在SDA和SCL线上各加一个4.7kΩ上拉电阻到3.3V。

5.3 系统整体测试与长期运行

当所有模块都能单独工作后,进行系统集成测试:

  1. 上电全功能测试:连接好所有部件,包括将PZEM接入交流市电(务必确保高压部分已绝缘隔离!)。观察屏幕是否正常显示实时数据,触摸切换页面是否流畅。
  2. 数据记录验证:等待一个记录周期(如5秒)后,安全断电,取出SD卡,插入电脑。检查是否生成了CSV文件,文件内容是否完整,时间戳是否正确递增。
  3. 压力测试与长期运行:让系统连续运行24小时。检查:
    • 内存泄漏:观察串口日志,是否有内存持续减少的警告(PlatformIO可以开启堆监控)。确保在loop()中动态创建的对象(如String)能及时释放,或使用全局/静态缓冲区。
    • 文件系统稳定性:长时间写入后,CSV文件是否依然能被正常打开和读取,没有乱码或中断。
    • 温升:触摸主要芯片(ESP32、PZEM),检查是否有异常发热。

6. 项目应用、优化与扩展思考

这个智能电能表建成后,它的用途远远超出了我最初的研究数据采集。

6.1 实际应用场景举例

  • 家电待机功耗普查:将电表插在插座上,家电插在电表上,连续监测24小时,你可以精确计算出电视、机顶盒、充电器等设备的待机功耗,从而找出家里的“电耗子”。
  • 太阳能系统效率监测:将电表接入太阳能逆变器的输出端,可以记录家庭光伏系统的日发电量曲线,与分析软件结合,评估系统效率。
  • 特定设备能耗分析:比如监测一台空调在制冷模式下的启动电流、稳定功率和周期,或者监测一台3D打印机完成一个模型的总耗电量,为成本核算提供数据。
  • DIY实验室仪器:作为一个教学工具,帮助学生直观理解交流电参数、功率因数的概念,以及数据采集系统的构成。

6.2 可能的优化方向

如果你想让这个项目更上一层楼,可以考虑以下优化:

  1. 无线数据传输:利用ESP32-C3内置的Wi-Fi,将实时数据或定时汇总数据上传到私有服务器(如Home Assistant)、物联网平台(如ThingsBoard)或简单的Web界面。这样就能实现远程监控和手机查看,摆脱对SD卡的依赖。
  2. 数据可视化增强:在本地屏幕上实现更复杂的图表,比如叠加显示当天与前一天的同时间功率对比曲线,或者计算并显示实时电费(根据阶梯电价)。
  3. 警报功能:增加一个蜂鸣器或LED,当功率超过设定的阈值(如检测到短路异常)或用电量达到每日预算时,发出声光警报。
  4. 改用锂电池供电与低功耗设计:通过ESP32的深度睡眠功能,让系统每隔一段时间(如5分钟)唤醒一次,读取数据并记录,然后继续睡眠。这样可以搭配一块大容量锂电池,实现完全无市电的便携式移动监测,适用于野外或临时场所的用电审计。

6.3 关于安全性的最后重申

在整个项目的实施过程中,尤其是在最后的部署阶段,安全必须放在首位。我强烈建议你为完成后的PCB定制一个非导电的壳体(3D打印或购买现成的塑料盒),将所有高压部分完全封闭在内。在壳体上只露出屏幕、按键和低压接口。每次进行硬件调整或测量时,务必先断开220V交流电。用电安全无小事,一个可靠的外壳不仅是产品的完成度,更是对使用者人身安全的基本保障。

基于ESP32与PZEM-004T的智能电力监测系统硬件连接到数据可视化
本文详细介绍了基于ESP32主控与PZEM-004T V3.0电参数测量模块的智能电力监测系统实现方案。涵盖硬件安全连接(220V接入、CT安装、3.3V串口通信)、Modbus RTU协议数据采集、ESP32 Wi-Fi数据上传,以及PC端上位机软件开发CSV日志可视化分析。强调电气隔离、防误接设计和调试方法论,适用于家庭能耗分析、电器状态监控IoT实践。
weixin_30619101
332
Tasmota数据可视化终极指南InfluxDBGrafana打造专业监控面板
本指南详解如何利用Tasmota固件采集ESP8266/ESP32设备的能源传感器数据,通过MQTT传输,经Telegraf桥接到InfluxDB时序数据库,并使用Grafana构建实时监控仪表盘。涵盖InfluxDB安装配置、数据保留策略、Grafana数据源对接、能源指标可视化(电压、电流、功率)及Modbus集成方法,适用于智能家居DIY与专业能源监控场景。
强美玮Quincy
728
sem:使用ESP32PZEM-004T v3.0的基于IoT的智能电表
总的来说,构建基于ESP32PZEM-004T v3.0的智能电表系统融合了硬件接口设计、嵌入式软件开发、网络通信、数据库管理以及前端和移动应用开发等多方面技术。
weird quirky
232
PZEM-004T esp32
本文介绍了如何将PZEM-004T模块与ESP32微控制器集成,实现能源监控数据的远程采集和控制。内容包括硬件连接、软件配置以及数据解析的具体步骤和代码示例。
chichuan0214
PZEM-004t-basic-ESP32-Arduino-ESP8266-Python-RPi:PZEM-004T基本测试和ESP32,Arduino Nano,ESP8266,Arduino UNO + Shield Ethernet W5100,带有Raspberry Pi的Python
具有Arduino ESP32 ESP8266 Python和Raspberry Pi的测试仪PZEM-004T 日期11-07-2018说明/描述在这次机会中,我们将使用Peacefair的新型电耗
KINSLAUGHTER
367
用于更新的 PZEM-004T v3.0 功率和电能表的 Arduino 库_C++_代码_相关文件_下载
本文汇总了PZEM-004T v3.0能源计量模块的使用资源,包括设置指南、硬件修改、通信协议和软件库等。详细介绍了如何通过Arduino等平台与PZEM模块进行通信,并提供了相关库和固件资源链接。
快撑死的鱼
228
基于 ESPhome 与 PZEM-004t 和 ESP 01/01S 的培正电表用电监测及 HomeAssistant 集成方案
实现整个方案需要以下步骤首先,要准备好所有硬件设备,包括PZEM-004t模块和ESP01/ESP01S模块。
KaiyuanCode
1
(源码)基于ESP32PZEM模块的能源监控系统.zip
# 基于ESP32PZEM模块的能源监控系统## 项目简介本项目是一个基于ESP32微控制器和PZEM004T电能监控模块的能源监控系统。通过使用Modbus协议,系统能够实时读取并记录电压、电流、
静默小音箱
16
培正电表用电监测,基于 ESPhome,使用 PZEM-004t 和 ESP 01/01S 将数据集成到 HomeAssistant
通过ESP 01/01S模块结合,PZEM-004t能够将采集到的数据通过Wi-Fi网络发送至家庭网络中。
fenfang2
7