It seems to be working fine at the moment, but I’d be curious to hear your ideas! Here’s an overview of the code:
Main()
- Initialize the clock and pins
- Run the animation
- Shut the LEDs off and pause for 20ms to allow things to settle down
- Run Set_Battery_Status
- Initialize the RTC to wake us up every 60 minutes
- Go to sleep (standby)
The RTC interrupt just clears the overflow flag and then calls Set_Battery_Status
Set_Battery_Status()
- Turn off all the LEDs
- Wait 10ms for things to settle down
- Run Get_Voltage
- Use the returned voltage to turn on desired LEDs
Get_Voltage()
- Set Vbandgap ref to internal 2.5V
- Set ADC ref to VDD
- Enable the ADC, set it to 10-bit resolution
- Get 15 ADC readings and throw them away
- Get 8 ADC readings and add them together
- Get the average of the 8 readings (bitshift: sum >> 3)
- Use a calibrated formula to get the voltage. Standard formula is (1023*2.5)/reading. My formula is (2643.3/reading)+0.0267.
- Turn off the ADC
- Return the reading
It’s probably a bit wasteful, but I have 4K of program space to work with and I’m just turning on and off a few indicator LEDs so I wasn’t very concerned about peak efficiency.