Final Product

In my free time I have been playing around with a new Arduino Parts kit I ordered online. I wanted to create a quick project to learn the ins and outs of using and 8×8 LED matrix with my Arduino Uno. The project is relatively straight forward but I learned a lot about working with LEDs.

I decided to model the cellular simulation called Conway’s Game of Life. Conway’s Game of Life simulates bacterial cells through an array of cells. There are simply three rules to Conway’s Game of Life.

If a cell has fewer than two neighbors it will die. If a cell has exactly three neighbors a new cell will be born. If a cell has more than three neighbors it will die.

While these rules may be simple they can produce startling results. Extremely complex patterns can arise as seen in the video below.

To begin with, I used

8x 220 Ohm Resistors

16x Jumper Cables

1x 8*8 LED Matrix Model Number: HL-M1588BR

1x Arduino Uno

2x Breadboard

The most crucial aspect of this project is understanding how to actually wire the 8*8 LED matrix. From the info sheet, you can find the circuit diagrams that tell you which pins align with each row or column.

What makes wiring the LEDs so difficult is that the pin numbers and the row and column number do not correspond. From the diagram, you can see that column one is tied not to the first pin, but the thirteenth. The best solution I found for this is to create a table. Don’t get too wrapped up in trying to make sense in the strange order of the wiring as it will be resolved in the code.

Pin Number on LED Matrix Row or Column Number 1 Row 5 2 Row 7 3 Column 2 4 Column 3 5 Row 8 6 Column 5 7 Row 6 8 Row 3 9 Row 1 10 Column 4 11 Column 6 12 Row 4 13 Column 1 14 Row 2 15 Column 7 16 Column 8

Once you understand how the wiring works on the 8×8 LED Matrix, the next step to actually place it on to the breadboards and hook it up. I matched the pin numbers on the matrix with the digital pins on the Arduino Uno Board. Because digital pins 0 & 1 are reserved for serial communication on the Arduino you must start with digital pin 2 on the board. Additionally, you will have to use analog pins 2-5 on the Arduino to connect all 16 wires to the matrix. In the code, you can use analog pins 2-5 as digital pins if you refer to them as pins 16-19.

Wiring the matrix to the Arduino.

To ensure the LED Matrix survives many cycles it is best to connect 8 220 ohm resistors between the breadboard and the Arduino.

Once everything is hooked up, it’s time to dive into the code. My code was heavily based on the Java Conway Game of Life code found here. I essentially rewrote the code to be Arduino compatible and to update the LEDs instead of printing out a virtual simulation. My full code will be available below, but I will walk you through the main features.

The Setup Method & Loop



const int rows[8] = {19, 12, 9, 16, 2, 8, 3, 6};

const int cols[8] = {13, 4, 5, 18, 7, 17, 11, 10};

const int BUTTON = 1;

const int numPatterns = 10;

int pixels[8][8];

int x = 0;

int y = 0;

int lifeMap[8][8];

void setup() {

randomSeed(analogRead(0));

// put your setup code here, to run once:

for(int thisPin = 0; thisPin < 8; thisPin++){

pinMode(rows[thisPin], OUTPUT);

pinMode(cols[thisPin], OUTPUT);

digitalWrite(cols[thisPin], HIGH);

digitalWrite(cols[thisPin], LOW);

}

pinMode(BUTTON, INPUT);

Serial.begin(9600);

randomLifeStart();

}

void loop() {

//Serial.println(analogRead(BUTTON));

refreshLife();

refreshPixelArray();

displayPixelArray();

// Serial.println(1);

}

The setup is pretty straightforward. First, it sets a random “seed” to be used later. It then registers each LED used as an output and begins serial communication for debugging. The very last line, “randomLifeStart()” randomly populates the Life Map with living cells. The Life Map is simply a 2D array that stores the status (living or dead) of each cell.

The loop calls three main methods. The first, “refreshLife()”, renders the next cycle of Conway’s Game of Life. It goes through each row and column and uses the three predefined rules to select if a cell lives or dies. I won’t cover how the refreshPixelArray() and displayPixelArray() methods work, but they are responsible for turning the LEDs on and off based on the Life Map.

The Refresh Life Method

The meat of the coding comes from this method. The refreshLife method is responsible for creating each new “Life Map.” The method calls four different methods: transform, flip, around, and eval. Transform creates a new blank life map and copies the contents of the old life map. Eval simple returns the current status of an individual cell. Eval is used by the Around method to count how many living cells surround a single cell. With the data from the Around method, flip decides if the new cell should live or die. Transform contains additional code I set up to prevent the game from getting stuck in an infinite loop.



void refreshLife(){

transform(lifeMap);

}

void transform (int oldMap[8][8]){

int newLife[8][8];

for(int i = 0; i < 8; i++){

for(int j = 0; j < 8; j++){

newLife[i][j] = flip(oldMap, i , j);

}

}

int countDead;

int countSame;

for (int a = 0; a < 8; a++){

for(int b = 0; b < 8; b++){

if(lifeMap[a][b] == newLife[a][b]){

countSame = countSame+1;

}

lifeMap[a][b]= newLife[a][b] ;

if (newLife[a][b] == LOW){

countDead = countDead+1;

}

}

}

if(countDead == 64 || countSame == 64){

randomLifeStart();

}

// memcpy(lifeMap, newLife, sizeOf lifeMap);

//lifeMap = newLife;

}

int flip (int oldMap[8][8], int i, int j){

int count = around(oldMap, i , j);

//Serial.print(count);

if(oldMap[i][j] == 1){

if(count < 2 || count > 3){

return 0;

}

return 1;

} else {

if(count == 3){

return 1;

}

return 0;

}

}

int around (int oldMap[8][8], int i, int j){

int count = 0;

for (int a = i-1; a <= i+1; a++){

for (int b = j-1; b <= j+1; b++){

if(a==i && b==j){

continue;

}

count+= eval(oldMap, a, b);

}

}

return count;

}

int eval(int oldMap[8][8], int i, int j){

if(i<0||j<0||i==7||j==7){

return 0;

}

if(oldMap[i][j]==1){

return 1;

}

return 0;

}

Again, this section of the code is heavily based upon the code found here. You can download my source code here. Have fun!