Adding A Battery Gauge To A Project With Zero Parts

The typical way of doing a low battery detector is throwing a comparator in the circuit, setting it to measure a certain threshold voltage, and sending that signal off to a microcontroller or other circuit to notify someone the battery is going dead. [Josh] has a simpler way using an 8-bit AVR and zero other parts.

The chip [Josh] is using is the ATtiny84. The ADC in this chip is usually used to measure an unknown voltage against a reference voltage. The trick [Josh] is using is to do this in reverse: The internal 1.1 Volt reference voltage is measured against an unknown scale, namely the input voltage.

The value provided by the ADC on the chip will always be Vin times 1024 over the reference voltage. Since Vin will be 1.1 V in this case, the ADC value is known, it’s only a matter of doing some 6th grade algebra to determine the value of the input voltage.

[Josh] put together a small demonstration where the chip blinks out the number of volts its receiving from a bench power supply. By blinking a LED, it can blink out the current value of VCC as integers, but by using this technique you should be able to get a fairly fine-grained reading of what VCC actually is. Video below.

41 thoughts on “Adding A Battery Gauge To A Project With Zero Parts

    1. Yeah nothing new at all. I use this trick when I need precision on an ADC, as in calculate the VCC so I can then use it to calculate the ADC reading without just chucking in a 3.3 or a 5 into the equation. My laptops USB power seems to only provide 4.8 so it can easily throw off readings if you use 5.

    2. My hunch is that the original idea for this technique goes all the way back to the Atmel chip designer who went to the trouble of wiring the 1.1V reference into the _input_ mux of the ADC- and then gave us excellent documentation on how to use it. Are there other interesting uses for this this connection besides indirectly measuring Vcc/AREF?

      1. From the manual (Data Sheet), the only other thing that I can see that you can do with it is to use it as an input to a comparator along with another MUX’d input as an interrupt trigger. Why you would do that? I don’t have a clue!

        I can’t see any way to get it back out of the chip so it can’t be used as a center rail for AC ADC.

        So apart from comparing it to Vcc or Aref, I can’t see any use for it.

    1. Pretty much every MCU with an ADC has a line for the internal VRef. I use a lot of STM32 devices… it’s 1.22V, but otherwise everything is the same. For me, a more important caveat is that, quite often, you still need a resistor divider between the voltage source and the ADC input. Sometimes you can get away with just a series resistor, by using the internal pulldown… BUT these usually need to be calibrated, because manufacturing tolerance on the pulldown is usually pretty sloppy.

    1. We can’t all be cutting-edge geniuses. And even they have to start somewhere. Aren’t you glad to have more people into electronics and processors? It means more software gets written, and keeps hobby suppliers in business. You benefit from that.

      Lots of super-smart stuff gets published here. If you want rocket science, go do some and HAD will surely cover it.

    2. There’s more to the word “efficient” than use of the least parts/the least clock cycles. Just because doing it with the fewest clock cycles is cool and nerdy and all, it’s not always the right thing to do (most likely it isn’t).

    3. I didn’t think there was an Arduino made with an atTiny84 and his code looks like C rather than sketch.

      In any case the Arduino environment doesn’t natively support the register changes to do this or to use the internal temperature sensor although it can be done with some direct register writes and C.

      The atMega’s and atTiny’s are micro-controllers within their own right and are not necessarily just for Arduinos.

      This bloke has has worked out how to do this himself by going to the manufacturers datasheet even if it has been done before so I wouldn’t call this copy and paste.

      For a new device or type of device, I always start with a copy and paste to ‘flash the led’. I would be very surprised if there are many who jump right into assembly on a new micro-controller or jump right in with verilog or VHDL.

    1. “Adding a battery gauge to a project with zero parts”. The important words there are “adding” and “project”, the “zero parts” is in that context. Seems there’s a lot of smartarses who can’t even understand basic English.

      1. No, he’s right. Either it’s “Adding a battery gauge to a project COMMA with zero parts” or ““Adding a battery gauge to a project with zero EXTRA parts”. You cannot omit the comma in this context without adding an explanatory extra word.

        1. It’s, and I hate having to do this cos I’m not formally trained in grammar, but…

          In “adding a battery gauge to a project with zero parts” the “zero parts” goes with the “adding”, not with “project”. It’s adding something, a feature, without adding parts, to a project. Not adding a feature, to a project that has no parts.

          The correct interpretation should be obvious, what sort of project has zero parts? It’s hack-a-day not koans-per-lifetime.

          To implement the new feature, zero parts are needed. Taking the other interpretation either means you’re completely stupid, new to English, or perhaps deliberately misunderstanding, being obtuse to score points in an imaginary one-upping grammar rodeo.

          Which one do you think might be the case here? As bleeding usual. Grammar copping is only good when you’re right.

          If someone who’s actually studied grammar would like to break the sentence down, using lots of parenthesis and footnotes, I’m sure that’d provide plenty more fuel for this stupid fire. Why not a GIF diagram?

        2. Perhaps you could use some critical thinking and take a look at the fact that measuring the battery on a project with zero parts makes no sense, and from there extrapolate what the real meaning is.

  1. My own practice is to add a boost converter to battery operated designs. This gives you a stable supply voltage over the entire range of the battery capacity, and then you can just feed the pre-boost battery voltage into an ADC pin and measure it in the traditional way. Since the boost converter output is regulated, it provides a stable – and higher – reference against which you can measure the battery.

    1. But since you don’t know how many coulombs went into the battery, and what its coulombic efficiency is, you can do very little with that information except calculate some crude estimate of watt-hours already used.

  2. Almost every project has a binary battery gauge built in. Does it work? Then the battery has some juice left. Not working, then the battery is empty. Not only doesn’t that add any parts, it doesn’t require a microcontroller.

  3. Although the internal band gap reference voltage is a nice tool to use in the avr, it is hardly accurate. It’s even stated in the datasheet, so you still need to calibrate the voltage before you can rely on it. Even then, I have found that it’s not too accurate and still drifts some. However for a simple Vcc measurement, then it works well. Just be prepared for it to be off by a few tenths of a volt.

    1. Great point Kyle.
      The internal reference has an initial accuracy, a drift over temperature and a drift over time (ageing).
      You can roughly estimate the state of change in a Li* battery by the open circuit voltage, but the change in voltage between 80% full and 20% full is really small. A friend of mine got caught out by this very same battery gauge trick – he prototypped with a ‘superhero’ AVR which was bang on spec. When they made 1000 units things did not go so well.

    2. The thermal stability of a band gap will always be a problem for internal references (Usually about 1.1 – 1.2V) because they are amplifying the Zener effect within transistor junctions (a current mirror). Unavoidable differences in Veb and gain cause thermal drift.

      The Zener effect is most thermally stable at about 5.6 Volts. Micro-controllers can’t have an internal reference this high because it’s above the Vcc.

      If you need high thermal stability then you need to make a boost or step up converter and then Zener down to 5.6 Volts. That is why micro-controllers always have an external Vref. From 5.6 Volts you can use a stable resistive divider to bring it back under Vcc.

  4. What a coincidence, I was actually thinking about this the other day for a PIC project.
    Speaking of ADC tricks, many AVRs (including the ATtiny84A used in this project) have an internal temperature sensor that can be read from ADC channel 8. A friend of mine used this as a hardware random number generator.

    1. I’ve used both in a pinch, but both the temperature sensor and the 1.1v reference are all over the place without calibration, and even then they are not very accurate.

      Check these application notes:

      There is even a section in the application note regarding the bandgap reference that talks about estimating temperature (-+5º) by measuring the voltage variation.

  5. Well I for one liked to see this post and visited the site and found I could post a comment on his site and thank him for that . Not common yet . I wondered if he could taske a look at my code for an RGB LED indicator and perhaps merge the code or advise me how the code could be changed to lower power consumption by turning the chip off for a while ?
    My project is at

Leave a Reply

Please be kind and respectful to help make the comments section excellent. (Comment Policy)

This site uses Akismet to reduce spam. Learn how your comment data is processed.