MAX7219 8x8 LED Matrix Module Arduino Interfacing
2024-05-16 | By Jobit Joseph
License: Attribution-NonCommercial-ShareAlike Arduino
The MAX7219 8x8 LED matrix module is a compact, versatile display unit favored by electronics hobbyists and developers working on microcontroller projects. It employs the MAX7219 LED driver IC, which simplifies the task of connecting and controlling multiple LEDs. This module can manage up to 64 LEDs in an 8x8 grid, enabling it to display characters, symbols, and animations by addressing each LED individually.
The module requires only three control signals, minimizing the number of necessary pins. Its daisy-chain capability allows for display expansion by connecting multiple modules without needing extra microcontroller pins. Operating on a simple serial interface, the MAX7219 module is compatible with most microcontrollers, including Arduino and Raspberry Pi. Its user-friendly design, low power consumption, and high visual impact make it an excellent choice for DIY projects, digital signage, and interactive displays.
The MAX7219 LED matrix module has ten connections, five of which are for interfacing with the microcontroller, and the other five are for daisy-chaining to the next module. Here is the PCB with the LED module removed for easy understanding followed by the pinout.
- Wide Operating Voltage: 3.7 to 5.3 V
- Input Current: 320 mA
- 8 x 8 dot matrix Display
- Serial Interface Control: Allows for control using a simple serial communication protocol, minimizing the number of microcontroller pins needed.
- Cascadable Design: Multiple MAX7219 modules can be daisy-chained to create larger displays without using additional microcontroller pins.
- Individual LED Control: Each of the 64 LEDs in the 8x8 matrix can be individually controlled, enabling the display of a wide range of characters, symbols, and animations.
- Brightness Control: Supports adjustable brightness levels, which can be programmed via software to suit different lighting conditions.
- Low Power Consumption: Efficient power management makes it suitable for portable battery-operated devices.
- Compact Form Factor: Its small size makes it ideal for space-constrained applications.
- Digital Error Correction: Automatically detects and corrects any errors in the communication data, ensuring reliable performance.
- Versatility: This can be used with popular microcontrollers like Arduino, Raspberry Pi, and others, which facilitates integration into various projects.
- PCB Dimensions: 30 x 30 x 1 mm
For interfacing with Arduino setup the connections as per the circuit diagram above. Connect VCC and GND to 5V and GND pins. Connect DIN to Pin 11, CLK to Pin 13, and CS to Pin 10.
Once the connection is done, in the Arduino IDE Install the MD_MAX72xx Library and copy the given code to a new sketch. Compile the code then upload it to the Arduino. Now you can see a smiley face animation on the display. To learn more about MAX7219 display interfacing please check out the Interfacing MAX7219 LED Dot Matrix Display with Arduino article.
The code for the above animations is given below.
#include <MD_MAX72xx.h>
#include <SPI.h>
// Define hardware type, size, and pins
#define HARDWARE_TYPE MD_MAX72XX::FC16_HW
#define MAX_DEVICES 1
#define CLK_PIN 13
#define DATA_PIN 11
#define CS_PIN 10
// Create a MAX72xx object
MD_MAX72XX display = MD_MAX72XX(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);
// Bitmaps for animations
byte smiley[2][8] = {
{0b00111100, 0b01000010, 0b10100101, 0b10000001, 0b10100101, 0b10011001, 0b01000010, 0b00111100},
{0b00111100, 0b01000010, 0b10100101, 0b10000001, 0b10111101, 0b10000001, 0b01000010, 0b00111100}
};
byte heart[2][8] = {
{0b00000000, 0b01100110, 0b11111111, 0b11111111, 0b01111110, 0b00111100, 0b00011000, 0b00000000},
{0b00000000, 0b01100110, 0b10111101, 0b10011001, 0b01000010, 0b00100100, 0b00011000, 0b00000000}
};
byte xmark[2][8] = {
{0b10000001, 0b01000010, 0b00100100, 0b00011000, 0b00011000, 0b00100100, 0b01000010, 0b10000001},
{0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000}
};
byte spinningLine[4][8] = {
{0b00011000, 0b00111100, 0b01111110, 0b11111111, 0b11111111, 0b01111110, 0b00111100, 0b00011000},
{0b00001000, 0b00011100, 0b00111110, 0b01111111, 0b01111111, 0b00111110, 0b00011100, 0b00001000},
{0b00000000, 0b00011000, 0b00111100, 0b01111110, 0b01111110, 0b00111100, 0b00011000, 0b00000000},
{0b00000000, 0b00000000, 0b00011000, 0b00111100, 0b00111100, 0b00011000, 0b00000000, 0b00000000}
};
byte scrollingArrow[3][8] = {
{0b00100000, 0b00110000, 0b11101000, 0b11111100, 0b11101000, 0b00110000, 0b00100000, 0b00000000},
{0b00010000, 0b00011000, 0b11110100, 0b11111110, 0b11110100, 0b00011000, 0b00010000, 0b00000000},
{0b00001000, 0b00001100, 0b11111010, 0b11111111, 0b11111010, 0b00001100, 0b00001000, 0b00000000}
};
// Bitmap definitions for ASCII characters
const byte ASCII[][8] = {
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // Space (32)
{0x00, 0x00, 0x5F, 0x5F, 0x00, 0x00, 0x00, 0x00}, // ! (33)
{0x00, 0x07, 0x03, 0x00, 0x07, 0x03, 0x00, 0x00}, // " (34)
{0x14, 0x7F, 0x7F, 0x14, 0x7F, 0x7F, 0x14, 0x00}, // # (35)
{0x24, 0x2E, 0x6B, 0x6B, 0x3A, 0x12, 0x00, 0x00}, // $ (36)
{0x46, 0x66, 0x30, 0x18, 0x0C, 0x66, 0x62, 0x00}, // % (37)
{0x30, 0x7A, 0x4F, 0x5D, 0x37, 0x7A, 0x48, 0x00}, // & (38)
{0x00, 0x04, 0x07, 0x03, 0x00, 0x00, 0x00, 0x00}, // ' (39)
{0x00, 0x1C, 0x3E, 0x63, 0x41, 0x00, 0x00, 0x00}, // ( (40)
{0x00, 0x41, 0x63, 0x3E, 0x1C, 0x00, 0x00, 0x00}, // ) (41)
{0x08, 0x2A, 0x3E, 0x1C, 0x1C, 0x3E, 0x2A, 0x08}, // * (42)
{0x08, 0x08, 0x3E, 0x3E, 0x08, 0x08, 0x00, 0x00}, // + (43)
{0x00, 0x80, 0xE0, 0x60, 0x00, 0x00, 0x00, 0x00}, // , (44)
{0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00}, // - (45)
{0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00}, // . (46)
{0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x00}, // / (47)
{0x3E, 0x7F, 0x59, 0x4D, 0x7F, 0x3E, 0x00, 0x00}, // 0 (48)
{0x42, 0x42, 0x7F, 0x7F, 0x40, 0x40, 0x00, 0x00}, // 1 (49)
{0x62, 0x73, 0x59, 0x49, 0x6F, 0x66, 0x00, 0x00}, // 2 (50)
{0x22, 0x63, 0x49, 0x49, 0x7F, 0x36, 0x00, 0x00}, // 3 (51)
{0x18, 0x1C, 0x52, 0x7F, 0x7F, 0x50, 0x00, 0x00}, // 4 (52)
{0x2F, 0x6F, 0x45, 0x45, 0x7D, 0x39, 0x00, 0x00}, // 5 (53)
{0x3E, 0x7F, 0x49, 0x49, 0x79, 0x30, 0x00, 0x00}, // 6 (54)
{0x03, 0x03, 0x71, 0x79, 0x0F, 0x07, 0x00, 0x00}, // 7 (55)
{0x36, 0x7F, 0x49, 0x49, 0x7F, 0x36, 0x00, 0x00}, // 8 (56)
{0x06, 0x4F, 0x49, 0x49, 0x7F, 0x3E, 0x00, 0x00}, // 9 (57)
{0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00}, // : (58)
{0x00, 0x80, 0xE6, 0x66, 0x00, 0x00, 0x00, 0x00}, // ; (59)
{0x08, 0x1C, 0x36, 0x63, 0x41, 0x00, 0x00, 0x00}, // < (60)
{0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x00, 0x00}, // = (61)
{0x00, 0x41, 0x63, 0x36, 0x1C, 0x08, 0x00, 0x00}, // > (62)
{0x02, 0x03, 0x51, 0x59, 0x0F, 0x06, 0x00, 0x00}, // ? (63)
{0x3E, 0x7F, 0x41, 0x5D, 0x55, 0x1F, 0x1E, 0x00}, // @ (64)
{0x7C, 0x7E, 0x13, 0x13, 0x7E, 0x7C, 0x00, 0x00}, // A (65)
{0x41, 0x7F, 0x7F, 0x49, 0x49, 0x7F, 0x36, 0x00}, // B (66)
{0x1C, 0x3E, 0x63, 0x41, 0x41, 0x63, 0x22, 0x00}, // C (67)
{0x41, 0x7F, 0x7F, 0x41, 0x63, 0x3E, 0x1C, 0x00}, // D (68)
{0x41, 0x7F, 0x7F, 0x49, 0x5D, 0x41, 0x63, 0x00}, // E (69)
{0x41, 0x7F, 0x7F, 0x49, 0x1D, 0x01, 0x03, 0x00}, // F (70)
{0x1C, 0x3E, 0x63, 0x41, 0x51, 0x73, 0x72, 0x00}, // G (71)
{0x7F, 0x7F, 0x08, 0x08, 0x7F, 0x7F, 0x00, 0x00}, // H (72)
{0x00, 0x41, 0x7F, 0x7F, 0x41, 0x00, 0x00, 0x00}, // I (73)
{0x30, 0x70, 0x40, 0x41, 0x7F, 0x3F, 0x01, 0x00}, // J (74)
{0x41, 0x7F, 0x7F, 0x08, 0x1C, 0x77, 0x63, 0x00}, // K (75)
{0x41, 0x7F, 0x7F, 0x41, 0x40, 0x60, 0x70, 0x00}, // L (76)
{0x7F, 0x7E, 0x0C, 0x18, 0x0C, 0x7E, 0x7F, 0x00}, // M (77)
{0x7F, 0x7F, 0x06, 0x0C, 0x18, 0x7F, 0x7F, 0x00}, // N (78)
{0x3E, 0x7F, 0x41, 0x41, 0x7F, 0x3E, 0x00, 0x00}, // O (79)
{0x41, 0x7F, 0x7F, 0x49, 0x09, 0x0F, 0x06, 0x00}, // P (80)
{0x1E, 0x3F, 0x21, 0x31, 0x7F, 0x5E, 0x00, 0x00}, // Q (81)
{0x41, 0x7F, 0x7F, 0x09, 0x19, 0x7F, 0x66, 0x00}, // R (82)
{0x26, 0x6F, 0x4D, 0x59, 0x7B, 0x32, 0x00, 0x00}, // S (83)
{0x03, 0x41, 0x7F, 0x7F, 0x41, 0x03, 0x00, 0x00}, // T (84)
{0x7F, 0x7F, 0x40, 0x40, 0x7F, 0x7F, 0x00, 0x00}, // U (85)
{0x1F, 0x3F, 0x60, 0x60, 0x3F, 0x1F, 0x00, 0x00}, // V (86)
{0x7F, 0x7F, 0x30, 0x18, 0x30, 0x7F, 0x7F, 0x00}, // W (87)
{0x63, 0x77, 0x1C, 0x08, 0x1C, 0x77, 0x63, 0x00}, // X (88)
{0x07, 0x4F, 0x78, 0x78, 0x4F, 0x07, 0x00, 0x00}, // Y (89)
{0x67, 0x73, 0x59, 0x4D, 0x47, 0x63, 0x71, 0x00}, // Z (90)
{0x00, 0x00, 0x7F, 0x7F, 0x41, 0x41, 0x00, 0x00}, // [ (91)
{0x01, 0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x00}, // \ (92)
{0x00, 0x41, 0x41, 0x7F, 0x7F, 0x00, 0x00, 0x00}, // ] (93)
{0x08, 0x0C, 0x06, 0x03, 0x06, 0x0C, 0x08, 0x00}, // ^ (94)
{0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}, // _ (95)
{0x00, 0x00, 0x03, 0x07, 0x04, 0x00, 0x00, 0x00}, // ` (96)
{0x20, 0x74, 0x54, 0x54, 0x3C, 0x78, 0x40, 0x00}, // a (97)
{0x41, 0x7F, 0x3F, 0x44, 0x44, 0x7C, 0x38, 0x00}, // b (98)
{0x38, 0x7C, 0x44, 0x44, 0x6C, 0x28, 0x00, 0x00}, // c (99)
{0x30, 0x78, 0x48, 0x49, 0x3F, 0x7F, 0x40, 0x00}, // d (100)
{0x38, 0x7C, 0x54, 0x54, 0x5C, 0x18, 0x00, 0x00}, // e (101)
{0x48, 0x7E, 0x7F, 0x49, 0x03, 0x02, 0x00, 0x00}, // f (102)
{0x98, 0xBC, 0xA4, 0xA4, 0xF8, 0x7C, 0x04, 0x00}, // g (103)
{0x41, 0x7F, 0x7F, 0x08, 0x04, 0x7C, 0x78, 0x00}, // h (104)
{0x00, 0x44, 0x7D, 0x7D, 0x40, 0x00, 0x00, 0x00}, // i (105)
{0x60, 0xE0, 0x80, 0x80, 0xFD, 0x7D, 0x00, 0x00}, // j (106)
{0x41, 0x7F, 0x7F, 0x10, 0x38, 0x6C, 0x44, 0x00}, // k (107)
{0x00, 0x41, 0x7F, 0x7F, 0x40, 0x00, 0x00, 0x00}, // l (108)
{0x7C, 0x7C, 0x18, 0x30, 0x18, 0x7C, 0x78, 0x00}, // m (109)
{0x7C, 0x7C, 0x04, 0x04, 0x7C, 0x78, 0x00, 0x00}, // n (110)
{0x38, 0x7C, 0x44, 0x44, 0x7C, 0x38, 0x00, 0x00}, // o (111)
{0x84, 0xFC, 0xF8, 0xA4, 0x24, 0x3C, 0x18, 0x00}, // p (112)
{0x18, 0x3C, 0x24, 0xA4, 0xF8, 0xFC, 0x84, 0x00}, // q (113)
{0x44, 0x7C, 0x78, 0x4C, 0x04, 0x1C, 0x18, 0x00}, // r (114)
{0x48, 0x5C, 0x54, 0x54, 0x74, 0x24, 0x00, 0x00}, // s (115)
{0x00, 0x04, 0x3E, 0x7F, 0x44, 0x24, 0x00, 0x00}, // t (116)
{0x3C, 0x7C, 0x40, 0x40, 0x3C, 0x7C, 0x40, 0x00}, // u (117)
{0x1C, 0x3C, 0x60, 0x60, 0x3C, 0x1C, 0x00, 0x00}, // v (118)
{0x3C, 0x7C, 0x70, 0x38, 0x70, 0x7C, 0x3C, 0x00}, // w (119)
{0x44, 0x6C, 0x38, 0x10, 0x38, 0x6C, 0x44, 0x00}, // x (120)
{0x9C, 0xBC, 0xA0, 0xA0, 0xFC, 0x7C, 0x00, 0x00}, // y (121)
{0x4C, 0x64, 0x74, 0x5C, 0x4C, 0x64, 0x00, 0x00}, // z (122)
{0x08, 0x08, 0x36, 0x77, 0x41, 0x41, 0x00, 0x00}, // { (123)
{0x00, 0x00, 0x00, 0x7F, 0x7F, 0x00, 0x00, 0x00}, // | (124)
{0x41, 0x41, 0x77, 0x36, 0x08, 0x08, 0x00, 0x00}, // } (125)
{0x08, 0x0C, 0x06, 0x0C, 0x18, 0x0C, 0x08, 0x00} // ~ (126)
};
// Scrolling text message
const char *scrollingText = " Components101 ";
uint16_t scrollDelay = 100; // Delay between shifts in milliseconds
uint16_t displayTime = 500; // Time each frame is shown in milliseconds
int brightnessLevel = 8; // Set brightness level (0 is minimum, 15 is maximum)
void setup() {
Serial.begin(115200);
display.begin(); // Initialize the display
display.control(MD_MAX72XX::INTENSITY, brightnessLevel); // Set the brightness level
display.clear(); // Clear the display
}
void loop() {
playAnimation(smiley, 2, 2);
playAnimation(heart, 2, 2);
scrollText(scrollingText);
playAnimation(xmark, 2, 2);
playAnimation(spinningLine, 4, 2);
playAnimation(scrollingArrow, 3, 2);
}
void playAnimation(byte animation[][8], int frameCount, int repeat) {
for (int r = 0; r < repeat; r++) {
for (int i = 0; i < frameCount; i++) {
displayFrame(animation[i]);
delay(displayTime); // Wait before showing next frame
}
}
}
void playRandomFlash(int count, int repeat) {
for (int r = 0; r < repeat; r++) {
for (int i = 0; i < count; i++) {
byte row = rand() % 8;
byte col = rand() % 8;
display.setPoint(row, col, true); // Turn on a random LED
display.update();
delay(50); // Short flash
display.setPoint(row, col, false); // Turn off the LED
display.update();
}
}
}
void displayFrame(byte frame[8]) {
for (int i = 0; i < 8; i++) {
display.setRow(0, i, frame[i]); // Display each row of the bitmap
}
display.update(); // Ensure the display is updated
}
void scrollText(const char *pText) {
int textLength = strlen(pText);
int maxPosition = textLength * 8; // Total pixels to scroll
for (int position = -MAX_DEVICES * 8; position < maxPosition; position++) {
display.clear(); // Ensure the display is cleared on each frame
for (int col = 0; col < MAX_DEVICES * 8; col++) {
int charIndex = (position + col) / 8;
int colInChar = (position + col) % 8;
if (charIndex >= 0 && charIndex < textLength) {
char ch = pText[charIndex];
int bitmapIndex = ch - 32; // Calculate the correct index in the bitmap array
if (bitmapIndex >= 0 && bitmapIndex < sizeof(ASCII) / sizeof(ASCII[0])) {
byte columnData = ASCII[bitmapIndex][colInChar];
display.setColumn(MAX_DEVICES * 8 - 1 - col, columnData);
} else {
display.setColumn(MAX_DEVICES * 8 - 1 - col, 0x00);
}
} else {
display.setColumn(MAX_DEVICES * 8 - 1 - col, 0x00);
}
}
display.update();
delay(scrollDelay);
if (position == -MAX_DEVICES * 8) {
Serial.print("Start Pos: ");
Serial.println(position);
Serial.print("First Char: ");
Serial.println(pText[0]);
}
}
}
Connecting Multiple Display Modules
As we mentioned earlier, these displays can be daisy-chained to connect multiple modules together. Daisy-chaining MAX7219 LED matrix modules is a highly effective way to create larger and more complex displays without requiring additional microcontroller pins beyond the initial setup. This method involves connecting multiple LED matrix modules in a series, where the output of one module feeds directly into the input of the next. The main advantage of daisy chaining is only a single connection to the microcontroller is needed for data transmission, as the first module in the chain will pass the data along to subsequent modules. The same clock and load signals from the microcontroller are shared across all chained modules.
Have questions or comments? Continue the conversation on TechForum, DigiKey's online community and technical resource.
Visit TechForum