Introduction: LED Matrix - Game of Life
This project will execute Conway's game of life on a 8x8 LED matrix.
It has 2 buttons, one for setting up a random field, the other to start or stop the iterations.
Step 1: Materials
- An 8x8 LED matrix
- 2x aprox. 1kOhm resistances
- 2x buttons
- cables
- Arduino Mega 2560 (or similar)
- Breadboard might be helpfull
Step 2: Connecting
Step 3: Code
//8x8 LED matrix row and column PINs
const int ROWS[8] = {52, 42, 53, 46, 39, 51, 41, 47};
const int COLUMNS[8] = {44, 43, 45, 50, 49, 48, 40, 38};//button PINs const int RANDOMIZE_BUTTON = 8; const int START_BUTTON = 9;
//gloabal variables
bool started = false;
bool field[8][8] = {};
bool nextField[8][8] = {};
unsigned long lastMillis = 0;void setup() {
// setup all PINs
for (int i = 0; i < 8; i++)
{
pinMode(ROWS[i], OUTPUT);
pinMode(COLUMNS[i], OUTPUT);
}
pinMode(RANDOMIZE_BUTTON, INPUT);
pinMode(START_BUTTON, INPUT);
}void loop() {
//read button states
int randomizeButton = digitalRead(RANDOMIZE_BUTTON);
int startButton = digitalRead(START_BUTTON);
if (randomizeButton) {// stops and sets a random field
started = false;
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
field[i][j] = random(2);
}
}
delay(200);
} else if (startButton) {// starts or stops the iterations
started = !started;
delay(200);
} else if (started) {
//calculate next field
if (millis() - 1000 > lastMillis) { //delay each iteration by 1000 milliseconds
fillNextField();
for (int y = 0; y < 8; y++) {
for (int x = 0; x < 8; x++) {
field[y][x] = nextField[y][x];
}
}
lastMillis = millis();
}
}
//refresh the 8x8 LED matrix
refreshScreen();
}//calculates the state of the next iteration
void fillNextField() {
for (int y = 0; y < 8; y++) {
for (int x = 0; x < 8; x++) {
nextField[y][x] = getCellsNextState(x, y);
}
}
}//returns the cell's next state, true if alive, false otherwise
bool getCellsNextState(int x, int y) {
bool shouldBeAlive = false;
shouldBeAlive |= (!field[y][x] && countAliveNeighbours(x, y) == 3);
shouldBeAlive |= (field[y][x] && countAliveNeighbours(x, y) == 3);
shouldBeAlive |= (field[y][x] && countAliveNeighbours(x, y) == 2);
return shouldBeAlive;
}// counts the alive neighbours this step
int countAliveNeighbours(int x, int y) {
int retVal = 0;
for (int row = y - 1; row <= y + 1; row++) {
for (int col = x - 1; col <= x + 1; col++) {
if ((row == y && col == x) || (row < 0) || (row > 7) || (col < 0) || (col > 7)) continue;
if (field[row][col]) retVal++;
}
}
return retVal;
}//refreshes the 8x8 LED matrix
void refreshScreen() {
// iterate over the rows (anodes):
for (int row = 0; row < 8; row++) {
// take the row pin (anode) high:
digitalWrite(ROWS[row], HIGH);
// iterate over the cols (cathodes):
for (int col = 0; col < 8; col++) {
// get the state of the current pixel;
int thisPixel = field[row][col];
// when the row is HIGH and the col is LOW,
// the LED where they meet turns on:
digitalWrite(COLUMNS[col], thisPixel ? LOW : HIGH);
// turn the pixel off:
if (thisPixel) {
digitalWrite(COLUMNS[col], HIGH);
}
}
// take the row pin low to turn off the whole row:
digitalWrite(ROWS[row], LOW);
}
}


