Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- Conway's Life, with respawner (cell dead for 200 cycles becomes live, you can set that with the respawnage value)
- for 16x16 max7219 matrix (four 8x8s , 2 by 2 side by side
- No extra libraries required, uses shiftout and simple routines. I don't know where I got the 7219 code from, but it is basic shift register code.
- by Gary Tait
- */
- #define shift_STB 12 // 7219 CS
- #define shift_CLK 11 // 7219 CLK
- #define shift_DO 10 // 7219 DI
- // grid size
- #define gridYmax 16
- #define gridXmax 16
- #define maxiterations 300
- int respawnage=200;
- // set up arrays
- bool screenA[gridYmax][gridXmax];
- bool screenB[gridYmax][gridXmax];
- int death[gridYmax][gridXmax];
- // send same data to all chips.
- void shift(byte send_to_address, byte send_this_data)
- {
- digitalWrite(shift_STB, LOW);
- for (byte b=0;b<4;b++){
- shiftOut(shift_DO, shift_CLK, MSBFIRST, send_to_address);
- shiftOut(shift_DO, shift_CLK, MSBFIRST, send_this_data);
- }
- digitalWrite(shift_STB, HIGH);
- }
- // send individual data to chips
- void shift_data(byte send_to_address, byte a, byte b, byte c, byte d) {
- byte data[4];
- data[0]=a;// sent first, last chip in chain, leftmost display with input connector right
- data[1]=b;
- data[2]=c;
- data[3]=d;
- digitalWrite(shift_STB, LOW);
- for (b=0;b<4;b++){
- shiftOut(shift_DO, shift_CLK, MSBFIRST, send_to_address);
- shiftOut(shift_DO, shift_CLK, MSBFIRST, data[b]);
- }
- digitalWrite(shift_STB, HIGH);
- }
- void setup() {
- // Serial.begin (9600);
- randomSeed(analogRead(0));
- max7219setup();
- clear();
- randomfill();
- }
- void loop() {// open void loop
- // for (byte it=0;it<maxiterations;it++){
- iterateLife();
- screenout();
- //delay(map(analogRead(1),0,1023,50,200));// pot connected to analog 1
- delay(100);// no pot, fixed speed
- // } // iterations loop deleted because of respawnage feature
- } // close void loop
- /// MAX 7219 initialisation and test
- void max7219setup(){
- // set output pins
- pinMode(shift_DO, OUTPUT);
- pinMode(shift_STB, OUTPUT);
- pinMode(shift_CLK, OUTPUT);
- digitalWrite(shift_CLK, HIGH);
- digitalWrite(shift_STB, HIGH);
- delay(10);
- //Setup of MAX7219 chip
- shift(0x0f, 0x00); //display test register - test mode off
- shift(0x0c, 0x01); //shutdown register - normal operation
- shift(0x0b, 0x07); //scan limit register - display digits 0 thru 7
- shift(0x0a, 0x03); //intensity register - max brightness
- shift(0x09, 0x00); //decode mode register - CodeB decode to BCD digits, set registers to 1, 0 for direct LED control.
- }
- void clear(){
- // clear display
- for (byte row = 0; row <8; row++) {
- shift (row+1,0);
- }
- } // close 7219 clear.
- //output screenA to display
- void screenout(){
- for (int k=0;k<8;k++) {
- byte outbyte3=0;
- byte outbyte2=0;
- byte outbyte1=0;
- byte outbyte0=0;
- for (byte m=0;m<8;m++){
- outbyte0 = outbyte0 | (screenA[k][m]<<(7-m)); // upper left display
- outbyte1 = outbyte1 | (screenA[k][m+8]<<(7-m));// upper right
- outbyte2 = outbyte2 | (screenA[k+8][m]<<(7-m));// lower left
- outbyte3 = outbyte3 | (screenA[k+8][m+8]<<(7-m));//lower right display
- }//close m
- shift_data(k+1,outbyte2,outbyte3,outbyte0,outbyte1 );
- // shift_data(k+1,255,outbyte3,outbyte0,255);
- }//close k
- } //close dispout
- // copy screenB to screenA
- void copyBA(){
- for (int k=0;k<gridYmax;k++) {
- for (int m=0;m<gridXmax;m++){
- screenA[k][m] = screenB[k][m];
- }//close m
- }//close k
- } //close copy
- // erase screenB
- void eraseB(){
- for (int k=0;k<gridYmax;k++) {
- for (int m=0;m<gridXmax;m++){
- screenB[k][m] = 0;
- }//close m
- }//close k
- } //close erase
- void iterateLife(){
- // eraseB();
- for (int k=0;k<gridYmax;k++) {
- for (int m=0;m<gridXmax;m++){
- screenB[k][m]=islife(countN(k,m),screenA[k][m]);
- if (screenA[k][m]==0){
- death[k][m]++;// increment death counter if cell is dead.
- }
- if (death[k][m]>respawnage){
- screenB[k][m]=1;
- }
- if (screenB[k][m]==1){
- death[k][m]=0;// zero death counter if life
- }
- }//close m
- }//close k
- copyBA();
- } //close iterate
- //count neighbours
- byte countN(int y, int x){
- byte nCount=0;
- for (int ty=-1;ty<2;ty++){
- for (int tx=-1;tx<2;tx++){
- int testy=(y+ty+gridYmax)%gridYmax;// wrap around if neccesary
- int testx=(x+tx+gridXmax)%gridXmax;
- nCount+=screenA[testy][testx];
- }//close for tx
- }//close for ty
- nCount-=screenA[y][x]; //deduct yourself if alive, we are counting only neigbors here.
- return nCount;
- }// close routine
- // determine if a cell should be alive (1) or dead (0)
- byte islife(byte ncount,byte isalive){
- bool life=0;// declare variable. Default is dead unless told otherwise.
- //sustain
- if ((isalive==1)&&((ncount==2)||(ncount==3))){
- life=1;
- }
- //birth 3 neigbors
- if ((isalive==0)&&(ncount==3)){
- life=1;
- }
- //birth 6 neigbors
- if ((isalive==0)&&(ncount>7)){
- life=0;
- }
- return life;
- }
- // randomly fill array
- void randomfill(){
- int rnv=random(50,75);// okay to play with these value to get sparse/dense initial population
- for (int k=0;k<gridYmax;k++) {
- for (int m=0;m<gridXmax;m++){
- int rn=random(0,150);
- if (rn<rnv)
- {screenA[k][m] = 1;}
- else
- {screenA[k][m] = 0;}
- screenout();// watch the screen get populated with life
- delay(30);
- }//close m
- }//close k
- } //close copy
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement