Waking an ATmega328P from deep sleep when a battery voltage drops below a set level
Founder of a tiny logistics startup, very new to hardware, so apologies if this is obvious.
We put solar-charged 12 V lead-acid batteries on trailer gate sensors. I want an Arduino Pro Mini (ATmega328P, 3.3 V, 8 MHz, power LED removed) to sleep in power-down and wake only when the battery falls below about 11.8 V, then send one message to Hermetry so someone swaps the battery. Divider is 100k/33k so 11.8 V is about 2.93 V at the pin.
I read about the analog comparator (AIN0/AIN1) and its interrupt, and wired the divider to AIN1 with a 2.5 V reference on AIN0. With the comparator interrupt set, sleep in SLEEP_MODE_PWR_DOWN never wakes. In SLEEP_MODE_IDLE it wakes fine but my meter shows about 1.3 mA, which kills the point.
Is there a register trick I’m missing to make the comparator wake it from power-down? Code is basically:
ACSR = (1 << ACIE) | (1 << ACIS1); // interrupt on falling edge
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_enable(); sei(); sleep_cpu();
Couldn’t you wake on the watchdog every 8 s, read the ADC, and go back to sleep? That’s what our door counters do.
Tried that, it works, average around 20 µA. I was hoping for less, and it feels clumsy.
Why does the reference matter so much? Couldn’t it use the internal 1.1 V bandgap?
No register trick, I’m afraid. As far as I remember the sleep mode table in the 328P datasheet, the analog comparator is only a wake source in idle (and ADC noise reduction), not power-down. In power-down only the external interrupts, pin change, TWI address match and the watchdog wake it. Your idle current is the clocks running.
Move the comparator outside. A nanopower comparator with push-pull output into INT0 (D2) lets the 328P sit in power-down at a few µA. TLV3691 draws about 75 nA, and the reference can be a micropower 2.5 V shunt. Add hysteresis with a resistor from output to the + input, a few hundred mV at the battery side, otherwise a battery hovering at 11.8 V will wake you a hundred times a night as the load changes.
attachInterrupt(digitalPinToInterrupt(2), wake, FALLING);
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_enable(); sleep_cpu(); // wakes on INT0 only
// on wake: read ADC once for the real value, send it, sleep again
Aoife: you can use the bandgap internally, but the comparator itself still can’t wake power-down, so it doesn’t help here.
On the Hermetry side I’d still send a heartbeat once a day with the voltage. Then an offline alarm on the profile tells you a sensor died, which a wake-only design never would. Put the low-voltage alarm rule on bat_v with some hysteresis too.
Ordered TLV3691s. Breadboard version with a 2.5 V reference and about 300 mV hysteresis sits at 4.8 µA in power-down and wakes cleanly at 11.79 V on my bench supply. Daily heartbeat added, and the offline rule. Thanks Laura, and Keisha the WDT version is my fallback.
- Debes estar registrado para responder a este debate.
Únete a la conversación
Inicia sesión para preguntar y responder, dar me gusta a las publicaciones útiles y marcar la respuesta que resolvió tu problema. Cada aportación suma puntos y niveles.

