Introduction: MAX7219 LED Matrix MQTT Using Esp8266

I was trying to connect my MAX7219 LED display to an MQTT server and receive a text from the MQTT subscription to display.

but I didn't get any suitable code on the internet, so I started building my own...

and the result comes quite well...

  • you can display any text on led display
  • you can adjust intensity of the display
  • you can set the scroll speed

Supplies

  1. An esp8266 development board. (my case it's NODE MCU v1.0)
  2. MAX7219 LED Matrix Display.

Software needed:

  1. Arduino IDE.
  2. An MQTT server. (my case Mosquitto)

Library required:

  1. ESP8266WiFi.h
  2. MD_MAX72xx.h
  3. EspMQTTClient.h

Step 1: Setup Arduino IDE for Esp8266 Development

open preferences of Arduino then paste the below URL in Aditional Boards Manager URLs:

https://arduino.esp8266.com/stable/package_esp8266com_index.json

then Tools > Boards > Boards Manager and search for esp8266 and install it.

now your Arduino ide is ready for esp8266 development.

Step 2: Download External Libraries

now we need some libraries for MAX7219 and MQTT Client.

let's download and set up the libraries

navigate to Sketch > Include Library > Manage Libraries on Arduino IDE

and search for EspMQTTClient and click Install


NB: Install all dependent libraries, it's important

Again search for MD_MAX72xx and click Install

Step 3: Write Some Code Now

Now paste the below code

#include <ESP8266WiFi.h>
#include <MD_MAX72xx.h>
#include <SPI.h>
#include "EspMQTTClient.h"

#define MAX_DEVICES 4 // your device count

#define CLK_PIN   D5 // or SCK
#define DATA_PIN  D7 // or MOSI
#define CS_PIN    D4 // or SS // you can set it to any pin

#define HARDWARE_TYPE MD_MAX72XX::PAROLA_HW // change according to your display type
MD_MAX72XX mx = MD_MAX72XX(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);

const uint8_t MESG_SIZE = 255;
const uint8_t CHAR_SPACING = 1;
uint8_t SCROLL_DELAY = 75; // default scroll delay
uint8_t INTENSITY = 5; // default intensity

char curMessage[MESG_SIZE];
char newMessage[MESG_SIZE];
bool newMessageAvailable = false;

void scrollDataSink(uint8_t dev, MD_MAX72XX::transformType_t t, uint8_t col) {}

uint8_t scrollDataSource(uint8_t dev, MD_MAX72XX::transformType_t t)
{
  static enum { S_IDLE, S_NEXT_CHAR, S_SHOW_CHAR, S_SHOW_SPACE } state = S_IDLE;
  static char   *p;
  static uint16_t curLen, showLen;
  static uint8_t  cBuf[8];
  uint8_t colData = 0;

  switch (state)
  {
  case S_IDLE: 
    p = curMessage;
    if (newMessageAvailable) 
    {
      strcpy(curMessage, newMessage);
      newMessageAvailable = false;
    }
    state = S_NEXT_CHAR;
    break;

  case S_NEXT_CHAR: 
    if (*p == '\0')
      state = S_IDLE;
    else
    {
      showLen = mx.getChar(*p++, sizeof(cBuf) / sizeof(cBuf[0]), cBuf);
      curLen = 0;
      state = S_SHOW_CHAR;
    }
    break;

  case S_SHOW_CHAR: 
    colData = cBuf[curLen++];
    if (curLen < showLen)
      break;

    showLen = (*p != '\0' ? CHAR_SPACING : (MAX_DEVICES*COL_SIZE)/2);
    curLen = 0;
    state = S_SHOW_SPACE;

  case S_SHOW_SPACE:  
    curLen++;
    if (curLen == showLen)
      state = S_NEXT_CHAR;
    break;

  default:
    state = S_IDLE;
  }

  return(colData);
}

EspMQTTClient client(
  "YOUR_SSID",
  "YOUR_WIFI_PASSWORD",
  "YOUR_MQTT_SERVER",  // MQTT Broker server ip
  "YOUR_MQTT_USER",   // Can be omitted if not needed
  "YOUR_MQTT_PASSWORD",   // Can be omitted if not needed
  "MAX7219_DISPLAY",     // Client name that uniquely identify your device
  1883              // The MQTT port, default to 1883. this line can be omitted
);

void scrollText(void)
{
  static uint32_t prevTime = 0;

  // Is it time to scroll the text?
  if (millis() - prevTime >= SCROLL_DELAY)
  {
    mx.transform(MD_MAX72XX::TSL);  // scroll along - the callback will load all the data
    prevTime = millis();      // starting point for next time
  }
}

void setup()
{
  Serial.begin(115200);
  mx.begin();
  mx.control(MD_MAX72XX::INTENSITY, INTENSITY);
  mx.setShiftDataInCallback(scrollDataSource);
  mx.setShiftDataOutCallback(scrollDataSink);
  curMessage[0] = newMessage[0] = '\0';
  sprintf(curMessage, "Smart Display");
}

void onConnectionEstablished()
{
// MQTT subscription topic for display text
  client.subscribe("leddisplay/text", [](const String & payload) {
    sprintf(curMessage, payload.c_str());
  });
  
<p>// MQTT subscription topic for display intensity controll</p>  client.subscribe("leddisplay/intensity", [](const String & payload) {
    mx.control(MD_MAX72XX::INTENSITY, payload.toInt());
  });

// MQTT subscription topic for display scroll speed controll
  client.subscribe("leddisplay/scroll", [](const String & payload) {
    SCROLL_DELAY = payload.toInt();
  });
}

void loop()
{
  client.loop();
  scrollText();
}

For detail information, refer to this repository

https://github.com/souravj96/max7219-mqtt-esp8266

Step 4: Circuit Diagram

connect MAX7219 display with NODE MCU

Step 5: Upload Code to Esp8266

now choose your correct board type and serial port then hit upload.

Step 6: Test Everything

if everything goes correct then your esp8266 will be connected to your MQTT server.

now, if anything will be published on leddisplay/text topic that will be displayed.

{
topic: "leddisplay/text",
payload: "your message here"
}

if you want to set the intensity of display

{
topic: "leddisplay/intensity",
payload: "2" // max is 15 and min 0
}

if you want to set the scroll speed of display

{
topic: "leddisplay/scroll",
payload: "100" // max is 255 and min 0
}

Happy coding