Measure DC Voltage ...
 
Notifications
Clear all

Measure DC Voltage and Current with Arduino

38 Posts
15 Users
19 Likes
6,425 Views
Will
 Will
(@will)
Member
Joined: 3 years ago
Posts: 2504
 

@holder3651 

According to ...

https://www.arduino.cc/reference/en/language/functions/analog-io/analogread/

"the maximum reading rate is about 10,000 times a second".

Anything seems possible when you don't know what you're talking about.


   
ReplyQuote
(@holder3651)
Member
Joined: 2 years ago
Posts: 8
 

@will,

Thanks for the response.  I now have a working voltage recorder and LCD display based on the Hall-effect sensor.

I'm now trying to create a current data logger based on an ACS712 bought from Amazon - WayInTop-US.  The code works well but I have very odd results suggesting the device should have VCC connected to a much lower voltage than the Arduino nominal 5V or my 4020 reference voltage regulator chip.

The issue is that the A/D pin that's reading the ACS712 sensor gives a value that's too high. 

Has anyone else found similar issues with that brand?

The ACS712 device from WayInTop seems to be almost identical to the one Will used in his tutorial except the circuit components and pins are 'handed'. 

Oddly, the Amazon information indicates connecting VCC to 3.3V / 5V. I thought connecting VCC to the Reference 4.098V would be great. But, with nothing connected to the sensed terminals, the sketch shoes about 0.6A.  Connecting to the Arduino's 5V, the sketch shows 7.5A. In both, I changed to code to match the VCC voltage supplied. 

I have the centre signal pin going to A2 because A0 is in use for the hardware, and A1 is the voltage feather sensor.

I can see the A/D readings because I changed the code to summate the pin values over a series of readings, then divide by the number of readings, before calculating the apparent voltage. Then, I wrote out all of the data used in the calculations and the results.  All made sense, except the A/D readings. 

With 5V supplied

Serial.print(resADC,6); Serial.print(", ");
Serial.print(zeroPoint,4); Serial.print(", ");
Serial.print(scale_factor,4); Serial.print(", ");
Serial.print(VADC,4); Serial.print(", ");
Serial.print(Vout,4); Serial.print(", ");
Serial.print(Vout-zeroPoint,4); Serial.print(", ");
Serial.print(Current,4); Serial.println();
Gives:
0.004883, 2.5000, 0.0660, 613.0000, 2.9932, 0.4932, 7.4722
 

   
ReplyQuote
Inst-Tech
(@inst-tech)
Member
Joined: 2 years ago
Posts: 554
 

@holder3651 ,

Hi, just now looking at the results of your print out, and a couple of things come to mind...

First, I have a couple of questions:, have you measured your circuit with a multi meter on amp scale to see what is actually the current you are using.. I see by your ACS712 scaling that you are using a 30A module.  second, did you change the analogReference() command in you code to tell the Arduino that your using an external reference..this will make a big difference in how the ADC converts the counts to voltage.. example: the resolution of a 5 v reference is 0.004828125 mV/count, but for a 4.096 V external reference it is 0.004 mV/count. for more information on the analogReference() , see https://www.arduino.cc/en/Reference.AnalogReference

It will be more helpful if you can provide a copy of your code as well, as we are just guessing at what might be the problem.

hope this helps, good luck,

Regards,

   LouisR

 

LouisR


   
ReplyQuote
(@holder3651)
Member
Joined: 2 years ago
Posts: 8
 

   
Inst-Tech reacted
ReplyQuote
(@holder3651)
Member
Joined: 2 years ago
Posts: 8
 

Physically, the VCC on ACS712 board is connected to the 4020 board 4.096V output pin and to the Uno VRef pin. 


   
ReplyQuote
Inst-Tech
(@inst-tech)
Member
Joined: 2 years ago
Posts: 554
 

@holder3651 

See attached document for how to wire up an external voltage reference

also note the following:

Arduino megaAVR Boards (Uno WiFi Rev2)

  • DEFAULT: a built-in 0.55V reference

  • INTERNAL: a built-in 0.55V reference

  • VDD: Vdd of the ATmega4809. 5V on the Uno WiFi Rev2

  • INTERNAL0V55: a built-in 0.55V reference

  • INTERNAL1V1: a built-in 1.1V reference

  • INTERNAL1V5: a built-in 1.5V reference

  • INTERNAL2V5: a built-in 2.5V reference

  • INTERNAL4V3: a built-in 4.3V reference

  • EXTERNAL: the voltage applied to the AREF pin (0 to 5V only) is used as the reference

 example: analogReference(EXTERNAL)

Notes and Warnings

After changing the analog reference, the first few readings from analogRead() may not be accurate.

Don’t use anything less than 0V or more than 5V for external reference voltage on the AREF pin! If you’re using an external reference on the AREF pin, you must set the analog reference to EXTERNAL before calling analogRead(). Otherwise, you will short together the active reference voltage (internally generated) and the AREF pin, possibly damaging the microcontroller on your Arduino board.

Alternatively, you can connect the external reference voltage to the AREF pin through a 5K resistor, allowing you to switch between external and internal reference voltages. Note that the resistor will alter the voltage that gets used as the reference because there is an internal 32K resistor on the AREF pin. The two act as a voltage divider, so, for example, 2.5V applied through the resistor will yield 2.5 * 32 / (32 + 5) = ~2.2V at the AREF pin.

regards,

LouisR

 

LouisR


   
ReplyQuote
Inst-Tech
(@inst-tech)
Member
Joined: 2 years ago
Posts: 554
 

@holder3651 

Question: How do you know the count is off.. have you measured the current in the circuit with a multi-meter in (current mode)? The math and the formulas look ok, so unless you have a floating ground, I can see no reason why this shouldn't work.. Check your grounding from the ACS712 to the Arduino to make sure you don't have a bad connection or a broken wire.. check this with an ohm meter to rule that out.. those tiny wires are easy to break!  good luck,

Regards,

LouisR

LouisR


   
ReplyQuote
(@holder3651)
Member
Joined: 2 years ago
Posts: 8
 

I’ll check the soldering tomorrow. 

Your last but one response showed the connections for the voltage sensor but my problem is with the ACS712 current sensor.  Apart from checking everything is soldered well, my doubts lie with how the ACS712 VCC pin should be connected.  I connected it to the 4020 board’s 4.096V pin that is already connected to the Arduino ARef pin. But now I’m wondering if that’s correct. 

Note, the same Adafruit data logger board that I used to successfully set up 25V voltage and 4020 reference boards, was modified by adding the ACS712. The signals from each sensor board were taken to different pins, A1 and A2, but there are interconnections because both are on the same data logger and share grounds and +ve.  

For a build with only the ACS712 and the 4020 voltage reference, it isn’t clear to me how they should be wired.  Without the 4020, the wiring would be as your tutorial, i.e. VCC to Arduino 5V, Signal to A2 or similar and -Ve to Arduino GND.  But with the 4020 added to Arduino ARef, should the ACS712 wiring change so VCC connects elsewhere? 

At the root of this is perhaps my lack of understanding of how the Arduino A/D system works without and with an external VRef. My understanding is that the ACS712 Hall-effect current sensor works by splitting the voltage between GND and VCC pins so that a portion related to current goes to the Signal pin with the A/D converter generates a digital code. 


   
Inst-Tech reacted
ReplyQuote
Inst-Tech
(@inst-tech)
Member
Joined: 2 years ago
Posts: 554
 

@holder3651 

I think your problem lies in the connection to the 4020 ref board. It is for reference ONLY.. no other connections to it as it has no capability to source any current.. The ACS712 VCC is connected to the Arduino +5v on the board, See attached file below. The reference board 4020 only affect the reference voltage used by the ADC mux., not the 5v buss that the ACS712 is using for power.. With the external reference board you get a little more resolution for the ADC , ~ 4 mV, (0.004) as opposed to the internal reference of 5v +/- 50 mV (at 1% tolerance) of 4.883 mV ( 0.004883). this will, in affect the accuracy of your counts in the ADC mux. But I digress.. I digital & analog inputs are subject to wild variations when their inputs are not connected, or grounding issues are present..Your on the right track.. just stick with it, and I'm sure you'll fix the problem..BTW,The code for your project is impressive..I'm not new to programming, but I'm just learning C++ after 30+ years of using MS VBA, and other industrial OOP like PLC (Programmatical Load Controller) and DCS (Distributed Control Systems) to program  industrial control systems.. At 75, I'm still learning, lol

Good luck, and keep me advised.. I'll probably be hitting you up on tips on programming.. it's a steep curve for ol' timers like me...hehehe

Regards,

LouisR

ACS712 connection to Arduino

 

 

LouisR


   
ReplyQuote
(@holder3651)
Member
Joined: 2 years ago
Posts: 8
 

I've took the ACS712 off the same data logger board as the 30V voltage sensor and LM4040 reference voltage card, and now have 'sensible' zero results from the ACS712. That is the readings with no current is close enough to zero that it is within the 512 +/- 2 bits accuracy limit that might be expected of the A/D converter.  I have to get another LM4040 reference voltage card so see if that makes any difference. 

Using a multimeter to check the Arduino nominal 5V to GND, I found the voltage was actually a bit lower than 5V.  That lead me to change the code to more replicate the voltage.  And, then to lower it a bit more.  Surprisingly, the specified vRef didn't really alter the measured zero with no external current.

In western Canada, I'm at the end of a long supply line for less common Adafruit parts, so it might be a while before I get another LM4040 reference voltage card.  The shipping cost is much more than the item, too. So, it might be a while before I test the setup with an LM4040 added. 

My next step is to measure check values from the ACS712 with a know current as you suggested. 

To summarise, it seems there was some odd interaction between the two measurement cards or the ACS712 and the LM4040 aren't compatible, that led to the patently incorrect readings. 


   
Inst-Tech reacted
ReplyQuote
Inst-Tech
(@inst-tech)
Member
Joined: 2 years ago
Posts: 554
 

Good job!..Indeed, I did some  measurement checking my self on the LM4020, and the Arduino Vcc +5V pin & Vref pin with external circuit loading, and unloading:  In the attached file are  are some of the results that I found. In conclusion, The results show that using the Arduino +5v pin to power anything over a few mA will pull the 5V down.. So I recommend using external power supply to power your circuits that are being connected to the Arduino, inputs and outputs.. making sure you tie the negative of the supply to the Arduino gnd connection to prevent ground loops, which can severely impact your readings.

See attached word doc for results of test:

kind regards,

LouisR

 

LouisR


   
ReplyQuote
(@holder3651)
Member
Joined: 2 years ago
Posts: 8
 

You are most helpful to do that work. I’ll have to wait a bit for parts. And, find a way to rig up a separate PS.  Unlike you, I don’t have a bench power supply.   

I’m now looking at the Adafruit ADS1115 and ADS1015, which offer much greater precision in the analogue - digital conversion, albeit at a fair loss of sampling speed. 

I’ll likely go silent for a while as I deal with other matters and supply chains.


   
Inst-Tech reacted
ReplyQuote
Inst-Tech
(@inst-tech)
Member
Joined: 2 years ago
Posts: 554
 

Good luck to you @Holder3651... let us know how it turns out..

Kind regards,

LouisR

LouisR


   
ReplyQuote
(@holder3651)
Member
Joined: 2 years ago
Posts: 8
 

I’ve now had a chance to try different LM4040 voltage regulator and a new data logger board, i.e. a clean setup completely disconnected from the voltage measuring board that I thought might be the issue.  However, the current measuring ACS712 still produces completely incorrect results when the voltage regulator is connected. Without the voltage regulator, the ACS712 shows a no load i.e. “zero” value, that one might expect, i.e. one or two bits wrong, <+/- 0.1A with a 30A range board. With a small current, the reading shifts about the right amount.  I will have to try the ACS712 with a large current and use another meter of known accuracy to confirm it works accurately near the top end of it’s range, i.e. 30A for the one I am using. 

I’ve not tried a separate power supply.  That would be more complex than I feel is reasonable. 


   
ReplyQuote
(@abdulhak33m)
Member
Joined: 3 years ago
Posts: 7
 

Thank you Bill.

I modified this sketch to control a battery charger so it can give a high signal to a gren led when battery voltage is above 13.8V and as well switch off charging via a relay module. 

its not working. please i appreciate any help

// Define analog input
#define ANALOG_IN_PIN A0

// Floats for ADC voltage &amp; 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 = 5.0;

// Integer for ADC value
int adc_value = 0;

// other parameters for battery control and user interfaces

int redled = 13;
int greenled = 12;
int blueled = 8;
int cutoffhigh = 7;
int cutofflow = 4;

void setup(){
// Setup Serial Monitor
Serial.begin(115200);

Serial.println(&quot;DC Voltage Test&quot;);
pinMode(redled, OUTPUT);
pinMode(greenled, OUTPUT);
pinMode(blueled, OUTPUT);
pinMode(cutoffhigh, OUTPUT);
pinMode(cutofflow, OUTPUT);

}

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 places
Serial.print(&quot;Input Voltage = &quot;);
Serial.println(in_voltage, 2);

// Short delay
delay(500);

if( in_voltage &gt;=0.00 &amp;&amp; in_voltage &lt;=10.00){
digitalWrite(cutofflow, HIGH);
digitalWrite(cutoffhigh, LOW);

digitalWrite(redled, LOW);
digitalWrite(greenled, LOW);
digitalWrite(blueled, LOW);
}

else if(in_voltage &gt;=10.10 &amp;&amp; in_voltage &lt;= 10.80){
digitalWrite(cutofflow, LOW);
digitalWrite(cutoffhigh, LOW);
digitalWrite(redled, HIGH);
digitalWrite(greenled, LOW);
digitalWrite(blueled, LOW);

}

else if( in_voltage &gt;10.81 &amp;&amp; in_voltage &lt;= 12.29 ){
digitalWrite(cutofflow, LOW);
digitalWrite(cutoffhigh, LOW);
digitalWrite(redled, LOW);
digitalWrite(greenled, LOW);
digitalWrite(blueled, HIGH);

}

else if (in_voltage &gt;= 12.30 &amp;&amp; in_voltage &lt;= 12.49){
digitalWrite(cutofflow, LOW);
digitalWrite(cutoffhigh, LOW);

digitalWrite(redled, LOW);
digitalWrite(greenled, HIGH);
digitalWrite(blueled, LOW);

}

else if (in_voltage &gt;12.50 &amp;&amp; in_voltage &gt;=12.6){
digitalWrite(cutofflow, LOW);
digitalWrite(cutoffhigh, HIGH);
digitalWrite(redled, LOW);
digitalWrite(greenled, LOW);
digitalWrite(blueled, LOW);

}

else {
digitalWrite(cutofflow, LOW);
digitalWrite(cutoffhigh, LOW);
digitalWrite(redled, LOW);
digitalWrite(greenled, LOW);
digitalWrite(blueled, LOW);

}

}

   
ReplyQuote
Page 2 / 3