MAX7219 Daisychaining - Current Supply Issues?

Hi all,

I am making a 7 segment display array - very similar to the one shown here, except I am making a larger overall display (100 x 4 digit 7 segment displays, 50 x max7219 chips) and using the max7219CWG instead of the max7219CNG (24 Wide SO vs 24 narrow DIP).

The first 20 displays (10 chips) display great and I'm having zero issues. However, once I start trying to get the next few displays to work, they will not turn on. I have discovered that if I put the first few displays into the shutdown mode (i.e turn them off in my code), that the next few displays down the line begin to function. In fact, I have soldered around 40 displays so far (20 chips) and I can get any 11 or 12 chips working that I desire by altering the code alone. This confirmed to me that I haven't soldered anything wrong or messed up my PCB design, but leads me to believe I have an issue with insufficient current.

The author of the post linked above doesn't mention this issue, however admittedly I am attempting a much larger display. But even then, I wouldn't be able to get a display their size working.

The MAX7219 datasheet implies that the max operating current could be as high as 330mA (with all segments on, which is much more than what I am attempting), which I guess makes sense why I am running out of current.

Does anyone know any trick to reduce the current draw of the chips? I'm hoping there's something smart I can do within the code.

The datasheet for the chip can be found here.

I've also appended the current code below for additional information.

Thanks for your help, I appreciate it!


#include <SPI.h>

// What pin on the Arduino connects to the LOAD/CS pin on the MAX7219/MAX7221
#define LOAD_PIN 7


void maxTransfer(uint8_t address, uint8_t value) {

  // Ensure LOAD/CS is LOW
  digitalWrite(LOAD_PIN, LOW);

  SPI.transfer(address);
  SPI.transfer(value);

  SPI.transfer(address);
  SPI.transfer(value);

  SPI.transfer(address);
  SPI.transfer(value);

  SPI.transfer(address);
  SPI.transfer(value);

  SPI.transfer(address);
  SPI.transfer(value);

  SPI.transfer(address);
  SPI.transfer(value);

  SPI.transfer(address);
  SPI.transfer(value);

  SPI.transfer(address);
  SPI.transfer(value);

  SPI.transfer(address);
  SPI.transfer(value);

  SPI.transfer(address);
  SPI.transfer(value);

  SPI.transfer(address);
  SPI.transfer(value);

  SPI.transfer(address);
  SPI.transfer(value);

  SPI.transfer(address);
  SPI.transfer(value);

  SPI.transfer(address);
  SPI.transfer(value);

  SPI.transfer(address);
  SPI.transfer(value);

  SPI.transfer(address);
  SPI.transfer(value);

  SPI.transfer(address);
  SPI.transfer(value);

  SPI.transfer(address);
  SPI.transfer(value);

  SPI.transfer(address);
  SPI.transfer(value);

  SPI.transfer(address);
  SPI.transfer(value);

  SPI.transfer(address);
  SPI.transfer(value);

  // Tell chip to load in data
  digitalWrite(LOAD_PIN, HIGH);
}
 

void setup() {
 
  // Set load pin to output
  pinMode(LOAD_PIN, OUTPUT);

  // Reverse the SPI transfer to send the MSB first  
  SPI.setBitOrder(MSBFIRST);
 
  // Start SPI
  SPI.begin();

  // Run test
  // All LED segments should light up
  maxTransfer(0x0F, 0x01);
  delay(1000);
  maxTransfer(0x0F, 0x00);
 
  // disable mode B
  maxTransfer(0x09, 0x00);
 
  // Use lowest intensity
  maxTransfer(0x0A, 0x00);
 
  // scan 8 digits
  maxTransfer(0x0B, 0x07);
 
  // Turn on chip
  maxTransfer(0x0C, 0x01);
 
}

void loop() {

  // This loop just turns on a single segment at a time in a circular pattern around the perimeter of each display.

  int delayspeed = 500;

  for (uint8_t i = 1; i < 0x09; ++i)
  {
    maxTransfer(i, 0x00);
  }
  maxTransfer(0x01, 0b01000000);
  delay(delayspeed);
 
  for (uint8_t i = 1; i < 0x09; ++i)
  {
    maxTransfer(i, 0x00);
  }
  maxTransfer(0x02, 0b01000000);
  delay(delayspeed);

  for (uint8_t i = 1; i < 0x09; ++i)
  {
    maxTransfer(i, 0x00);
  }
  maxTransfer(0x03, 0b01000000);
  delay(delayspeed);

  for (uint8_t i = 1; i < 0x09; ++i)
  {
    maxTransfer(i, 0x00);
  }
  maxTransfer(0x04, 0b01000000);
  delay(delayspeed);

  for (uint8_t i = 1; i < 0x09; ++i)
  {
    maxTransfer(i, 0x00);
  }
  maxTransfer(0x04, 0b00100000);
  delay(delayspeed);

  for (uint8_t i = 1; i < 0x09; ++i)
  {
    maxTransfer(i, 0x00);
  }
  maxTransfer(0x04, 0b00010000);
  delay(delayspeed);

  for (uint8_t i = 1; i < 0x09; ++i)
  {
    maxTransfer(i, 0x00);
  }
  maxTransfer(0x08, 0b00100000);
  delay(delayspeed);

  for (uint8_t i = 1; i < 0x09; ++i)
  {
    maxTransfer(i, 0x00);
  }
  maxTransfer(0x08, 0b00010000);
  delay(delayspeed);

  for (uint8_t i = 1; i < 0x09; ++i)
  {
    maxTransfer(i, 0x00);
  }
  maxTransfer(0x08, 0b00001000);
  delay(delayspeed);

  for (uint8_t i = 1; i < 0x09; ++i)
  {
    maxTransfer(i, 0x00);
  }
  maxTransfer(0x07, 0b00001000);
  delay(delayspeed);

  for (uint8_t i = 1; i < 0x09; ++i)
  {
    maxTransfer(i, 0x00);
  }
  maxTransfer(0x06, 0b00001000);
  delay(delayspeed);

  for (uint8_t i = 1; i < 0x09; ++i)
  {
    maxTransfer(i, 0x00);
  }
  maxTransfer(0x05, 0b00001000);
  delay(delayspeed);

  for (uint8_t i = 1; i < 0x09; ++i)
  {
    maxTransfer(i, 0x00);
  }
  maxTransfer(0x05, 0b00000100);
  delay(delayspeed);

  for (uint8_t i = 1; i < 0x09; ++i)
  {
    maxTransfer(i, 0x00);
  }
  maxTransfer(0x05, 0b00000010);
  delay(delayspeed);

  for (uint8_t i = 1; i < 0x09; ++i)
  {
    maxTransfer(i, 0x00);
  }
  maxTransfer(0x01, 0b00000100);
  delay(delayspeed);

  for (uint8_t i = 1; i < 0x09; ++i)
  {
    maxTransfer(i, 0x00);
  }
  maxTransfer(0x01, 0b00000010);
  delay(delayspeed);
 
}

Does the library has a method to control panel brightness?

It does, I’ve already coded all the chips to display the lowest brightness setting.

Why don't you supply more current?

You haven't mentioned how much is available from your current power supply.

The other factor that affects the current consumption is the Iset resistor attached to each max chip. Increasing its value will lower the current consumption.

I think that's what I'm opting for now. Previously only supplied by the 5V pin of the Arduino Nano, which I've read has a maximum current draw of ~800mA.

I will redesign the PCB to support a DC barrel jack, probably will get a 5V 3A DC power supply. I'll also incorporate some jumpers in the new design so that I can measure my current draw from the power supply.

Follow-up question; what is the best way I can now supply power to the Nano from the 5V DC power supply? I was thinking I could purchase and incorporate a 5V -> 12V buck converter, then push the 12V into the VIN pin of the Nano.... But it seems a bit silly to do this? Would you have any better suggestions?

Thanks again for your help.

Maybe Uno, under carefully chosen circumstances, but not Nano.

USB can supply only around 500mA in total.

If using the Vin pin on the Nano, with 7.5V supply you might be ok drawing maybe 400mA, but as that input voltage increases, the output current must be correspondingly lower, otherwise the Nano's onboard regulator can very easily overheat and shut down or be damaged. At 12V supply, 150mA is about as much as you would want to draw.

Connect it to the 5V pin on the Nano.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.