// Multiplexed PWM RGB Led Demo
// By Petri Hakkinen
// 24th November 2014
//
// Arduino Uno driving a single RGB led with only one resistor.
//
// Make the following connections:
// * Connect Arduino pins D2,D3,D3 to anodes of a RGB led.
// * Connect cathode of the RGB led to 330 ohm resistor.
// * Connect the other end of the resistor to ground.
//
// A multiplexed PWM signal is generated by a timer interrupt routine.
//
// Uses TimerOne library, download from here:
// http://playground.arduino.cc/Code/Timer1
#include <TimerOne.h>
volatile uint8_t color[3]; // R,G,B led intensities in range [0,255]
volatile uint8_t phase = 0; // phase of the PWM signal, counts from 0 to 255
volatile uint8_t led = 0; // which led to update, counts from 0 to 2
// Look up table of sin values for mega demo effect.
uint8_t sintab[64];
// The interrupt routine that updates the states of leds.
void interruptRoutine()
{
// turn all leds off
PORTD &= B11100011;
// sample pwm and turn on one led
if(phase < color[led])
PORTD |= 1<<(led+2);
led = (led + 1) & 3;
phase++;
}
void setup()
{
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
// attach interrupt routine
Timer1.initialize(50);
Timer1.attachInterrupt(interruptRoutine);
// init sin table for mega demo effect
for(uint8_t i = 0; i < 64; i++)
sintab[i] = (uint8_t)(sin(i * M_PI * 2 / 64) * 127.0f + 128.0f);
}
void loop()
{
const uint8_t speed = 13;
color[0] = 0;
color[1] = 0;
color[2] = 0;
// fade red
for(int i = 0; i < 256; i++) {
color[0] = i;
delay(speed);
}
// fade green
for(int i = 0; i < 256; i++) {
color[1] = i;
delay(speed);
}
// fade blue
for(int i = 0; i < 256; i++) {
color[2] = i;
delay(speed);
}
// mega demo effect
for(int i = 0; i < 500; i++) {
color[0] = sintab[i & 63];
color[1] = sintab[(i*2 + 123) & 63];
color[2] = sintab[(i*2/3 + 35) & 63];
delay(speed);
}
}