// FullColorLED // 2011.12.3. Toshi Nagata // D2,D5,D8,D11: R with 220 ohm // D3,D6,D9,D12: G with 100 ohm // D4,D7,D10,D13: B with 100 ohm // Cathode -> GND #define PMAX 2048 // Color change // Walk on the surface {x=1,y>=0,z>=0}, {x>=0,y=1,z>=0}, {x>=0,y>=0,z=1} unsigned char colors[12] = {255, 0, 0, 0, 0, 255, 255, 0, 0, 0, 0, 255}; signed char dcol[12] = {0, 1, 3, 1, 3, 0, 2, 6, 0, 0, 1, 3}; unsigned char pwm[12] = {255, 0, 0, 0, 0, 255, 255, 0, 0, 0, 0, 255}; // Brightness change // Linear back-and-forth move between -PMAX to PMAX*2, and // limit the qunatity within [0, PMAX] short pulser[4] = {-PMAX, -PMAX, -PMAX, -PMAX}; signed char dpulser[4] = {7, 11, 4, 2}; // Timer for PWM output // Output i is 0 when timer >= pwm[i], 1 otherwise unsigned char timer = 0; // Scaler for color change unsigned char scaler = 0; // Table for converting amplitude to PWM strength // (to make brightness change smoother) unsigned char table[256] = { 0,1,1,2,2,3,4,4,5,5,6,7,7,8,8,9, 10,10,11,12,12,13,13,14,15,15,16,17,17,18,19,19, 20,21,21,22,23,23,24,25,25,26,27,27,28,29,29,30, 31,32,32,33,34,34,35,36,37,37,38,39,39,40,41,42, 42,43,44,45,45,46,47,48,48,49,50,51,52,52,53,54, 55,56,56,57,58,59,60,60,61,62,63,64,65,65,66,67, 68,69,70,70,71,72,73,74,75,76,77,77,78,79,80,81, 82,83,84,85,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,131,132,133,134,135,136,137,138,139,141,142,143,144,145,146, 147,149,150,151,152,153,154,156,157,158,159,160,162,163,164,165, 166,168,169,170,171,173,174,175,177,178,179,180,182,183,184,186, 187,188,189,191,192,193,195,196,197,199,200,202,203,204,206,207, 208,210,211,213,214,216,217,218,220,221,223,224,226,227,229,230, 232,233,235,236,238,239,241,242,244,245,247,248,250,251,253,255, }; void setup() { DDRD |= B11111100; // PD2-PD7 for output DDRB |= B00111111; // PB0-PB5 for output // Set up Timer 2 // Disable overflow interrupt TIMSK2 &= ~(1< timer) m1 |= mask[i]; } PORTD = m1; m1 = 0; for (i = 6; i < 12; i++) { if (pwm[i] > timer) m1 |= mask[i]; } PORTB = m1; } void loop() { short c; unsigned char m1; unsigned char i, j = 0; scaler++; if (scaler == 28) { scaler = 0; for (i = 0; i < 12; i++) { c = (short)colors[i] + (short)dcol[i]; if (c < 0) { c = -c; dcol[i] = -dcol[i]; } else if (c > 255) { c = 255; m1 = -dcol[i]; dcol[i] = 0; i -= j; if (dcol[i] == 0) { dcol[i] = m1; } else if (dcol[i + 1] == 0) { dcol[i + 1] = m1; } else { dcol[i + 2] = m1; } i += j; } colors[i] = c; j++; if (j == 3) j = 0; } } for (i = 0; i < 4; i++) { c = pulser[i] + dpulser[i]; if (c > PMAX * 2 || c < -PMAX) { dpulser[i] = -dpulser[i]; } pulser[i] = c; if (c < 0) c = 0; else if (c > PMAX) c = PMAX; c /= (PMAX / 128); for (j = 0; j < 3; j++) { pwm[i * 3 + j] = table[((short)colors[i * 3 + j] * c) / 128]; } } }