Battery Level Monitor

I want to add the capability to read the battery percentage from the arduboy, as I’ve found myself using it as a temp and humidity probe for long periods thanks to my STEMMA QT mod. As I understand, all that’s needed is two resistors of the same value in series with ground, voltage output, and the connection between them going to an ADC capable pin. If I were to add these resistors and wires to a production arduboy, would the correct voltage output to connect to be VCC? I know usually you should go for VIN, but I’m not sure if they’re effectively the same here or not. As for the ADC pin, I think A5 would be best, I don’t know that it has any function implemented besides being brought out as a test pad. Can anyone confirm that? Or recommend a better pin to use?

If you have a voltmeter and don’t mind calibrating for each Arduboy, and hard coding or storing calibration values in EEPROM, you can use the bandgap reference to monitor battery voltage without any additional components.

Honestly was looking to do it with additional components just because it tends to be more fun for me to work with a soldering iron than software :sweat_smile: plus it seemed more straightforward

The resistor divider technique needs a known stable voltage. It’s usually used when you have a battery with a voltage that’s higher than a regulator it’s using to power the microprocessor. For instance, a 6V battery feeding a 5V LDO regulator that provides 5V VCC. You need the voltage divider because the battery voltage is higher than VCC and the ADC can only handle voltages up to VCC.

(If you have a boost regulator, where the regulator is providing VCC higher than the highest battery voltage, then you wouldn’t need the resistor divider. Just feed the battery voltage directly into the ADC pin.)

One thing to be careful about is that you shouldn’t feed any voltage into the ADC pin when VCC isn’t powering the microprocessor. Usually you would use the switched battery voltage that’s only present when powering the regulator.


Thanks!! that’s really useful. I’ll post back with updates soon.


Is this the case with the production arduboy? I know there’s a battery protection and charge controller IC, but not sure if either of those are the aforementioned boost regulator.

There is no regulator. The 32u4 microprocessor, display and everything else runs directly from the battery (after the protection circuitry). This is why you would need some kind of an accurate external voltage reference, or calibrate for using an internal reference.


I see. Hmm. What would be the process to calibrate my arduboy to monitor it in a sketch? I went over the thread you linked earlier but I didn’t quite grasp what needed to be done.

I would replace the battery with a variable power supply that is well regulated and can be set between about 2.8V and 4.2V (the battery voltage range). Use an accurate voltmeter to measure the “battery” voltage provided by the supply.

Use the bandgap technique to measure and display the raw ADC reading that corresponds to the battery voltage.

If you only want a single “battery low” indication, set the power supply to that voltage and store that reading as the battery low threshold. Use that value to trigger whatever you want to do when the battery drops below that level.

If you want to be able to know the actual battery voltage throughout it’s range, then take readings with the power supply set to many points over the battery voltage range and plot the result. I think it will be linear and if so you can save a single calibration point and use that to scale a battery voltage algorithm. If it isn’t linear but a precise curve, you still could come up with an algorithm to match.

Note that the bandgap not only may be above or below the specified typical voltage but it also varies with temperature. This variance may be low enough that it doesn’t affect things enough to be a problem for your purposes, especially if the temperature doesn’t change much in your case. If the temperature does end up to be a factor, you could also read the microprocessor’s internal (and thus basically the bandgap) temperature and have your algorithm compensate. To figure out how to compensate, you could do the above calibration test at various temperatures or you might get away with using the graph in the datasheet.


Honestly most of that is beyond me and I was hoping to keep the original battery for this. Should I go the route of adding a voltage regulator? From what you said it seems if one were in play, it’d be incredibly easy to measure the actual battery voltage. It may be a bit tricky, but I do have an LM317T variable voltage regulator that might be good for this purpose. But I’m pretty terrible at math ironically :sweat_smile: so I’m not sure what resistors I should use to get between 3.7-5v.

Substituting the battery with a power supply is only temporary, for the sake of calibration. Otherwise, you would have to charge and discharge the battery for it to provide the various voltage levels you need for calibration. Once you’ve calibrated for the bandgap’s voltage and other characteristics in the specific 32u4 you’re using (because it can be different from part to part), you would then remove the power supply and reinstall the battery.

However, thinking about this further:
Assuming the bandgap voltage variance over your 32u4 operating temperature range isn’t a significant factor, you really just need to know the bandgap voltage for your particular 32u4. If you use a voltmeter to know exactly the battery voltage at a particular instance in time, you can use that reading along with the ADC to determine the bandgap voltage and thus calibrate for it.

If you want to use the original Arduboy battery, you can’t easily add a voltage regulator. The battery only provides between 3.0V and 4.2V, which is just barely enough. Adding a regulator would only lower the voltage more.

What you need is an external voltage reference. The only reason for using an external reference is if its voltage is exactly known and more stable than the internal bandgap reference. This would eliminate the need for software calibration because the external reference would itself be calibrated.

The software for using the internal bandgap or an external voltage reference is pretty much the same in terms of complexity.

The problem is that the bandgap voltage can vary from part to part and your software needs to know how to compensate for that using a calibration value. You have to measure to determine what that bandap value is for each individual chip. With an external reference that is always the same, the software can be hard coded with a single calibration value for it.