My favorites | Sign in
Project Home Downloads Wiki Issues Source
Checkout   Browse   Changes    
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
/*
* rgb_strobe.c
*
* Distributed under Creative Commons 3.0 -- Attib & Share Alike
*
* Created on: Feb 6, 2010
* Author: PaulBo
*/
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>

#ifndef F_CPU
#define F_CPU 8000000UL
#endif

//Hardware definitions
#define RED_LED PB2
#define GREEN_LED PB1
#define BLUE_LED PB0
#define ALL_LEDS ((1 << RED_LED) | (1 << GREEN_LED) | (1 << BLUE_LED))

//Maximum value for led brightness
#define R_MAX 150
#define G_MAX 150
#define B_MAX 150

#define RED_INDEX 0
#define GREEN_INDEX 1
#define BLUE_INDEX 2

//Cycle States
#define RedToYellow 0
#define YellowToGreen 1
#define GreenToCyan 2
#define CyanToBlue 3
#define BlueToMagenta 4
#define MagentaToRed 5

//set red to max (we start in the RedToYellow state)
volatile unsigned char mRgbBuffer[] = {0,0,0};
unsigned char mRgbValues[] = {R_MAX,0,0};
unsigned char mState;

void init_timers()
{
TIMSK = (1 << TOIE0);// enable overflow interrupt
TCCR0B = (1 << CS00); // start timer, no prescale

//enable interrupts
sei();
}

void rgbCycle(){
switch (mState) {
case RedToYellow:
mRgbValues[GREEN_INDEX]++;
if (mRgbValues[GREEN_INDEX] == G_MAX)
mState++;
break;
case YellowToGreen:
mRgbValues[RED_INDEX]--;
if (mRgbValues[RED_INDEX] == 0)
mState++;
break;
case GreenToCyan:
mRgbValues[BLUE_INDEX]++;
if (mRgbValues[BLUE_INDEX] == B_MAX)
mState++;
break;
case CyanToBlue:
mRgbValues[GREEN_INDEX]--;
if (mRgbValues[GREEN_INDEX] == 0)
mState++;
break;
case BlueToMagenta:
mRgbValues[RED_INDEX]++;
if (mRgbValues[RED_INDEX] == R_MAX)
mState++;
break;
case MagentaToRed:
mRgbValues[BLUE_INDEX]--;
if (mRgbValues[BLUE_INDEX] == 0)
mState++;
break;
}

//state should never advance beyond 5.
//It wraps back to 0 when we reach 6
mState %= 6;
}

int main(void){
//Set LED pins to output
DDRB |= ALL_LEDS;

init_timers();

while (1) {
rgbCycle();
_delay_ms(250);

//I like the orange state and it only lasts for a second
//so lets extend it a little bit more
if(mState == RedToYellow)
{
_delay_ms(250);
}
}
return 0;
}

/*
* Timer/Counter overflow interrupt. This is called each time
* the counter overflows (255 counts/cycles).
*/
ISR(TIM0_OVF_vect)
{
//static variables maintain state from one call to the next
static unsigned char sPortBmask = ALL_LEDS;
static unsigned char sCounter = 255;

//set port pins straight away (no waiting for processing)
PORTB = sPortBmask;

//this counter will overflow back to 0 after reaching 255.
//So we end up adjusting the LED states for every 256 interrupts/overflows.
if(++sCounter == 0)
{
mRgbBuffer[RED_INDEX] = mRgbValues[RED_INDEX];
mRgbBuffer[GREEN_INDEX] = mRgbValues[GREEN_INDEX];
mRgbBuffer[BLUE_INDEX] = mRgbValues[BLUE_INDEX];

//set all pins to high (this is a common cathode LED)
sPortBmask = ALL_LEDS;
}
//this loop is considered for every overflow interrupt.
//this is the software PWM.
if(mRgbBuffer[RED_INDEX] == sCounter) sPortBmask &= ~(1 << RED_LED);
if(mRgbBuffer[GREEN_INDEX] == sCounter) sPortBmask &= ~(1 << GREEN_LED);
if(mRgbBuffer[BLUE_INDEX] == sCounter) sPortBmask &= ~(1 << BLUE_LED);
}

Change log

r82 by paulboardman on Aug 6, 2011   Diff
changed to use common cathode RGB led and
shorter pause in the RED->Yellow
transition.
Go to: 
Project members, sign in to write a code review

Older revisions

r76 by paulboardman on Jun 24, 2011   Diff
replace mistakenly deleted opeining
switch statement.
r34 by PaulBoardman on Feb 7, 2010   Diff
comments
r33 by PaulBoardman on Feb 6, 2010   Diff
[No log message]
All revisions of this file

File info

Size: 3451 bytes, 142 lines

File properties

svn:mime-type
text/plain
Powered by Google Project Hosting