How to Read Voltage on an Arduino
Part 1 – Straight Electric current
In the first part of our wait at measuring voltage and electric current with microcontrollers, we will run into how to measure DC voltage and current using an Arduino.
In role two nosotros will practise the same thing with AC, merely today our focus is on Direct Electric current.
Introduction
There are many reasons why you might want to use a microcontroller to measure DC voltage and current. You might be monitoring the output of a generator or solar assortment, you could be measuring the current consumption of your projection or you might want to observe the charging and discharging of a bombardment.
In this commodity, I will show you how to measure DC voltage and current using an Arduino. The techniques hither apply to any microcontroller, in fact devices similar the ESP-32 or Seeeduino XIAO can actually perform ameliorate DC voltage measurements as they have analog to digital converters with a higher resolution.
Permit's get started!
Measuring DC Voltage
Measuring DC Voltage with a microcontroller (or any digital information device) requires the use of an Analog to Digital Converter (ADC). Many modern microcontrollers, including the Arduino Uno, accept a built-in ADC, making DC voltage measurement the simplest of our four tasks.
Analog to Digital Converters
An Analog to Digital Converter is pretty well exactly what information technology sounds like. It'southward a component that accepts an analog input and produces a digital output, the output being a digital representation of the level of the input.
The accuracy of this conversion is determined by a few different factors:
Number of Bits – This determines how many "steps" the converter can divide the input into. The more boots, the more granular the output can exist.
Voltage Reference – The converter is merely as precise as the reference voltage applied to it. This also determines the maximum voltage the ADC can take at its input.
Linearity – The converter needs to accept a linear output, that is to say, it needs to have its output readings increment by the same amount for each increment.
Many microcontrollers, like the Arduino Uno, have built-in ADCs. The Uno has six 10-fleck ADCs, meaning that they can resolve the input downward to 1024 discrete steps (2 to the power of 10 equals 1024).
Other microcontrollers also have congenital-in ADCs, some of them with a greater resolution than the Arduino Uno. With the ESP32 and Seeeduino XIAO, we accept a selection of 12-chip ADCs, allowing them to resolve the input voltage downward to 4096 steps.
Voltage Dividers
The maximum input voltage that you can feed into an Arduino Uno ADC is five-volts, with microcontrollers using 3.3-volt logic information technology is fifty-fifty less. Manifestly, this is a bit impractical, as you'll probably desire to measure input voltages exceeding that.
To accomplish this we tin use a voltage divider, a very simple circuit synthetic using two resistors. This reduces the voltage and has the added do good of increasing the input impedance, which means that the measurement device won't load downward the circuit information technology is trying to measure and distort the reading.
Yous tin certainly construct a voltage divider using discrete resistors, in fact, if y'all are planning to measure out very high voltages then you'll probably accept to. However, If you are planning on using your Arduino to measure lower voltages, less than 26-volts, y'all can purchase a premade split that will exercise the task. These devices are extremely inexpensive and use precision resistors to give an accurate reading.
I'll be using one of these dividers in our experiments. It consists of a 7.5k resistor and a 30k resistor.
Voltage References
As stated earlier one of the factors that make up one's mind the accuracy of our ADC is its reference voltage.
Past default, the Arduino Uno uses its ability supply voltage equally the reference. This is supposed to exist 5-volts and can be derived either from its USB port or from its internal linear voltage regulator, which is used when the Uno is powered using the barrel connector.
These voltages are non e'er precise, the USB voltage is dependent upon your computer's power supply and the length and estimate of the USB cablevision itself. When using the linear regulator with an external supply the accuracy is determined by that regulator,, which can as well vary from exactly 5-volts.
As long as the voltage is betwixt four.75 and 5.25 volts the Arduino logic circuitry will be happy. But that variance tin can bear on the accuracy of the analog to digital converter when it'southward used as a reference.
The Arduino Uno is besides capable of using an external voltage reference, which is connected to the AREF pin. This reference voltage cannot exceed 5-volts.
In lodge to use the external reference in your code, you need to specify it using the analogReference command. This command lets the Arduino know that it should employ the external reference on the AREF pin instead of the supply voltage.
You'll notation from the link in a higher place that there are actually multiple parameters you tin can give to analogReference, yet not all microcontrollers support them:
- DEFAULT – Use the microcontroller'south power supply voltage as a reference. If you lot don't specify anything then this is what will exist used.
- EXTERNAL – Apply the external voltage reference practical to the AREF pin.
- INTERNAL – Some microcontrollers as well have an internal precision reference. The link above explains this in particular.
By using the correct external reference voltage yous can meliorate the performance of the Arduino ADC.
Measuring DC Voltage with the Arduino
We will brainstorm our experiments past measuring DC voltage. And the Arduino Uno has 6 10-flake ADCs we could actually measure multiple voltages simultaneously, but today we'll merely focus on using one input and measuring a single voltage.
Arduino Hookup 1 – Basic DC Voltage Measurement
The hookup for our get-go experiment is very unproblematic:
All we are doing here is using a resistive voltage divider in front end of ane of the analog inputs on the Arduino. Here is an image of that divider, which is commonly available at just well-nigh any electronics shop:
If you don't have one of these you tin use a couple of resistors. The divider I used has ii resistors:
- A 30k resistor on the "loftier-side", the connexion betwixt the output and the input voltage.
- A 7.5k resistor between the output and ground.
This will reduce the voltage input by nigh a factor of 5.
You can also calculate your own divider if you want to measure higher voltages.
Arduino Sketch 1 – Bones DC Voltage Measurement
Here is the sketch we are using for our DC voltage measurement experiment:
one 2 iii iv 5 half-dozen 7 8 nine 10 11 12 xiii 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 thirty 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | /* Arduino DC Voltage Demo ane dc-voltage-demo.ino Use Arduino A/D converter to measure out voltage Utilize external voltage divider with 30k & 7.5k resistors Results displayed on Serial Monitor DroneBot Workshop 2021 https://dronebotworkshop.com */ // Define analog input #define ANALOG_IN_PIN A0 // Floats for ADC voltage & Input voltage float 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 Voltage float ref_voltage = v.0 ; // Integer for ADC value int adc_value = 0 ; void setup ( ) { // Setup Serial Monitor Series . begin ( 9600 ) ; Serial . println ( "DC Voltage Exam" ) ; } 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 ii decimal places Series . print ( "Input Voltage = " ) ; Serial . println ( in_voltage , 2 ) ; // Short filibuster filibuster ( 500 ) ; } |
This is a pretty unproblematic sketch, then you should have no problem understanding it.
After defining the analog input pivot we are using we declare a few floats that represent the voltage at the input of the ADC, as well every bit the voltage we are trying to measure out on the input of the divider.
Nosotros then declare the values of the resistors in the divider. If you are making your own divider with different resistors you'll need to change this.
Nosotros define a bladder for the reference voltage, which in this case is v-volts as we are using the Arduino's power supply voltage equally a reference.
And the last variable we ascertain is the value produced by the analog to digital converter, which is an integer that tin range from 0 to 1023.
Nosotros will brandish our results on the serial monitor, then we ascertain that in the Setup.
In the loop, we read the value from the ADC and and so calculate the voltage level based upon that. We so factor in the resistors to make up one's mind the actuarial input voltage to the divider.
Afterwards that we merely print the results to the serial monitor, add a delay and then do it all again.
Load the sketch to your Arduino and discover the results.
If you have a multimeter (and you should have one if you work with this stuff) measure the voltage and compare the measurement to what yous run into on the serial monitor. Depending upon how close to 5-volts your Arduino power source is y'all may or may not see the same value.
Permit's see if we can ameliorate that!
LM4040 Precision Voltage Reference
In order to ameliorate the performance of our basic DC voltage measurements, nosotros will need to provide our Arduino with an external voltage reference, which we will connect to the AREF pin.
There are many different reference chips and modules you lot can choose from. I have decided to apply one from Adafruit that I think is pretty absurd.
The LM4040 is a precision regulator chip, and this module really contains 2 of them. They are arranged to provide two precision outputs:
- 4.096 VDC – Ideal for v-volt microcontrollers like our Arduino Uno.
- 2.048 VDC – Great for 3.3-volt devices like the ESP32 or Seeeduino XIAO.
At showtime glance you might find those to be oddball values until y'all look at them in millivolts – they are 4096 and 2048 mv respectively. Because your ADC has resolutions of 1024 or 4096 parts information technology suddenly makes perfect sense!
So our Arduino Uno ADC with a 10-bit (1024 parts) resolution would exist measuring 4mv for each increase.
Let's use this device with our circuit and see if information technology helps with the accuracy.
Arduino Hookup 2 – DC Voltage Measurement with LM4040
Here is the revised hookup for our DC voltage measurement experiment:
Note that the just alter is the add-on of the LM34040 module, which is powered from the v-volt output of our Arduino
Arduino Sketch ii – DC Voltage Measurement with LM4040
Here is the sketch nosotros volition exist using to measure out DC voltage with an external voltage reference.
1 ii three 4 5 half-dozen 7 8 nine 10 xi 12 thirteen 14 15 16 17 eighteen 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 l 51 52 53 54 55 | /* Arduino DC Voltage Demo ii dc-voltage-demo-vref.ino Use Arduino A/D converter to measure voltage Use external voltage reference Use external voltage divider with 30k & seven.5k resistors Results displayed on Serial Monitor DroneBot Workshop 2021 https://dronebotworkshop.com */ // Define analog input #define ANALOG_IN_PIN A0 // Floats for ADC voltage & Input voltage float adc_voltage = 0.0 ; float in_voltage = 0.0 ; // Floats for resistor values in divider (in ohms) float R1 = 30000.0 ; bladder R2 = 7500.0 ; // Float for Reference Voltage bladder ref_voltage = 4.096 ; // Integer for ADC value int adc_value = 0 ; void setup ( ) { // Use external voltage reference analogReference ( EXTERNAL ) ; // Setup Serial Monitor Serial . begin ( 9600 ) ; Serial . println ( "DC Voltage Exam" ) ; } 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 ; // Summate voltage at divider input in_voltage = adc_voltage / ( R2/( R1+R2 ) ) ; // Print results to Series Monitor to ii decimal places Serial . print ( "Input Voltage = " ) ; Serial . println ( in_voltage , 2 ) ; // Short delay delay ( 500 ) ; } |
Note that this sketch is nigh identical to the previous 1, in fact, information technology only has two differences:
- The reference voltage has been set to 4.096.
- The analogReference command specifies an EXTERNAL voltage reference.
And then load this sketch to the Arduino and give information technology a test.
I noticed a great improvement over the previous sketch, which was to be expected.
BTW, you can also use the LM4040 to test the accuracy of your multimeter. I was actually surprised at how accurate my inexpensive DMM was!
Measuring DC Electric current
At present that we have seen how to measure voltage with our Arduino permit'south turn our attention to the measurement of current.
Measuring electric current usually involves turning that current into a voltage, which tin then be measured using an ADC every bit we did above. There are a couple of different means of accomplishing this.
Invasive vs. Not-Invasive Techniques
We can divide our current measurement techniques into two categories – Invasive and Non-invasive.
An invasive method is inserted in serial with the circuit whose current we wish to measure. Information technology is "invasive" equally its insertion slightly affects the performance of the circuit itself, although this effect is usually fairly trivial.
A non-invasive method does non require any directly connection to the circuit. Instead, the magnetic field that the current produces in a usher is measured. If you have seen (or own) those clamp-on meters this is how they operate.
Nigh invasive methods utilise a low-value resistor, which is wired in series with the circuit whose current you wish to measure. The voltage drop across the resistor is measured and Ohm's Law is used to summate the electric current flow.
The most common noninvasive method for measuring DC current involves the apply of a Hall Effect sensor. This is placed nigh a conductor to measure out the magnetic field surrounding the conductor. That field strength is used to make up one's mind the current.
Although y'all tin obtain Hall-Issue sensors that don't crave a connexion to the excursion, the one we will be using does, equally the usher whose field strength it measures is internal to the IC chip on the sensor.
Measuring DC Current with the Arduino
We will use both methods, invasive and noninvasive, to measure current with our Arduino. We will begin with a very normally available noninvasive sensor, the ACS712.
ACS712 Hall Outcome Sensor
The ACS712 has been around for years, in fact, it has been superseded by other models and is no longer used for new designs. Notwithstanding information technology is still commonly available and, best of all , is extremely inexpensive.
This hall-effect current sensor can be used with both DC and Ac current, although today nosotros will focus on its use with Directly Current.
This device operates on a v-volt ability supply and outputs a voltage proportional to the electric current it is measuring. The input connection is isolated from the output, making it condom to employ for high voltage applications.
In that location are actually 3 versions of this sensor, they differ in the maximum current they tin can mensurate:
- 5 Amp
- 20 Amp
- 30 Amp
As most modules don't have marking identifying which version they are using you'll probably need to expect straight at the ACS712 chip itself to decide this.
In the in a higher place example, you'll come across that this is a xx-ampere version.
The ACS712 outputs a voltage of two.5-volts when NO current is detected. Voltage above this is a positive flowing electric current, while below two.v-volts indicated a negative current.
Because in that location are three versions of this scrap you need to apply a "calibration cistron" to determine the current, as shown here:
The formula food determining the current is also shown in the analogy.
ACS712 Hall Effect Sensor Hookup
Here is how we will exist hooking upwardly the ACS712 to our Arduino Uno:
Information technology'south a pretty simple hookup, the ACS712 output is continued to the Arduino analog input.
Note that the input connections to the ACS712 are non marked with polarity, as information technology can read both positive and negative electric current. If you hook information technology up as per the above diagram your readings will be positive.
ACS712 Hall Upshot Sensor Sketch
Hither is the sketch we will exist using to measure out DC current with the ACS712 hall-event current sensor:
1 2 3 4 5 6 7 8 9 10 11 12 13 xiv fifteen 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 lx 61 | /* ACS712 DC Current Sit-in acs712-dc-demo.ino Read electric current using ACS712 Hall Effect sensor DroneBot Workshop 2021 https://dronebotworkshop.com */ // Variables for Measured Voltage and Calculated Electric current double Vout = 0 ; double Current = 0 ; // Constants for Scale Factor // Use one that matches your version of ACS712 //const double scale_factor = 0.185; // 5A const double scale_factor = 0.1 ; // 20A //const double scale_factor = 0.066; // 30A // Constants for A/D converter resolution // Arduino has ten-bit ADC, then 1024 possible values // Reference voltage is 5V if not using AREF external reference // Zero indicate is half of Reference Voltage const double vRef = v.00 ; const double resConvert = 1024 ; double resADC = vRef/resConvert ; double zeroPoint = vRef/2 ; void setup ( ) { Serial . brainstorm ( 9600 ) ; } void loop ( ) { // Vout is read 1000 Times for precision for ( int i = 0 ; i < one thousand ; i++) { Vout = ( Vout + ( resADC * analogRead ( A0 ) ) ) ; filibuster ( one ) ; } // Become Vout in mv Vout = Vout /1000 ; // Convert Vout into Current using Scale Gene Current = ( Vout - zeroPoint )/ scale_factor ; // Print Vout and Current to two Electric current = "); Serial . print ( "Vout = " ) ; Series . print ( Vout , 2 ) ; Serial . print ( " Volts" ) ; Series . print ( "\t Current = " ) ; Serial . print ( Current , 2 ) ; Serial . println ( " Amps" ) ; delay ( chiliad ) ; } |
Well-nigh of the sketch involves reading the analog input voltage and using math to determine the current.
The resADC variable is calculated using the voltage reference, which with our hookup is v-volts. If you want to build a more accurate sensor you tin can alter it to utilize the LM4040 module we used earlier, if and so you'll want to alter the value of vRef accordingly.
Also annotation that the zeroPoint is adamant by the ability supply voltage from the Arduino, and not by the voltage reference. You can change this to two.50 if you alter the circuit for an external reference.
You'll desire to make sure your ACS712 scale gene is accommodated, otherwise, the readings will be meaningless. I show the twenty amp version of the ACS712 being used in this sketch, but I've also provided the values you lot need for the other two versions.
In the loop nosotros read the value a thousand times, and so nosotros can get a expert average. We then use the formula you saw before to convert the voltage reading into current. And so we display it on the series monitor.
Load the sketch to your Arduino and detect your electric current readings. Mine were off slightly, but I could run across that with no electric current flowing I was nevertheless getting a slight reading, which accounted for the mistake. This was likely due to two factors:
- The voltage reference was the DEFAULT, using an external reference like the LM4040 module would accept helped here.
- The 5-volts supplied to the ACS712 may have also been off a fleck, affecting the nada-point.
Just all in all, it wasn't off by too much, so this is a pretty easy way to measure DC current (and, as you'll run across in a hereafter article, AC electric current every bit well).
Adafruit INA219 Current & Voltage Sensor
The concluding sensor that we will exist using today is quite different from the others we have seen so far.
The Adafruit INA219 sensor is capable of measuring both DC voltage and current simultaneously. It also doesn't accept an analog output like aloof the other devices we take used and then far, instead, this device has an I2C output. This makes it suitable for not only microcontrollers but also for microcomputers.
It is actually available in 2 form factors, a stand-alone module and one made for use with the Adafruit Featherwing processors. Either one would be suitable for our experiment.
One slap-up advantage about this module is that information technology is inserted on the "high side" of the excursion instead of the basis side, which is how many of those Voltage and Current display modules are wired. This makes information technology ideal for use as a voltage and current display, it would be a neat replacement for the meter I used in the Convert an ATX Computer Supply to a Bench Power Supply article I did a while back.
The device has an internal 12-bit ADC and can mensurate upward to 3.2 amperes. It is an intrusive sensor, using a 0.one-ohm precision resistor. If yous're a true hacker you lot tin can supersede the resistor with another one to change the range, personally, I'm not that brave!
The Adafruit INA219 operates on a power supply of 5-volts, which can be supplied past the Arduino.
Adafruit INA219 Current & Voltage Sensor Hookup
Here is how we will hook upwards our Adafruit INA219 sensor to an Arduino:
Notation that this is an I2C device so the A4 and A5 pins are being used as SDA and SCL, non equally analog inputs.
Adafruit INA219 Current & Voltage Sensor Sketch
In order to use this device, y'all'll need to install a library that Adafruit has provided.
In your Library Director practice a search for "Adafruit INS219". Yous'll go i effect, a library that you need to install. You'll also be prompted to install some dependent libraries if you oasis't installed them previously, you'll desire to go alee and practise that.
In one case you lot have the library installed you can run the case sketch provided past Adafruit. Go into the Examples From Custom Libraries and look for the Adafruit INA219.
Open the "getcurrent" sketch, which is shown here:
ane 2 3 4 five six 7 8 ix 10 xi 12 xiii xiv fifteen xvi 17 18 19 xx 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 xl 41 42 43 44 45 46 47 48 49 l 51 52 53 54 55 56 | #include <Wire.h> #include <Adafruit_INA219.h> Adafruit_INA219 ina219 ; void setup ( void ) { Serial . begin ( 115200 ) ; while ( ! Series ) { // will pause Zero, Leonardo, etc until serial console opens delay ( 1 ) ; } uint32_t currentFrequency ; Serial . println ( "Hi!" ) ; // Initialize the INA219. // By default the initialization volition use the largest range (32V, 2A). Even so // you tin can call a setCalibration function to change this range (meet comments). if ( ! ina219 . begin ( ) ) { Serial . println ( "Failed to find INA219 flake" ) ; while ( one ) { delay ( 10 ) ; } } // To utilize 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(); Series . println ( "Measuring voltage and electric current with INA219 ..." ) ; } void loop ( void ) { bladder 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 / g ) ; Serial . print ( "Charabanc Voltage: " ) ; Serial . print ( busvoltage ) ; Series . println ( " V" ) ; Series . impress ( "Shunt Voltage: " ) ; Serial . print ( shuntvoltage ) ; Serial . println ( " mV" ) ; Series . print ( "Load Voltage: " ) ; Serial . print ( loadvoltage ) ; Serial . println ( " 5" ) ; Series . print ( "Current: " ) ; Serial . print ( current_mA ) ; Serial . println ( " mA" ) ; Series . print ( "Power: " ) ; Serial . impress ( power_mW ) ; Serial . println ( " mW" ) ; Serial . println ( "" ) ; filibuster ( 2000 ) ; } |
Thanks to the library, using this sensor is very unproblematic. In the sketch, an object called "ina219" is defined, and its properties take everything you need, no calculations required. Of course, the sketch likewise uses the Arduino Wire library, as information technology is an I2C device.
The sketch prints out a number of parameters, including voltage, current, power, and the actual voltage measured beyond the resistor.
Load information technology up and have a look, making sure that your load doesn't exceed iii.2 amps. You should observe that information technology works very effectively, and as it uses its ain internal ADC information technology is not affected by the Arduino ADC voltage reference.
Conclusion
Equally you have seen it is fairly uncomplicated to measure DC voltage and current using an Arduino, and you lot tin can expand these sketches to use other microcontrollers.
This is the first of a ii-function series on measuring voltage and current, side by side time we will run across what is required to exercise the aforementioned play a trick on using Alternating Electric current.
Until so happy measuring!
Resources
Code for this article – All of the sketches used today, in an like shooting fish in a barrel to use ZIP file.
Arduino analogReference – The Arduino analogReference command allows y'all to use dissimilar voltage references for your Arduino ADC. This link besides shows features for other processors as well.
Adafruit INA219 – A detailed article from Adafruit for using the INA219 Voltage and Current sensor.
Voltage Divider Calculator – make your own custom voltage dividers.
Summary
Article Proper noun
Measure DC Voltage and Current with an Arduino
Description
Learn how to measure DC voltage and current using an Arduino. The showtime commodity in a ii-part serial, the subsequent commodity will deal with AC.
Author
DroneBot Workshop
Publisher Name
DroneBot Workshop
Publisher Logo
How to Read Voltage on an Arduino
Source: https://dronebotworkshop.com/dc-volt-current/
0 Response to "How to Read Voltage on an Arduino"
Post a Comment