#include /* for cheap Chinese 64 dots LED-Projector Board has unmarked chip in socket - pin layout fits to ATTiny 2313 an 4313 the LEDS are connected to 8 pcs 74HC595 --u-- RST 1 20 VCC NC (0) 2 19 (16) IN SCK NC (1) 3 18 (15) IN MISO XTAL 4 17 (14) IN MOSI XTAL 5 16 (13) IN OUT (4) 6 15 (12) IN OUT (5) 7 14 (11) IN OUT (6) 8 13 (10) IN NC (7) 9 12 (9) MIC GND 10 11 (8) IN ----- () = Arduino Pins RST = Reset - 10K to GND, 10uF to VCC XTAL = 16 MHz Crystal IN = switches MIC = Input from microphone amplifier (LM358) */ /* x XXXXXXX XX XXX XX XXXXXXXXXXX X XXXXXXX X X X X X XX XX */ #define LATCHPIN 5 #define DATAPIN 4 #define CLOCKPIN 6 byte ledsData[8]; byte currentled = 0; // low level functions void clear() { for (int i=0; i < 8; i++) { // low is led on ledsData[i] = 255; } } void writebuffer(byte ledNr) { byte chipNr = ledNr / 8; byte pinNr = ledNr % 8; if(chipNr < 8) { bitWrite(ledsData[chipNr], pinNr, LOW); } } void writexy(byte x, byte y) { byte lednr = x*8 + y; writebuffer(lednr); } byte rowmask[8] = {5,3,1,0,2,4,6,7}; void pushout() { digitalWrite(LATCHPIN, LOW); for(int i = 8-1; i>=0; i--) { byte row = rowmask[i]; shiftOut(DATAPIN, CLOCKPIN, MSBFIRST, ledsData[row]); } digitalWrite(LATCHPIN, HIGH); } // space invader //byte invaderA0[11] = {112,24,125,182,188,60,188,182,125,24,112}; //byte invaderA1[11] = {14,24,189,118,60,60,60,118,189,24,14}; static byte invaderA0[8] = {152,92,182,95,95,182,92,152}; static byte invaderA1[8] = {88,188,22,63,63,22,188,88}; bool invaderread(int x, int y, bool invaderstate) { if (invaderstate) { return bitRead(invaderA0[x],y); } else { return bitRead(invaderA1[x],y); } } void drawinvader(int xposition, int yposition, bool invaderstate) { for (int x=0; x<8; x++) { int screenx = x+xposition; if (screenx >=0 && screenx < 8) { for (int y=0; y<8; y++) { int screeny = y+yposition; if (screeny >=0 && screeny < 8) { if ( invaderread(x,y,invaderstate) ) { writexy(screenx,screeny); } } } } } } byte currentcol=1; bool direction = true; int invaderstart = -12; int invaderend = 8; int invaderposition = invaderstart; bool invaderstate = true; int statecount = 0; // Game of life byte gol_last[8]; byte gol_next[8]; byte gol_last2[8]; byte gol_last3[8]; byte gol_last4[8]; long gol_stepcount; int gol_deadcount = 0; void gol_setup() { gol_deadcount = 0; for (int x=0; x<8; x++) { gol_last[x] = 0; for (int y=0; y<8; y++) { if (random(4)<1) { bitWrite(gol_last[x], y, HIGH); } } } } static byte gol_glider[8] = {4,5,6,0,0,0,0,0}; void gol_setup_glider() { gol_deadcount = 0; for (int i=0; i<8; i++) { gol_last[i] = gol_glider[i]; } } static byte gol_spaceship[8] = {12,28,26,14,4,0,0,0}; void gol_setup_spaceship() { gol_deadcount = 0; for (int i=0; i<8; i++) { gol_last[i] = gol_spaceship[i]; } } void setup() { pinMode(LATCHPIN, OUTPUT); pinMode(DATAPIN, OUTPUT); pinMode(CLOCKPIN, OUTPUT); gol_setup(); clear(); pushout(); } void gol_clearnext() { for (int i=0; i<8; i++) { gol_next[i] = 0; } } bool gol_getstate(int x, int y) { // warp around if (x<0) { x=7; } if (x>7) { x=0; } if (y<0) { y=7; } if (y>7) { y=0; } return bitRead(gol_last[x],y); } byte gol_countNeighbours(int x, int y) { byte count = 0; for (int xoff=-1; xoff <= 1; xoff++) { for (int yoff=-1; yoff <= 1; yoff++) { if ( !(xoff==0 && yoff==0) ) { if (gol_getstate(x+xoff, y+yoff) ) { count++; } } } } return count; } void gol_setnext(int x, int y) { bitWrite( gol_next[x], y, HIGH); } void gol_writeLEDS() { for(int x=0; x<8; x++) { for (int y=0; y<8; y++) { if (bitRead(gol_next[x],y)) { writexy(x, y); } } } } int gol_pixelcount; int gol_diffrences; int gol_diffrences2; int gol_diffrences3; int gol_diffrences4; void gol_step() { gol_clearnext(); gol_pixelcount = 0; for (int x=0; x<8; x++) { for (int y=0; y<8; y++) { bool myself = gol_getstate(x,y); byte neighbours = gol_countNeighbours(x,y); if ( neighbours==3) { gol_setnext(x,y); gol_pixelcount++; } if ( neighbours==2 && myself) { gol_setnext(x,y); gol_pixelcount++; } } } gol_writeLEDS(); pushout(); gol_diffrences = 0; gol_diffrences2 = 0; gol_diffrences3 = 0; gol_diffrences4 = 0; for (int i=0; i<8; i++) { if (gol_last4[i] != gol_next[i]) { gol_diffrences4++; } gol_last4[i] = gol_last3[i]; if (gol_last3[i] != gol_next[i]) { gol_diffrences3++; } gol_last3[i] = gol_last2[i]; if (gol_last2[i] != gol_next[i]) { gol_diffrences2++; } gol_last2[i] = gol_last[i]; if (gol_last[i] != gol_next[i]) { gol_diffrences++; } gol_last[i] = gol_next[i]; } if (gol_diffrences == 0 || gol_diffrences2==0 || gol_diffrences3 == 0 || gol_diffrences4 == 0 || gol_pixelcount == 0) { //went static gol_deadcount++; } gol_stepcount++; delay(200); } // main loop int mode = 0; #define NRMODES 3 void switchmode( ){ mode = random(NRMODES); switch(mode) { case 0: //game of life gol_stepcount = 0; gol_setup(); break; case 1: // gol glider; gol_stepcount = 0; gol_setup_glider(); break; case 2: // gol spaceship gol_stepcount = 0; gol_setup_spaceship(); break; } } void loop() { clear(); // check for end switch(mode) { case 0: // game of life case 1: case 2: if (gol_stepcount >100) { switchmode(); } if (gol_deadcount > 12) { switchmode(); } break; } switch(mode) { case 0: // game of life case 1: case 2: gol_step(); break; } /* // x-line for(byte i=0; i<8; i++) { writexy(i,currentcol-1); } // y line for(byte i=0; i<8; i++) { writexy(currentcol-1,i); } */ /* invaders drawinvader(0,0, invaderstate); pushout(); invaderstate = !invaderstate; statecount++; if (statecount >=4) { invaderposition++; if (invaderposition >=invaderend) { invaderposition = invaderstart; } statecount = 0; } invaders end */ /* if(direction) { currentcol++; } else { currentcol--; } if (currentcol >8) { currentcol = 7; direction = false; } if (currentcol <=0) { currentcol=2; direction = true; } */ }