Arduino as Volt Meter

Geek

Member
Joined
Aug 15, 2017
Messages
920
After a bit of Googling around, I find myself more confused than informed.

What is the most effective way of getting accurate voltage measurements with an Arduino? Preference is using the internal ADC. There are apparently issues with powering it from the source you are measuring.

I know a few members are using Arduino/ESP etc. based BMS. Just wondering what method are you using?
 
It'll depend on the voltages you're trying to measure.
Specs suggest power supply voltage limits are from 6-20V for powering via regular methods.
https://store.arduino.cc/usa/arduino-uno-rev3

This link discusses specialized changes for fixed 3.3V operation, not so easy....
https://forum.arduino.cc/index.php?topic=409415.0

If you tried powering via fixed 5V or 3.3V & accidentally applied a higher voltage, the magic smoke would come out.

The internal voltage reference can be switched to use a 1.1V or 5V internal source. So if working with say the 1.1V ref, your "full scale" would be when 1.1V arrived at the analogue input pin - so you would scale down higher voltages to be in that range with resistor dividers.
 
You "can" measure the voltage you are powering from. However, you must calibrate the ADC before each major read (ie, ever 250ms or so).

Even if you aren't measuring the same voltage as your powering voltage, you should still calibrate the ADC.

As Redpacket mentions, the internal voltage reference 1.1V. This voltage is dependent on the input voltage. If there is exactly 5V to the arduino, this voltage should be 1.1V on the nose. If it's 4.7V, then it could be 1.06V, or something like that. By measuring the internal voltage first, you can then get a more accurate reading on the ADC.

Code:
long readVcc() {
  long result;
  // Read 1.1V reference against AVcc
  ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
  delay(2); // Wait for Vref to settle
  ADCSRA |= _BV(ADSC); // Convert
  while (bit_is_set(ADCSRA,ADSC));
  result = ADCL;
  result |= ADCH<<8;
  result = 1125300L / result; // Back-calculate AVcc in mV
  return result;
}

void setup() {
  Serial.begin(9600);
}

void loop() {
  Serial.println( readVcc(), DEC );
  delay(1000);
}

References:
https://hackingmajenkoblog.wordpress.com/2016/02/01/making-accurate-adc-readings-on-the-arduino/
https://provideyourown.com/2012/secret-arduino-voltmeter-measure-battery-voltage/
 
Korishan, I think it comes back to how the arduino is being powered:
If from 6-20V external source then the +5V & 1.1V internally generated voltages should be quite stable but need calibrating
If powered from 5V, then the 5V ref only as stable as your 5V source is & still needs calibrating.
If using the 1.1V ref it should be stable if other sources vary but still need calibrating.
 
Thanks for the info! Surprising how hard it can be to find simple tricks online.
 
Geek said:
Thanks for the info! Surprising how hard it can be to find simple tricks online.

Yeah, it's not so much that the info isn't there, it's know the right combination of words to use as the search criteria.

As Redpacket mentions, the power voltage "should" be stable if the main power is >5.5-6V and bucked down to 5V. But, we know that this is not "always" true. Connection issues can always cause issues, and this can vary between power ups. If the power is being provided via a usb cable or other type of connector, there can be variations on the input. So it's pretty good to calibrate on startup/bootup. Maybe even have an option to re-calibrate manually if you suspect an issue.
But usually once is fine after power up.

However, if the power source is lower than 5V and boosted up, then you probably want to calibrate on a pretty regular basis just before you do a read with the ADC. Just remember you have to pause a little to give time for the internals to reset back from internal to external pins. That is discussed in those articles.
 
I think there might be another nuance to it:
The arduino's external 6-20V input has a ~1V drop out threshold headroom, ie it needs to be min 1V higher than the 5V internal reference it's generating (they say 7-12V so is may be 2V droput headroom needed).
 
Redpacket said:
I think there might be another nuance to it:
The arduino's external 6-20V input has a ~1V drop out threshold headroom, ie it needs to be min 1V higher than the 5V internal reference it's generating (they say 7-12V so is may be 2V droput headroom needed).

I imagine that shouldn't cause too much trouble for the 1.1vinternal reference. I don't need incredibly accurate - about +/-0.05v. But it does need to be reasonably consistent.
 
This is crazy 'accurate' thanks guys. Is there an easy way to get a proper reference voltage? I have seen setups on Ali for sale. But this is so consistent I'd like to go the next level.



image_zofqpk.jpg
 
Geek said:
This is crazy 'accurate' thanks guys. Is there an easy way to get a proper reference voltage? I have seen setups on Ali for sale. But this is so consistent I'd like to go the next level.



image_zofqpk.jpg




Could you advise thesetup you hadfor that?
ie, what supply voltage, which reference used, what voltage divider resistors, etc?

I'd suggest using the 1.1V internal ref, calibrate it once, save that cal value, then log some values.

Also beware of supply noise, so have eg a 10uF capacitor across it.
 
Redpacket said:
Geek said:
This is crazy 'accurate' thanks guys. Is there an easy way to get a proper reference voltage? I have seen setups on Ali for sale. But this is so consistent I'd like to go the next level.






Could you advise thesetup you hadfor that?
ie, what supply voltage, which reference used, what voltage divider resistors, etc?

I'd suggest using the 1.1V internal ref, calibrate it once, save that cal value, then log some values.

Also beware of supply noise, so have eg a 10uF capacitor across it.



I am using the USB on my PC. The voltage drop is caused by theschottky diode on the USB input.Interesting idea with the cap. I am going to try this with a battery.

Here is some code that will work for all Atmega Arduino. The remark on the top of readVcc gives a slightly better description of what is going on.

Code:
long readVcc() {
 // Read 1.1V reference against AVcc
 // set the reference to Vcc and the measurement to the internal 1.1V reference
 #if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
  ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
 #elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
   ADMUX = _BV(MUX5) | _BV(MUX0) ;
 #else
  ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
 #endif 
 
 delay(2); // Wait for Vref to settle
 ADCSRA |= _BV(ADSC); // Start conversion
 while (bit_is_set(ADCSRA,ADSC)); // measuring
 
 uint8_t low = ADCL; // must read ADCL first - it then locks ADCH 
 uint8_t high = ADCH; // unlocks both
 
 long result = (high<<8) | low;
 
 result = 1125300L / result; // Calculate Vcc (in mV); 1125300 = 1.1*1023*1000
 return result; // Vcc in millivolts
}
 
With that readVCC example, you should really do that quite often throughout testing. Perhaps when detecting there's a load on the probes. Power can fluctuate, even on batteries.
Also, after running readVCC, on most of the atmegas, there needs to be a pause before resetting it back and reading the pins. Well, that is, if you use the A0 pin (i think that's the one) for your probes. Otherwise, the ADC might not be ready yet switching the mode on that pin.

I did have that issue on my nano. waiting about 20ms or so is usually long enough, tho.

Also, that code only works with the atmel's. I haven't seen any that work with the esp or the stm mcu's yet. Not that it's not out there, just that I haven't found it yet
 
Korishan said:
With that readVCC example, you should really do that quite often throughout testing. Perhaps when detecting there's a load on the probes. Power can fluctuate, even on batteries.
Also, after running readVCC, on most of the atmegas, there needs to be a pause before resetting it back and reading the pins. Well, that is, if you use the A0 pin (i think that's the one) for your probes. Otherwise, the ADC might not be ready yet switching the mode on that pin.

I did have that issue on my nano. waiting about 20ms or so is usually long enough, tho.

Also, that code only works with the atmel's. I haven't seen any that work with the esp or the stm mcu's yet. Not that it's not out there, just that I haven't found it yet

Agreed. In the chart I posted before there was a 500ms delay, and a 1500ms delay after printing the result. Apparently you can also get inaccurate results if the device is not properly grounded. This is one reason why I want to try the same thing from a battery. Will be interesting to see what happens.
 
I should probably be posting this on another forum. However, it is my mission to create the most simple BMS possible, with the most functions feasible. I should be asking the same questions on AVRFreaks, or Arduno forums. There are so many knowledgeable people on this forum. My theory is, if you guys can help me create this, then anyone can build it.

I have reasonable electronics skills. Limited soldering skills. The goal is to make something as simple as possible as an Arduino based BMS. Just a few simple signals, mostly composed of software, and as few components as possible.

I need some advice in laymans terms (how to decouple VCC). I personally desperately need a decent oscilloscope . At the moment I am trying to investigate the shortcomings of an unearthed Atmega chip.

As this project continues, as much advice as I can get is received with gratitude.
 
Geek said:
I should probably be posting this on another forum. However, it is my mission to create the most simple BMS possible, with the most functions feasible. I should be asking the same questions on AVRFreaks, or Arduno forums. There are so many knowledgeable people on this forum. My theory is, if you guys can help me create this, then anyone can build it.

I have reasonable electronics skills. Limited soldering skills. The goal is to make something as simple as possible as an Arduino based BMS. Just a few simple signals, mostly composed of software, and as few components as possible.

I need some advice in laymans terms (how to decouple VCC). I personally desperately need a decent oscilloscope . At the moment I am trying to investigate the shortcomings of an unearthed Atmega chip.

As this project continues, as much advice as I can get is received with gratitude.
Chuckle, you can see my babbling about something like that in the general section, i mean an active balancer, not a BMS. Basically, it could be combined...

I have a concept (for a Balancer, but had just not enough time to make even the most simple tests.

If you want to have a cheap "oszilloscope" with basic functions google DSO 138. Take it with case, not without.
It is simple but effective, compared to having no one.
 
Cherry67 said:
Geek said:
I should probably be posting this on another forum. However, it is my mission to create the most simple BMS possible, with the most functions feasible. I should be asking the same questions on AVRFreaks, or Arduno forums. There are so many knowledgeable people on this forum. My theory is, if you guys can help me create this, then anyone can build it.

I have reasonable electronics skills. Limited soldering skills. The goal is to make something as simple as possible as an Arduino based BMS. Just a few simple signals, mostly composed of software, and as few components as possible.

I need some advice in laymans terms (how to decouple VCC). I personally desperately need a decent oscilloscope . At the moment I am trying to investigate the shortcomings of an unearthed Atmega chip.

As this project continues, as much advice as I can get is received with gratitude.
Chuckle, you can see my babbling about something like that in the general section, i mean an active balancer, not a BMS. Basically, it could be combined...

I have a concept (for a Balancer, but had just not enough time to make even the most simple tests.

If you want to have a cheap "oszilloscope" with basic functions google DSO 138. Take it with case, not without.
It is simple but effective, compared to having no one.

Got a link?

The concept I have in mind is a self powered active balancing device. So each Arduino is powered from a string of cells. Each has a FET and a load. Start burning power at 4.15v. For emergency shutdown such as under or over voltage use optocoupled relays to drive shunt trips or SSRs to shut the system down.

The parts would mostly be available as pre fabricated units and pretty much plug and play.

The system would be so simple and require so very few components. I understand that it would consume too much power for a small pack. But if you want a BMS for a small pack - get one of those el-cheapo units from AliExpress.

I plan to fit each one with a 'black box' capability. So it can be connected to a PC and a sketch uploaded to dump the eeprom - and retrieve a log if necessary.

The only problem I am having - I need to be certainthat the voltage readings will be consistent. Even leaving a little margin for error - you still don't want your system just shutting down unexpectedly, or not shutting down in an emergency.

Also, if I was to share such a design, I would want it to be 'foolproof'. If its intended users would have little knowledge of such a system - I need to be sure that however it gets set up - it absorbs a lot of room for error.
 
Do you mean a link for the DSO 138 ?

https://www.google.com/search?q=DSO138

I think only about 1 arduino, if any at all.... a basic unit works without, but is missing some conveniences.
I do not think about loading higher cells, i talk about feeding lower ones. ACTIVE Balancing.
 
Cherry67 said:
Do you mean a link for the DSO 138 ?

https://www.google.com/search?q=DSO138

I think only about 1 arduino, if any at all.... a basic unit works without, but is missing some conveniences.
I do not think about loading higher cells, i talk about feeding lower ones. ACTIVE Balancing.

No for your balancing threads -

https://secondlifestorage.com/t-Balancing-with-a-modular-system

https://secondlifestorage.com/t-Alternative-BMS-concept-modular-Banks

That DSO does look interesting though.
 
Geek said:
Cherry67 said:
Do you mean a link for the DSO 138 ?

https://www.google.com/search?q=DSO138

I think only about 1 arduino, if any at all.... a basic unit works without, but is missing some conveniences.
I do not think about loading higher cells, i talk about feeding lower ones. ACTIVE Balancing.

No for your balancing threads -

https://secondlifestorage.com/t-Balancing-with-a-modular-system

https://secondlifestorage.com/t-Alternative-BMS-concept-modular-Banks

That DSO does look interesting though.
At that time ( of the links you found) i didnt thik about the balancing i have in my nose now.

Yet, daromer hast destroyed (by PM) my rosy clouds, looks like it is already well known what i thought i had figured out.

The DSO is imited to 1 Mhz sampling rate and only one channel, but for all what is within this limitations its quite nice. At least better than nothing, especially when you think about switched supplies and so on....
 
Back
Top