270h Final Project
Contents
Proposal
Overview
The Goal: An Arduino only project that mimics the game of life on an 8x8 LED matrix. The project would also have a light sensor and an LED. If there is enough light received by the light sensor, the game would continue and the LED would turn on. Otherwise, the game would pause and the LED would be off.
The Game of Life is very simple and only has four rules:
- Any live cell with fewer than two live neighbours dies, as if caused by underpopulation.
- Any live cell with two or three live neighbours lives on to the next generation.
- Any live cell with more than three live neighbours dies, as if by overpopulation.
- Any dead cell with exactly three live neighbours becomes a live cell, as if by reproduction.
Plan of Attack
- Getting familiar with 8x8 LED matrix
- Program the 8x8 LED matrix to display my name
- Program the 8x8 LED matrix to mimic game of life
- Connect the LED, light sensor and the 8x8 LED matrix
- Finish and compile the code
- Testing
The Project
Materials
- Arduino
- MAX7219 64-LED matrix display
- Photoresistor
- Green LED
- Wires
Schematics
Arduino Code
Part 1
/*
Display my name on 64-LED Matrix
Chujun He
The Matrix displays "C-H-U-J-U-N-❤" repeatedly
*/
#include <LedControl.h>
int DIN = 8;
int CS = 9;
int CLK = 10;
// Define the letters
byte C[8] = {B01111110,B01000000,B01000000,B01000000,B01000000,B01000000,B01000000,B01111110, };
byte H[8] = {B01000010,B01000010,B01000010,B01111110,B01000010,B01000010,B01000010,B01000010, };
byte U[8] = {B01000010,B01000010,B01000010,B01000010,B01000010,B01000010,B01000010,B01111110, };
byte J[8] = {B01111110,B00001000,B00001000,B00001000,B00001000,B00001000,B00001000,B01111000, };
byte N[8] = {B10000001,B11000001,B10100001,B10010001,B10001001,B10000101,B10000011,B10000001, };
byte HEART[8] = {0x00,0x66,0xff,0xff,0x7e,0x3c,0x18,0x00, };
LedControl lc = LedControl(DIN, CLK, CS, 0);
void setup() {
lc.shutdown(0, false);
lc.setIntensity(0,15); // Set the brightness to maximum value
lc.clearDisplay(0); // and clear the display
}
void loop() {
printByte(C);
delay(1000);
printByte(H);
delay(1000);
printByte(U);
delay(1000);
printByte(J);
delay(1000);
printByte(U);
delay(1000);
printByte(N);
delay(1000);
printByte(HEART);
delay(1000);
}
// function that turn on the matrix as designated
void printByte(byte character [] ){
int i = 0;
for(i = 0; i < 8; i++){
lc.setRow(0,i,character[i]);
}
}
Part 4
/*
* CSC270 Final Project
* Chujun He
*
* Mimic Conway's Game of Life on 64 LED matrix. The game would continue when the light sensor receives enough light and the LED would be on.
* Otherwise, the game would pause and the LED would be off.
*/
#include <LedControl.h>
int DIN = 8; // Digintal input
int CS = 9; // Chip select
int CLK = 10; // Clock signal
int lightSensor = A0; // photoresistor
int LED = 13;
LedControl lc = LedControl(DIN, CLK, CS, 0);
void setup() {
// 64 LED matrix
lc.shutdown(0, false);
lc.setIntensity(0,8); // Set the brightness to maximum value
lc.clearDisplay(0); // and clear the display
// Set up LED
pinMode(LED, OUTPUT);
// enable serial monitor for debugging
Serial.begin(9600);
}
void loop(){
// get the lightsensor data
int val = analogRead(lightSensor);
// define the game of life data
bool cgrid[8][8], ngrid[8][8]; // define current grid and next grid
int neighbors = 0;
bool gameover = false; // breaks the game loop
randomSeed(millis()); //random seed
// initialize the game grid with random cells
for (int i = 0; i < 7; i ++){
for(int j = 0; j <7; j ++){
if(random(5) > 3){
cgrid[i][j] = true;
}else{
cgrid[i][j] = false;
}
ngrid[i][j] = false; // Initialize next grid to be dead.
}
}
Serial.println("new game");
// when the game should begin/continue
while(gameover == false){
int val = analogRead(lightSensor);
Serial.println(val);
gameover = true; // initialize it to be true and change accordingly
// display the current grids
displayGeneration(cgrid);
delay(2000); // delay for a second
// If there is enough light, the game continues to next generation
if(val >= 100){
digitalWrite(LED, HIGH);
for(int i = 0; i<8; i ++){
for(int j = 0; j<8; j ++){
neighbors = countNeighbors(cgrid, i, j);
//If a cell is alive, the game continues
if(cgrid[i][j] == true){
gameover = false;
// if the cell has less than 2 neighbors, it dies in the next generation
if(neighbors < 2){
ngrid[i][j] = false;
}else if(neighbors == 3){ // 3 neighbors make the cell remain alive
ngrid[i][j] = true;
}else if(neighbors > 3){ // die due to overpopulation
ngrid[i][j] = false;
}
}else{ //if the cell is currently dead, apply dead cell rules.
if(neighbors == 3){
ngrid[i][j] = true; //become alive by reproduction
}
}
}
}
// next generation becomes current generation if not in stable states
if(memcmp(cgrid, ngrid, sizeof(cgrid)) == 0){ // If in stable or repetitive state, restart.
gameover = true;
}else{
memcpy(cgrid, ngrid, sizeof(cgrid)); //Current grid becomes next grid.
}
}else{ // If there is not enough light, remain on the current generation
gameover = false;
digitalWrite(LED, LOW);
}
}
}
// Display generation on the 64 LED matrix
void displayGeneration(bool ba[8][8]){
for (int i = 0; i < 8; i++){
lc.setRow(0, i, (byte) (ba[i][0] | ba[i][1] << 1 | ba[i][2] << 2 | ba[i][3] << 3 | ba[i][4] << 4 | ba[i][5] << 5 | ba[i][6] << 6 | ba[i][7] << 7));
}
}
// count number of neighbors for the cell
int countNeighbors(bool grid[8][8], int i, int j){
int neighbors = 0;
for (int x = -1; x < 2; x++){ //Continue statements detect and skip off-field cells
if ((i + x < 0) | (i + x > 7)) continue;
for (int y = -1; y < 2; y++){
if ((j + y < 0) | (j + y > 7)) continue;
if ((x == 0) && (y == 0)) continue;
if (grid[i + x][j + y] == true) neighbors++;
}
}
return neighbors;
}
Languages & Libraries
- Libraries: LedControl
Final Project Demo
Progress Log
2020-04-22 Update:
Objective: Display my name on the 64-LED matrix dislay.
I programmed the 64-LED matrix display to show my name: C-H-U-J-U-N.
2020-04-23 Update:
Objective: Display game of life on the 64-LED matrix display.
I programmed the 64-LED matrix display the game of life.
2020-04-24 Update:
Objective: Add button switch and LED to the project.
I added the sound sensor to the project so that only when the sound sensors receives the sound higher than a certain level, the game would continue. Otherwise, the game would pause. After experiments, I found that the sound sensor is not very stable and can't remain HIGH or LOW for a certain time since it's more sensitive to clip and things like that. Thus, I decided to use switch to control the game of life instead.
2020-04-28 Update:
Objective: Replace switch with light sensor.
Instead of using switch to control the circuit, I would use the light sensor. The game of life would continue only if the light sensor receives a certain amount of light. Otherwise, the game of life would pause and the green LED would be off.
References
LED Hex/ Binary Pattern Generator For Arduino
- An online led matrix font generator with binary and hex codes for Arduino.
- A tutorial for programming 64 LED matrix on Arduino.
- A tutorial for programming game of life on 64 LED matrix.
How to Use a Photoresistor (or Photocell) - Arduino Tutorial
- A tutorial for using a photoresistor.