AVR 8-channel Software PWM

The goal of this project was to make 8 LEDs pulsate with individual frequencies, so that with differently colored LEDs, the combined color would slowly change.

To control the intensity of the LEDs an AT Tiny26L microcontroller was chosen. The AT Tiny26 has one built-in PWM (Wikipedia: PWM) channel that can be used to control the intensity of a LED, but 8 channels is needed to control 8 LEDs, so the PWM-functionality has to be provided by a software program.

One such program is provided by Atmel, AVR136: Low-Jitter Multi-Channel Software PWM. It uses a timer in the AT Tiny26L to execute a piece of code every 256th clock cycle. This piece of code generates the PWM output. It is however, with a 1MHz clock frequency, limited to a PWM frequency of 1MHz / (256 * 256) ≈ 15Hz, witch is too low and show as an annoying flickering of the LEDs. This is also not easily changed with that implementation, mainly due to it being written in C.

To generate a PWM output with a higher frequency, a similar, but more efficient, PWM generating code was written. The timer was changed to generate the PWM output approximately every 90th clock cycle and the output was changed from 256 levels to 128. This results in a PWM frequency of 1MHz / (90 * 128) ≈ 86Hz, which is high enough to eliminate flicker.

The code is organized in initialization, main-loop and PWM-code. The main-loop alters the intensity of each LED and the PWM-code then use that intensity the generate the PWM-output. If you are interested in the precise workings of the code, please write an e-mail.

The prototype is shown in the YouTube video below. Two of the LEDs got broken during assembly and testing and the flickering seen in the video is due to aliasing between the camera and the PWM.

YouTube video

© 2024 Mats Mattsson