May 26, 2013 | AVR Programming |

ATmega168 Power Save Mode and Pin Change Interrupt

Most times your microcontroller is running in a loop, waiting for something to happen - like a button press. All this while it is consuming power, and this could be an issue, especially if you are running the circuit from a battery. To counter this problem, there are ways of reducing the power consumption of your chip. Here are the various "sleep modes" supported by the ATmega168.

[Table reproduced from Atmel ATmega168 datasheet for illustrative purpose]

In a previous post about an Ambient Light sensor using an Op-Amp Comparator, I mentioned that we would be using the op-amp output to "wake up" an ATmega168. So here, we will be using the "power-save" mode from the above table, and use a pin-change interrupt to wake up from this sleep mode.

The setup used is shown below in the 2 schematics I had posted before. The output Vo from the op-amp should be connected to the pin 14 of the ATmega168 (PCINT0/PB0). Also, in this case, we are not using serial output, so you can remove the connections to the FTDI adapter.

Here is what the circuit looks like, hooked up on a breadboard:

This is the how the program works:

  • When the program starts, start the 16-bit timer, set to fire an interrupt every 3 seconds. Start the timer only if pin 14 is low. (This means that the light level is high in our sensor circuit.).
  • When the chip is not sleeping, it will be flashing an LED attached to pin 6.
  • When the 16-bit timer interrupt happens, set a flag (a volatile variable) so that the main loop reads this flag and puts the chip to sleep mode. It will also turn the LED off at this point.
  • Set up a pin change interrupt on PCINT0 for any logical change in input. When the interrupt fires, if it was caused by a rising edge (ie., light to dark), wake up the chip, and stop the 16-bit timer. If the interrupt was caused by a falling edge (ie., dark to light), re-start the 16-bit timer.

You can read about pin-change interrupts and the 16-bit timer in the Atmel ATmega168 datasheet.

The complete code listing is below. The opening comments in the code also have all the required build commands.


We love hearing from our readers. Email us at for questions or comments on this article. If you found this article useful, please support us by buying some of our Open Source hardware products - like ZeroDriver - an Arduino Zero compatible motor driver for robotics. ZeroDriver is crowdfunding right now. Please click here to support our campaign. and bring this product to market!

Please sign up for updates

Once in a while, we will send you an email update on the latest Electronut Labs projects and products. Your email address will never be shared or abused, ever.

2016 Electronut Labs. All rights reserved.