Projects‎ > ‎Programming‎ > ‎ATMEL AVR‎ > ‎


This code was used in a touch light controller for the Illuminate Project. In reads in a single touch sensor and pulses the gate of a MOSFET to control the brightness of an LED bank. There are two brightness levels, and the unit goes into sleep mode when it not controlling any LEDs. Because this circuit is going into a camper which is often run from batteries, low power consumption is a priority. The MCU shouldn't be drawing (much) power when it is not in use.

Included Header Files

I used my standard custom AVR.h file in addition to the sleep.h file which comes with WinAVR. The sleep.h file contains all of the macros necessary to enable and enter into sleep mode.

#include <custom/avr.h>
#include <avr/sleep.h>


I only had a few constants in this program: the HIGH and LOW values for the output compare register. Otherwise, I gave each MCU pin a custom name and included a couple of status flag bits.

// Constants

Global Variables

There was only one global variable - the eight bit status flag. This has to be global because it is used in the interrupt handlers. The two defined status flag bits are a part of this variable.

static volatile uint8_t stat_flag = 0x00;


The main part of the program is divided into two sections. First, the AVR chip is initialized. It then enters a forever loop. In the initialization, the power reduction register is set to shut off all features. A timer is then set up for the pulse to control the LED brightness. The reading of the sensor is handled entirely within a "pin change" interrupt, so that had to be enabled on the pin connected to the touch sensor. Finally, the program puts the MCU to sleep while it waits on input from the sensor. The sleep mode is set to "power down" for maximum energy savings.


Interrupt Handlers

The only interrupt in use is for the pin change. This happens asynchronously, so it can be used to wake the MCU from sleep mode. Because I only care when the sensor is touched, I filter out the negative edges of the pin change with an 'if' statement. A 'switch' statement is then used to determine the correct action based on the state and mode of the LEDs. If they are off, the lights turn on in LOW mode. The program would then either enter HIGH mode and turn the lights off on subsequent interrupts. A final loop is used to hold the program until the user stops touching the sensor. Without this loop, this interrupt would be continuously triggered while the sensor is being touched.



  Click here to download all of the necessary source code files!