该存储库包含Arduino的Truerms C ++库。使用此库,可以计算ADC输入信号的平均值和RMS (根平方)或有效值。该库还计算了来自电压和电流输入信号的实体,明显的功率和功率因数。从1.3版中,该项目添加了能量计量。
通过使用适当的输入电路将测得的数量缩放到ADC的0-5V兼容电压范围内,可以用ARDUINO的ADC来测量电流的电压和电压表示。提供的解决方案使用一种简单的方法来缩放测得的数量。用户只需要定义AC输入电压和电流的全尺度峰值峰值值。当测得的数量的单元以伏特和安培定义定义时,计算出的功率为瓦特,而能量为ws(焦耳)。该库很容易移植到其他平台。
实施以下图书馆类:
AverageRmsRms2PowerPower2平均计算来自ADC的许多输入样本(通常)的平均值。 RMS或RMS2旨在计算信号和功率或功率2的根平方值旨在计算电压和电流输入的功率。
RMS2和Power2在中断服务程序中使用时的性能更好,通过在示例时间插槽中扩散处理负担。一个RMS采集运行(扫描)的样本数量定义为窗口。当自动基线恢复选项(BLR_ON)时, RMS2和Power2占据了一个额外的样本时间插槽(窗口长度+1)。
存在以下方法:
begin()start()stop()update()update1()update2()publish() 要快速启动,请检查库随附的示例Arduino草图。
这些是成功实施的步骤:
begin() 。此方法用于初始化,它需要输入以设置测量单元的缩放,采样窗口的大小,所使用ADC的位数(或输入信号)和采集模式(连续扫描/单扫描)。start()开始收购。update() (或update1() + update2() for Power2 )以恒定的速率重复。publish()获取结果。对于Power2类update(),将其分解为update1()和update2() 。必须首先调用update1()以从输入电压和update2()处理样本,以从输入电流或VICA VECA(电压电流)处理样品。采样电压和电流通常用于多路复用ADC。
对于班级的平均用途:
void begin(float range, unsigned char window, unsigned char nob, bool mode);
和:
range是交流输入信号的最大预期全摆动(峰值峰值值)。window以整体样品表示样品窗口的长度。nob是输入信号(ADC位深度)的位分辨率。使用预定义常数: ADC_8BIT , ADC_10BIT或ADC_12BIT 。mode将模式设置为连续扫描或单扫描。使用预先的常数CNT_SCAN或SGL_SCAN 。 void start(void);该方法开始采集连续扫描和单扫描模式。
void stop(void);此方法停止了收购。
void update(int instVal);分配当前的样本值。
void publish(void);从上次完成的收购运行中发布结果。结果在下一定义的输出变量中。
公共定义的变量是:
int instVal最后获得样品的值
float average - 平均值结果
bool acquire - 状态位,在扫描尚待审查时为真。
对于类RMS或RMS2使用:
void begin(float range, unsigned char window, unsigned char nob, bool blr, bool mode);
和:
range是交流信号的最大预期如图(峰值峰值值)。window以整个样本表示样本窗口的长度。nob是输入信号的位分辨率,通常这是ADC位深度。使用预定义常数: ADC_8BIT , ADC_10BIT或ADC_12BIT 。blr设置自动打开或关闭的基线恢复功能。使用预先的常数BLR_ON或BLR_OFF 。mode将模式设置为连续扫描或单扫描。使用预先的常数CNT_SCAN或SGL_SCAN 。 void start(void);该方法开始采集连续扫描和单扫描模式。
void stop(void);此方法停止了收购。
void update(int instVal);分配当前的样本值。
void publish(void);从上次完成的收购运行中发布结果。结果在下一定义的输出变量中。
公共定义的变量是:
int instVal最后获得的样品的值,当BLR_ON恢复为基线
float rmsVal RMS值结果
int dcBias ADC -units中的DCBIAS值。仅在blr_on时相关
bool acquire - 状态位,如果扫描待定,则为真实
用于班级功率使用:
void begin(float range1, float range2, unsigned char window, unsigned char nob, bool blr, bool mode);
和:
range1, range2是电压和电流的交流信号(峰值峰值值)的最大预期全摆动。window以整个样本表示样本窗口的长度。nob是输入信号的位分辨率,通常这是ADC位深度。使用预先限制的常数: ADC_8BIT , ADC_10BIT或ADC_12BIT 。blr设置自动打开或关闭的基线恢复功能。使用预先的常数BLR_ON或BLR_OFF 。mode将模式设置为连续扫描或单扫描。使用预先的常数CNT_SCAN或SGL_SCAN 。 void start(void);该方法开始采集连续扫描和单扫描模式。
void stop(void);此方法停止了收购。
void update(int instVal1, int instVal2);一次分配当前的样品值(例如电压和电流)。
void publish(void);从上次完成的收购运行中发布结果。结果在下一定义的输出变量中。
公共定义的变量是:
int instVal1最后获得的样品(电压)的值,恢复为blr_on时基线
int instVal2最后获得的样品(当前)的值,当Blr_on时还原为基线
float rmsVal1 -rms value1(电压)
float rmsVal2 -rms value2(当前)
int dcBias1 ADC -units中的DCBIAS1值。仅在blr_on时相关
int dcBias2 adc -units中的dcbias2值。仅在blr_on时相关
float apparentPwr - 明显的力量
float realPwr真正的力量
float pf功率因数
float energy - 净能量
bool acquire - 状态位,如果扫描待定,则为真实
对于类Power2使用:
void begin(float range1, float range2, unsigned char window, unsigned char nob, bool blr, bool mode);
和:
range1, range2是电压和电流的交流信号(峰值峰值值)的最大预期全摆动。window以整个样本表示样本窗口的长度。nob是输入信号的位分辨率,通常这是ADC位深度。使用预先限制的常数: ADC_8BIT , ADC_10BIT或ADC_12BIT 。blr设置自动打开或关闭的基线恢复功能。使用预先的常数BLR_ON或BLR_OFF 。mode将模式设置为连续扫描或单扫描。使用预先的常数CNT_SCAN或SGL_SCAN 。 void start(void);该方法开始采集连续扫描和单扫描模式。
void stop(void);此方法停止了收购。
void update1(int instVal);为电压分配当前的样本值。
void update2(int instVal);为当前的当前示例值分配。在采样循环中交替调用update1()和update2() 。
void publish(void);从上次完成的收购运行中发布结果。结果可从下一定义的输出变量获得。
公共定义的变量是:
int instVal1最后获得的样品(电压)的值,恢复为blr_on时基线
int instVal2最后获得的样品(当前)的值,当Blr_on时还原为基线
float rmsVal1 -rms value1(电压)
float rmsVal2 -rms value2(当前)
int dcBias1 ADC -units中的DCBIAS1值。仅在blr_on时相关
int dcBias2 adc -units中的dcbias2值。仅在blr_on时相关
float apparentPwr ,明显的力量
float realPwr真正的力量
float pf功率因数
float energy - 净能量
bool acquire - 状态位,如果扫描待定,则为真实
Rms gridVolt;
void setup() {
...
gridVolt.begin(700, 40, ADC_10BIT, BLR_ON, CNT_SCAN);`
...
}
论点的意思是:
完整的ADC范围(0至5伏)表示信号峰值峰值值为700V。对于正弦波,这等于350V或247.5VRM的信号振幅。
RMS窗口为40个样品,这意味着当以1000个样本/秒选择采样率时,窗口覆盖了两个50Hz周期。
ADC位分辨率为10位(Arduino Uno)。
BLR_ON意味着基线修复已打开。为了捕获ADC的交流信号,必须通过添加与ADC输入电路的DC偏移电压,将信号的零值转移到ADC范围的中点。之后,必须通过从获得的ADC值中减去恒定值来纠正此偏移量。可以使用BLR_ON自动进行此校正,并且不需要校准。在图1中,蓝线表示最大缩放输入信号,电压摇摆为5V,并在2.5V上偏置。绿线显示一个振幅为1V的输入信号,并测量1V/sqrt(2)= 0.71VRM。

使用选项CNT_SCAN,采集设置为连续模式。完成最后一次扫描后,该收购将自动重新启动。
致电gridVolt.update(adcVal);从主循环或中断服务例程(ISR)。确保循环以恒定速率重复。
使用gridVolt.publish()获取结果并获得RMS值: float Voltage = gridVolt.rmsVal;
void loop() { // loop must run at 1kHz
...
adcValue = analogRead(AN0); // read the ADC.
gridVolt.update(adcValue);
counter++;
if(counter >= 500) { // publish every 0.5s
gridVolt.publish();
Voltage = gridVolt.rmsVal;
counter = 0;
}
...
while(loop_timer_not_expired) {1}
...
}
Measure_avg.ino此示例显示了如何计算用ADC测量的信号的平均值。
Measure_rms.ino在此示例中,确定ADC输入电压的RMS值。
AC_powermeter.ino此示例演示了完整的AC -Power测量应用。它需要在两个ADC通道上的输入,电压和电压表示。它计算电压和电流的RMS值,明显的功率,实际功率和功率因数。
AC_powermeter_advanced.ino此示例还展示了完整的AC -Power测量应用程序。它以中断为基础,以获得更好的稳定读数。电压和电流均在3kHz处采样。当Arduino LED点亮时,ADC夹(输入峰值电压过高)或直流偏置范围之外。
Energy_metering.ino显示WH中的电压,电流,实际功率和净能量。
与Arduino ADC接口AC高电压的最简单方法是使用电压传感器,例如来自LEM USA Inc.的LV 25-P 25-P电压传感器。该换能器提供镀锌隔离,缩放和水平的速度和电平转换。对于当前的感应, LEM还制造了LEM_LA55-P ,具有与电压传感器相同的优势。
如果一个人更喜欢从离散组件中构建输入缩放电路,则属于Texas Instruments Incorporated的电压源代码逆变器参考设计的应用程序Note Note tiduay6c.pdf中给出了详细的设计描述。请注意警告!提议的电路很容易适应Arduino的0-5V范围。
在任何时候,都使用隔离变压器来安全!
3相功率测量。
通过使用替代的Arduino-ide Sloeber,在开发此库中节省了很多时间。 Sloeber是Eclipse的精彩Arduino插件。感谢Jantje及其贡献者!