Advertisement
classicsat

7219 Life

Feb 3rd, 2021 (edited)
900
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.61 KB | None | 0 0
  1. /*
  2.  
  3. Conway's Life, with respawner (cell dead for 200 cycles becomes live, you can set that with the respawnage value)
  4.  
  5. for 16x16 max7219 matrix (four 8x8s , 2 by 2 side by side
  6.  
  7. 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.
  8.  
  9. by Gary Tait
  10. */
  11.  
  12. #define shift_STB 12 // 7219 CS
  13. #define shift_CLK 11 // 7219 CLK
  14. #define shift_DO 10 // 7219 DI
  15.  
  16. // grid size
  17. #define gridYmax 16
  18. #define gridXmax 16
  19. #define maxiterations 300
  20. int respawnage=200;
  21. // set up arrays
  22. bool screenA[gridYmax][gridXmax];
  23. bool screenB[gridYmax][gridXmax];
  24. int death[gridYmax][gridXmax];
  25.  
  26. // send same data to all chips.
  27. void shift(byte send_to_address, byte send_this_data)
  28. {
  29. digitalWrite(shift_STB, LOW);
  30. for (byte b=0;b<4;b++){
  31. shiftOut(shift_DO, shift_CLK, MSBFIRST, send_to_address);
  32. shiftOut(shift_DO, shift_CLK, MSBFIRST, send_this_data);
  33. }
  34.  
  35. digitalWrite(shift_STB, HIGH);
  36. }
  37.  
  38. // send individual data to chips
  39. void shift_data(byte send_to_address, byte a, byte b, byte c, byte d) {
  40.  
  41. byte data[4];
  42. data[0]=a;// sent first, last chip in chain, leftmost display with input connector right
  43. data[1]=b;
  44. data[2]=c;
  45. data[3]=d;
  46.  
  47. digitalWrite(shift_STB, LOW);
  48.  
  49. for (b=0;b<4;b++){
  50. shiftOut(shift_DO, shift_CLK, MSBFIRST, send_to_address);
  51. shiftOut(shift_DO, shift_CLK, MSBFIRST, data[b]);
  52. }
  53.  
  54. digitalWrite(shift_STB, HIGH);
  55. }
  56.  
  57. void setup() {
  58.  
  59. // Serial.begin (9600);
  60. randomSeed(analogRead(0));
  61. max7219setup();
  62. clear();
  63. randomfill();
  64. }
  65.  
  66. void loop() {// open void loop
  67.  
  68. // for (byte it=0;it<maxiterations;it++){
  69. iterateLife();
  70. screenout();
  71. //delay(map(analogRead(1),0,1023,50,200));// pot connected to analog 1
  72. delay(100);// no pot, fixed speed
  73. // } // iterations loop deleted because of respawnage feature
  74.  
  75. } // close void loop
  76.  
  77. /// MAX 7219 initialisation and test
  78. void max7219setup(){
  79.  
  80. // set output pins
  81. pinMode(shift_DO, OUTPUT);
  82. pinMode(shift_STB, OUTPUT);
  83. pinMode(shift_CLK, OUTPUT);
  84. digitalWrite(shift_CLK, HIGH);
  85. digitalWrite(shift_STB, HIGH);
  86. delay(10);
  87.  
  88. //Setup of MAX7219 chip
  89. shift(0x0f, 0x00); //display test register - test mode off
  90. shift(0x0c, 0x01); //shutdown register - normal operation
  91. shift(0x0b, 0x07); //scan limit register - display digits 0 thru 7
  92. shift(0x0a, 0x03); //intensity register - max brightness
  93. shift(0x09, 0x00); //decode mode register - CodeB decode to BCD digits, set registers to 1, 0 for direct LED control.
  94. }
  95.  
  96. void clear(){
  97. // clear display
  98.  
  99. for (byte row = 0; row <8; row++) {
  100.  
  101. shift (row+1,0);
  102. }
  103.  
  104. } // close 7219 clear.
  105.  
  106. //output screenA to display
  107. void screenout(){
  108.  
  109. for (int k=0;k<8;k++) {
  110. byte outbyte3=0;
  111. byte outbyte2=0;
  112. byte outbyte1=0;
  113. byte outbyte0=0;
  114. for (byte m=0;m<8;m++){
  115. outbyte0 = outbyte0 | (screenA[k][m]<<(7-m)); // upper left display
  116. outbyte1 = outbyte1 | (screenA[k][m+8]<<(7-m));// upper right
  117. outbyte2 = outbyte2 | (screenA[k+8][m]<<(7-m));// lower left
  118. outbyte3 = outbyte3 | (screenA[k+8][m+8]<<(7-m));//lower right display
  119. }//close m
  120. shift_data(k+1,outbyte2,outbyte3,outbyte0,outbyte1 );
  121. // shift_data(k+1,255,outbyte3,outbyte0,255);
  122. }//close k
  123. } //close dispout
  124.  
  125. // copy screenB to screenA
  126. void copyBA(){
  127. for (int k=0;k<gridYmax;k++) {
  128. for (int m=0;m<gridXmax;m++){
  129. screenA[k][m] = screenB[k][m];
  130. }//close m
  131. }//close k
  132. } //close copy
  133.  
  134. // erase screenB
  135. void eraseB(){
  136. for (int k=0;k<gridYmax;k++) {
  137. for (int m=0;m<gridXmax;m++){
  138. screenB[k][m] = 0;
  139. }//close m
  140. }//close k
  141. } //close erase
  142.  
  143. void iterateLife(){
  144. // eraseB();
  145. for (int k=0;k<gridYmax;k++) {
  146. for (int m=0;m<gridXmax;m++){
  147. screenB[k][m]=islife(countN(k,m),screenA[k][m]);
  148. if (screenA[k][m]==0){
  149. death[k][m]++;// increment death counter if cell is dead.
  150. }
  151.  
  152. if (death[k][m]>respawnage){
  153. screenB[k][m]=1;
  154. }
  155.  
  156. if (screenB[k][m]==1){
  157. death[k][m]=0;// zero death counter if life
  158. }
  159.  
  160. }//close m
  161. }//close k
  162. copyBA();
  163. } //close iterate
  164.  
  165. //count neighbours
  166. byte countN(int y, int x){
  167. byte nCount=0;
  168.  
  169.  
  170. for (int ty=-1;ty<2;ty++){
  171. for (int tx=-1;tx<2;tx++){
  172. int testy=(y+ty+gridYmax)%gridYmax;// wrap around if neccesary
  173. int testx=(x+tx+gridXmax)%gridXmax;
  174.  
  175. nCount+=screenA[testy][testx];
  176.  
  177. }//close for tx
  178. }//close for ty
  179.  
  180. nCount-=screenA[y][x]; //deduct yourself if alive, we are counting only neigbors here.
  181.  
  182. return nCount;
  183.  
  184. }// close routine
  185.  
  186.  
  187. // determine if a cell should be alive (1) or dead (0)
  188. byte islife(byte ncount,byte isalive){
  189.  
  190. bool life=0;// declare variable. Default is dead unless told otherwise.
  191.  
  192. //sustain
  193. if ((isalive==1)&&((ncount==2)||(ncount==3))){
  194. life=1;
  195. }
  196.  
  197. //birth 3 neigbors
  198. if ((isalive==0)&&(ncount==3)){
  199. life=1;
  200. }
  201.  
  202. //birth 6 neigbors
  203. if ((isalive==0)&&(ncount>7)){
  204. life=0;
  205. }
  206. return life;
  207. }
  208.  
  209. // randomly fill array
  210. void randomfill(){
  211. int rnv=random(50,75);// okay to play with these value to get sparse/dense initial population
  212. for (int k=0;k<gridYmax;k++) {
  213. for (int m=0;m<gridXmax;m++){
  214. int rn=random(0,150);
  215. if (rn<rnv)
  216. {screenA[k][m] = 1;}
  217. else
  218. {screenA[k][m] = 0;}
  219. screenout();// watch the screen get populated with life
  220. delay(30);
  221. }//close m
  222. }//close k
  223. } //close copy
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement