在本文中,将向您展示如何利用Arduino丈量直流电压和电流。这里的技能适用于任何单片机,实际上,诸如ESP-32或Seeeduino XIAO之类的设备实际上可以实行更好的DC电压丈量,由于它们具有更高分辨率的模数转换器。
目录
1第1部分–直流
1.1弁言
1.2丈量直流电压
1.2.1模数转换器
1.2.2分压器
1.2.3参考电压
1.3用Arduino丈量直流电压
1.3.1 Arduino Hookup 1 –基本直流电压丈量
1.3.2 Arduino Sketch 1 –基本直流电压丈量
1.3.3 LM4040精密基准电压源
1.3.4 Arduino Hookup 2 –利用LM4040进行直流电压丈量
1.3.5 Arduino Sketch 2 –利用LM4040进行直流电压丈量
1.4丈量直流电流
1.4.1接入与非接入技能
1.5用Arduino丈量直流电流
1.5.1 ACS712霍尔效应传感器
1.5.2 ACS712霍尔效应传感器连接
1.5.3 ACS712霍尔效应传感器代码
1.5.4 Adafruit INA219电流和电压传感器
1.5.5 Adafruit INA219电流和电压传感器连接
1.5.6 Adafruit INA219电流和电压传感器代码
1.6结论
1.6.1资源
第1部分–直流在利用单片机丈量电压和电流的第一部分中,我们将看到如何利用Arduino丈量DC电压和电流。
图1
用单片机(或任何数字数据设备)丈量直流电压须要利用模数转换器(ADC)。许多当代单片机(包括Arduino Uno)都具有内置ADC,这使得直流电压丈量成为我们四项任务中最大略的一项。
模数转换器
模数转换器听起来确实很不错。它是一个接管仿照输入并产生数字输出的组件,该输出是输入电平的数字表示。
图2
此转换的准确性取决于几个不同的成分:
位数–这决定了转换器可以将输入分为多少“步”。步越多,输出就可以越细化。
图3
参考电压–转换器的最高值与其所施加的参考电压一样。这也决定了ADC在其输入端可以接管的最大电压。
图4
线性度–转换器须要具有线性输出,也便是说,转换器的输出读数每次增加都要增加相同的量。
许多单片机(例如Arduino Uno)都具有内置ADC。Uno有六个10位ADC,这意味着它们可以将输入分解为1024个离闲步长(2的10的幂即是1024)。
其他单片机也具有内置ADC,个中一些具有比Arduino Uno更高的分辨率。借助ESP32和Seeeduino XIAO,我们可以选择12位ADC,使它们能够将输入电压解析为4096步。
图5
分压器
可以输入到Arduino Uno ADC的最大输入电压为5伏,而利用3.3伏逻辑的单片机乃至更低。显然,这有点不切实际,由于您可能想要丈量超过此值的输入电压。
图6
为此,我们可以利用分压器,这是一个由两个电阻器构成的非常大略的电路。这样可以降落电压,并具有增加输入阻抗的额外好处,这意味着丈量设备不会降落它正在考试测验丈量的电路的负载并使读数失落真。
图7
您当然可以利用分立电阻构建一个分压器,实际上,如果您打算丈量非常高的电压,则可能必须这样做。但是,如果您打算利用Arduino丈量低于26伏的较低电压,则可以购买预制的分压器来完成这项事情。这些设备非常便宜,并利用精密电阻器来供应准确的读数。
我将在我们的实验中利用这些分频器之一。它由一个7.5k电阻和一个30k电阻组成。
参考电压如前所述,决定我们ADC精度的成分之一是其参考电压。
默认情形下,Arduino Uno利用其电源电压作为参考。该电压假定为5伏,可以从其USB端口或内部线性稳压器得到。
这些电压并不总是精确的,USB电压取决于打算机的电源以及USB电缆本身的长度和规格。当将线性稳压器与外部电源一起利用时,精度由该稳压器确定,精度也可能恰好在5伏之间。
只要电压在4.75到5.25伏之间,Arduino逻辑电路就可以正常事情。但是,当将其用作参考时,该差异会影响模数转换器的精度。
图8
Arduino Uno还能够利用连接到AREF引脚的外部参考电压。该参考电压不能超过5伏。
为了在代码中利用外部引用,您须要利用analogReference命令指定它。此命令使Arduino知道应利用AREF引脚上的外部基准而不是电源电压。
您会从上面的链接中把稳到,实际上可以给AnalogReference供应多个参数,但是并非所有的单片机都支持它们:
默认值–利用单片机的电源电压作为参考。如果您未指定任何内容,则将利用此名称。EXTERNAL –利用施加到AREF引脚的外部参考电压。内部–一些单片机也具有内部精度基准。上面的链接对此进行了详细解释。通过利用精确的外部参考电压,您可以改进Arduino ADC的性能。
利用Arduino丈量直流电压
我们将通过丈量直流电压开始我们的实验。Arduino Uno有六个我们可以同时丈量多个电压的10位ADC,但是本日我们只关注利用一个输入并丈量一个电压。
Arduino 接线- 1 –基本直流电压丈量
我们的第一个实验的连接非常大略:
图9
图10
如果您没有这些电阻,则可以利用几个电阻。我利用的分压器有两个电阻:
在“高端”上有一个30k电阻,用于输出和输入电压之间的连接。输出和地之间的7.5k电阻。这将使输入的电压降落约5倍。
如果要丈量更高的电压,也可以打算自己的分压器。
Arduino Sketch 1 –基本直流电压丈量这是我们用于直流电压丈量实验的代码:
/Arduino DC Voltage Demo 1dc-voltage-demo.inoUse Arduino A/D converter to measure voltageUse external voltage divider with 30k & 7.5k resistorsResults displayed on Serial MonitorDroneBot Workshop 2021https://dronebotworkshop.com/// Define analog input#define ANALOG_IN_PIN A0// Floats for ADC voltage & Input voltagefloat adc_voltage = 0.0;float in_voltage = 0.0;// Floats for resistor values in divider (in ohms)float R1 = 30000.0;float R2 = 7500.0;// Float for Reference Voltagefloat ref_voltage = 5.0;// Integer for ADC valueint adc_value = 0;void setup(){ // Setup Serial Monitor Serial.begin(9600); Serial.println("DC Voltage Test");}void loop(){ // Read the Analog Input adc_value = analogRead(ANALOG_IN_PIN); // Determine voltage at ADC input adc_voltage= (adc_value ref_voltage) / 1024.0; // Calculate voltage at divider input in_voltage = adc_voltage / (R2/(R1+R2)); // Print results to Serial Monitor to 2 decimal placesSerial.print("Input Voltage = ");Serial.println(in_voltage, 2);// Short delaydelay(500);}
这是一个非常大略的代码,因此您该当毫无困难地理解它。
在定义了仿照输入引脚之后,我们利用一些浮点数来表示ADC输入真个电压,以及试图在分压器输入端丈量的电压。
然后,我们在分压器中声明电阻的值。如果您要利用不同的电阻制作自己的分压器,则须要变动此设置。
我们为参考电压定义了一个浮点数,在本例中为5伏,由于我们利用的是Arduino的电源电压作为参考。
我们定义的末了一个变量是模数转换器产生的值,它是一个整数,范围为0到1023。
我们将结果显示在串口监视器上,因此我们在安装程序中对其进行定义。
在loop中,我们从ADC读取值,然后根据该值打算电压电平。然后,我们将电阻器分解,以确定分压器的输入电压。
之后,我们将结果打印到串口监视器上,添加一个延迟,然后再次实行所有操作。
将代码加载到您的Arduino并不雅观察结果。
图11
如果您有万用表(如果利用此表,则该当有一个)丈量电压,并将丈量结果与串口监视器上看到的进行比较。取决于您的Arduino电源靠近5伏的程度,您可能会看到或可能不会看到相同的值。
让我们看看是否可以改进这一点!
为了改进基本直流电压丈量的性能,我们须要为Arduino供应一个外部电压基准,该基准将连接到AREF引脚。
您可以选择许多不同的参考芯片和模块。我决定利用Adafruit的一款我认为很酷的产品。
图12
该LM4040是一款高精度稳压芯片,并且该模块实际上包含两个。它们被安排为供应两个精度输出:
4.096 VDC –非常适宜像Arduino Uno这样的5伏单片机。2.048 VDC –非常适用于ESP32或Seeeduino XIAO之类的3.3伏设备。乍一看,您可能会创造它们是奇数值,直到您以毫伏为单位查看它们–分别为4096和2048 mv。考虑到您的ADC的分辨率为1024或4096个部分,这溘然变得很合理!
因此,我们的Arduino Uno ADC分辨率为10位(1024个部分),每个增量的丈量结果为4mv。
让我们在电路中利用该器件,看看它是否对精度有帮助。
Arduino 接线 2 –利用LM4040进行直流电压丈量这是我们的直流电压丈量实验的修订版连接:
图13
请把稳,唯一的变革是添加了LM34040模块,该模块由我们Arduino的5伏输出供电
Arduino Sketch 2 –利用LM4040进行直流电压丈量
这是我们将利用外部参考电压来丈量DC电压的代码。
/Arduino DC Voltage Demo 2dc-voltage-demo-vref.inoUse Arduino A/D converter to measure voltageUse external voltage referenceUse external voltage divider with 30k & 7.5k resistorsResults displayed on Serial MonitorDroneBot Workshop 2021https://dronebotworkshop.com/// Define analog input#define ANALOG_IN_PIN A0// Floats for ADC voltage & Input voltagefloat adc_voltage = 0.0;float in_voltage = 0.0;// Floats for resistor values in divider (in ohms)float R1 = 30000.0;float R2 = 7500.0;// Float for Reference Voltagefloat ref_voltage = 4.096;// Integer for ADC valueint adc_value = 0;void setup(){// Use external voltage referenceanalogReference(EXTERNAL); // Setup Serial Monitor Serial.begin(9600); Serial.println("DC Voltage Test");}void loop(){ // Read the Analog Input adc_value = analogRead(ANALOG_IN_PIN); // Determine voltage at ADC input adc_voltage= (adc_value ref_voltage) / 1024.0; // Calculate voltage at divider input in_voltage = adc_voltage / (R2/(R1+R2)); // Print results to Serial Monitor to 2 decimal placesSerial.print("Input Voltage = ");Serial.println(in_voltage, 2);// Short delaydelay(500);}
请把稳,此代码大部分与上一个代码相同,它只有两个差异:
参考电压已设置为4.096。用analogReference命令指定了一个外部电压参考。因此,将此代码加载到Arduino并进行测试。
图14
我把稳到比以前的代码有了很大的改进,这是可以预期的。
顺便说一句,您还可以利用LM4040来测试万用表的准确性。实际上,我对我的廉价数字万用表的精确度感到惊异!
现在,我们已经理解了如何利用Arduino丈量电压,现在我们将把稳力转移到电流丈量上。
丈量电流利常涉及将电流转换成电压,然后可以像上面所做的那样利用ADC进行丈量。有两种不同的方法可以完成此操作。
接入式和非接入式我们可以将当前的丈量技能分为两类:接入式和非接入式。
与我们要丈量其电流的电路串联。它是“接入性的”,由于其插入会轻微影响电路本身的性能,只管这种影响常日相称眇小。
非接入性方法不须要直接连接到电路。取而代之的是,丈量电流在导体中产生的磁场。如果您已经看到(或拥有)这些钳流表,这便是它们的事情办法。
图15
大多数接入式方法利用低值电阻器,该电阻器与要丈量其电流的电路串联。丈量电阻两端的压降,并利用欧姆定律打算电流。
丈量直流电流最常见的非接入性方法涉及利用霍尔效应传感器。将其放置在导体附近,以丈量导体周围的磁场。该场强用于确定电流。
只管可以得到不须要连接电路的霍尔效应传感器,但我们将利用的霍尔效应传感器确实可以作为导体,它所丈量的场强在传感器的IC芯片内部。
用Arduino丈量直流电流我们将利用接入性和非接入性这两种方法来丈量Arduino的电流。我们将从一个非常普遍利用的非接入传感器ACS712开始。
ACS712霍尔效应传感器ACS712已经存在了很多年,实际上,它已被其他型号取代,并且不再用于新设计。但是,它仍旧是普遍可用的,而且最主要的是,它非常便宜。
该霍尔效应电流传感器可用于直流和互换电流,只管本日我们将重点先容其与直流电一起利用。
该设备利用5伏电源供电,并输出与所丈量电流成比例的电压。输入连接与输出隔离,因此可以安全地用于高压运用。
该传感器实际上有三种版本,它们可以丈量的最大电流不同:
5安培20安培30安培由于大多数模块没有标识它们正在利用哪个版本的标记,因此您可能须要直接查看ACS712芯片本身来确定这一点。
图16
在上面的示例中,您将看到这是20安培的版本。
当未检测到电流时,ACS712输出2.5伏的电压。高于此电压是正向流动的电流,而低于2.5伏电压则表明为负向电流。
由于该芯片有三个版本,因此须要利用“比例因子”来确定电流,如下所示:
图17
图示中还显示了确定电流的打算公式。
ACS712霍尔效应传感器连接这是我们将ACS712连接到Arduino Uno的方法:
图18
这是一个非常大略的连接,ACS712输出连接到Arduino仿照输入。
请把稳,ACS712的输入连接未标有极性,由于它可以读取正电流和负电流。如果按照上面的图表进行连接,您的读数将为正。
ACS712霍尔效应传感器代码这是我们将利用ACS712霍尔效应电流传感器丈量直流电流的代码:
/ACS712 DC Current Demonstrationacs712-dc-demo.inoRead current using ACS712 Hall Effect sensorDroneBot Workshop 2021https://dronebotworkshop.com/// Variables for Measured Voltage and Calculated Currentdouble Vout = 0;double Current = 0;// Constants for Scale Factor// Use one that matches your version of ACS712//const double scale_factor = 0.185; // 5Aconst double scale_factor = 0.1; // 20A//const double scale_factor = 0.066; // 30A// Constants for A/D converter resolution// Arduino has 10-bit ADC, so 1024 possible values// Reference voltage is 5V if not using AREF external reference// Zero point is half of Reference Voltageconst double vRef = 5.00;const double resConvert = 1024;double resADC = vRef/resConvert;double zeroPoint = vRef/2;void setup(){Serial.begin(9600);}void loop(){// Vout is read 1000 Times for precisionfor(int i = 0; i < 1000; i++) {Vout = (Vout + (resADC analogRead(A0)));delay(1);}// Get Vout in mvVout = Vout /1000;// Convert Vout into Current using Scale FactorCurrent = (Vout - zeroPoint)/ scale_factor;// Print Vout and Current to two Current = ");Serial.print("Vout = ");Serial.print(Vout,2);Serial.print(" Volts");Serial.print("\t Current = ");Serial.print(Current,2);Serial.println(" Amps");delay(1000);}
大部分代码涉及读取仿照输入电压并利用数学方法确定电流。
resADC变量是利用参考电压来打算的,在我们的连接中,参考电压为5伏。如果要构建更精确的传感器,则可以对其进行修正以利用我们之前利用的LM4040模块,如果要这样做,则须要相应地变动vRef的值。
还要把稳,zeroPoint是由Arduino的电源电压确定的,而不是由电压基准确定的。如果您修正电路作为外部参考,则可以将其变动为2.50。
您须要确保已考虑ACS712比例因子,否则读数将毫无意义。我展示了此代码中利用的ACS712的20安培版本,但我还供应了其他两个版本所需的值。
在循环中,我们读取该值一千次,因此可以得到一个很好的均匀值。然后,我们利用您之前看到的公式将电压读数转换为电流。然后我们将其显示在串口监视器上。
图19
将代码加载到您的Arduino并不雅观察您当前的读数。我可以看到没有电流流过,仍旧得到了一点读数,这可能是由于两个成分造成的:
基准电压为DEFAULT,利用LM4040模块之类的外部基准电压可能会有所帮助。供应给ACS712的5伏电压可能也有一点偏离,从而影响了零点。但是总的来说,它并没有太多的变革,因此这是一种丈量直流电流的非常大略的方法(正如您将在往后的文章中看到的,互换电流也是如此)。
Adafruit INA219电流和电压传感器我们本日将要利用的终极传感器与迄今为止所见的其他传感器完备不同。
INA219传感器能够同时丈量直流电压和电流。它也没有像我们到目前为止利用的其他设备那样的仿照输出,相反,该设备具有I2C输出。这使得它不仅适用于单片机,而且适用于微型打算机。
图20
它实际上有两种形式,一种是独立模块,另一种是与Adafruit Featherwing处理器一起利用的。任一种都适宜我们的实验。
此模块的一大上风是,它插入电路的“高端”而不是接地端,这是连接了多少个电压和电流显示模块。这使得它非常适宜用作电压和电流显示。
该器件具有一个内部12位ADC,可丈量高达3.2A的电流。它是一种接入式传感器,利用0.1欧姆的精密电阻器。如果您是真正的高手,则可以用另一个电阻器更换电阻器以变动量程!
INA219的事情电压为5伏特,可以由Arduino供应。
Adafruit INA219电流和电压传感器接线
这是我们将Adafruit INA219传感器连接到Arduino的方法:
图21
请把稳,这是一个I2C器件,因此A4和A5引脚被用作SDA和SCL,而不是仿照输入。
Adafruit INA219电流和电压传感器代码为了利用此设备,您须要安装Adafruit供应的库。
在您的库管理器中搜索“ Adafruit INA219”。您将得到一个结果,一个须要安装的库。如果您以前没有安装过某些依赖库,还将提示您安装它们,您将连续进行。
一旦安装了库,就可以运行Adafruit供应的示例代码。进入自定义库的示例,然后查找Adafruit INA219。
打开“ getcurrent ”代码,如下所示:
#include <Wire.h>#include <Adafruit_INA219.h>Adafruit_INA219 ina219;void setup(void){Serial.begin(115200);while (!Serial) {// will pause Zero, Leonardo, etc until serial console opensdelay(1);}uint32_t currentFrequency;Serial.println("Hello!");// Initialize the INA219.// By default the initialization will use the largest range (32V, 2A).However// you can call a setCalibration function to change this range (see comments).if (! ina219.begin()) {Serial.println("Failed to find INA219 chip");while (1) { delay(10); }}// To use a slightly lower 32V, 1A range (higher precision on amps)://ina219.setCalibration_32V_1A();// Or to use a lower 16V, 400mA range (higher precision on volts and amps)://ina219.setCalibration_16V_400mA();Serial.println("Measuring voltage and current with INA219 ...");}void loop(void){float shuntvoltage = 0;float busvoltage = 0;float current_mA = 0;float loadvoltage = 0;float power_mW = 0;shuntvoltage = ina219.getShuntVoltage_mV();busvoltage = ina219.getBusVoltage_V();current_mA = ina219.getCurrent_mA();power_mW = ina219.getPower_mW();loadvoltage = busvoltage + (shuntvoltage / 1000);Serial.print("Bus Voltage: "); Serial.print(busvoltage); Serial.println(" V");Serial.print("Shunt Voltage: "); Serial.print(shuntvoltage); Serial.println(" mV");Serial.print("Load Voltage:"); Serial.print(loadvoltage); Serial.println(" V");Serial.print("Current: "); Serial.print(current_mA); Serial.println(" mA");Serial.print("Power: "); Serial.print(power_mW); Serial.println(" mW");Serial.println("");delay(2000);}
有了库后,利用此传感器非常大略。在代码中,定义了一个名为“ ina219 ”的工具,该工具的属性具有您须要的所有内容,而无需进行任何打算。当然,该代码还利用了Arduino Wire库,由于它是I2C设备。
代码打印出许多参数,包括电压,电流,功率以及电阻两端测得的实际电压。
图22
加载并查看,确保您的负载不超过3.2安培。您该当创造它事情非常有效,并且由于它利用自己的内部ADC,因此不受Arduino ADC参考电压的影响。
结论如您所见,利用Arduino丈量DC电压和电流非常大略,您可以扩展这些代码以利用其他单片机。