<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://pauljmac.com/projects/index.php?action=history&amp;feed=atom&amp;title=RGB_driver</id>
	<title>RGB driver - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://pauljmac.com/projects/index.php?action=history&amp;feed=atom&amp;title=RGB_driver"/>
	<link rel="alternate" type="text/html" href="https://pauljmac.com/projects/index.php?title=RGB_driver&amp;action=history"/>
	<updated>2026-04-21T13:58:03Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.42.3</generator>
	<entry>
		<id>https://pauljmac.com/projects/index.php?title=RGB_driver&amp;diff=12&amp;oldid=prev</id>
		<title>Paul: Created page with &quot;==Abstract== This project was for a Halloween prop wand. A tiny circuit board with a AA battery pack and RGB LED was held in the hand with a ~10&quot; acrylic light pipe to pose as the wand. The wand had 4 modes.   RGB cycle mode - The wand cycled through the RGB color spectrum slowly fading into surrounding colors.   Color lock - Locks the wand onto the currently displayed color.   &quot;Tink&quot; mode - The wand slowly pulsates a tan color, much like what you would picture Tinkerbel...&quot;</title>
		<link rel="alternate" type="text/html" href="https://pauljmac.com/projects/index.php?title=RGB_driver&amp;diff=12&amp;oldid=prev"/>
		<updated>2024-12-08T16:08:03Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;==Abstract== This project was for a Halloween prop wand. A tiny circuit board with a AA battery pack and RGB LED was held in the hand with a ~10&amp;quot; acrylic light pipe to pose as the wand. The wand had 4 modes.   RGB cycle mode - The wand cycled through the RGB color spectrum slowly fading into surrounding colors.   Color lock - Locks the wand onto the currently displayed color.   &amp;quot;Tink&amp;quot; mode - The wand slowly pulsates a tan color, much like what you would picture Tinkerbel...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;==Abstract==&lt;br /&gt;
This project was for a Halloween prop wand. A tiny circuit board with a AA battery pack and RGB LED was held in the hand with a ~10&amp;quot; acrylic light pipe to pose as the wand. The wand had 4 modes. &lt;br /&gt;
&lt;br /&gt;
RGB cycle mode - The wand cycled through the RGB color spectrum slowly fading into surrounding colors. &lt;br /&gt;
&lt;br /&gt;
Color lock - Locks the wand onto the currently displayed color. &lt;br /&gt;
&lt;br /&gt;
&amp;quot;Tink&amp;quot; mode - The wand slowly pulsates a tan color, much like what you would picture Tinkerbell&amp;#039;s wand doing. &lt;br /&gt;
&lt;br /&gt;
Off - Off!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Video of said wand: [http://www.youtube.com/watch?v=B4l27Mpw3fE http://www.youtube.com/watch?v=B4l27Mpw3fE]&lt;br /&gt;
&lt;br /&gt;
== Parts ==&lt;br /&gt;
Attiny45&lt;br /&gt;
&lt;br /&gt;
RGB LED&lt;br /&gt;
&lt;br /&gt;
NOMO button&lt;br /&gt;
&lt;br /&gt;
2 cell battery pack&lt;br /&gt;
&lt;br /&gt;
Light pipe&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
Currently there is a bug I was unable to trace that causes the light to very quickly go out at what seems to be random intervals. It’s not totally obvious so I let it slide.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
#include &amp;lt;util/delay.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/pgmspace.h&amp;gt; &lt;br /&gt;
&lt;br /&gt;
#define bit_get(p,m) ((p) &amp;amp; (m))&lt;br /&gt;
#define bit_set(p,m) ((p) |= (m))&lt;br /&gt;
#define bit_clear(p,m) ((p) &amp;amp;= ~(m))&lt;br /&gt;
#define bit_flip(p,m) ((p) ^= (m))&lt;br /&gt;
#define bit_write(c,p,m) (c ? bit_set(p,m) : bit_clear(p,m))&lt;br /&gt;
#define BIT(x) (0x01 &amp;lt;&amp;lt; (x))&lt;br /&gt;
#define LONGBIT(x) ((unsigned long)0x00000001 &amp;lt;&amp;lt; (x))&lt;br /&gt;
#define NOP asm(&amp;quot;nop&amp;quot;)&lt;br /&gt;
#define OUT 1&lt;br /&gt;
#define IN 0&lt;br /&gt;
#define RED_DEF 2&lt;br /&gt;
#define BLUE_DEF 0&lt;br /&gt;
#define GREEN_DEF 1&lt;br /&gt;
&lt;br /&gt;
#define PRELOAD 0xCE&lt;br /&gt;
&lt;br /&gt;
volatile uint8_t red=0, green=0, blue=0, mode=0, RGB_mode=0, PWM=100, t0_preload=0xCF,&lt;br /&gt;
 last_mode, tink_play=0;&lt;br /&gt;
volatile uint16_t button_cooldown=0;&lt;br /&gt;
&lt;br /&gt;
//this is kind of like a play file&lt;br /&gt;
//the rutine will play though this file in order&lt;br /&gt;
//format is R, G, B in % of light&lt;br /&gt;
static unsigned char file1[] PROGMEM =&lt;br /&gt;
{&lt;br /&gt;
	20,10,0,&lt;br /&gt;
	22,11,0,&lt;br /&gt;
	25,12,0,&lt;br /&gt;
	28,15,0,&lt;br /&gt;
	31,18,0,&lt;br /&gt;
	35,23,0,&lt;br /&gt;
	38,25,0,&lt;br /&gt;
	42,30,0,&lt;br /&gt;
	45,35,0,&lt;br /&gt;
	50,40,0,&lt;br /&gt;
	55,45,0,&lt;br /&gt;
	59,50,0,&lt;br /&gt;
	65,53,0,&lt;br /&gt;
	70,58,0,&lt;br /&gt;
	75,60,0,&lt;br /&gt;
	85,64,0,&lt;br /&gt;
	90,70,0,&lt;br /&gt;
	95,73,0,&lt;br /&gt;
	100,76,0,&lt;br /&gt;
	100,78,0,&lt;br /&gt;
	100,82,0,&lt;br /&gt;
	100,84,0,&lt;br /&gt;
	100,84,0,&lt;br /&gt;
	100,84,0,&lt;br /&gt;
	95,80,0,&lt;br /&gt;
	92,76,0,&lt;br /&gt;
	90,73,0,&lt;br /&gt;
	87,68,0,&lt;br /&gt;
	82,62,0,&lt;br /&gt;
	79,60,0,&lt;br /&gt;
	75,55,0,&lt;br /&gt;
	72,53,0,&lt;br /&gt;
	70,50,0,&lt;br /&gt;
	68,49,0,&lt;br /&gt;
	65,46,0,&lt;br /&gt;
	63,44,0,&lt;br /&gt;
	60,42,0,&lt;br /&gt;
	50,40,0,&lt;br /&gt;
	47,39,0,&lt;br /&gt;
	44,37,0,&lt;br /&gt;
	41,34,0,&lt;br /&gt;
	38,32,0,&lt;br /&gt;
	36,30,0,&lt;br /&gt;
	34,28,0,&lt;br /&gt;
	32,26,0,&lt;br /&gt;
	30,24,0,&lt;br /&gt;
	28,22,0,&lt;br /&gt;
	26,20,0,&lt;br /&gt;
	24,18,0,&lt;br /&gt;
	22,16,0,&lt;br /&gt;
	20,14,0&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ISR(TIMER0_OVF_vect){ //SPECIAL COLOR STUFFF&lt;br /&gt;
	TCNT0=t0_preload;&lt;br /&gt;
	if(mode==1){ //rgb mode&lt;br /&gt;
		switch (RGB_mode){ //0 is red++, 1 is green++, 2 is blue ++;&lt;br /&gt;
			case 0:&lt;br /&gt;
				blue--;&lt;br /&gt;
				red++;&lt;br /&gt;
				if(red==100){&lt;br /&gt;
					RGB_mode=1;&lt;br /&gt;
				}&lt;br /&gt;
				break;&lt;br /&gt;
			case 1:	&lt;br /&gt;
				red--;&lt;br /&gt;
				green++;&lt;br /&gt;
				if(green==100){&lt;br /&gt;
					RGB_mode=2;&lt;br /&gt;
				}&lt;br /&gt;
				break;&lt;br /&gt;
			case 2:&lt;br /&gt;
				green--;&lt;br /&gt;
				blue++;&lt;br /&gt;
				if(blue==100){&lt;br /&gt;
					RGB_mode=0;&lt;br /&gt;
				}&lt;br /&gt;
			default:&lt;br /&gt;
				break;&lt;br /&gt;
			&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	else if(mode==3){ //rgb mode&lt;br /&gt;
		red=pgm_read_byte(&amp;amp;file1[tink_play]);&lt;br /&gt;
		green=pgm_read_byte(&amp;amp;file1[++tink_play]);&lt;br /&gt;
		blue=pgm_read_byte(&amp;amp;file1[++tink_play]);&lt;br /&gt;
		tink_play++;&lt;br /&gt;
		if(tink_play&amp;gt;147){&lt;br /&gt;
			tink_play=0;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
ISR(TIMER1_OVF_vect){ //COLOR UPDATE&lt;br /&gt;
	TCNT1=PRELOAD;&lt;br /&gt;
	if(bit_get(PINB, BIT(3))==0){ //if button pressed&lt;br /&gt;
		if(button_cooldown==0){ &lt;br /&gt;
			mode++;&lt;br /&gt;
			button_cooldown=2000;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	if(button_cooldown &amp;gt; 0){&lt;br /&gt;
		button_cooldown--;&lt;br /&gt;
	}&lt;br /&gt;
	if(PWM==red){&lt;br /&gt;
		bit_set(PORTB, BIT(RED_DEF));&lt;br /&gt;
	}&lt;br /&gt;
	if(PWM==green){&lt;br /&gt;
		bit_set(PORTB, BIT(GREEN_DEF));&lt;br /&gt;
	}&lt;br /&gt;
	if(PWM==blue){&lt;br /&gt;
		bit_set(PORTB, BIT(BLUE_DEF));&lt;br /&gt;
	}&lt;br /&gt;
	PWM--;&lt;br /&gt;
	if (PWM==0){&lt;br /&gt;
		bit_clear(PORTB, BIT(RED_DEF));&lt;br /&gt;
		bit_clear(PORTB, BIT(GREEN_DEF));&lt;br /&gt;
		bit_clear(PORTB, BIT(BLUE_DEF));&lt;br /&gt;
		PWM=100;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void timer0_setup(void){&lt;br /&gt;
	TIMSK|=(1&amp;lt;&amp;lt;TOIE0);&lt;br /&gt;
	TCNT0=t0_preload;&lt;br /&gt;
	TCCR0B=(1&amp;lt;&amp;lt;CS02)|(0&amp;lt;&amp;lt;CS01)|(1&amp;lt;&amp;lt;CS00); // 1024 div&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void timer0_stop(void){&lt;br /&gt;
	bit_clear(TIMSK, (BIT(TOIE0)));&lt;br /&gt;
	TCCR0B=(0&amp;lt;&amp;lt;CS13)|(0&amp;lt;&amp;lt;CS12)|(0&amp;lt;&amp;lt;CS11)|(0&amp;lt;&amp;lt;CS10);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void timer1_setup(void){ //COLOR UPDATE &lt;br /&gt;
	TCNT1=PRELOAD;&lt;br /&gt;
	TIMSK|=(1&amp;lt;&amp;lt;TOIE1);&lt;br /&gt;
	TCCR1=(0&amp;lt;&amp;lt;CS13)|(1&amp;lt;&amp;lt;CS12)|(0&amp;lt;&amp;lt;CS11)|(1&amp;lt;&amp;lt;CS10); //16 dev&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void port_setup(void){&lt;br /&gt;
	DDRB = (IN&amp;lt;&amp;lt;DDB3)|(OUT&amp;lt;&amp;lt;BLUE_DEF)|(OUT&amp;lt;&amp;lt;GREEN_DEF)|(OUT&amp;lt;&amp;lt;RED_DEF);&lt;br /&gt;
	PORTB = (1&amp;lt;&amp;lt;PORTB3); //enable pullup&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
	port_setup();&lt;br /&gt;
	timer1_setup();&lt;br /&gt;
	sei();&lt;br /&gt;
	for(;;){&lt;br /&gt;
		if (mode &amp;gt;= 5){&lt;br /&gt;
			mode=0;&lt;br /&gt;
			last_mode=0;&lt;br /&gt;
		}&lt;br /&gt;
		switch (mode){&lt;br /&gt;
			case 0: //off&lt;br /&gt;
				red=0;&lt;br /&gt;
				green=0;&lt;br /&gt;
				blue=0;&lt;br /&gt;
				break;&lt;br /&gt;
			case 1: //RGB mode&lt;br /&gt;
				if(last_mode == 0){&lt;br /&gt;
					last_mode=mode;&lt;br /&gt;
					blue=100;&lt;br /&gt;
					red=0;&lt;br /&gt;
					green=0;&lt;br /&gt;
					RGB_mode=0;&lt;br /&gt;
					t0_preload=0x00; //&lt;br /&gt;
					NOP;&lt;br /&gt;
					timer0_setup();&lt;br /&gt;
				}&lt;br /&gt;
				break;&lt;br /&gt;
			case 2: //lock&lt;br /&gt;
				if(last_mode == 1){&lt;br /&gt;
					last_mode=mode;&lt;br /&gt;
					timer0_stop();&lt;br /&gt;
				}&lt;br /&gt;
				break;&lt;br /&gt;
			case 3: //tink mode&lt;br /&gt;
				if(last_mode == 2){&lt;br /&gt;
					last_mode=mode;&lt;br /&gt;
					t0_preload=0x00; //&lt;br /&gt;
					timer0_setup();&lt;br /&gt;
				}&lt;br /&gt;
				break;&lt;br /&gt;
			case 4: //white&lt;br /&gt;
				if(last_mode == 3){&lt;br /&gt;
					last_mode=mode;&lt;br /&gt;
					timer0_stop();&lt;br /&gt;
				}&lt;br /&gt;
				red=100;&lt;br /&gt;
				green=100;&lt;br /&gt;
				blue=100;&lt;br /&gt;
				break;&lt;br /&gt;
			default:&lt;br /&gt;
				break;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Paul</name></author>
	</entry>
</feed>