LED matrix

The MAX7219 LED matrix module used in this example has 64 distinct LEDs that can be individually turned on or off in the Arduino code.

It uses SPI to control 64 individual LEDs while consuming just three GPIO pins on the microcontroller, plus the VCC and GND pins for powering the LED module. The module also has output pins that can be chained together with up to eight (or more) modules.

We will use a library called LEDMatrixDriver, which purports to be faster than another library called LedControl.

The bitmaps for all the characters together are too large to fit into a couple kilobytes of SRAM, so we will store the data in the Flash storage where program code is also stored.

For this we need to #include <avr/pgmspace.h> which then makes it possible to store data with the PROGMEM macro: PROGMEM prog uchar data[] = (the data).

The main tradeoff for using PROGMEM memory is that it cannot be modified at run-time.

Creating your own fonts and graphics

GitHub user Xantorohara has created a very convenient LED Matrix Editor with which you can draw your own characters and generate the corresponding Arduino code and data.

Example code

The following is a simple example that loops through the characters in "NOVELIDE".

#include <LedControl.h>

const int DIN_PIN = 7;
const int CS_PIN = 6;
const int CLK_PIN = 5;

// The characters in "NOVELIDE". Notice we only
// define "E" once and will reuse the data.
const uint64_t IMAGES[] PROGMEM = {
	0x0000000000000000, // 0: [blank]
	0x81c1a19189858381, // 1: N
	0xff818181818181ff, // 2: O
	0x1818242442428181, // 3: V
	0xff0101013f0101ff, // 4: E
	0xff01010101010101, // 5: L
	0xff080808080808ff, // 6: I
	0x3f4181818181413f  // 7: D
};

const int IMAGES_LEN = sizeof(IMAGES) / 8;

// The letters in "NOVELIDE" as indexed above,
// followed by a blank space.
const byte SEQUENCE[] = {
	1, 2, 3, 4, 5, 6, 4, 0
};

// Must be equal to the number of
// elements in SEQUENCE above.
const int SEQ_LENGTH = sizeof(SEQUENCE);

// Stores our current place in SEQUENCE,
// gets incremented in loop().
int seqIndex = 0;

LedControl display = LedControl(DIN_PIN, CLK_PIN, CS_PIN);

void setup() {
	display.clearDisplay(0);
	display.shutdown(0, false);
	display.setIntensity(0, 10);
}

void drawBitmap(uint64_t image) {
	for (int i = 0; i < 8; i++) {
		byte row = (image >> i * 8) &amp; 0xFF;

		for (int j = 0; j < 8; j++) {
			display.setLed(0, i, j, bitRead(row, j));
		}
	}
}

void loop() {
	// Read data from PROGMEM.
	uint64_t bitmap;
	memcpy_P(&bitmap, &IMAGES[seqIndex], 8);

	// Draw the current character.
	drawBitmap(bitmap);

	// Move to the next character.
	++seqIndex;

	// If we're past the end of SEQUENCE,
	// cycle back to the beginning.
	if (seqIndex >= SEQ_LENGTH) {
		seqIndex = 0;
	}

	delay(500);
}