如何利用Arduino构建一个功率计

作为电子爱好者,我们常常依靠一些仪表或仪器来测量和分析电路。从简单的万用表到复杂的功率分析仪或dsos,所有的仪表都有它们自己独特的用途。这些仪表的大部分都有成品,我们可以根据特定的需要来购买。有时我们可能会想自己制作一个仪表。例如,当我们准备做一个太阳能光伏项目时,我们想计算负载的功耗,在这种情况下,我们就可以用一个像arduino这样的微控制器平台来构建我们自己的功率计了。
构建自己的功率计不仅可以降低成本,还可以为我们提供更深入了解开发测试功能的途径。例如,使用arduino的功率计可以很容易地调整串口监视器上的监控结果,可以在串口上绘制图形,可以添加sd卡在预定义的时间内自动记录电压、电流和功率的数值。
功率计材料清单
arduino nano
lm358运放
7805
lcd1602
0.22欧姆2瓦电阻
10k可调电阻
10k,20k,2.2k,1k电阻
0.1uf电容
测试负载
面包板
功率计电路图
下面是arduino功率计项目的完整电路图:
为了便于理解,我们把arduino功率计电路被分为两个部分。电路的上半部分是测量单元,电路的下半部分是计算和显示单元。该电路测量范围适合于0-24v,考虑到太阳能光伏电池的规格,电流为0-1a。电路的基本原理是通过测量负载的电流和电压,从而计算出负载所消耗的能量,并将测量值显示在1602显示器上。
下面,我们再把电路分成多个功能块进行介绍,这样我们就能更清楚地了解电路是如何工作的。
测量单元
测量单元包含一个分压器可以帮助我们测量电压;一个非反向的运算放大器帮助我们测量通过电路的电流。上述电路的分压部分如下所示:
这里输入电压是由vcc表示的,就像前面说的,我们正在设计从0到24v的电压范围的电路。但是像arduino这样的微控制器无法测量如此高的电压值,它只能测量0-5v的电压。因此,我们必须将0-24v的电压(转换)到0-5v。这因此我们通过使用一个分压电路来实现,如下所示。10k和2.2k电阻形成了分压电路,用下面的公式可计算出分压器的输出电压。
vout = (vin × r2) / (r1 + r2)
电路图中标记为voltage的电压可以从两个电阻中间获得,这个转换后的电压就可以被输入到arduino的模拟针中。接下来就是电流测量单元,我们知道微控制器只能读取模拟电压,所以我们需要将电流的值转换成电压。这时,可以通过在电路中添加一个电阻(并联)来实现,根据欧姆定律,它会降低电压值,这与流过它的电流成正比。这样获得的值会非常小,所以我们用一个运算放大器来放大它。电路如下所示:
分流电阻(sr1)的值是0.22欧姆。就像之前说的,我们设计的是0-1a的测量电路,基于欧姆定律,我们可以计算出这个电阻的电压降,当最大的1a电流通过负载时,它的电压会在0.2v左右。这个电压对于微控制器来说是非常小的,我们使用一个运算放大器来将电压从0.2v放大到到更高。这个放大器的增益是21,所以0.2*21=4.2v。计算运算放大器增益的公式如下所示:
gain = vout / vin = 1 + (rf / rin)
在例子中,rf的值是20k而rin的值是1k,这样我们就能获得21的增益值。然后,将放大器的放大电压输入到一个由电阻1k和电容0.1uf组成的的rc滤波电路,过滤掉耦合噪声。最后,将得到的电压输入到arduino模拟针上。
测量单元最后的部分是电压调节电路。由于实际输入的电压可能是可变的,而arduino和运算放大器需要一个稳定的+5v来保证正常工作,因此我们用7805稳压模块并添加一个噪声电容来进行电压调节。电路如下:
计算和显示单元
在测量单元中,我们将电压和电流参数转换成了0-5v,使之可以用在arduino模拟输入上。现在,我们需要将这些电压信号与arduino连接起来,并将1602液晶显示器连接到arduino上,这样我们就可以查看最终结果了。
如上图所示,voltage针与arduino模拟针a3相连,而current针连接到arduino模拟针a4,1602液晶显示器的电源来自于7805输出的+5 v,同时将1602其它信号针与arduino的数字数字针相连,以4-bit模式工作,同时我们使用了一个电位计(10 k)连接到1602的 con 针用来调节lcd的对比度。
arduino编程部分
硬件部分讨论结束后,现在轮到软件部分了。软件部分代码的基本思路是读取a3和a4上的模拟电压,并计算电压、电流和功率值,最后将其显示在lcd屏幕上。下面我们将代码分割成小段来解释。和所有arduino程序一样,开始都是定义使用的引脚。在本例中,a3和a4针分别用于测量电压和电流,数字针3,4,8,9,10和11用于与arduino进行交互。
int read_voltage = a3;
int read_current = a4;
const int rs = 3, en = 4, d4 = 8, d5 = 9, d6 = 10, d7 = 11; //1602 lcd 连接针
liquidcrystal lcd(rs, en, d4, d5, d6, d7);
included一个名为“liquid crystal”的头文件。然后setup 函数中,初始化lcd显示屏,并将串口显示文本设置为“arduino wattmeter”,然后等待两秒钟。代码如下所示:
void setup() {
lcd.begin(16, 2); //initialise 16*2 lcd
lcd.print(“ arduino wattmeter”);
lcd.setcursor(0, 1);
lcd.print(“-circuitdigest”);
delay(2000);
lcd.clear();
}
在主循环函数中,我们使用analogread函数来读取a3和a4的电压值。我们知道arduino adc的输出值是0-1203,因为它有一个10位的adc,这个值必须被转换成0-5v,可以通过乘以(5/1023)来完成。在硬件介绍部分,我们已经完成从0-24v到0-5v的电压转换,以及0-1a到0-5v的转换。所以现在我们要用一个乘数把这些值恢复到实际值。可以通过将其与乘数值相乘来完成。乘数的值可以用硬件部分提供的公式来计算,或者如果你已知电压和电流值,你可以实际计算它。本例遵循了后一种选择,因为它在现实中往往更准确。所以乘数的值是6.46和0.239。因此,代码如下所示:
float voltage_value = analogread(read_voltage);
float current_value = analogread(read_current);
voltage_value = voltage_value * (5.0/1023.0) * 6.46;
current_value = current_value * (5.0/1023.0) * 0.239;
如何提高测量精度?
上述计算实际电压和电流值的方法可以很好地工作。但是也有一个缺点,那就是测量的adc电压和实际电压之间的关系不是线性的,因此得到的结果不会非常精确。为了提高精确度,我们可以用已知的一组值来建立测量的adc值的集合,然后利用这些数据,使用线性回归方法推导出乘数方程。一旦我们计算出了实际电压和实际电流值,我们就可以用公式计算出功率(p=v*i)。然后使用下面的代码在lcd上显示这三个值。
lcd.setcursor(0, 0);
lcd.print(“v=”); lcd.print(voltage_value);
lcd.print(“ ”);
lcd.print(“i=”);lcd.print(current_value);
float power_value = voltage_value * current_value;
lcd.setcursor(0, 1);
lcd.print(“power=”); lcd.print(power_value);
完整测试代码
/*
* wattmeter for solar pv using arduino * dated: 2-10-2018 * website: www.basemu.com * translation to:circuitdigest.com * power lcd and circuitry from the +5v pin of arduino whcih is powered via 7805 * lcd rs -> pin 2 * lcd en -> pin 3 * lcd d4 -> pin 8 * lcd d5 -> pin 9 * lcd d6 -> pin 10 * lcd d7 -> pin 11 * potetnital divider to measure voltage -> a3 * op-amp output to measure current -> a4 */#include int read_voltage = a3;int read_current = a4;const int rs = 3, en = 4, d4 = 8, d5 = 9, d6 = 10, d7 = 11; liquidcrystal lcd(rs, en, d4, d5, d6, d7);void setup() { lcd.begin(16, 2); lcd.print( arduino wattmeter); lcd.setcursor(0, 1); lcd.print( with arduino ); delay(2000); lcd.clear();}void loop() { float voltage_value = analogread(read_voltage); float current_value = analogread(read_current); voltage_value = voltage_value * (5.0/1023.0) * 6.46; current_value = current_value * (5.0/1023.0) * 0.239; lcd.setcursor(0, 0); lcd.print(v=); lcd.print(voltage_value); lcd.print( ); lcd.print(i=);lcd.print(current_value); float power_value = voltage_value * current_value; lcd.setcursor(0, 1); lcd.print(power=); lcd.print(power_value); delay(200);}  

基于WSN路由算法在无线传感器网络检测粮库中的应用研究
零基础开发安信可小安派-Eyes-S1【入门篇】——安装VMware与Ubuntu
常见的转换器交流性能特征有哪些,都有什么作用
GaAs MMIC 低噪声放大器MGA-633P8性能分析
生物识别技术四大种类介绍(人脸、指纹、虹膜、声纹)
如何利用Arduino构建一个功率计
中国智慧城市建设后来居上,运营商5G新基建赋能智慧城市建设
互联网+医疗健康发展的政策效应日益显现
抢“鲜”了解!第二届CCF“司南杯”量子计算编程挑战赛赛程概况
OPPOK5全曝光,6400万四摄内置30W闪存
集成电路装备厂商中科仪正式被上交所受理科创板IPO
利用3D打印技术打造别墅
专用无线网络为大中型企业带来的好处
从云到边缘的转变,标志着物联网连接真正的自主革命
机器人能玩耍也能学习?加州大学为你解谜
iPhone8、三星note8、华为mate10最新消息汇总:配置、性能、拍照、功能、外观、续航哪家强?
mos管的三个极区分
日之的机场和汽车服务已经开始接受数字货币支付
“鱼鹰”有源相控阵雷达的特点及具有哪些优势
三星S21系列旗舰的表现如何?