public
Last active

AVR Attiny13 RGB Led Driver

  • Download Gist
rgb_driver-v6.c
C
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 143 144 145 146
/**
* AVR program to provide lighting modes for an RGB LED
* Copyright (c) 2011 Akoi Meexx (http://akoimeexx.com/)
*
* Chip type: Attiny13
* Clock frequency: Default internal clock (9.6MHz / 8 = 1.2MHz)
* +--------+
* [ (PB5) |1* 8| (VCC) Power ]
* [ Button (PB3) |2 7| (PB2) BLUE ]
* [ (PB4) |3 6| (PB1) GREEN ]
* [ Ground (GND) |4 5| (PB0) RED ]
* +--------+
*/
 
/**
* AVR-specific defines and includes
*/
#include <avr/io.h>
#define F_CPU 1200000UL // 1.2 MHz
// Some macros that make the code more readable
#define output_low(port,pin) port &= ~(1<<pin)
#define output_high(port,pin) port |= (1<<pin)
#define set_output(portdir,pin) portdir |= (1<<pin)
 
/**
* Alias our color channel pinouts
*/
#define RED PB0
#define GREEN PB1
#define BLUE PB2
 
/**
* Create our rgb structure and declare it below as a global
*/
typedef struct {
int red;
int green;
int blue;
} rgb;
rgb channels = { 0x00, 0x00, 0x00 };
 
/**
* Define our lighting modes and declare our mode global
*/
#define DEBUG_MODE 0
#define RAINBOW_MODE 1
#define SOLID_MODE 2
#define PULSE_MODE 3
int lighting_mode;
 
/**
* TODO: Optimize. This method just feels too 'clunky'.
*/
void rainbow_step(void) {
//Fade from blue to red
if(channels.blue > 0x00 && channels.red == 0xFF && channels.green == 0x00) {
channels.blue--;
}
if(channels.blue == 0xFF && channels.red < 0xFF && channels.green == 0x00) {
channels.red++;
}
//Fade from green to blue
if(channels.green > 0x00 && channels.blue == 0xFF && channels.red == 0x00) {
channels.green--;
}
if(channels.green == 0xFF && channels.blue < 0xFF && channels.red == 0x00) {
channels.blue++;
}
// Fade from red to green
if(channels.red > 0x00 && channels.green == 0xFF && channels.blue == 0x00) {
channels.red--;
}
if(channels.red == 0xFF && channels.green < 0xFF && channels.blue == 0x00) {
channels.green++;
}
}
 
/**
* TODO: Build function
*/
void solid_step(void) {
// Do nothing, the pwm running should be more than enough
}
 
/**
* TODO: Build function
*/
void pulse_step(void) {
//
}
 
/**
* Software Pulse Width Modulation for RGB
*/
void do_pwm(int r_duty, int g_duty, int b_duty, int rate) {
int i;
 
while (rate != 0) {
// Set our LED pins as output high
PORTB |= (1<<RED) | (1<<GREEN) | (1<<BLUE);
for (i=0; i < 255; i++) {
if (i == r_duty)
output_low(PORTB, RED);
if (i == g_duty)
output_low(PORTB, GREEN);
if (i == b_duty)
output_low(PORTB, BLUE);
}
rate--;
}
}
 
void init(void) {
channels.red = 0xFF;
lighting_mode = RAINBOW_MODE;
set_output(DDRB, RED);
set_output(DDRB, GREEN);
set_output(DDRB, BLUE);
}
 
int main(void) {
init();
while(1) {
switch (lighting_mode) {
case DEBUG_MODE:
break;
case RAINBOW_MODE:
rainbow_step();
break;
case SOLID_MODE:
solid_step();
break;
case PULSE_MODE:
pulse_step();
break;
default:
lighting_mode = RAINBOW_MODE;
}
do_pwm(channels.red, channels.green, channels.blue, 15);
}
return 0;
}

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.