How to let your Arduino go to sleep and wake up on an external event.
Although it may seem like a good idea to put your Arduino to sleep, it is not ideal. The Arduino serial and USB boards use a 7805 type of power regulator, which needs 10mA when the Atmega IC is in idle mode. But if you plan to use the Atmega8 chip on its own board after programming on the Arduino, you can choose any regulator you like, even none if you use Li-ion battery, for example.
Figure 1: a 220 Ohm resistor connects RX to pin 2
Sleep is assisted by interrupts. without them, only a reset can wake the Arduino up again. Fortunately interrupts are incorporated since the 0007 version of the Arduino IDE.
On the hardware front, the Arduino is equipped with two interrupt ports: digital pin 2 and 3. So the Arduino can sense those pins for an event to wake up and resume execution of code. It is even possible to execute special code depending on which pin triggered the wake up (the interrupt).
Events on the USART (the serial port) will also wake up the Arduino. In order for this to work, the Arduino must be in POWER_MODE_IDLE, the only power mode that doesn't disable the USART. Although this mode doesn't give great power savings you can use the functions provided in avr/power.h ( power_adc_disable(),power_spi_disable(),power_timer0_disable(), power_timer1_disable(),power_timer2_disable(),power_twi_disable()) to disable other hardware modules to achieve greater power savings. See this link for example code.
Because of the dominant way an interrupt breaks in in the execution of the main code, it is wise to make the code executed by an interrupt as short as possible. Maybe even just set a variable which will be handled in the main program. As long as the code for the interrupt runs, internal timers are waiting.
This code makes use of the Serial port to receive commands. In parallel to that it will count 10 seconds before going into sleep mode. The 220 Ohm resistor keeps pin 2 HIGH (because RX is internally pulled-up to 5V when used as Serial port) until there is serial information coming in.
Note to the author: there is no need for a resistor between RX and pin 2 and the above statement is rather confusing. In fact RX and pin 2 can be connected directly as RX is already connected to the output of the USB to serial converter and a serial line when in idle state is at logic HIGH (in TTL that means 5V). So pin 2 is effectively already pulled up at a HIGH state. A resistor may only be useful to limit contention between two outputs if one programs pin 2 as output by mistake (pins are input by default anyway), though current is already internally limited to 40mA.
This code assumes Arduino-0007. It uses calls to the included interrupts.c file in the distribution. If you find a way to make it run in older versions of the IDE, please attach the needed alterations underneath this page.