// Matt Edwards // RGB LED color test (for MDE RGB board v1) // Based on hello.array.44.c, "Charlieplex LED array hello-world", by Neil Gershenfeld #include #include #include #define output(directions,pin) (directions |= pin) // set port direction for output #define input(directions,pin) (directions &= (~pin)) // set port direction for input #define set(port,pin) (port |= pin) // set port pin #define clear(port,pin) (port &= (~pin)) // clear port pin #define pin_test(pins,pin) (pins & pin) // test for port pin #define bit_test(byte,bit) (byte & (1 << bit)) // test for bit set #define led_port PORTA #define input_port PORTA #define input_pins PINA #define led_direction DDRA #define input_direction DDRA #define input_pin1 (1 << PA6) #define input_pin2 (1 << PA5) #define input_pin3 (1 << PA4) #define A (1 << PA0) // rail 1 #define B (1 << PA1) // rail 2 #define C (1 << PA2) // rail 3 #define D (1 << PA3) // rail 4 void rgbflash(uint8_t from, uint8_t to1, uint8_t to2, uint8_t to3, uint8_t Rpct, uint8_t Gpct, uint8_t Bpct, uint8_t cycles) { // source from, sink to, flash set(led_port,from); clear(led_port,to1); clear(led_port,to2); clear(led_port,to3); output(led_direction,from); for (uint8_t j = 0; j < cycles; ++j) { output(led_direction,to1); output(led_direction,to2); output(led_direction,to3); for (uint8_t i = 0; i < 100; ++i) { if (i >= Rpct) { clear(led_direction,to1); } if (i >= Gpct) { clear(led_direction,to2); } if (i >= Bpct) { clear(led_direction,to3); } _delay_us(1); } } input(led_direction,from); input(led_direction,to1); input(led_direction,to2); input(led_direction,to3); } int main(void) { // set clock divider to /1 CLKPR = (1 << CLKPCE); CLKPR = (0 << CLKPS3) | (0 << CLKPS2) | (0 << CLKPS1) | (0 << CLKPS0); set(input_port, input_pin1); set(input_port, input_pin2); set(input_port, input_pin3); input(input_direction, input_pin1); input(input_direction, input_pin2); input(input_direction, input_pin3); const uint8_t lights = 4; uint8_t redA[lights], greenA[lights], blueA[lights]; for (uint8_t i = 0; i < lights-1; ++i) { redA[i] = 0; greenA[i] = 0; blueA[i] = 0; } redA[lights-1] = (rand() % 80); greenA[lights-1] = (rand() % 80); blueA[lights-1] = (rand() % 80); uint8_t red = 0, green = 0, blue = 0; uint8_t switch1 = 0, switch2 = 0, switch3 = 0; uint8_t targ = 0, all = 0, crazy = 0, temp = 0, MODE = 1, countdown = 0; while (1) { if (MODE) { // random color rotation switch1 = !pin_test(input_pins, input_pin1); switch2 = !pin_test(input_pins, input_pin2); switch3 = !pin_test(input_pins, input_pin3); if (switch1 || switch2 || switch3) { MODE = !MODE; countdown = 75; } for (uint8_t i = 0; i < lights-1; ++i) { redA[i] = redA[i+1]; greenA[i] = greenA[i+1]; blueA[i] = blueA[i+1]; } redA[lights-1] += ((rand() % 31) - 5); greenA[lights-1] += ((rand() % 31) - 5); blueA[lights-1] += ((rand() % 31) - 5); redA[lights-1] %= 80; greenA[lights-1] %= 80; blueA[lights-1] %= 80; for (uint8_t rep = 0; rep <= 120; ++rep) { rgbflash(A, B, C, D, redA[3], greenA[3], blueA[3], 1); rgbflash(D, C, B, A, redA[2], greenA[2], blueA[2], 1); rgbflash(B, A, D, C, redA[1], greenA[1], blueA[1], 1); rgbflash(C, D, A, B, redA[0], greenA[0], blueA[0], 1); } } else { // interactive mode switch1 = !pin_test(input_pins, input_pin1); switch2 = !pin_test(input_pins, input_pin2); switch3 = !pin_test(input_pins, input_pin3); if (switch1 || switch2 || switch3) { countdown = 75; } if (switch1 && switch2 && switch3){ crazy = !crazy; } else if (switch1 && switch3) { all = !all; } else if (switch1 && switch2){ targ++; } else if (switch2 && switch3) { red = 0; green = 0; blue = 0; } else if (switch1) { red += 5; } else if (switch2) { green += 5; } else if (switch3) { blue += 5; } red = red % 90; green = green % 90; blue = blue % 90; targ = targ % 4; for (uint8_t rep = 0; rep <= 200; ++rep) { if (all) { rgbflash(A, B, C, D, red, green, blue, 1); if (crazy) {temp = red; red = green; green = blue; blue = temp;} rgbflash(D, C, B, A, red, green, blue, 1); if (crazy) {temp = red; red = green; green = blue; blue = temp;} rgbflash(B, A, D, C, red, green, blue, 1); if (crazy) {temp = red; red = green; green = blue; blue = temp;} rgbflash(C, D, A, B, red, green, blue, 1); } else { switch (targ) { case 0: rgbflash(A, B, C, D, red, green, blue, 1); break; case 1: rgbflash(D, C, B, A, red, green, blue, 1); break; case 2: rgbflash(B, A, D, C, red, green, blue, 1); break; case 3: rgbflash(C, D, A, B, red, green, blue, 1); break; } } } countdown--; if (countdown <= 0) { MODE = !MODE; } } } }