MAX7219 and 7 segment display

Hi!

I have a 4 digit 7 segment common cathode display and a MAX7219. I checked my wirings several times, so I'm sure it is correct. Output voltage is correct.

Since I can't find another, I'm using the LedControl Library and tried it with several Arduinos and different IDE versions.

Unfortunately, also with the examplecode, I only get characters without any sense. So you would think I just wired the segments wrong, but no, if I send every digit a "5", it doesnt show thr same character on every digit. Every different number shows something different and every segment gets voltage one time (and the segments light up), so I'm sure the display is working fine.

I did realize that the display changes its "characters", but commands like turnoff or brightness dont have any influence. I do see that when I disconnect one of the 3 wires from the Arduino, also something changes, so I guess they're also connected correctly. Oh and yeah, I also changed the MAX once.

Let me sum up:
the wires are connected correctly
the pins on the Arduino are declared correctly
the display works
the MAX7219 is working
the error is not dependant on Arduino or IDE

Any ideas? Thanks! :slight_smile:

Turn off code b decoding and send each digit the same segment information, like 0x01, 0x02, 0x04, etc. and that will help you identify the segments that may be incorrectly wired up.

The worst mistake in debugging is tunnel vision.

Why is everyone always so hesitant to post code? Worried about trade secrets getting stolen? The MAX7219 is pretty easy to wire assuming you don't get the polarity backwards (and that is easy to diagnose - you get no output despite obvious activity on the 16 outputs), the problem is always in the code.

"the problem is always in the code" I second that! When its not the wiring anyway 8)

http://arduino.cc/forum/index.php/topic,126144.0.html

thanks for your help! I didn't post my code since I used the demo code from the library.

//We always have to include the library
#include "LedControl.h"

/*
 Now we need a LedControl to work with.
 ***** These pin numbers will probably not work with your hardware *****
 pin 12 is connected to the DataIn 
 pin 11 is connected to the CLK 
 pin 10 is connected to LOAD 
 We have only a single MAX72XX.
 */
LedControl lc=LedControl(12,11,10,1);

/* we always wait a bit between updates of the display */
unsigned long delaytime=250;

void setup() {
  /*
   The MAX72XX is in power-saving mode on startup,
   we have to do a wakeup call
   */
  lc.shutdown(0,false);
  /* Set the brightness to a medium values */
  lc.setIntensity(0,8);
  /* and clear the display */
  lc.clearDisplay(0);
}


/*
 This method will display the characters for the
 word "Arduino" one after the other on digit 0. 
 */
void writeArduinoOn7Segment() {
  lc.setChar(0,0,'a',false);
  delay(delaytime);
  lc.setRow(0,0,0x05);
  delay(delaytime);
  lc.setChar(0,0,'d',false);
  delay(delaytime);
  lc.setRow(0,0,0x1c);
  delay(delaytime);
  lc.setRow(0,0,B00010000);
  delay(delaytime);
  lc.setRow(0,0,0x15);
  delay(delaytime);
  lc.setRow(0,0,0x1D);
  delay(delaytime);
  lc.clearDisplay(0);
  delay(delaytime);
} 

/*
  This method will scroll all the hexa-decimal
 numbers and letters on the display. You will need at least
 four 7-Segment digits. otherwise it won't really look that good.
 */
void scrollDigits() {
  for(int i=0;i<13;i++) {
    lc.setDigit(0,3,i,false);
    lc.setDigit(0,2,i+1,false);
    lc.setDigit(0,1,i+2,false);
    lc.setDigit(0,0,i+3,false);
    delay(delaytime);
  }
  lc.clearDisplay(0);
  delay(delaytime);
}

void loop() { 
  writeArduinoOn7Segment();
  scrollDigits();
}

Since this didn't work, I modified it a bit, but nothing special, just like making a number out of the i's.

I checked the wiring together with my gf, so I'm not allowed to say there could be a mistake :wink: But look, here's my "proof" why wiring has to be "correct". For the moment, I don't care if segment a is wired to segment a (even if I wired it this way), since I want it to display 8s on every digit, including the point. So all segments have to light up in a way. If I send random numbers to the display, every segment lights up (just not the correct ones for the specific number), so I know cathodes and anodes are correct. And this leads me to the conclusion that the wiring is probably correct, but either way, for an 8, everything should light up.

I'll try the segment information idea.

That's one of the problems with library's - you don't really see what you're doing or understand.

Try this - uses SPI instead equivalent of shiftout() to put the data in the MAX7219.
Bury all the set up stuff in a function or something if you want.
Might be some unused stuff in here, ignore it, am planning ahead for next test phase.

/* program to scroll message across a MAX7219.
 Set up in No Decode mode.
 */
// ************************************ //
//a_presetup
#include <SPI.h>

// define pins usage
// D0, D1 Serial interface
// D11-12-13 SPI interface

byte ss0 = 10; // latch to MAX7210

byte intensity = 0x0f;
byte  bitSel = 0;

// define variables

// connect so that Upper Left is 7,7  Lower Right is 0,0

// define 7219 register addresses for setup
byte decode_mode = 0x09; // 0x00 = No decode for digits 7-0
byte intensity_level = 0x0A; // 0x08 = mid level. Range is 0x00 to 0x0F
byte scan_limit = 0x0B; // 0x07 for all columns
byte shutdown_normal = 0x0C; // 0x00 - shutdown, 0x01 = normal
byte display_test = 0x0F; // 0x00 = normal, 0x01 = display test mode all on full

byte x; // for:next counter
byte digitRegister = 0;
unsigned long currentMillis;
unsigned long previousMillis;
// 1/3 second hold each position - base this on a pot reading or something later
unsigned long holdDuration =1000; 

byte incomingByte = 0;

// ************************************ //

// b_setup
void setup(){
  pinMode (ss0, OUTPUT);  
  digitalWrite (ss0, HIGH);
  Serial.begin(115200);

  // turn on SPI port
  SPI.begin();

  /*  set up MAX7219 registers  */

  // decode to No decode mode
  digitalWrite (ss0, LOW);
  SPI.transfer (decode_mode);
  SPI.transfer (0x00);
  digitalWrite (ss0, HIGH);

  Serial.println("No decode mode");

  // intensity to mid level
  digitalWrite (ss0, LOW);
  SPI.transfer (intensity_level);
  SPI.transfer (intensity);
  digitalWrite (ss0, HIGH);

  Serial.println("Intensity");

  // scan limit to all 7 columns
  digitalWrite (ss0, LOW);
  SPI.transfer (scan_limit);
  SPI.transfer (0x07);
  digitalWrite (ss0, HIGH);

  Serial.println("Scan Limit");


  // dispay test On
  digitalWrite (ss0, LOW);
  SPI.transfer (display_test);
  SPI.transfer (0x01);
  digitalWrite (ss0, HIGH);
  delay(50);

  Serial.println("Display test on");

  // dispay test to normal
  digitalWrite (ss0, LOW);
  SPI.transfer (display_test);
  SPI.transfer (0x00);
  digitalWrite (ss0, HIGH);
  delay(50);

  Serial.println("Display test off");

  // shutdown to Normal mode
  digitalWrite (ss0, LOW);
  SPI.transfer (shutdown_normal);
  SPI.transfer (0x01);
  digitalWrite (ss0, HIGH);

  Serial.println("Normal mode");

  delay(50);

  // clear the display

  for (x = 1; x<9; x=x+1){  // pick a column
    for (bitSel = 0x80; bitSel>0; bitSel = bitSel >>1){

      SPI.transfer (x);
      SPI.transfer(0);
      digitalWrite (ss0, LOW);
      digitalWrite (ss0, HIGH);

    }
  }
  Serial.println("setup done");
}

// c_loop
void loop(){

  for (x = 8; x>0; x=x-1){  // pick a column
    for (bitSel = 0x80; bitSel>0; bitSel = bitSel>>1){
      SPI.transfer (x); // selecting the digit register/column
      SPI.transfer(bitSel); // and data for that column
      digitalWrite (ss0, LOW);
      digitalWrite (ss0, HIGH);

      delay(255);

      SPI.transfer (x);
      SPI.transfer(0x00);
      digitalWrite (ss0, LOW);
      digitalWrite (ss0, HIGH);

    }
  }
} // end loop

This is the code I have running here, but stripped down to 1 display.
http://arduino.cc/forum/index.php/topic,126144.0.html

Thank you for your help. I just noticed, 2 out of 4 ordered displays are common anode, and of course I tried these first. With the common cathode it works better. Actually I didn't order CAs...

But here's a new problem. A lot of numbers work very good. But some just don't. There are some combinations of numbers and the dot that work. But if I send another number/dot combination, the display flashes shortly and display nothing. If I send a "working" number again, I have to reset the Arduino a few times until it works... What do you think could I do?

This might help all those working on seven segment display with max7219

all the best

I pasted the wrong link in the above post.Consider this one

You have a single, 4-digit display, or do you have 4 separate, 1-digit displays?
Or do you have several or some kind? I'm confused as you're saying you have both common anode types and common cathode types.

Regardless of the type, a 4-digit display that has 12 pins can be wired directly to 12 pins on the Arduino if you want to confirm that the display works as it should.

The 4-digit, 8-segment (has decimal point), 12-pin display I have is currently wired directly
Board pins D2/D3/D4/D5/D6/D7/D8/D9 control A/B/C/D/E/F/G/DP segment respectively
Board pins D10/D11/D12/D13 control DIG1/DIG2/DIG3/DIG4 respectively

E.g., for common anode, the digit on HIGH and segment on LOW will make it light up.

If wiring it up directly, make sure to use current limit resistors. The resistors should go between D2 thru D9 and the anodes A thru DP.

The digit pins have to sink all of the current from 8 segments - make sure to use resistors to not exceed the pin current rating. Better way is to use a transistor for sinking current.

This is from a 3-digit example, 4 digit just need another transistor at the bottom.