Skip to content
  • MySensors
  • OpenHardware.io
  • Categories
  • Recent
  • Tags
  • Popular
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Brand Logo
  1. Home
  2. Development
  3. 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 ;-)

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 ;-)

Scheduled Pinned Locked Moved Development
supplyvcc
90 Posts 20 Posters 143.3k Views 13 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • YveauxY Offline
    YveauxY Offline
    Yveaux
    Mod
    wrote on last edited by Yveaux
    #1

    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.zip

    Have fun!

    http://yveaux.blogspot.nl

    axillentA BSoftB DammeD 3 Replies Last reply
    4
    • marceltrapmanM Offline
      marceltrapmanM Offline
      marceltrapman
      Mod
      wrote on last edited by
      #2

      Hi, nice stuff but...
      What would be the advantage (except for not having to add those 2 resistors)?

      Fulltime Servoy Developer
      Parttime Moderator MySensors board

      I use Domoticz as controller for Z-Wave and MySensors (previously Indigo and OpenHAB).
      I have a FABtotum to print cases.

      YveauxY 1 Reply Last reply
      0
      • marceltrapmanM marceltrapman

        Hi, nice stuff but...
        What would be the advantage (except for not having to add those 2 resistors)?

        YveauxY Offline
        YveauxY Offline
        Yveaux
        Mod
        wrote on last edited by
        #3

        @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.

        http://yveaux.blogspot.nl

        1 Reply Last reply
        1
        • marceltrapmanM Offline
          marceltrapmanM Offline
          marceltrapman
          Mod
          wrote on last edited by
          #4

          @Yveaux But it would mean that every board has to be measured is it not?

          Fulltime Servoy Developer
          Parttime Moderator MySensors board

          I use Domoticz as controller for Z-Wave and MySensors (previously Indigo and OpenHAB).
          I have a FABtotum to print cases.

          YveauxY 1 Reply Last reply
          0
          • marceltrapmanM marceltrapman

            @Yveaux But it would mean that every board has to be measured is it not?

            YveauxY Offline
            YveauxY Offline
            Yveaux
            Mod
            wrote on last edited by
            #5

            @marceltrapman What do you mean? You don't have to measure it :frowning: Only when it makes sense, e.g. for battery powered sensors.

            http://yveaux.blogspot.nl

            1 Reply Last reply
            0
            • marceltrapmanM Offline
              marceltrapmanM Offline
              marceltrapman
              Mod
              wrote on last edited by
              #6

              @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 :)

              Fulltime Servoy Developer
              Parttime Moderator MySensors board

              I use Domoticz as controller for Z-Wave and MySensors (previously Indigo and OpenHAB).
              I have a FABtotum to print cases.

              YveauxY 1 Reply Last reply
              0
              • marceltrapmanM marceltrapman

                @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 :)

                YveauxY Offline
                YveauxY Offline
                Yveaux
                Mod
                wrote on last edited by
                #7

                @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!

                http://yveaux.blogspot.nl

                1 Reply Last reply
                2
                • marceltrapmanM Offline
                  marceltrapmanM Offline
                  marceltrapman
                  Mod
                  wrote on last edited by
                  #8

                  @Yveaux ah ok, that clears things up :) Thanks

                  Fulltime Servoy Developer
                  Parttime Moderator MySensors board

                  I use Domoticz as controller for Z-Wave and MySensors (previously Indigo and OpenHAB).
                  I have a FABtotum to print cases.

                  1 Reply Last reply
                  0
                  • YveauxY Yveaux

                    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.zip

                    Have fun!

                    axillentA Offline
                    axillentA Offline
                    axillent
                    Mod
                    wrote on last edited by axillent
                    #9

                    @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 1023

                    actually 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

                    sense and drive

                    1 Reply Last reply
                    0
                    • axillentA Offline
                      axillentA Offline
                      axillent
                      Mod
                      wrote on last edited by
                      #10

                      one more comment
                      just had a look inside Vcc.cpp

                      you use a range from 0 till expected to calculate percentage
                      it is incorrect

                      actually 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

                      sense and drive

                      YveauxY 1 Reply Last reply
                      0
                      • axillentA axillent

                        one more comment
                        just had a look inside Vcc.cpp

                        you use a range from 0 till expected to calculate percentage
                        it is incorrect

                        actually 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

                        YveauxY Offline
                        YveauxY Offline
                        Yveaux
                        Mod
                        wrote on last edited by
                        #11

                        @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.

                        http://yveaux.blogspot.nl

                        axillentA YveauxY 2 Replies Last reply
                        0
                        • YveauxY Yveaux

                          @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.

                          axillentA Offline
                          axillentA Offline
                          axillent
                          Mod
                          wrote on last edited by
                          #12

                          @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

                          sense and drive

                          YveauxY 2 Replies Last reply
                          1
                          • axillentA axillent

                            @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

                            YveauxY Offline
                            YveauxY Offline
                            Yveaux
                            Mod
                            wrote on last edited by axillent
                            #13

                            @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

                            http://yveaux.blogspot.nl

                            Z 1 Reply Last reply
                            0
                            • axillentA axillent

                              @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

                              YveauxY Offline
                              YveauxY Offline
                              Yveaux
                              Mod
                              wrote on last edited by Yveaux
                              #14

                              @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?

                              http://yveaux.blogspot.nl

                              axillentA 1 Reply Last reply
                              0
                              • hekH Offline
                                hekH Offline
                                hek
                                Admin
                                wrote on last edited by
                                #15

                                @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

                                1 Reply Last reply
                                0
                                • YveauxY Yveaux

                                  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.zip

                                  Have fun!

                                  BSoftB Offline
                                  BSoftB Offline
                                  BSoft
                                  wrote on last edited by BSoft
                                  #16

                                  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).

                                  YveauxY 1 Reply Last reply
                                  0
                                  • YveauxY Yveaux

                                    @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?

                                    axillentA Offline
                                    axillentA Offline
                                    axillent
                                    Mod
                                    wrote on last edited by
                                    #17

                                    @Yveaux sorry, something went wrongly
                                    I just tried to do a reply

                                    sense and drive

                                    1 Reply Last reply
                                    0
                                    • BSoftB BSoft

                                      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).

                                      YveauxY Offline
                                      YveauxY Offline
                                      Yveaux
                                      Mod
                                      wrote on last edited by
                                      #18

                                      @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.

                                      http://yveaux.blogspot.nl

                                      1 Reply Last reply
                                      0
                                      • DammeD Offline
                                        DammeD Offline
                                        Damme
                                        Code Contributor
                                        wrote on last edited by
                                        #19

                                        The tone in here sounds a bit dull..

                                        Well,
                                        @yveaux
                                        I Like the contribution! I will use it. Thanks!

                                        1 Reply Last reply
                                        0
                                        • YveauxY Yveaux

                                          @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.

                                          YveauxY Offline
                                          YveauxY Offline
                                          Yveaux
                                          Mod
                                          wrote on last edited by
                                          #20

                                          @Yveaux said:

                                          I'll add a configurable lower bound to the interface.

                                          Done. Now you can pass the expected range when reading voltage as a percentage, e.g. [0.6,..,1.5] volts for AA alkaline.
                                          I also updated the examples.

                                          http://yveaux.blogspot.nl

                                          1 Reply Last reply
                                          0
                                          Reply
                                          • Reply as topic
                                          Log in to reply
                                          • Oldest to Newest
                                          • Newest to Oldest
                                          • Most Votes


                                          12

                                          Online

                                          11.7k

                                          Users

                                          11.2k

                                          Topics

                                          113.1k

                                          Posts


                                          Copyright 2025 TBD   |   Forum Guidelines   |   Privacy Policy   |   Terms of Service
                                          • Login

                                          • Don't have an account? Register

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • MySensors
                                          • OpenHardware.io
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular