Can't Light Multiple LEDs with MAX7219 and 5x7 Matrix

Hi,

I'm using the LedControl.h library to control a 5x7 LED matrix through a MAX7219.

If I light each LED in sequence then everything works okay. [using lc.setLed(0,col,row,true);]

If I use lc.setColumn(0,1,B10101000); then the relevant LEDs in row 1 light up.
If I use lc.setColumn(0,2,B10101000); then the relevant LEDs in row 2 light up.

etc.

(Note: I'm padding the 8-bit binary value with 000 to use the library with a 5 column matrix).

So, onto my problem!

If I then use two any lc.setColumn commands in the same sketch nothing lights up!

My first thought is that this something to do with there not being enough power to light the LEDs. This happens using both USB power and 9V power source.

Any advice would be gratefully received.

Did you run the demo for talking with a 5X7 matrix that can be found in the playground ? it is pretty involved to make a max device work. I hav a couple of these devices and have just begun to study the data sheet and the demo code. I would load up that sketch and get it to work. Doing that should get you heded down the right path for your project.

RWW

Pretty involved? You write a few registers to configure it, then you send it data.
I felt it was pretty straightforward, for driving 8 7-segment+DP displays anyway.

Here is my setup code for it. Nothing fancy, just putting data in the registers with the display off to start, then setting up the rest of them.

Yeah, maybe its redundant and calling out to be rewritten as a function or something now that I re-read it 6 months later, but its clear and you have control and can see what’s going on.
And I thought it wasn’t bad for a hardware guy! And it executes quick, probably because the SPI.xxx commands are not further buried in something else (yeah, that’s my story and I’m sticking with it …)

// addresses for the MAX7221, and the values/ranges to write in

#define DECODE_MODE 0x09 // write data 0xFF, Code B Decode for all digits
#define INTENSITY_ADDRESS 0x0A // 0x07 to start, half intensity. valid from 0x00 (min) to 0x0F (max)
#define SCANLIMIT_ADDRESS 0x0B // 0xFF, all 8 digits on
#define SHUTDOWN_ADDRESS 0x0C  // 0x01, normal operation (0x01 = shutdown) - powers up in shutdown mode

#define DISPLAYTEST_ADDRESS 0x0F // 0x01 = all lights on full, 0x00 = normal ops
#define leftscore_tens_address 0x01 // digit 0, leftscore_tens+left_yellow, fill right hand byte with data to display
// data = 0-9, A='-', B='E', C='H', D='L', E='P', F=blank
#define leftscore_ones_address 0x02 // digit 1, leftscore_ones+right_yellow
#define rightscore_tens_address 0x03 // digit 2, rightscore_tens+right_red
#define rightscore_ones_address 0x04 // digit 3, rightscore_ones+right_yellow
#define minutes_tens_address 0x05 // digit 4, minutes_tens+colon
#define minutes_ones_address 0x06 // digit 5, minutes_ones+left_priority
#define seconds_tens_address 0x07 // digit 6, seconds_tens+right_priority
#define seconds_ones_address 0x08 // digit 7, seconds_ones+swap

void setup() // stuff that runs once before looping forever
{
  // start up SPI to talk to the MAX7221
  SPI.begin(); // nothing in () because we are the master
  pinMode(SS, OUTPUT);  // Slave Select for SPI  <--- Need this here before any SPI writes

  //  MAX7221: write shutdown register  
  digitalWrite(SS,LOW);  // take the SS pin low to select the chip:
  SPI.transfer(SHUTDOWN_ADDRESS);  // select the Address,
  SPI.transfer(0x00);      // select the data, 0x00 = Outputs turned off
  digitalWrite(SS,HIGH);   // take the SS pin high to de-select the chip:
  // Serial.println("shutdown register, dislays off");

  // put known values into MAX7221 so doesn't have weird display when actually turned on
  // 0x0F = blank digit
  digitalWrite(SS,LOW);  // take the SS pin low to select the chip:
  SPI.transfer(leftscore_tens_address);  // select the Address,
  SPI.transfer(0x0F);      // select the data
  digitalWrite(SS,HIGH);   // take the SS pin high to de-select the chip

  digitalWrite(SS,LOW);  // take the SS pin low to select the chip:
  SPI.transfer(leftscore_ones_address);  // select the Address,
  SPI.transfer(0x0F);      // select the data
  digitalWrite(SS,HIGH);   // take the SS pin high to de-select the chip

  digitalWrite(SS,LOW);  // take the SS pin low to select the chip:
  SPI.transfer(rightscore_tens_address);  // select the Address,
  SPI.transfer(0x0F);      // select the data
  digitalWrite(SS,HIGH);   // take the SS pin high to de-select the chip  

  digitalWrite(SS,LOW);  // take the SS pin low to select the chip:
  SPI.transfer(rightscore_ones_address);  // select the Address,
  SPI.transfer(0x0F);      // select the data
  digitalWrite(SS,HIGH);   // take the SS pin high to de-select the chip

  digitalWrite(SS,LOW);  // take the SS pin low to select the chip:
  SPI.transfer(minutes_tens_address);  // select the Address,
  SPI.transfer(0x0F);      // select the data
  digitalWrite(SS,HIGH);   // take the SS pin high to de-select the chip

  digitalWrite(SS,LOW);  // take the SS pin low to select the chip:
  SPI.transfer(minutes_ones_address);  // select the Address,
  SPI.transfer(0x0F);      // select the data 
  digitalWrite(SS,HIGH);   // take the SS pin high to de-select the chip

  digitalWrite(SS,LOW);  // take the SS pin low to select the chip:
  SPI.transfer(seconds_tens_address);  // select the Address,
  SPI.transfer(0x0F);      // select the data
  digitalWrite(SS,HIGH);   // take the SS pin high to de-select the chip  

  digitalWrite(SS,LOW);  // take the SS pin low to select the chip:
  SPI.transfer(seconds_ones_address);  // select the Address,
  SPI.transfer(0x0F);      // select the data 
  digitalWrite(SS,HIGH);   // take the SS pin high to de-select the chip


  //  MAX7221: 
  //  write intensity register
  digitalWrite(SS,LOW);  // take the SS pin low to select the chip:
  SPI.transfer(INTENSITY_ADDRESS);  // select the Address,
  SPI.transfer(intensity);      // select the data
  digitalWrite(SS,HIGH);   // take the SS pin high to de-select the chip:
  //Serial.println("intensity register ");

  // write scanlimit register
  digitalWrite(SS,LOW);  // take the SS pin low to select the chip:
  SPI.transfer(SCANLIMIT_ADDRESS);  // select the Address,
  SPI.transfer(0xFF);      // select the data - FF = all 8 digits
  digitalWrite(SS,HIGH);   // take the SS pin high to de-select the chip:
  //Serial.println("scanlimit register ");

  // write decode register
  digitalWrite(SS,LOW);  // take the SS pin low to select the chip:
  SPI.transfer(DECODE_MODE);  // select the Address,
  SPI.transfer(0xFF);      // select the data - FF = all 8 digits
  digitalWrite(SS,HIGH);   // take the SS pin high to de-select the chip:
  //Serial.println("decode register ");

  //display test
  digitalWrite(SS,LOW);  // take the SS pin low to select the chip:
  SPI.transfer(DISPLAYTEST_ADDRESS);  // select the Address,
  SPI.transfer(0x01);      // select the data
  digitalWrite(SS,HIGH);   // take the SS pin high to de-select the chip:
  //Serial.println("digit display test on ");
  delay (100);

  digitalWrite(SS,LOW);  // take the SS pin low to select the chip:
  SPI.transfer(DISPLAYTEST_ADDRESS);  // select the Address,
  SPI.transfer(0x00);      // select the data
  digitalWrite(SS,HIGH);   // take the SS pin high to de-select the chip:
  //Serial.println("digit display test off ");
  delay (100);

  // write shutdown register for normal display operations
  digitalWrite(SS,LOW);  // take the SS pin low to select the chip:
  SPI.transfer(SHUTDOWN_ADDRESS);  // select the Address,
  SPI.transfer(0x01);      // select the data, 0x01 = Normal Ops
  digitalWrite(SS,HIGH);   // take the SS pin high to de-select the chip:

day26,
When I wrote that, I was just starting out with arduino also, the most I had done by then was receive 5 bytes of data over a serial port and turn 1 of 6 outputs on or off.
Can’t much more help without your schematic & code. If you posted them already I apologize, I’m not seeing attachments at the moment (some kind of bug since I’ve been bumped to moderator). If you haven’t, please do so.

MAX6953 might have been a better choice, can control 1-2-3-4 5x7 matrix.
Max7219/7221 can do an 8x8.
I assume you’re running in “no decode” mode?
Since the hardware assumes you have 8 digits with 8 segments each, you probably have to set the registers to only be 5 digits, and maybe even add 5 dummy diodes to look like a six 8-segment displays (but probably not, the device is not charlieplexing, so not connecting 1 segment should not matter).
See page 9 of the datasheet where it discusses the Scan Limit Register.

A little experimentation seems to point to it being a lack of power.

I'm going to get a separate power supply tomorrow to run the LEDs off to confirm.

Okay! I seem to have confirmed that a lack of power is the problem.

I then started to look at how much power I should need and managed to get myself seriously confused. I write software by day and did do some basic electronics quite a few years ago. However, if anyone could explain where I'm going wrong with the following (and be gentle with me as I'm getting on and my mind isn't as agile as it once was!).

I took a look at the following page: http://www.ehow.com/how_7725475_diy-uv-led.html


Point 2 - Forward Voltage of 1 LED * Number of LEDs in a column * 1.25 = Required Voltage

Forward Voltage of 1 LED (typical) = 3V
Number of LEDs in a column = 7

= 3 * 7 * 1.25 = 26.25V (!)

Point 3 - Total Current Load Of LED Matrix = Current Through One Column (equal to the forward current of a single LED) * Number of Columns * 1.25

= 13 * 7 * 1.25 = 113.75ma

Surely I'm going wrong somewhere here!

The 5x7 I'm using is this one: http://optoelectronics.liteon.com/en-us/Product/detail.aspx?txtSpecNo=DS-30-99-394&txtPartNo=LTP-1157AG

I need to buy/make a power supply to run this through a MAX7219 but the MAX7219 has a maximum operating supply of 5.5V.

How can I supply 26.25V to the LED matrix but only 5.5V to the MAX7219?

I've obviously wandered off the path of reality here and would welcome any help finding my way.

That's a common-anode part, the 7219 wants to be total controller of a common cathode part.
The 7219 takes care of muxing the current between the LEDs, so you only need give it power, it takes over for all the LEDs.

I think maxim-ic.com has an application note on driving other displays, I'll see if I can find it for you.

Thanks CrossRoads.

in one article I read the Dig. pins are handling the -ve and the Seg. pins handling the +ve. And that seems to work okay for most part.

When you say "you only need give it power" are you saying that the 7219 deals with distributing the power to each of the LEDs? (I suppose I'm asking if you think I'm thinking of powering the LEDs separately from the 7219).

My questions regarding the power required stem from the fact that it would seem from the article I read that the LEDs need 26V which would obviously kill the 7219! (However, it being a eHow article I'm not placing 100% faith in it).

It's so hard putting thoughts into posts and I realise that I'm not making sense here!

My main questions are:

  • are the calculations in the article on eHow correct? (I want to get this right in future).
  • if so, where have I gone wrong? (Have I read the datasheet incorrectly?)

it would seem from the article I read that the LEDs need 26V

What makes you think that, a search of the page in question makes no mention of 26V

Indeed it does not Grumpy_Mike.

I refer instead to my own calculations (shown in post above) that are derived from the formulae within the article.

Your calculations do not take the 7219 multiplexing into account.
With a common cathode part, 1 Seg would go low and up to 8 Digs would go high, turning on up to 8 LEDs.
So 20ma (depending on current limit resister) x 8 = 160mA.

With a common anode part, 1 Dig would go high and up to 8 Segs would go low, turning on up to 8 LEDs.
Again, 20ma (depending on current limit resister) x 8 = 160mA.

As you are mixing up Common Cathode signals with Common Anode, am not sure its gonna play nice.
Maybe it would just light up twisted 90 degrees from what you expected.

Here’s the application note I was after
http://www.maxim-ic.com/app-notes/index.mvp/id/1196
One of the first things is discusses is driving common anode parts.
A few transisters may solve your problem.

Mike, is there a PNP equivalen to ULN2803?

Excellent CrossRoads! Thanks for the article link.

As you suggest in your post the matrix is rotated 90o due to the row/column swap.

And, thanks for your quick calculation. I can’t believe I forgot to take into account the fact that the 7219 was multiplexing!

Many thanks to everyone who helped here.

is there a PNP equivalen to ULN2803?

From Allegro the 2981 & 2982

From Infineon the BTS 6143D

From ST the VN750-E

They are all high side drivers.

Thanks Mike, UDN2981/2982, that's what I was after.

Would be awesome for driving common cathode displays.
Website says Allegro is in Worcster, just 20 miles down the road from me.