Software

In order to maximize space available in the ATtiny13 the application was developed using assembler. To speed initial development a template was used from www.avrfreaks.net to handle initialisation of the AVR. Andy Gayne originally wrote this template.

A 256-byte look-up table containing sine wave values is used to produce natural looking pulse on the laser and motor. This table originated from Jesper Hansen’s mini DDS project at http://www.myplace.nu/avr/. The speed at which this table is read is controlled by PWM_SPD, which is defined near the top of the main program file.

The program consists of three main active parts: the main loop which is the high level operation of the application and two interrupt service routines (ISRs) which monitor and set flags in response to changes in hardware.

Changing the value TIME_INC at the start of the code can customise the increment. A future enhancement to this device would see the addition of a small rotary switch to change the increment between 1, 2, 5 and 10 minutes, enabling the device to be more versatile while maintaining simplicity.

Main Loop

The main is, as the name implies, the main section of the code. This section reads the current state of the device and adjusts the outputs accordingly. After each iteration of the main loop the system is put into a low power mode to conserve battery power. It is woken automatically by the interrupts, which are handled by the ISRs before program flow is returned to the main loop for another iteration.

Timer ISR

The timer ISR is called periodically and used to measure time in the application. This routines increments the real time counter to measure seconds as well as monitoring the de-bounce time and button press time flags set elsewhere in the code. This section also advances the PWM value used to drive the motor or laser one step through the look-up table.

Pin Change ISR

The pin change ISR is used to set state variables to notify the main loop of button presses. On a button press the value is read and then a flag is set to ignore subsequent interrupts for a period of around 20ms. This is done to avoid false triggering due to the bouncing of the switch contacts.