Maker Pro

MAX7219 8x8 LED Matrix Module Arduino Interfacing

May 16, 2024 by jobitjoseph1

The article provides an in-depth exploration of the MAX7219 8x8 LED Matrix Module, and how to interface it with an Arduino.

The MAX7219 8x8 LED matrix module is a compact, versatile display unit favoured 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.

MAX7219 LED Matrix Module Pinout

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.

MAX7219 Pinout

MAX7219 8x8 LED Module Specifications

  • 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

MAX7219 LED Matrix Display Arduino Interfacing

MAX7219 Display Module Interfacing Connection Diagram

For interfacing with Arduino do 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.

MAX7219 Display Module Interfacing with Arduino

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 MAX_DEVICES 1
#define CLK_PIN   13
#define DATA_PIN  11
#define CS_PIN    10

// Create a MAX72xx object

// 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() {
  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);

  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++) {
      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
      delay(50);  // Short flash
      display.setPoint(row, col, false); // Turn off the LED

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);
        if (position == -MAX_DEVICES * 8) {
            Serial.print("Start Pos: ");
            Serial.print("First Char: ");

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.

Daisy Chaining MAX7219 Display Module

Related Content


You May Also Like