MAX7219 Not Lighting Up With Wemos D1 Mini Lite ESP8285

Hi all, this is the first time posting on this forum, so I apologize if this is in the wrong category. I’m also very new to the Arduino scene, and hardware in general, so I may not be familiar with all the lingo yet.

I am building a “clock” that will display Stripe revenue from their API. I have written the code for this and it works great in the Serial output, however, I can’t for the life of me to get the MAX7219 to work. I am working with the MAX72XX library.

This is my current hardware:
Wemos D1 Mini Lite (https://www.amazon.com/gp/product/B07BK435ZW/ref=ppx_yo_dt_b_asin_title_o01_s00?ie=UTF8&psc=1)
MAX7219 https://www.amazon.com/gp/product/B07FFV537V/ref=ppx_yo_dt_b_asin_title_o00_s00?ie=UTF8&psc=1
Jumper Wires https://www.amazon.com/gp/product/B077N5RLHN/ref=ppx_yo_dt_b_asin_title_o01_s02?ie=UTF8&psc=1
Breadboard https://www.amazon.com/gp/product/B01EV6SBXQ/ref=ppx_yo_dt_b_asin_title_o01_s02?ie=UTF8&psc=1

This is my current configuration:
Wemos D5 → MAX7219 CLK
Wemos D7 → MAX7219 DIN
Wemos D8 → MAX7219 CS
Wemos GND → MAX7219 GND
Wemos 5V → MAX7219 VCC

I have configured it this way from following the pin layout from this URL:
https://wiki.wemos.cc/products:d1:d1_mini_lite

My board configuration:
LOLIN(WEMOS) D1 mini Lite, 80 MHz, Flash, 1M (no SPIFFS), v2 Lower Memory, Disabled, None, Only Sketch, 921600 on /dev/cu.wchusbserial1420

Additionally, this is the code that I am using (Example from MAX72XX library):

// Use the MD_MAX72XX library to Print some text on the display
//
// Demonstrates the use of the library to print text.
//
// User can enter text on the serial monitor and this will display as a
// message on the display.

#include <MD_MAX72xx.h>
#include <SPI.h>

#define PRINT(s, v) { Serial.print(F(s)); Serial.print(v); }

// Define the number of devices we have in the chain and the hardware interface
// NOTE: These pin numbers will probably not work with your hardware and may
// need to be adapted
#define HARDWARE_TYPE MD_MAX72XX::PAROLA_HW
#define MAX_DEVICES 4

#define CLK_PIN   D5  // or SCK
#define DATA_PIN  D7  // or MOSI
#define CS_PIN    D8 // or SS

// SPI hardware interface
MD_MAX72XX mx = MD_MAX72XX(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);
// Arbitrary pins
//MD_MAX72XX mx = MD_MAX72XX(HARDWARE_TYPE, DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES);

// Text parameters
#define CHAR_SPACING  1 // pixels between characters

// Global message buffers shared by Serial and Scrolling functions
#define BUF_SIZE  75
char message[BUF_SIZE] = {"Hello!"};
bool newMessageAvailable = true;

void readSerial(void)
{
  static uint8_t putIndex = 0;

  while (Serial.available())
  {
    message[putIndex] = (char)Serial.read();
    if ((message[putIndex] == '\n') || (putIndex >= BUF_SIZE-3))  // end of message character or full buffer
    {
      // put in a message separator and end the string
      message[putIndex] = '\0';
      // restart the index for next filling spree and flag we have a message waiting
      putIndex = 0;
      newMessageAvailable = true;
    }
    else
      // Just save the next char in next location
      message[putIndex++];
  }
}

void printText(uint8_t modStart, uint8_t modEnd, char *pMsg)
// Print the text string to the LED matrix modules specified.
// Message area is padded with blank columns after printing.
{
  uint8_t   state = 0;
  uint8_t   curLen;
  uint16_t  showLen;
  uint8_t   cBuf[8];
  int16_t   col = ((modEnd + 1) * COL_SIZE) - 1;

  mx.control(modStart, modEnd, MD_MAX72XX::UPDATE, MD_MAX72XX::OFF);

  do     // finite state machine to print the characters in the space available
  {
    switch(state)
    {
      case 0: // Load the next character from the font table
        // if we reached end of message, reset the message pointer
        if (*pMsg == '\0')
        {
          showLen = col - (modEnd * COL_SIZE);  // padding characters
          state = 2;
          break;
        }

        // retrieve the next character form the font file
        showLen = mx.getChar(*pMsg++, sizeof(cBuf)/sizeof(cBuf[0]), cBuf);
        curLen = 0;
        state++;
        // !! deliberately fall through to next state to start displaying

      case 1: // display the next part of the character
        mx.setColumn(col--, cBuf[curLen++]);

        // done with font character, now display the space between chars
        if (curLen == showLen)
        {
          showLen = CHAR_SPACING;
          state = 2;
        }
        break;

      case 2: // initialize state for displaying empty columns
        curLen = 0;
        state++;
        // fall through

      case 3: // display inter-character spacing or end of message padding (blank columns)
        mx.setColumn(col--, 0);
        curLen++;
        if (curLen == showLen)
          state = 0;
        break;

      default:
        col = -1;   // this definitely ends the do loop
    }
  } while (col >= (modStart * COL_SIZE));

  mx.control(modStart, modEnd, MD_MAX72XX::UPDATE, MD_MAX72XX::ON);
}

void setup()
{
  mx.begin();

  Serial.begin(57600);
  Serial.print("\n[MD_MAX72XX Message Display]\nType a message for the scrolling display\nEnd message line with a newline");
}

void loop()
{
  readSerial();
  if (newMessageAvailable)
  {
    PRINT("\nProcessing new message: ", message);
    printText(0, MAX_DEVICES-1, message);
    newMessageAvailable = false;
  }
}

When I run this code, it compiles and uploads just fine. I can even see the serial output telling me to “write a new message”, and yet nothing happens on the LEDs.

I’m not sure if this is relevant, but if I shimmy the USB out, sometimes all the LEDs will light up at full brightness.

I also have two of every part, and have tried each one to no avail, so I do not believe it is a faulty part.

If anyone has any feedback or ideas I would be glad to hear them. I have researched for this issue but couldn’t find anything. I also posted on the Arduino Stack Exchange but had no luck there as well.

I realize the more information the better, so if I left anything out I would be happy to add it.

Here are some images of the components:

Thanks for any advice!

I don't know this library and normally manipulate the MAX7219 directly. However, this looks wrong:

#define CLK_PIN   D5  // or SCK
#define DATA_PIN  D7  // or MOSI
#define CS_PIN    D8 // or SS

// SPI hardware interface
MD_MAX72XX mx = MD_MAX72XX(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);
// Arbitrary pins
//MD_MAX72XX mx = MD_MAX72XX(HARDWARE_TYPE, DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES);

You appear to be using arbitrary pins so should change the comments accordingly.

6v6gt:
You appear to be using arbitrary pins so should change the comments accordingly.

Looks right to me. On Wemos, D5 is SCK, D6 is MISO, D7 is MOSI and D8 is SS. So correctly using the constructor for H/W SPI.

I have driven max7219 from Wemos before now with no problem, with the max powered from 5V and no level shifting from the Wemo's 3.3V signals to 5V needed, for example this video. However, maybe I have just been lucky, because the data sheet gives the minimum input voltage for a high level as 3.5V.

I suggest:

  1. Confirm that your max chip is working correctly by connecting it to a 5V Arduino.
  2. Try level shifting between the Wemos and the max chip. Try 74HC14 or 74HCT14. These are hex inverters, so connect 2 inverters in series between D5 (SCK) and CLK, two between D7 (MOSI) and DATA and 2 between D8 (SS) and CS.

Hi @6v6gt,

Thanks for your reply! I am using this code as an example.

The only thing I changed was the values for the CLK_PIN, DATA_PIN, and CS_PIN variables.

Hi @PaulRB,

Thank you for your suggestions! I have a couple of questions.

Confirm that your max chip is working correctly by connecting it to a 5V Arduino.

When you say connect to a 5V Arduino, do you mean a different chip than the Wemos? I currently only have two of the Wemos D1 Mini Lite chips, just getting into this hobby :slight_smile:

Try level shifting between the Wemos and the max chip. Try 74HC14 or 74HCT14. These are hex inverters, so connect 2 inverters in series between D5 (SCK) and CLK, two between D7 (MOSI) and DATA and 2 between D8 (SS) and CS.

Forgive my ignorance, I assume for this that I would need additional equipment (inverters)? I currently don't have access to this equipment right now, but I could try and get it.

Are you familiar with any way to debug within Arduino to determine if the Max is getting the necessary input?

Additionally, are you familiar if the Wemos D1 Mini Lite is supported like your Wemos D1 Mini? To my understanding, it is just a memory difference, but I could be wrong.

Thank you so much for your input so far. It means a lot. I've been trying this all week and following plenty of guides but can't seem to get this working.

sundaycode:
When you say connect to a 5V Arduino, do you mean a different chip than the Wemos?

Yes, I mean an Arduino which runs at 5V logic levels, such as Uno or Nano. If you can't borrow one, just buy a Nano.

sundaycode:
Forgive my ignorance, I assume for this that I would need additional equipment (inverters)? I currently don't have access to this equipment right now, but I could try and get it.

74HC14 is cheap and very commonly available. You would just need one chip for this. Plus I assume you already have breadboards, connecting wire, common components such as resistors & caps?

sundaycode:
Are you familiar with any way to debug within Arduino to determine if the Max is getting the necessary input?

I can't think of a way, except to try a 5V Arduino or level shifting.

sundaycode:
Additionally, are you familiar if the Wemos D1 Mini Lite is supported like your Wemos D1 Mini? To my understanding, it is just a memory difference, but I could be wrong.

I agree. No difference between Mini and Mini Lite would cause this issue, I'm sure.

sundaycode:
I've been trying this all week and following plenty of guides but can't seem to get this working.

Right now my guess would be a faulty max chip, or that you have not been as lucky as me and you need those level shifters.

Thank you for your thorough answer. i just realized I'll have access to an Uno in the coming days so I'll give it a shot on that and will report back with what I find. This is my second MAX that I ordered from Amazon because I thought the first was faulty. I would have to have some pretty bad luck to get two defective units in a row, but I'm not ruling it out. Thanks again!

In the meantime, it might be worth trying some really simple example sketches, ones which just display simple patterns and don't require any serial or other input, perhaps examples from the library? There is also example sketch called MD_MAX72XX_Message_ESP8266 which sounds relavent.

First thing to try with your current setup - choose software SPI.

// HARDWARE SPI
// MD_Parola P = MD_Parola(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);
// SOFTWARE SPI
MD_Parola P = MD_Parola(HARDWARE_TYPE, DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES);

Next, correct your mistake:

#define HARDWARE_TYPE MD_MAX72XX::PAROLA_HW
#

to

#define HARDWARE_TYPE MD_MAX72XX::FC16_HW

Hey @Paul__B, I gave your recommendations a shot but still no dice. I'm still waiting on getting an Arduino Uno for testing. So I'll report back soon if that changes anything.

Looking at the picture of the wemos D1 mini lite mounted in the breadboard, it appears that, if you are using standard header pins, these have been mounted on the wrong side of the board and may not project deeply enough into the breadboard to make a good connection.

Looks like the OP has used the headers with the extra long pins that are normally supplied with Wemos mini. I hope they are soldered to the Wemos, not just pushed through!

Could be but from this link supplied by the OP, these seem to be standard.
https://www.amazon.com/gp/product/B07BK435ZW/ref=ppx_yo_dt_b_asin_title_o01_s00?ie=UTF8&psc=1

With Wemos D1 minis I have purchased, it is the supplied female header pins which have the long tails. The males are standard.

This is also a hint at a possible connection problem:

I'm not sure if this is relevant, but if I shimmy the USB out, sometimes all the LEDs will light up at full brightness.