I bought a larger LED display some months ago, and haven’t really had time to muck around with it until now. Previously though, I used this display and fiddled around with a Raspberry Pi and used the code and guide you can see here. I decided that i’d like to use and manipulate the display from scratch, and naturally I used Arduino this time around.

Here is there data sheet for the display, as well as a location you can purchase one. There are several great features of this display that I’d like to highlight:

Each pixel (LED) can be lit as red, green or orange.

The display is shift-register based. So only (9) minimal pins are needed to operate all 640 pixels.

It’s fairly low powered. I can run it straight from the Arduino pins. You can also power it independently.

The data sheet specified certain combinations of A, B, C and D to activate 16 rows, but you can ignore this and only use 8. I personally found the trickiest part of playing with this was hooking it up properly.

Here, I simply used a continuity check on the ribbon cable to see how it worked before putting the cables into the Arduino pins and the ribbon cable itself. Be sure to insert the pins in the correct orientation (In the perspective of looking down) as to get it up and running properly.

For convenience purposes, I converted some Raspberry Pi code (Python) and converted it to Arduino compatible code (C). After this was done, It was simply a matter of managing the way I wrote data to the display. For my following examples, I used a 8×80 2D array (as 1s and 0s) and wrote the data to the screen, but did other computations on this seperately. I did three examples to see how well the display could operate, these were the Game of Life, a general text display and a ‘bouncing balls’ container. In the end they all worked quite well, and you can see me demonstrating this in the video.

What I didn’t mention in this video is that I could obviously vary the speed of all the transitions. I also adapted some pixel bitmaps from various other projects as to not write all ascii characters out by hand.

Here is the code for the game of life I made:

/* - Game Of Life - Josip Simunic I basically re-wrote some parts from Pete Goss' http://www.raspberrypi.org/forums/viewtopic.php?f=41&t=67520 Python to C. */ #define A 13 #define B 12 #define C 11 #define D 10 #define enable 9 #define latch 8 #define shift 7 #define green 6 // Active low #define red 5 // Active low #define orange 4 // unused long startTime = 0; // Used for timing. long endTime = 0; /* Make map bigger by a byte in each direction for ease of neighbour computations */ byte gameOfLifeBefore[10][82]; byte gameOfLifeAfter[10][82]; void setup() { //Serial.begin(9600); pinMode(A, OUTPUT); pinMode(B, OUTPUT); pinMode(C, OUTPUT); pinMode(D, OUTPUT); pinMode(enable, OUTPUT); pinMode(latch, OUTPUT); pinMode(shift, OUTPUT); pinMode(green, OUTPUT); pinMode(red, OUTPUT); // Initialise pins. digitalWrite(red, HIGH); digitalWrite(green, HIGH); digitalWrite(shift, HIGH); digitalWrite(latch, LOW); digitalWrite(enable, LOW); clear(); /* Starting randomisation */ randomSeed(analogRead(0)); /* Initialising the maps to 0 */ for (int row = 0; row < 10; row++) { for (int col = 0; col < 82; col++) { gameOfLifeBefore[row][col] = 0; gameOfLifeAfter[row][col] = 0; } } /* Glider */ //gameOfLifeAfter[3][1] = 1; gameOfLifeAfter[3][2] = 1;gameOfLifeAfter[3][3] = 1; gameOfLifeAfter[2][3] = 1; gameOfLifeAfter[1][2] = 1; /* Oscillator */ //gameOfLifeBefore[7][10] = 1; gameOfLifeBefore[7][11] = 1;gameOfLifeBefore[7][12] = 1; /* Toad */ //gameOfLifeBefore[5][20] = 1; gameOfLifeBefore[5][21] = 1; gameOfLifeBefore[5][22] = 1; //gameOfLifeBefore[4][21] = 1; gameOfLifeBefore[4][22] = 1; gameOfLifeBefore[4][23] = 1; /* Die hard */ //gameOfLifeAfter[1][1] = 1; gameOfLifeAfter[1][2] = 1;gameOfLifeAfter[2][2] = 1; //gameOfLifeAfter[2][6] = 1; gameOfLifeAfter[2][7] = 1;gameOfLifeAfter[2][8] = 1; gameOfLifeAfter[1][7] = 1; /* Line oscillator */ //gameOfLifeAfter[4][36] = 1; gameOfLifeAfter[4][37] = 1; gameOfLifeAfter[4][38] = 1; gameOfLifeAfter[4][39] = 1; gameOfLifeAfter[4][40] = 1; //gameOfLifeAfter[4][41] = 1; gameOfLifeAfter[4][42] = 1; gameOfLifeAfter[4][43] = 1; gameOfLifeAfter[4][44] = 1; gameOfLifeAfter[4][45] = 1; //gameOfLifeAfter[4][16] = 1; gameOfLifeAfter[4][17] = 1; gameOfLifeAfter[4][18] = 1; gameOfLifeAfter[4][19] = 1; gameOfLifeAfter[4][20] = 1; //gameOfLifeAfter[4][21] = 1; gameOfLifeAfter[4][22] = 1; gameOfLifeAfter[4][23] = 1; gameOfLifeAfter[4][24] = 1; gameOfLifeAfter[4][25] = 1; //gameOfLifeAfter[4][56] = 1; gameOfLifeAfter[4][57] = 1; gameOfLifeAfter[4][58] = 1; gameOfLifeAfter[4][59] = 1; gameOfLifeAfter[4][60] = 1; //gameOfLifeAfter[4][61] = 1; gameOfLifeAfter[4][62] = 1; gameOfLifeAfter[4][63] = 1; gameOfLifeAfter[4][64] = 1; gameOfLifeAfter[4][65] = 1; } int index = 0; void loop() { /* Only do this every second */ if (isEmpty(gameOfLifeAfter)) { seed(gameOfLifeAfter); } startTime = millis(); if ((startTime - endTime) > 500) { nextStepOfLife(gameOfLifeBefore, gameOfLifeAfter); copyMap(gameOfLifeAfter, gameOfLifeBefore); endTime = startTime; } for (int i = 0; i < 8; i++) { for (int j = 0; j < 80; j++) { if (gameOfLifeAfter[i + 1][j + 1]) { insert(4 + random(3)); // Inserts a random colour everytime. } else { shiftIT(); } } showRow(i); delay(1); clear(); } } /* Shifts the LED info */ void shiftIT() { digitalWrite(shift, HIGH); digitalWrite(shift, LOW); digitalWrite(shift, HIGH); } /* Clears the selected row */ void clear() { digitalWrite(red, HIGH); digitalWrite(green, HIGH); for (int i = 0; i < 80; i++) { shiftIT(); } } /* Illuminates a selected row of LEDS */ void showRow(int n) { switch (n) { case 0: digitalWrite(A, LOW); digitalWrite(B, LOW); digitalWrite(C, LOW); digitalWrite(D, LOW); break; case 1: digitalWrite(A, HIGH); digitalWrite(B, LOW); digitalWrite(C, LOW); digitalWrite(D, LOW); break; case 2: digitalWrite(A, LOW); digitalWrite(B, HIGH); digitalWrite(C, LOW); digitalWrite(D, LOW); break; case 3: digitalWrite(A, HIGH); digitalWrite(B, HIGH); digitalWrite(C, LOW); digitalWrite(D, LOW); break; case 4: digitalWrite(A, LOW); digitalWrite(B, LOW); digitalWrite(C, HIGH); digitalWrite(D, LOW); break; case 5: digitalWrite(A, HIGH); digitalWrite(B, LOW); digitalWrite(C, HIGH); digitalWrite(D, LOW); break; case 6: digitalWrite(A, LOW); digitalWrite(B, HIGH); digitalWrite(C, HIGH); digitalWrite(D, LOW); break; case 7: digitalWrite(A, HIGH); digitalWrite(B, HIGH); digitalWrite(C, HIGH); digitalWrite(D, LOW); break; case 8: digitalWrite(A, LOW); digitalWrite(B, LOW); digitalWrite(C, LOW); digitalWrite(D, HIGH); break; default: digitalWrite(A, LOW); digitalWrite(B, LOW); digitalWrite(C, LOW); digitalWrite(D, LOW); break; } /* Latches the data */ digitalWrite(latch, HIGH); digitalWrite(latch, LOW); /* Displays the data */ digitalWrite(enable, HIGH); } /* Shifts a given colour into the display */ void insert(int colour) { if (colour == orange) { digitalWrite(red, LOW); digitalWrite(green, LOW); shiftIT(); digitalWrite(red, HIGH); digitalWrite(green, HIGH); } else if ((colour == red) || (colour == green)) { digitalWrite(colour, LOW); shiftIT(); digitalWrite(colour, HIGH); } else { shiftIT(); } } void copyMap(byte oldArray[][82], byte newArray[][82]) { for (int row = 0; row < 10; row++) { for (int col = 0; col < 82; col++) { newArray[row][col] = oldArray[row][col]; } } } /* Creates the next transition of life from */ void nextStepOfLife(byte oldArray[][82], byte newArray[][82]) { for (int row = 1; row < 9; row++) { for (int col = 1; col < 81; col++) { /* Check the neighbours of a cell */ int liveNeighbours = oldArray[row - 1][col - 1] + oldArray[row - 1][col] + oldArray[row - 1][col + 1] + \ oldArray[row][col - 1] + /*This is my cell */ + oldArray[row][col + 1] + \ oldArray[row + 1][col - 1] + oldArray[row + 1][col] + oldArray[row + 1][col + 1]; if (oldArray[row][col]) { // If we're currently alive. if (liveNeighbours < 2) newArray[row][col] = 0; // Dies from under population. if ((liveNeighbours == 2) || (liveNeighbours == 3)) newArray[row][col] = 1; // Lives on. if (liveNeighbours > 3) newArray[row][col] = 0; // Dies from voer crowding. } else { // If we're dead. if (liveNeighbours == 3)newArray[row][col] = 1; // We come alive. } } } } int isEmpty(byte oldArray[][82]) { for (int row = 1; row < 9; row++) { for (int col = 1; col < 81; col++) { if (oldArray[row][col] != 0) { return 0; } } } return 1; } void seed(byte oldArray[][82]) { for (int i = 0; i < 100; i ++) { oldArray[1 + random(8)][1 + random(80)] = 1; } }