1. 项目概述基于Linky智能电表的家庭电力负荷管理器如果你家也和我一样从传统的机械电表换成了法国电力公司EDF推广的Linky智能电表那你可能已经注意到了这个绿色小盒子带来的新可能性。它不再只是一个默默计费的设备其内置的通信接口为我们这些喜欢动手折腾的“家庭电工”打开了一扇窗。我家的用电情况有点复杂三相供电家里有泳池泵、空调、热泵还有一台电动汽车充电桩。这些“电老虎”一起开动时总功率轻松就能突破供电合同的限制导致主断路器跳闸全家断电。更头疼的是在三相系统中如果负载在各相之间分配不均还会造成额外的线路损耗甚至影响供电质量。传统的解决方案是安装一个“电力负荷管理器”Délesteur它监测总功耗在接近上限时按预设优先级切断一些非必要负载比如关掉热水器暂停泳池泵等负荷降下来再恢复供电。但市售的成品要么功能单一要么价格昂贵而且往往无法与Linky电表直接“对话”获取实时、精确的数据。于是我决定自己动手利用Linky电表标准配置的历史数据输出接口打造一个完全定制化、可通过网页远程管理、且成本可控的智能负荷管理器。这个项目的核心是实时监测三相电流和视在功率计算并记录峰值并能在功率超过设定阈值时自动控制继电器断开预设的非关键负载。所有数据通过一个本地网页服务器呈现你可以在手机或电脑上随时查看用电情况、设置参数甚至远程手动控制负载。对于像我这样使用三相电且有大功率电器的家庭来说它不仅能防止意外跳闸更是优化用电、平衡三相负载的得力工具。下面我就把从硬件选型、软件实现到调试安装的完整过程以及我踩过的那些“坑”毫无保留地分享出来。2. 核心硬件选型与设计思路2.1 为什么选择ESP32与Automator模块市面上主流的物联网开发板很多比如Arduino、树莓派Pico等。我最终选择了ESP32作为主控芯片并基于Elektor Automator模块进行开发主要基于以下几点考量双核处理与无线连接能力ESP32拥有两个处理核心这允许我将一个核心专用于与Linky电表的高速、定时串口通信和数据解析另一个核心则负责运行Web服务器、处理用户界面和逻辑控制。两者互不干扰保证了系统的实时性和响应速度。其内置的Wi-Fi和蓝牙模块使得实现远程网页控制变得轻而易举无需额外模块。电气隔离的安全性与电表通信安全是第一位的。Linky电表的数据输出接口通常是红外或串行通信是弱电信号但我们必须假设其与强电系统在物理上可能存在潜在联系。直接连接非常危险。Elektor Automator模块的一个关键优势是它板载了光耦隔离器。这意味着我的ESP32电路与Linky电表之间通过光信号传递数据实现了完全的电气隔离彻底杜绝了强电串入弱电控制部分的风险这是DIY家庭电力项目不可妥协的底线。丰富的扩展性与成熟的生态Automator模块提供了标准的扩展总线方便我后续增加更多的继电器输出通道例如管理多个可卸载的负载。ESP32的Arduino核心拥有极其庞大的开源库和社区支持无论是Web服务器、NTP对时还是JSON处理都有成熟稳定的库可用大大缩短了开发周期。注意如果你找不到或不想使用Automator模块也可以使用通用的ESP32开发板如ESP32 DevKitC配合一个独立的光耦隔离模块如6N137或PC817来实现串口隔离。但务必确保光耦两侧使用独立的电源供电才能真正实现隔离。2.2 Linky电表通信接口解析Linky电表提供了多种数据输出方式最常见的是通过红外窗口Teleinfo模式或一个专用的串行接口通常位于电表侧面需要打开一个保护盖。我使用的是串行接口因为它更稳定不受环境光影响也方便布线。Linky电表通过这个接口以异步串行通信方式持续发送遵循法国Teleinfo标准的帧数据。关键参数如下波特率1200 baud这是标准值早期电表可能是9600但新Linky统一为1200。数据格式7个数据位偶校验1个停止位7E1。这是一个比较特殊的格式在配置串口时需要特别注意。帧结构数据以文本形式发送每行是一个数据项格式如ADCO 012345678901 X其中ADCO是电表标识符012345678901是值X是校验和。帧之间大约每1到3秒发送一次包含了瞬时电流、功率、电价时段等数十个信息。2.3 外围设备与电路设计除了核心的主控和隔离部分整个系统还需要以下部件OLED显示屏我选用了一款0.96英寸的I2C接口OLED屏。它的作用是本地显示最关键的信息三相的瞬时电流A和总视在功率VA以及它们的今日峰值。在调试初期没有网络的情况下这块屏幕是确认系统是否正常工作的唯一窗口。选择I2C接口是因为它接线简单仅需4根线且ESP32的I2C资源充足。继电器模块用于执行“卸载”动作。我选择了一个带光耦隔离和晶体管驱动的单路继电器模块可以控制250VAC/10A的负载足以应对大多数家用热水器或泳池泵。继电器的控制引脚连接到ESP32的一个GPIO口通过一个简单的digitalWrite函数即可控制其通断。按钮与LED指示灯一个常闭型自复位按钮连接在ESP32的某个GPIO和地之间并启用内部上拉电阻。这个按钮有三个功能长按5秒进入Wi-Fi配置模式短按用于点亮/关闭OLED屏幕为了保护屏幕寿命在Web界面中也可以将其配置为手动触发继电器的紧急按钮。两颗LED一颗蓝色LED连接到与Linky通信的串口RX引脚附近每当成功接收到一帧完整数据时就闪烁一下作为“心跳”指示。另一颗红色LED连接到控制继电器的GPIO继电器吸合时点亮直观显示系统正处于“卸载”状态。电源整个系统需要稳定的5V或3.3V直流供电。我使用了一个高质量的5V/2A的USB电源适配器并经过一个低压差线性稳压器LDO为ESP32和OLED屏提供稳定的3.3V。继电器模块则直接使用5V供电。确保电源有足够的余量特别是在继电器动作时可能会产生电流尖峰。3. 软件架构与核心功能实现3.1 数据解析与实时计算逻辑软件的核心是一个状态机它持续监听来自Linky电表串口的数据流。以下是关键步骤的代码逻辑概述// 伪代码示例说明核心逻辑 void handleTeleinfoData() { static String buffer; // 存储接收到的字符 while (serialLinky.available()) { char c serialLinky.read(); if (c \n) { // 一帧结束 processLine(buffer); // 解析一行数据 buffer ; } else if (c ! \r) { // 忽略回车符 buffer c; } } } void processLine(String line) { // 示例解析电流行 IINST1 015 A if (line.startsWith(IINST1)) { int currentPhase1 line.substring(7, line.indexOf( )).toInt(); // 提取数值“015” updateCurrent(0, currentPhase1); // 更新第一相电流 digitalWrite(BLUE_LED_PIN, HIGH); // 闪烁蓝灯 delay(50); digitalWrite(BLUE_LED_PIN, LOW); } // 类似地解析 IINST2, IINST3, PAPP (视在功率) } void updateCurrent(int phase, int value) { currents[phase] value; // 计算总视在功率假设功率因数已知或从PAPP获取 // 更新今日峰值 if (value maxCurrents[phase]) { maxCurrents[phase] value; maxCurrentsTime[phase] now(); // 记录峰值发生时间 } }峰值管理与午夜清零系统为每相电流和总功率维护一个“今日最大值”变量。这些值在每天午夜00:00:00自动重置为零。时间的准确性至关重要因此我集成了NTP网络时间协议客户端。ESP32在连接Wi-Fi后会自动从互联网时间服务器获取精确时间并自动处理夏令时/冬令时切换。重置逻辑很简单在每次数据更新时检查当前时间如果日期已变更则执行重置。通信超时处理电力监控系统必须可靠。如果因为线路故障、电表重启等原因导致超过60秒没有收到任何有效数据系统会在OLED屏幕和Web界面上显示“Linky Timeout!”警告。这提醒我需要检查物理连接。同时负荷管理功能会进入安全模式——通常我会编程让继电器在通信丢失时自动释放恢复供电防止在未知状态下错误地切断负载。3.2 网页服务器与用户界面设计我使用ESPAsyncWebServer库来构建异步Web服务器它性能好能同时处理多个连接。服务器提供以下几个页面主仪表板Dashboard这是默认首页。以清晰的大字体和柱状图形式展示三相的瞬时电流、今日电流峰值及发生时间、总视在功率及其峰值。当系统因功率超限而激活卸载功能时对应相的数据会高亮为红色非常醒目。页面每3秒通过AJAX自动刷新数据无需手动刷新。历史峰值页面除了今日峰值我还利用Linky电表每天发送的“昨日最大功率”数据PPOT标签在页面上显示前一天的峰值功率。这对于分析长期用电习惯、验证负载调整效果非常有用。正是通过对比连续几天的数据我发现电动汽车充电时导致某一相负载过重从而决定将其充电桩的电源线改接到另一相上。参数配置页面这是系统的“大脑”。所有设置通过一个表单提交保存到ESP32的非易失性存储NVS中。可配置项包括网络设置Wi-Fi的SSID和密码、静态IP地址可选、网关和DNS。卸载参数这是核心逻辑。你需要为每一相或总功率设置两个阈值激活阈值Activation当功率/电流超过此值继电器断开卸载负载。恢复阈值Deactivation当功率/电流回落至此值以下继电器重新闭合恢复供电。恢复阈值必须低于激活阈值形成一个“迟滞区间”防止继电器在临界点附近频繁跳动称为“继电器震颤”这会严重损害继电器和负载。我通常设置至少10%的差值。屏幕保护设置可以设置OLED屏幕常亮或仅在按钮按下后点亮5分钟。系统操作页面提供一键“恢复出厂设置”按钮将NVS中的参数重置为代码中编译的默认值以及手动控制继电器的开关按钮用于测试。3.3 负载管理与卸载逻辑实现卸载逻辑是项目的最终执行层。它作为一个独立的任务运行定期例如每秒检查当前数据。void loadSheddingTask(void *parameter) { for (;;) { int totalPower calculateTotalPower(); // 计算当前总功率 bool overload false; // 检查是否任何一相或总功率超过激活阈值 for (int i0; i3; i) { if (currents[i] activationThreshold[i]) { overload true; overloadPhase i; // 记录是哪一相超了 break; } } if (totalPower totalActivationThreshold) { overload true; overloadPhase -1; // 表示是总功率超限 } if (overload !relayState) { // 超限且继电器当前为断开负载通电状态 - 执行卸载 digitalWrite(RELAY_PIN, HIGH); // 断开继电器根据模块逻辑可能是LOW relayState true; logEvent(Load shed activated due to overload on phase String(overloadPhase)); } else if (!overload relayState) { // 功率已恢复且继电器当前为吸合负载断电状态 - 恢复供电 // 需要额外检查是否所有值都低于恢复阈值 bool safeToRestore true; for (int i0; i3; i) { if (currents[i] deactivationThreshold[i]) safeToRestore false; } if (totalPower totalDeactivationThreshold) safeToRestore false; if (safeToRestore) { digitalWrite(RELAY_PIN, LOW); relayState false; logEvent(Load restored.); } } vTaskDelay(1000 / portTICK_PERIOD_MS); // 每秒检查一次 } }关键设计点逻辑判断必须放在非中断服务程序中。串口接收数据是在中断中处理的但卸载逻辑涉及复杂的比较和状态控制应放在一个独立的、低优先级的任务中避免阻塞通信。同时所有对共享数据如currents[]数组的访问都需要使用信号量或互斥锁进行保护防止数据在读取过程中被串口中断更新而导致错误。4. 组装、配置与安装实操指南4.1 硬件组装与接线步骤准备与规划在开始焊接或接线前绘制一张简单的接线图。明确ESP32/Automator模块的每个引脚3.3V, GND, GPIOxx, RX, TX, SDA, SCL需要连接到哪里。这将极大减少错误。焊接与连接将OLED显示屏的VCC、GND、SDA、SCL分别连接到ESP32的3.3V、GND、GPIO21默认SDA、GPIO22默认SCL。将继电器模块的VCC、GND、IN引脚连接到ESP32的5V或外部5V电源正极、GND、以及一个GPIO口例如GPIO23。将按钮一端连接到你选择的GPIO例如GPIO4另一端接地。在代码中启用该GPIO的内部上拉电阻。将蓝色LED通过一个220欧姆的限流电阻连接到另一个GPIO例如GPIO2用于通信指示。最关键的一步连接Linky电表。使用一根双绞线或屏蔽线一端连接Linky电表的串行输出接口通常是两个端子Data和GND另一端连接到Automator模块的光耦隔离输入侧。务必对照Automator模块和Linky电表的说明书确认正负极和信号线。接反可能无法通信甚至损坏光耦。电源连接使用万用表确认你的5V电源适配器输出正常。先将电源连接到继电器模块如果需要5V驱动然后通过LDO或DC-DC降压模块为ESP32和OLED提供稳定的3.3V。在上电前反复检查所有电源线特别是3.3V和5V没有短路正负极没有接反。4.2 首次上电与Wi-Fi配置进入配置模式按住电路板上的配置按钮不放然后给系统上电。保持按住约5秒直到OLED屏幕显示“AP Mode”或类似信息蓝色LED可能呈现快速闪烁模式。这表明ESP32已启动为接入点AP模式。连接配置网络用手机或电脑的Wi-Fi搜索一个名为“ESP32_Linky_”的网络名称可能在代码中自定义连接它。这个网络通常没有密码或者初始密码是“12345678”。访问配置页面打开浏览器输入地址http://192.168.4.1。你将看到Web配置界面。首先进入“参数”页面。设置网络参数在“Wi-Fi设置”部分填入你家庭路由器的SSID和密码。可选如果你希望设备使用固定IP在此处设置IP地址、网关和子网掩码。使用DHCP自动获取通常更简单。在“卸载设置”部分暂时将激活阈值设为一个很高的值比如9999禁用自动卸载功能等测试完成再调整。点击“保存并重启”。切换至工作模式设备将重启并尝试连接到你指定的Wi-Fi。连接成功后OLED屏幕会显示获取到的IP地址例如192.168.1.123。现在你可以通过这个IP地址在家庭网络内的任何设备上访问它的Web界面了。4.3 安装到配电箱与负载连接安全警告以下操作涉及家庭强电电路。如果你不具备电工资质或足够的经验和信心请务必聘请专业电工完成。操作前必须断开总电源开关并使用电笔确认无电后再进行。选择被控负载确定你想要管理哪个电器。通常选择热水器、空调外机、泳池泵、电动汽车充电桩调低充电电流等非即时性、可短暂中断的负载。切勿用于冰箱、照明、安防系统等关键负载。继电器接入在配电箱中找到控制目标负载的电路断路器空气开关。将该断路器的输出线火线切断。将来自电源侧的一端接入继电器模块的公共端COM将通往负载的一端接入继电器模块的常开端NO。这样当继电器吸合时电路断开释放时电路接通这是最安全的断电逻辑。将继电器模块的控制电路低压部分与你之前做好的ESP32控制板连接好。固定设备将ESP32控制板安装在配电箱内一个安全、干燥、远离强电线缆和发热元件的位置。可以使用导轨安装壳或绝缘胶固定。最终测试合上总闸恢复供电。观察OLED屏幕应能看到来自Linky电表的实时电流和功率数据在变化。通过Web界面手动控制继电器开关测试负载是否能被正确切断和恢复。最后在Web界面上设置合理的激活和恢复阈值。一个保守的起始点可以是激活阈值设为供电合同最大电流的80%恢复阈值设为70%。例如对于12kW三相电每相约17.3A可以设置激活阈值为14A恢复阈值为12A。5. 调试心得与常见问题排查在开发和安装过程中我遇到了不少问题这里总结一下希望能帮你少走弯路。5.1 通信问题收不到Linky数据这是最常见的问题。现象是OLED屏幕数据不更新蓝灯不闪。检查接线这是第一步。确认Linky电表输出端到光耦输入端的线连接正确且牢固。尝试交换Data和GND线在断电情况下操作。确认串口参数在代码中初始化串口的参数必须严格匹配Serial.begin(1200, SERIAL_7E1, RX_PIN, TX_PIN);。7E17位数据、偶校验、1位停止位是关键用8N1绝对收不到正确数据。检查电表输出最可靠的方法是用一个USB转TTL串口模块如FT232RL直接连接Linky电表输出端在电脑上用串口调试助手如Putty、Arduino IDE串口监视器查看原始数据。设置正确的波特率和格式如果能收到类似ADCO ...的文本证明电表输出正常。这能帮你快速定位是电表问题还是你的电路问题。电源干扰如果使用开关电源为ESP32供电其噪声可能干扰串口通信。尝试在串口信号线上加一个100欧姆的电阻和100pF的电容组成低通滤波器或者换用线性稳压电源测试。5.2 Wi-Fi连接不稳定或Web界面无法访问信号强度配电箱往往是金属外壳对Wi-Fi信号屏蔽严重。确保你的路由器信号能良好覆盖安装位置。可以考虑使用Wi-Fi中继器或者将ESP32的天线部分引出配电箱注意绝缘和安全。IP冲突如果你设置了静态IP确保该IP不在路由器的DHCP分配范围内否则会导致冲突。建议初期使用DHCP在路由器后台查看ESP32获取到的IP并将其设置为“静态地址分配”或DHCP保留这样既能固定IP又避免冲突。Web服务器库确保使用稳定的ESPAsyncWebServer和AsyncTCP库版本。过旧或过新的版本可能存在兼容性问题。5.3 卸载逻辑误动作或不动作阈值设置不当恢复阈值必须低于激活阈值。如果两者相等或太接近负载功率的微小波动就会导致继电器频繁通断。将迟滞区间拉大例如设置2-3A的差值。数据抖动Linky电表发送的瞬时电流值本身可能有1-2A的瞬时跳动。在软件中可以加入简单的软件滤波例如对电流值进行移动平均计算用过去几次采样的平均值来做判断而不是用瞬时值。// 简单的移动平均滤波示例 #define FILTER_SIZE 5 int currentSamples[FILTER_SIZE]; int sampleIndex 0; int getFilteredCurrent(int newSample) { currentSamples[sampleIndex] newSample; sampleIndex (sampleIndex 1) % FILTER_SIZE; long sum 0; for (int i0; iFILTER_SIZE; i) sum currentSamples[i]; return sum / FILTER_SIZE; }继电器类型确认你使用的是常开NO型继电器并且接线正确COM接电源进线NO接负载线。这样在系统断电或ESP32重启时继电器会处于断开状态负载断电符合故障安全原则。5.4 OLED屏幕寿命问题OLED屏幕有烧屏风险长期显示静态内容会损坏像素。这就是我加入屏幕保护模式的原因。在Web界面中启用“屏幕省电模式”后屏幕默认关闭只有短按按钮才会点亮5分钟。这个功能极大地延长了屏幕寿命。如果屏幕已经出现残影尝试长时间关闭或显示全白/全黑图像进行一定程度的恢复。这个项目从构思到稳定运行花费了我不少周末的时间但带来的价值是巨大的。它不仅让我家再也没有因过载而跳闸更让我对家庭的用电模式有了前所未有的清晰认识。通过分析历史数据我优化了大型电器的使用时间成功平衡了三相负载理论上还能节省一些电费。最重要的是这个自己搭建的系统完全在我的控制之下可以根据需求随时调整逻辑或增加功能比如接入Home Assistant实现智能联动。如果你也有类似的用电管理需求并且喜欢动手创造那么基于Linky电表打造一个属于自己的智能负荷管理器绝对是一个充满乐趣和成就感的项目。
基于ESP32与Linky电表打造三相智能电力负荷管理器
发布时间:2026/5/25 21:27:02
1. 项目概述基于Linky智能电表的家庭电力负荷管理器如果你家也和我一样从传统的机械电表换成了法国电力公司EDF推广的Linky智能电表那你可能已经注意到了这个绿色小盒子带来的新可能性。它不再只是一个默默计费的设备其内置的通信接口为我们这些喜欢动手折腾的“家庭电工”打开了一扇窗。我家的用电情况有点复杂三相供电家里有泳池泵、空调、热泵还有一台电动汽车充电桩。这些“电老虎”一起开动时总功率轻松就能突破供电合同的限制导致主断路器跳闸全家断电。更头疼的是在三相系统中如果负载在各相之间分配不均还会造成额外的线路损耗甚至影响供电质量。传统的解决方案是安装一个“电力负荷管理器”Délesteur它监测总功耗在接近上限时按预设优先级切断一些非必要负载比如关掉热水器暂停泳池泵等负荷降下来再恢复供电。但市售的成品要么功能单一要么价格昂贵而且往往无法与Linky电表直接“对话”获取实时、精确的数据。于是我决定自己动手利用Linky电表标准配置的历史数据输出接口打造一个完全定制化、可通过网页远程管理、且成本可控的智能负荷管理器。这个项目的核心是实时监测三相电流和视在功率计算并记录峰值并能在功率超过设定阈值时自动控制继电器断开预设的非关键负载。所有数据通过一个本地网页服务器呈现你可以在手机或电脑上随时查看用电情况、设置参数甚至远程手动控制负载。对于像我这样使用三相电且有大功率电器的家庭来说它不仅能防止意外跳闸更是优化用电、平衡三相负载的得力工具。下面我就把从硬件选型、软件实现到调试安装的完整过程以及我踩过的那些“坑”毫无保留地分享出来。2. 核心硬件选型与设计思路2.1 为什么选择ESP32与Automator模块市面上主流的物联网开发板很多比如Arduino、树莓派Pico等。我最终选择了ESP32作为主控芯片并基于Elektor Automator模块进行开发主要基于以下几点考量双核处理与无线连接能力ESP32拥有两个处理核心这允许我将一个核心专用于与Linky电表的高速、定时串口通信和数据解析另一个核心则负责运行Web服务器、处理用户界面和逻辑控制。两者互不干扰保证了系统的实时性和响应速度。其内置的Wi-Fi和蓝牙模块使得实现远程网页控制变得轻而易举无需额外模块。电气隔离的安全性与电表通信安全是第一位的。Linky电表的数据输出接口通常是红外或串行通信是弱电信号但我们必须假设其与强电系统在物理上可能存在潜在联系。直接连接非常危险。Elektor Automator模块的一个关键优势是它板载了光耦隔离器。这意味着我的ESP32电路与Linky电表之间通过光信号传递数据实现了完全的电气隔离彻底杜绝了强电串入弱电控制部分的风险这是DIY家庭电力项目不可妥协的底线。丰富的扩展性与成熟的生态Automator模块提供了标准的扩展总线方便我后续增加更多的继电器输出通道例如管理多个可卸载的负载。ESP32的Arduino核心拥有极其庞大的开源库和社区支持无论是Web服务器、NTP对时还是JSON处理都有成熟稳定的库可用大大缩短了开发周期。注意如果你找不到或不想使用Automator模块也可以使用通用的ESP32开发板如ESP32 DevKitC配合一个独立的光耦隔离模块如6N137或PC817来实现串口隔离。但务必确保光耦两侧使用独立的电源供电才能真正实现隔离。2.2 Linky电表通信接口解析Linky电表提供了多种数据输出方式最常见的是通过红外窗口Teleinfo模式或一个专用的串行接口通常位于电表侧面需要打开一个保护盖。我使用的是串行接口因为它更稳定不受环境光影响也方便布线。Linky电表通过这个接口以异步串行通信方式持续发送遵循法国Teleinfo标准的帧数据。关键参数如下波特率1200 baud这是标准值早期电表可能是9600但新Linky统一为1200。数据格式7个数据位偶校验1个停止位7E1。这是一个比较特殊的格式在配置串口时需要特别注意。帧结构数据以文本形式发送每行是一个数据项格式如ADCO 012345678901 X其中ADCO是电表标识符012345678901是值X是校验和。帧之间大约每1到3秒发送一次包含了瞬时电流、功率、电价时段等数十个信息。2.3 外围设备与电路设计除了核心的主控和隔离部分整个系统还需要以下部件OLED显示屏我选用了一款0.96英寸的I2C接口OLED屏。它的作用是本地显示最关键的信息三相的瞬时电流A和总视在功率VA以及它们的今日峰值。在调试初期没有网络的情况下这块屏幕是确认系统是否正常工作的唯一窗口。选择I2C接口是因为它接线简单仅需4根线且ESP32的I2C资源充足。继电器模块用于执行“卸载”动作。我选择了一个带光耦隔离和晶体管驱动的单路继电器模块可以控制250VAC/10A的负载足以应对大多数家用热水器或泳池泵。继电器的控制引脚连接到ESP32的一个GPIO口通过一个简单的digitalWrite函数即可控制其通断。按钮与LED指示灯一个常闭型自复位按钮连接在ESP32的某个GPIO和地之间并启用内部上拉电阻。这个按钮有三个功能长按5秒进入Wi-Fi配置模式短按用于点亮/关闭OLED屏幕为了保护屏幕寿命在Web界面中也可以将其配置为手动触发继电器的紧急按钮。两颗LED一颗蓝色LED连接到与Linky通信的串口RX引脚附近每当成功接收到一帧完整数据时就闪烁一下作为“心跳”指示。另一颗红色LED连接到控制继电器的GPIO继电器吸合时点亮直观显示系统正处于“卸载”状态。电源整个系统需要稳定的5V或3.3V直流供电。我使用了一个高质量的5V/2A的USB电源适配器并经过一个低压差线性稳压器LDO为ESP32和OLED屏提供稳定的3.3V。继电器模块则直接使用5V供电。确保电源有足够的余量特别是在继电器动作时可能会产生电流尖峰。3. 软件架构与核心功能实现3.1 数据解析与实时计算逻辑软件的核心是一个状态机它持续监听来自Linky电表串口的数据流。以下是关键步骤的代码逻辑概述// 伪代码示例说明核心逻辑 void handleTeleinfoData() { static String buffer; // 存储接收到的字符 while (serialLinky.available()) { char c serialLinky.read(); if (c \n) { // 一帧结束 processLine(buffer); // 解析一行数据 buffer ; } else if (c ! \r) { // 忽略回车符 buffer c; } } } void processLine(String line) { // 示例解析电流行 IINST1 015 A if (line.startsWith(IINST1)) { int currentPhase1 line.substring(7, line.indexOf( )).toInt(); // 提取数值“015” updateCurrent(0, currentPhase1); // 更新第一相电流 digitalWrite(BLUE_LED_PIN, HIGH); // 闪烁蓝灯 delay(50); digitalWrite(BLUE_LED_PIN, LOW); } // 类似地解析 IINST2, IINST3, PAPP (视在功率) } void updateCurrent(int phase, int value) { currents[phase] value; // 计算总视在功率假设功率因数已知或从PAPP获取 // 更新今日峰值 if (value maxCurrents[phase]) { maxCurrents[phase] value; maxCurrentsTime[phase] now(); // 记录峰值发生时间 } }峰值管理与午夜清零系统为每相电流和总功率维护一个“今日最大值”变量。这些值在每天午夜00:00:00自动重置为零。时间的准确性至关重要因此我集成了NTP网络时间协议客户端。ESP32在连接Wi-Fi后会自动从互联网时间服务器获取精确时间并自动处理夏令时/冬令时切换。重置逻辑很简单在每次数据更新时检查当前时间如果日期已变更则执行重置。通信超时处理电力监控系统必须可靠。如果因为线路故障、电表重启等原因导致超过60秒没有收到任何有效数据系统会在OLED屏幕和Web界面上显示“Linky Timeout!”警告。这提醒我需要检查物理连接。同时负荷管理功能会进入安全模式——通常我会编程让继电器在通信丢失时自动释放恢复供电防止在未知状态下错误地切断负载。3.2 网页服务器与用户界面设计我使用ESPAsyncWebServer库来构建异步Web服务器它性能好能同时处理多个连接。服务器提供以下几个页面主仪表板Dashboard这是默认首页。以清晰的大字体和柱状图形式展示三相的瞬时电流、今日电流峰值及发生时间、总视在功率及其峰值。当系统因功率超限而激活卸载功能时对应相的数据会高亮为红色非常醒目。页面每3秒通过AJAX自动刷新数据无需手动刷新。历史峰值页面除了今日峰值我还利用Linky电表每天发送的“昨日最大功率”数据PPOT标签在页面上显示前一天的峰值功率。这对于分析长期用电习惯、验证负载调整效果非常有用。正是通过对比连续几天的数据我发现电动汽车充电时导致某一相负载过重从而决定将其充电桩的电源线改接到另一相上。参数配置页面这是系统的“大脑”。所有设置通过一个表单提交保存到ESP32的非易失性存储NVS中。可配置项包括网络设置Wi-Fi的SSID和密码、静态IP地址可选、网关和DNS。卸载参数这是核心逻辑。你需要为每一相或总功率设置两个阈值激活阈值Activation当功率/电流超过此值继电器断开卸载负载。恢复阈值Deactivation当功率/电流回落至此值以下继电器重新闭合恢复供电。恢复阈值必须低于激活阈值形成一个“迟滞区间”防止继电器在临界点附近频繁跳动称为“继电器震颤”这会严重损害继电器和负载。我通常设置至少10%的差值。屏幕保护设置可以设置OLED屏幕常亮或仅在按钮按下后点亮5分钟。系统操作页面提供一键“恢复出厂设置”按钮将NVS中的参数重置为代码中编译的默认值以及手动控制继电器的开关按钮用于测试。3.3 负载管理与卸载逻辑实现卸载逻辑是项目的最终执行层。它作为一个独立的任务运行定期例如每秒检查当前数据。void loadSheddingTask(void *parameter) { for (;;) { int totalPower calculateTotalPower(); // 计算当前总功率 bool overload false; // 检查是否任何一相或总功率超过激活阈值 for (int i0; i3; i) { if (currents[i] activationThreshold[i]) { overload true; overloadPhase i; // 记录是哪一相超了 break; } } if (totalPower totalActivationThreshold) { overload true; overloadPhase -1; // 表示是总功率超限 } if (overload !relayState) { // 超限且继电器当前为断开负载通电状态 - 执行卸载 digitalWrite(RELAY_PIN, HIGH); // 断开继电器根据模块逻辑可能是LOW relayState true; logEvent(Load shed activated due to overload on phase String(overloadPhase)); } else if (!overload relayState) { // 功率已恢复且继电器当前为吸合负载断电状态 - 恢复供电 // 需要额外检查是否所有值都低于恢复阈值 bool safeToRestore true; for (int i0; i3; i) { if (currents[i] deactivationThreshold[i]) safeToRestore false; } if (totalPower totalDeactivationThreshold) safeToRestore false; if (safeToRestore) { digitalWrite(RELAY_PIN, LOW); relayState false; logEvent(Load restored.); } } vTaskDelay(1000 / portTICK_PERIOD_MS); // 每秒检查一次 } }关键设计点逻辑判断必须放在非中断服务程序中。串口接收数据是在中断中处理的但卸载逻辑涉及复杂的比较和状态控制应放在一个独立的、低优先级的任务中避免阻塞通信。同时所有对共享数据如currents[]数组的访问都需要使用信号量或互斥锁进行保护防止数据在读取过程中被串口中断更新而导致错误。4. 组装、配置与安装实操指南4.1 硬件组装与接线步骤准备与规划在开始焊接或接线前绘制一张简单的接线图。明确ESP32/Automator模块的每个引脚3.3V, GND, GPIOxx, RX, TX, SDA, SCL需要连接到哪里。这将极大减少错误。焊接与连接将OLED显示屏的VCC、GND、SDA、SCL分别连接到ESP32的3.3V、GND、GPIO21默认SDA、GPIO22默认SCL。将继电器模块的VCC、GND、IN引脚连接到ESP32的5V或外部5V电源正极、GND、以及一个GPIO口例如GPIO23。将按钮一端连接到你选择的GPIO例如GPIO4另一端接地。在代码中启用该GPIO的内部上拉电阻。将蓝色LED通过一个220欧姆的限流电阻连接到另一个GPIO例如GPIO2用于通信指示。最关键的一步连接Linky电表。使用一根双绞线或屏蔽线一端连接Linky电表的串行输出接口通常是两个端子Data和GND另一端连接到Automator模块的光耦隔离输入侧。务必对照Automator模块和Linky电表的说明书确认正负极和信号线。接反可能无法通信甚至损坏光耦。电源连接使用万用表确认你的5V电源适配器输出正常。先将电源连接到继电器模块如果需要5V驱动然后通过LDO或DC-DC降压模块为ESP32和OLED提供稳定的3.3V。在上电前反复检查所有电源线特别是3.3V和5V没有短路正负极没有接反。4.2 首次上电与Wi-Fi配置进入配置模式按住电路板上的配置按钮不放然后给系统上电。保持按住约5秒直到OLED屏幕显示“AP Mode”或类似信息蓝色LED可能呈现快速闪烁模式。这表明ESP32已启动为接入点AP模式。连接配置网络用手机或电脑的Wi-Fi搜索一个名为“ESP32_Linky_”的网络名称可能在代码中自定义连接它。这个网络通常没有密码或者初始密码是“12345678”。访问配置页面打开浏览器输入地址http://192.168.4.1。你将看到Web配置界面。首先进入“参数”页面。设置网络参数在“Wi-Fi设置”部分填入你家庭路由器的SSID和密码。可选如果你希望设备使用固定IP在此处设置IP地址、网关和子网掩码。使用DHCP自动获取通常更简单。在“卸载设置”部分暂时将激活阈值设为一个很高的值比如9999禁用自动卸载功能等测试完成再调整。点击“保存并重启”。切换至工作模式设备将重启并尝试连接到你指定的Wi-Fi。连接成功后OLED屏幕会显示获取到的IP地址例如192.168.1.123。现在你可以通过这个IP地址在家庭网络内的任何设备上访问它的Web界面了。4.3 安装到配电箱与负载连接安全警告以下操作涉及家庭强电电路。如果你不具备电工资质或足够的经验和信心请务必聘请专业电工完成。操作前必须断开总电源开关并使用电笔确认无电后再进行。选择被控负载确定你想要管理哪个电器。通常选择热水器、空调外机、泳池泵、电动汽车充电桩调低充电电流等非即时性、可短暂中断的负载。切勿用于冰箱、照明、安防系统等关键负载。继电器接入在配电箱中找到控制目标负载的电路断路器空气开关。将该断路器的输出线火线切断。将来自电源侧的一端接入继电器模块的公共端COM将通往负载的一端接入继电器模块的常开端NO。这样当继电器吸合时电路断开释放时电路接通这是最安全的断电逻辑。将继电器模块的控制电路低压部分与你之前做好的ESP32控制板连接好。固定设备将ESP32控制板安装在配电箱内一个安全、干燥、远离强电线缆和发热元件的位置。可以使用导轨安装壳或绝缘胶固定。最终测试合上总闸恢复供电。观察OLED屏幕应能看到来自Linky电表的实时电流和功率数据在变化。通过Web界面手动控制继电器开关测试负载是否能被正确切断和恢复。最后在Web界面上设置合理的激活和恢复阈值。一个保守的起始点可以是激活阈值设为供电合同最大电流的80%恢复阈值设为70%。例如对于12kW三相电每相约17.3A可以设置激活阈值为14A恢复阈值为12A。5. 调试心得与常见问题排查在开发和安装过程中我遇到了不少问题这里总结一下希望能帮你少走弯路。5.1 通信问题收不到Linky数据这是最常见的问题。现象是OLED屏幕数据不更新蓝灯不闪。检查接线这是第一步。确认Linky电表输出端到光耦输入端的线连接正确且牢固。尝试交换Data和GND线在断电情况下操作。确认串口参数在代码中初始化串口的参数必须严格匹配Serial.begin(1200, SERIAL_7E1, RX_PIN, TX_PIN);。7E17位数据、偶校验、1位停止位是关键用8N1绝对收不到正确数据。检查电表输出最可靠的方法是用一个USB转TTL串口模块如FT232RL直接连接Linky电表输出端在电脑上用串口调试助手如Putty、Arduino IDE串口监视器查看原始数据。设置正确的波特率和格式如果能收到类似ADCO ...的文本证明电表输出正常。这能帮你快速定位是电表问题还是你的电路问题。电源干扰如果使用开关电源为ESP32供电其噪声可能干扰串口通信。尝试在串口信号线上加一个100欧姆的电阻和100pF的电容组成低通滤波器或者换用线性稳压电源测试。5.2 Wi-Fi连接不稳定或Web界面无法访问信号强度配电箱往往是金属外壳对Wi-Fi信号屏蔽严重。确保你的路由器信号能良好覆盖安装位置。可以考虑使用Wi-Fi中继器或者将ESP32的天线部分引出配电箱注意绝缘和安全。IP冲突如果你设置了静态IP确保该IP不在路由器的DHCP分配范围内否则会导致冲突。建议初期使用DHCP在路由器后台查看ESP32获取到的IP并将其设置为“静态地址分配”或DHCP保留这样既能固定IP又避免冲突。Web服务器库确保使用稳定的ESPAsyncWebServer和AsyncTCP库版本。过旧或过新的版本可能存在兼容性问题。5.3 卸载逻辑误动作或不动作阈值设置不当恢复阈值必须低于激活阈值。如果两者相等或太接近负载功率的微小波动就会导致继电器频繁通断。将迟滞区间拉大例如设置2-3A的差值。数据抖动Linky电表发送的瞬时电流值本身可能有1-2A的瞬时跳动。在软件中可以加入简单的软件滤波例如对电流值进行移动平均计算用过去几次采样的平均值来做判断而不是用瞬时值。// 简单的移动平均滤波示例 #define FILTER_SIZE 5 int currentSamples[FILTER_SIZE]; int sampleIndex 0; int getFilteredCurrent(int newSample) { currentSamples[sampleIndex] newSample; sampleIndex (sampleIndex 1) % FILTER_SIZE; long sum 0; for (int i0; iFILTER_SIZE; i) sum currentSamples[i]; return sum / FILTER_SIZE; }继电器类型确认你使用的是常开NO型继电器并且接线正确COM接电源进线NO接负载线。这样在系统断电或ESP32重启时继电器会处于断开状态负载断电符合故障安全原则。5.4 OLED屏幕寿命问题OLED屏幕有烧屏风险长期显示静态内容会损坏像素。这就是我加入屏幕保护模式的原因。在Web界面中启用“屏幕省电模式”后屏幕默认关闭只有短按按钮才会点亮5分钟。这个功能极大地延长了屏幕寿命。如果屏幕已经出现残影尝试长时间关闭或显示全白/全黑图像进行一定程度的恢复。这个项目从构思到稳定运行花费了我不少周末的时间但带来的价值是巨大的。它不仅让我家再也没有因过载而跳闸更让我对家庭的用电模式有了前所未有的清晰认识。通过分析历史数据我优化了大型电器的使用时间成功平衡了三相负载理论上还能节省一些电费。最重要的是这个自己搭建的系统完全在我的控制之下可以根据需求随时调整逻辑或增加功能比如接入Home Assistant实现智能联动。如果你也有类似的用电管理需求并且喜欢动手创造那么基于Linky电表打造一个属于自己的智能负荷管理器绝对是一个充满乐趣和成就感的项目。