如何使用Arduino进行交流电能监测
我从事电能计量IC的研发已有段时间。在尝试了接口较为简单的BL0937之后,今天终于拿到了BL0940。两者在结构上相似,都是单相电能计量IC,但最让我感到意外的是其功能特性。与BL系列中较为简单的BL0937不同,BL0940无需进行元件校准即可提供电压、电流、有功功率、能量累积、相位角、功率因数和温度等信息,所有数据均可通过UART或SPI接口获取。
但目前本教程主要介绍SPI通信模式。只需将SEL引脚拉高即可实现SPI通信,IC会自动切换其整个通信接口。我围绕该IC开发了一个完整的Arduino库,并提供了五个即用型示例。整个项目的总成本非常低,仅需一个1毫欧的分流电阻、一个电压分压网络以及几个电容即可完成模拟前端设计。这是一个开源项目,您可以通过GITHUB获取设计文件。我已在JLCPCB上制作了专用PCB板,并在实验室中进行了实时能耗监测测试。
BL0940是什么?
BL0940 是一款单相电能计量IC,内置两个Sigma-Delta ADC,可同时采样电压和电流;配备数字乘法器,用于实时计算有功功率;并带有带脉冲输出的储能单元。该IC工作电压为3.3V,所有测量均使用内部1.218V参考电压供电。通过我设计的PCB板,可接入1W至2500W的负载。BL0940具备内部相位角寄存器,可通过该寄存器计算电压与电流之间的相位差,从而无需额外信号处理即可获得真实的功率因数cos(phi)。此外,BL0940还内置温度传感器,并支持在VT引脚上连接外部NTC热敏电阻。
以下是数据表中的关键规格:
•供电电压:3.0VV 至 3.6V(典型值为 3.3V)
•内部参考电压:1.218V(典型值)
•差分输入(IP/IN),最大输入 ±200 mV
•差分输入(VP/VN),最大输入 ±200 mV(经分压器后)
•4800波特率的UART(固定)或最高900 kHz的SPI
•温度传感器:内置(TPS1)++ 外置NTC(TPS2),10位ADC
•防爬行登记
•能量脉冲输出
•零交叉输出
所需部件
•BL0940 电能计量IC(SOP-14)
•Arduino Uno/Nano
•1毫欧(1 mOhm)分流电阻
•4个300K欧姆电阻,用于电压分压器的高侧(总阻值为1.2兆欧)
•1个510欧姆电阻,用于电压分压器的低侧
•VP和IP通道上的抗混叠滤波器用2 x 2.2 uF电容
•2个100 nF(0.1 μF)去耦电容
•1 x 10 uF 电解电容
•JLCPCB定制PCB
电路图
我已按照数据手册的说明,使用了文档中配置的电路。电流检测路径采用一个1毫欧的分流电阻,连接在IP1和IN1引脚之间。在最大额定电流下,该分流电阻两端的电压降始终保持在±200 mV以内。在IP/IN输入端并联了2.2微法的带通滤波电容,用于滤除来自电源的高频噪声。这一点非常重要,因为BL0940内部的Sigma-Delta ADC在高频率谐波处可能发生混叠。
四个300K欧姆的电阻串联(总阻值为1.2M欧姆)构成高侧,一个510欧姆的电阻构成低侧。这使得分压比约为2354:1,可将220V的主电源安全地降压至约93mV,并保持在ADC输入范围之内。BL0940的工作电源为3.3V。我已在VDD引脚旁放置了一个100nF的陶瓷电容,用于高频去耦,电源通过内置LDO AMS1117 3.3V供电。
CF引脚输出能量脉冲,可用于千瓦时计数或报警输出,而ZX引脚提供与主电源频率同步的零交叉信号。这些功能在本教程版本中未使用。所有读数均发送至串行监视器,库会处理所有寄存器级别的通信。
理解寄存器映射
理解寄存器映射至关重要,因为该库完全围绕读取这些寄存器而构建:
•I_FAST_RMS (0x00):测量快速电流的均方根值(半周期/全周期)
•I_WAVE (0x01):存储瞬时电流波形数据
•V_WAVE (0x03):存储瞬时电压波形数据
•I_RMS (0x04):测量在400/800毫秒窗口内的电流有效值
•V_RMS (0x06):测量400/800毫秒窗口内的电压有效值
•WATT (0x08):存储有功功率测量值
•CF_CNT (0x0A):能量脉冲计数器寄存器
•角(0x0C):测量电压与电流之间的相位角
•TPS1 (0x0E):内部温度传感器读数
•TPS2(0x0F):外部温度传感器(NTC)读数
设计与改造:
BL09400 支持两种通信模式,理解其协议非常重要,因为 UART 和 SPI 的数据字节顺序不同。我主要关注 SPI SPI 模式,因为它更稳定且速度更快。库中也提供了 UART UART 模式的代码,以及 SPI SPI 模式(SEL = = 高电平)的代码。在 SPI SPI 模式下,BL0940 使用模式 1(CPOL=0, CPHA=1),采用最高有效位优先(MSB first),最大时钟频率为 900 kHz。帧结构与 UART 类似,但字节顺序相反,在 SPI SPI 模式下为最高有效位优先。该库默认使用 500 kHz 作为 SPI 时钟,以确保可靠运行。
两种模式都使用相同的校验和计算公式:即除校验和本身外所有字节的和的按位取反。我编写这个库时力求简洁明了。接下来让我为您讲解其中的关键设计决策和函数。
初始化与验证:`begin()`()` 函数用于初始化通信接口,并验证 BL0940 是否正常响应。我选择使用 TPS1(内部温度)寄存器进行验证,因为只要芯片处于供电并通信状态,该寄存器始终会返回一个有效的非零值。如果 `begin()` 返回 false,您就可以立即判断出线路连接或 SEL SEL 引脚配置存在问题。
测量转换:BL0940的原始寄存器值需要通过校准因子转换为工程单位。以下是电压读数在内部的工作原理:
`_voltageDiv` 是一个校准常数,取决于您具体的电压分压值。数据表给出了如下公式:
电流和功率的校准分压器类似(默认值分别为1 mOhm分流电阻时的266.0和1158.2)。您可以通过 `setVoltageDiv()`、`setCurrentDiv()` 和 `setPowerDiv()`()` 来覆盖这些默认值。
使用负载进行校准:
在SPI模式下,SEL引脚必须连接到VDD(3.3V)。现在使用一个100W的灯泡,记录插座的电压和电流,并用万用表手动计算功率。然后将这些数值按如下方式输入代码中:
按照此处所示搭建电路,必须使用OLED,当IC接入220V时,切勿使用笔记本电脑的串口监视器。笔记本电脑仅用于上传Arduino程序。
上传后,连接5V电源适配器并按照此处所示进行加载,记录OLED屏幕上显示的系数。请将这些系数记下,并复制到主工作代码中用于校准。
工作代码:
上传校准系数后,这是主要的运行代码,请查看读数的变化情况。
PCB概述:
我将PCB设计得尽量简洁,便于插接。它是一种扩展板,包含主IC和辅助电子元件,可与任何微控制器连接使用。目前我正在使用Arduino Nano。
PCB结构简单却功能可靠,我已经进行了全面测试。请注意地线和零线的连接,在操作交流电压时务必小心。你可以从这里下载包含工作代码的文件。我使用EasyEDA进行设计,并通过JLCPCB完成制作,实际调试过程中花费了大约一个小时的焊接时间才使其能正常运行。如果你希望获得一次就能成功焊接、稳定可靠的解决方案,我建议你选择JLCPCB的PCB组装服务,现在可在此以最低价格体验他们的产品。
高级功能:
过流检测(快速RMS):BL0940配备专用的快速RMS引擎,可在交流电源波形的一个半周期内检测过流情况。该功能比常规的RMS计算快得多,后者使用400或800毫秒的时间窗口。您可以设置一个阈值,并通过CF/报警引脚触发继电器或保护电路:
I_FAST_RMSCTRLCTRL 寄存器还允许您在半周期和全周期刷新模式之间进行选择。
防爬升阈值:在实际的电能表中,即使没有连接负载,也会存在微小的残余功耗读数。这种现象称为“爬升”,可能导致电能计数器缓慢累积。BL094000 拥有 WA_CREEPP 寄存器,您可以在其中设置一个最低功率阈值。任何低于该阈值的功耗读数都将被视为零:
本文编译自hackster.io





