#define __spi_clock 13 // SCK - hardware SPI #define __spi_latch 10 #define __spi_data 11 // MOSI - hardware SPI #define __spi_data_in 12 // MISO - hardware SPI (unused) #define __display_enable 9 #define __rows 8 #define __max_row __rows-1 #define __leds_per_row 8 #define __max_led __leds_per_row-1 #define __brightness_levels 28 // 0...15 above 32 is bad for ISR #define __max_brightness __brightness_levels-1 #define __potentiometer 2 // analog 2 <--> PORTC: pin 2 #define __TIMER1_MAX 0xFFFF // 16 bit CTR #define __TIMER1_CNT 0x0130 // 32 levels --> 0x0130; 38 --> 0x0157 (flicker) #include #include #include byte brightness_red[__leds_per_row][__rows]; byte brightness_green[__leds_per_row][__rows]; byte brightness_blue[__leds_per_row][__rows]; /* images in PROGMEM */ const char frame1[193] PROGMEM = {31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,31,31,31,31,31,31,24,24,24,8,8,8,8,8,8,8,8,8,8,8,8,24,24,24,31,31,31,31,31,31,24,24,24,8,8,8,0,0,0,0,0,0,8,8,8,24,24,24,31,31,31,31,31,31,24,24,24,8,8,8,0,0,0,0,0,0,8,8,8,24,24,24,31,31,31,31,31,31,24,24,24,8,8,8,8,8,8,8,8,8,8,8,8,24,24,24,31,31,31,31,31,31,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31}; const char frame2[193] PROGMEM = {24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,24,24,24,24,24,24,8,8,8,0,0,0,0,0,0,0,0,0,0,0,0,8,8,8,24,24,24,24,24,24,8,8,8,0,0,0,31,0,0,31,0,0,0,0,0,8,8,8,24,24,24,24,24,24,8,8,8,0,0,0,31,0,0,31,0,0,0,0,0,8,8,8,24,24,24,24,24,24,8,8,8,0,0,0,0,0,0,0,0,0,0,0,0,8,8,8,24,24,24,24,24,24,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24}; const char frame3[193] PROGMEM = {8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,8,8,8,8,8,0,0,0,31,0,0,31,0,0,31,0,0,31,0,0,0,0,0,8,8,8,8,8,8,0,0,0,31,0,0,31,31,31,31,31,31,31,0,0,0,0,0,8,8,8,8,8,8,0,0,0,31,0,0,31,31,31,31,31,31,31,0,0,0,0,0,8,8,8,8,8,8,0,0,0,31,0,0,31,0,0,31,0,0,31,0,0,0,0,0,8,8,8,8,8,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8}; const char frame4[193] PROGMEM = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,31,0,0,31,0,0,31,0,0,31,0,0,31,0,0,31,0,0,0,0,0,0,0,0,31,0,0,31,31,31,31,31,31,31,31,31,31,31,31,31,0,0,0,0,0,0,0,0,31,0,0,31,31,31,16,0,0,16,0,0,31,31,31,31,0,0,0,0,0,0,0,0,31,0,0,31,31,31,16,0,0,16,0,0,31,31,31,31,0,0,0,0,0,0,0,0,31,0,0,31,31,31,31,31,31,31,31,31,31,31,31,31,0,0,0,0,0,0,0,0,31,0,0,31,0,0,31,0,0,31,0,0,31,0,0,31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; const char frame5[193] PROGMEM = {31,0,0,31,0,0,31,0,0,31,0,0,31,0,0,31,0,0,31,0,0,31,0,0,31,0,0,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,0,0,31,0,0,31,31,31,16,0,0,16,0,0,16,0,0,16,0,0,31,31,31,31,0,0,31,0,0,31,31,31,16,0,0,0,16,0,0,16,0,16,0,0,31,31,31,31,0,0,31,0,0,31,31,31,16,0,0,0,16,0,0,16,0,16,0,0,31,31,31,31,0,0,31,0,0,31,31,31,16,0,0,16,0,0,16,0,0,16,0,0,31,31,31,31,0,0,31,0,0,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,0,0,31,0,0,31,0,0,31,0,0,31,0,0,31,0,0,31,0,0,31,0,0,31,0,0}; const char frame6[193] PROGMEM = {31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,31,31,31,31,31,31,24,24,24,8,8,8,8,8,8,8,8,8,8,8,8,24,24,24,31,31,31,31,31,31,24,24,24,8,8,8,0,0,0,0,0,0,8,8,8,24,24,24,31,31,31,31,31,31,24,24,24,8,8,8,0,0,0,0,0,0,8,8,8,24,24,24,31,31,31,31,31,31,24,24,24,8,8,8,8,8,8,8,8,8,8,8,8,24,24,24,31,31,31,31,31,31,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31}; const char frame7[193] PROGMEM = {24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,24,24,24,24,24,24,8,8,8,0,0,0,0,0,0,0,0,0,0,0,0,8,8,8,24,24,24,24,24,24,8,8,8,0,0,0,31,0,0,31,0,0,0,0,0,8,8,8,24,24,24,24,24,24,8,8,8,0,0,0,31,0,0,31,0,0,0,0,0,8,8,8,24,24,24,24,24,24,8,8,8,0,0,0,0,0,0,0,0,0,0,0,0,8,8,8,24,24,24,24,24,24,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24}; const char frame8[193] PROGMEM = {8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,8,8,8,8,8,0,0,0,31,0,0,31,0,0,31,0,0,31,0,0,0,0,0,8,8,8,8,8,8,0,0,0,31,0,0,31,31,31,31,31,31,31,0,0,0,0,0,8,8,8,8,8,8,0,0,0,31,0,0,31,31,31,31,31,31,31,0,0,0,0,0,8,8,8,8,8,8,0,0,0,31,0,0,31,0,0,31,0,0,31,0,0,0,0,0,8,8,8,8,8,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8}; const char frame9[193] PROGMEM = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,31,0,0,31,0,0,31,0,0,31,0,0,31,0,0,31,0,0,0,0,0,0,0,0,31,0,0,31,31,31,31,31,31,31,31,31,31,31,31,31,0,0,0,0,0,0,0,0,31,0,0,31,31,31,16,0,0,16,0,0,31,31,31,31,0,0,0,0,0,0,0,0,31,0,0,31,31,31,16,0,0,16,0,0,31,31,31,31,0,0,0,0,0,0,0,0,31,0,0,31,31,31,31,31,31,31,31,31,31,31,31,31,0,0,0,0,0,0,0,0,31,0,0,31,0,0,31,0,0,31,0,0,31,0,0,31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; const char frame10[193] PROGMEM = {31,0,0,31,0,0,31,0,0,31,0,0,31,0,0,31,0,0,31,0,0,31,0,0,31,0,0,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,0,0,31,0,0,31,31,31,16,0,0,16,0,0,16,0,0,16,0,0,31,31,31,31,0,0,31,0,0,31,31,31,16,0,0,0,16,0,0,16,0,16,0,0,31,31,31,31,0,0,31,0,0,31,31,31,16,0,0,0,16,0,0,16,0,16,0,0,31,31,31,31,0,0,31,0,0,31,31,31,16,0,0,16,0,0,16,0,0,16,0,0,31,31,31,31,0,0,31,0,0,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,0,0,31,0,0,31,0,0,31,0,0,31,0,0,31,0,0,31,0,0,31,0,0,31,0,0}; const char * frames[] = {frame1,frame2,frame3,frame4,frame5,frame6,frame7,frame8,frame9,frame10}; void setup(void) { Serial.begin(57600); pinMode(__spi_clock,OUTPUT); pinMode(__spi_latch,OUTPUT); pinMode(__spi_data,OUTPUT); pinMode(__spi_data_in,INPUT); pinMode(__display_enable,OUTPUT); pinMode(__potentiometer,INPUT); digitalWrite(__spi_latch,HIGH); digitalWrite(__spi_data,HIGH); digitalWrite(__spi_clock,HIGH); setup_hardware_spi(); setup_timer1_ovf(); set_matrix_rgb(255,255,255); } void loop(void) { byte image = analogRead(__potentiometer) / 64; if (image > 9) { image = 9; } show_image(image,1); } void show_image(byte image, int img_delay) { byte row; byte led; for ( row = 0; row < 8; row++) { for ( led = 0; led < 8; led++ ) { set_led_red(row,led,pgm_read_byte( &frames[image][row*3*8+led*3+0] )); set_led_green(row,led,pgm_read_byte( &frames[image][row*3*8+led*3+1] )); set_led_blue(row,led,pgm_read_byte( &frames[image][row*3*8+led*3+2] )); } } delay(img_delay); } byte spi_transfer(byte data) { SPDR = data; // Start the transmission while (!(SPSR & (1< __max_row) || (led > __max_led) ) { return; } brightness_red[row][led] = red; } void set_led_green(byte row, byte led, byte green) { if( (row > __max_row) || (led > __max_led) ) { return; } brightness_green[row][led] = green; } void set_led_blue(byte row, byte led, byte blue) { if( (row > __max_row) || (led > __max_led) ) { return; } brightness_blue[row][led] = blue; } void set_led_rgb(byte row, byte led, byte red, byte green, byte blue) { set_led_red(row,led,red); set_led_green(row,led,green); set_led_blue(row,led,blue); } void set_matrix_rgb(byte red, byte green, byte blue) { byte ctr1; byte ctr2; for(ctr2 = 0; ctr2 <= __max_row; ctr2++) { for(ctr1 = 0; ctr1 <= __max_led; ctr1++) { set_led_rgb(ctr2,ctr1,red,green,blue); } } } void setup_hardware_spi(void) { byte clr; // spi prescaler: // SPI2X SPR1 SPR0 // 0 0 0 fosc/4 // 0 0 1 fosc/16 // 0 1 0 fosc/64 // 0 1 1 fosc/128 // 1 0 0 fosc/2 // 1 0 1 fosc/8 // 1 1 0 fosc/32 // 1 1 1 fosc/64 SPCR |= ( (1<