New library to read Arduino VCC supply level without resistors for battery powered sensor nodes that do not use a voltage regulator but connect directly to the batteries ;-)
-
Hi there!
Inspired by the Blog entry at http://provideyourown.com/2012/secret-arduino-voltmeter-measure-battery-voltage/ I decided to write a simple Arduino library to measure VCC level without any external components!
This library can be used to measure the VCC level from e.g. battery powered sensors that do not use a voltage regulator but are powered directly from the batteries and send the battery level to the gateway.The trick is to use the AVR's internal 1.1V reference to measure AVcc. This does not require an external voltage divider.
The Vcc component can report the VCC level either in volts, or in percentage. Reporting in percentage is a nice way to report the battery level in MySensors!
For example:#include <Vcc.h> const float VccExpected = 3.0; const float VccCorrection = 2.860/2.92; // Measured Vcc by multimeter divided by reported Vcc Vcc vcc(VccCorrection); static int oldBatteryPcnt = 0; void loop() { int batteryPcnt = (int)vcc.Read_Perc(VccExpected); if (oldBatteryPcnt != batteryPcnt) { gw.sendBatteryLevel(batteryPcnt); oldBatteryPcnt = batteryPcnt; } }Deviations can easily be corrected for by running one of the example sketches and at the same time measure VCC with a multimeter.
The correction factor should be entered as (VCC multimeter/VCC reported) in the constructor of the Vcc component (the VccCorrection parameter in the example above).
See the example sketches and code for more info.The library can be found at: https://github.com/Yveaux/arduino_vcc
Or download as ZIP: https://github.com/Yveaux/arduino_vcc/archive/master.zipHave fun!
-
Hi, nice stuff but...
What would be the advantage (except for not having to add those 2 resistors)? -
Hi, nice stuff but...
What would be the advantage (except for not having to add those 2 resistors)?@marceltrapman The resistor divider always draws some current, even when the Arduino is sleeping.
This just shortens the battery life and doesn't bring anything...
Furthermore VCC measurement can be added to any hardware, even if the resistor divider is not on the board. -
@Yveaux But it would mean that every board has to be measured is it not?
-
@Yveaux I mean that you have to 'calibrate' the value (sorry for not being more clear) on first time use. And yes, obviously only when you intend to use batteries :)
@marceltrapman you don't have to calibrate it to use it. Only the 1v1 reference is created using a bandgap diode which can have slight deviations for each AVR you buy ( approx. In the 1.0..1.2 volts range) If you don't calibrate it, the reading can be 10% off.
If you need accuracy, just calibrate it! -
Hi there!
Inspired by the Blog entry at http://provideyourown.com/2012/secret-arduino-voltmeter-measure-battery-voltage/ I decided to write a simple Arduino library to measure VCC level without any external components!
This library can be used to measure the VCC level from e.g. battery powered sensors that do not use a voltage regulator but are powered directly from the batteries and send the battery level to the gateway.The trick is to use the AVR's internal 1.1V reference to measure AVcc. This does not require an external voltage divider.
The Vcc component can report the VCC level either in volts, or in percentage. Reporting in percentage is a nice way to report the battery level in MySensors!
For example:#include <Vcc.h> const float VccExpected = 3.0; const float VccCorrection = 2.860/2.92; // Measured Vcc by multimeter divided by reported Vcc Vcc vcc(VccCorrection); static int oldBatteryPcnt = 0; void loop() { int batteryPcnt = (int)vcc.Read_Perc(VccExpected); if (oldBatteryPcnt != batteryPcnt) { gw.sendBatteryLevel(batteryPcnt); oldBatteryPcnt = batteryPcnt; } }Deviations can easily be corrected for by running one of the example sketches and at the same time measure VCC with a multimeter.
The correction factor should be entered as (VCC multimeter/VCC reported) in the constructor of the Vcc component (the VccCorrection parameter in the example above).
See the example sketches and code for more info.The library can be found at: https://github.com/Yveaux/arduino_vcc
Or download as ZIP: https://github.com/Yveaux/arduino_vcc/archive/master.zipHave fun!
@Yveaux cool job but not technically correct
the resistor divider is always needed if measured voltage is above the reference voltage used.
you cannot brake this rule, because by hardware any value above reference voltage will be read as 1023actually you do other thing. You use AVCC as a reference instead of an internal 1.1V reference and you do automatic calibration
this allow you to measure voltage bellow AVCC but higher than 1.1V without resistive devider -
one more comment
just had a look inside Vcc.cppyou use a range from 0 till expected to calculate percentage
it is incorrectactually any battery type is working only inside a certain voltage range
for example alkaline bellow 0.6V is 0% capacity
li-on bellow 2.7V is 0%to simplify you can treat linear discharge (it is not correct but at least it is much better)
but you need to use an interval starting from none zero -
one more comment
just had a look inside Vcc.cppyou use a range from 0 till expected to calculate percentage
it is incorrectactually any battery type is working only inside a certain voltage range
for example alkaline bellow 0.6V is 0% capacity
li-on bellow 2.7V is 0%to simplify you can treat linear discharge (it is not correct but at least it is much better)
but you need to use an interval starting from none zero -
@axillent You're right, but I implemented it like the external voltage dividers I've seen in sketches.
I'll add a configurable lower bound to the interface.@Yveaux said:
@axillent You're right, but I implemented it like the external voltage dividers I've seen in sketches.
I'll add a configurable lower bound to the interface.I recommend you to read atmega328 datasheet though. You will get an original inside on all things :)
you will also be surprised that atmega328p has an internal (but very low precision) analog temperature sensor -
@Yveaux said:
@axillent You're right, but I implemented it like the external voltage dividers I've seen in sketches.
I'll add a configurable lower bound to the interface.I recommend you to read atmega328 datasheet though. You will get an original inside on all things :)
you will also be surprised that atmega328p has an internal (but very low precision) analog temperature sensor@axillent
Off-topic: why the heck did @hek add support for this temperature sensor to mysensors 1.4 library??? IMHO It doesn't belong there at all!from my experience this temperature sensor is very useless for any sens purpose
you probably will get an acceptable result after calibration, but calibration itself will kill any benefit
it is much easier to use an external pre-calibrated sensor -
@Yveaux said:
@axillent You're right, but I implemented it like the external voltage dividers I've seen in sketches.
I'll add a configurable lower bound to the interface.I recommend you to read atmega328 datasheet though. You will get an original inside on all things :)
you will also be surprised that atmega328p has an internal (but very low precision) analog temperature sensor -
@Yveaux said:
Off-topic: why the heck did @hek add support for this temperature sensor to mysensors 1.4 library??? IMHO It doesn't belong there at all!
You're right. The temp reading will probably not be there in the final version. It's pretty useless and was added for fun when I was testing.
Don't know what happened to you post. Will check with Alex... I'm sure he didn't mean to censor anything :D
-
Hi there!
Inspired by the Blog entry at http://provideyourown.com/2012/secret-arduino-voltmeter-measure-battery-voltage/ I decided to write a simple Arduino library to measure VCC level without any external components!
This library can be used to measure the VCC level from e.g. battery powered sensors that do not use a voltage regulator but are powered directly from the batteries and send the battery level to the gateway.The trick is to use the AVR's internal 1.1V reference to measure AVcc. This does not require an external voltage divider.
The Vcc component can report the VCC level either in volts, or in percentage. Reporting in percentage is a nice way to report the battery level in MySensors!
For example:#include <Vcc.h> const float VccExpected = 3.0; const float VccCorrection = 2.860/2.92; // Measured Vcc by multimeter divided by reported Vcc Vcc vcc(VccCorrection); static int oldBatteryPcnt = 0; void loop() { int batteryPcnt = (int)vcc.Read_Perc(VccExpected); if (oldBatteryPcnt != batteryPcnt) { gw.sendBatteryLevel(batteryPcnt); oldBatteryPcnt = batteryPcnt; } }Deviations can easily be corrected for by running one of the example sketches and at the same time measure VCC with a multimeter.
The correction factor should be entered as (VCC multimeter/VCC reported) in the constructor of the Vcc component (the VccCorrection parameter in the example above).
See the example sketches and code for more info.The library can be found at: https://github.com/Yveaux/arduino_vcc
Or download as ZIP: https://github.com/Yveaux/arduino_vcc/archive/master.zipHave fun!
I think the big question beside all methods, is none take in account the non linear discharge function..
I mean, considering a Lipo between 4.2V and 3.2V, it's not with 20% at 3.4V (but with 1-1.5% instead).
For a correct percentage value, we have to interpolate the discharge function of a battery.
Another alternative is to measure current but we have to know the initial battery charge (mAh).
-
@axillent Did you just edit my post???
I didn't type that and most part of my reply got deleted. ….
Is this forum getting censored? -
I think the big question beside all methods, is none take in account the non linear discharge function..
I mean, considering a Lipo between 4.2V and 3.2V, it's not with 20% at 3.4V (but with 1-1.5% instead).
For a correct percentage value, we have to interpolate the discharge function of a battery.
Another alternative is to measure current but we have to know the initial battery charge (mAh).
@BSoft Aargh! Can we just stick to the thread?
I think measuring VCC in this way is a neat and simple method working IMHO just as fine as an external voltage divider with some added advantages.
Of course the discharge curve is non-linear and you can indeed model it and compensate for it in software, but that's not the (initial) scope of the library I wanted to present here.
I just wanted to create a re-usable library for it and think it can be a nice addition to MySensors sensor nodes.
-
@axillent You're right, but I implemented it like the external voltage dividers I've seen in sketches.
I'll add a configurable lower bound to the interface.