max7219 code problem

I'm creating a project using 7-segment displays and the max7219. To test the 7219, which I've never used before, I wrote a simple program to increment a number and output to the display every 20ms. My problem is that at 800 the program stops. Any ideas on why this happens? It doesn't matter if I start at zero or 500 or 750, it always stops after 800. Here's the code and a link to the video.

http://youtu.be/CVRvgKvepLs

#include "LedControl.h"
LedControl lc=LedControl(12,11,10,1);

int delayTime = 20;
int tick = 500;

void setup(){
  lc.shutdown(0,false);
  lc.setIntensity(0,8);
  lc.clearDisplay(0);
}

void loop(){
    int thousands, hundreds, tens, ones;
    thousands = tick/1000;
    hundreds = tick/100;
    hundreds = hundreds - ((hundreds/10)*10);
    tens = tick/10;
    tens = tens - ((tens/10)*10);
    ones = tick - ((tick/10)*10);
    
    if(tick >= 1000){
      lc.setDigit(0,3,thousands,true);
    }
    if(tick >= 100){
      lc.setDigit(0,2,hundreds,true);
    }
    if(tick >= 10){
      lc.setDigit(0,1,tens,true);
    }
    lc.setDigit(0,0,ones,true);
    
    tick++;
    delay(delayTime);
}

Sorry about that old chap, but I simply cannot replicate your problem (using a Pro Mini, which should be equivalent, and different pin connections).

Just for fun I ran it with five digits (note, actually a matrix display) and it seems to have jammed on the number “32760” which is of course, (more or less) the maximum value of a 16 bit signed integer.

But according to your video, it reaches “800” and then the display disappears.

I have to conclude that there is some glitch somewhere, but not in the code you gave.

I would suggest two experiments. Try pulling it down and re-wiring it, and/ or try my code to see where it gets to:

#include "LedControl.h"
LedControl lc=LedControl(12,11,10,1);

int delayTime = 20;
int tick = 500;

void setup(){
  lc.shutdown(0,false);
  lc.setIntensity(0,8);
  lc.clearDisplay(0);
}

void loop(){
    int tenthou, thousands, hundreds, tens, ones;
    tenthou = tick/10000;
    thousands = tick/1000;
    thousands = thousands - ((thousands/10)*10);
    hundreds = tick/100;
    hundreds = hundreds - ((hundreds/10)*10);
    tens = tick/10;
    tens = tens - ((tens/10)*10);
    ones = tick - ((tick/10)*10);
    
    if(tick >= 10000){
      lc.setDigit(0,4,tenthou,true);
    }
    if(tick >= 1000){
      lc.setDigit(0,3,thousands,true);
    }
    if(tick >= 100){
      lc.setDigit(0,2,hundreds,true);
    }
    if(tick >= 10){
      lc.setDigit(0,1,tens,true);
    }
    lc.setDigit(0,0,ones,true);
    
    tick++;
    delay(delayTime);
}

If it behaves differently, it may in fact be a RAM crash due to the library - it is mentioned that the library has some potential problems.

Thanks for the reply, Paul. I'd ordered a couple of the cheap fake max7219s and was using one of those in my circuit. Switched to the real $11 max and it works fine. Thanks for wiring up a circuit to test it.

While you have it up and running....if you still have it...care to try and see how the decimal point works? Need it to display on digit 2 to indicate dollars and cents. I checked out this guy's experiment:

http://forum.arduino.cc/index.php?topic=112756.0

...But it doesn't work. When I use lc.setChar, the decimal does not come on, and it forces the digit to flash on and off very dimly. Not sure how to use the LedControl library to get around this. Please note that I am using one of those quad 4-digit displays, not individual 1-digit displays. See the video below.

http://youtu.be/qWJSJfKA50k

Note: the video may or may not work....it seems to be having trouble processing at youtube.

Here is some code that I was working on. I provides a dp and suppresses the first zero when appropriate

/* This is a bluetooth repeater.
It takes whatever is sent, whenever it is sent for 
display on 4x7 to 2 decimal places

   pin 12 is connected to the MAX7221        pin 1
   pin 11 is connected to the CLK           pin 13
   pin 10 is connected to LOAD              pin 12
*/
#include "LedControl.h" 
LedControl lc=LedControl(12,11,10,1); // lc is our object

float input;
int num = 0;   // for incoming serial data
int digit0, digit1, digit2, digit3;

void setup()
{
  Serial.begin (9600);
  // the zero refers to the MAX7219 number, it is zero for 1 chip
  lc.shutdown(0,false);// turn off power saving, enables display
  lc.setIntensity(0,8);// sets brightness (0~15 possible values)
  lc.clearDisplay(0);// clear screen 
}

void loop()
{
          if (Serial.available() > 0) {
                // read the incoming byte:
                num = Serial.read();
  cfgdigits();

  lc.setDigit(0,0,digit0,false);  
  lc.setDigit(0,1,digit1,false);
  lc.setDigit(0,2,digit2,true);// true gives DP!
  
if (num > 999)
  {
  lc.setDigit(0,3,digit3,false);  
  }
else
  {
    lc.setChar(0,3,' ',false);
  }
  }
}
  
void cfgdigits () { 
if (num > 999)
  {
    float result = num / 1000;  // = 3.456
    digit3 = result; //digit3 is int, so it's just thous  =3
    int remain = num%1000; // result is int so this gets the remainder = 456
    digit2=remain/100; //digit2 is int, so its just the huns = 4
    remain = num%100; // result is float so this gets the remainder =56.00
    digit1=remain/10; //digitTwo is int, so its just the tens = 5
    digit0 = remain % 10;  //this gets the remainder of 56.00/10 =6
  }
else if (num > 99)
  {
    float result = num / 100;  // = 4.56
    digit3 = 0;   // NO diigit3 - leadingg zero is blank
    digit2 = result; //digitThree is int, so it's just huns  =4
    int remain = num%100; // result is float fo this gets the remainder =56.00
    digit1=remain/10; //digitTwo is int, so its just the tens = 5
    digit0 = remain % 10;  //this gets the remainder of 56.00/10 =6
  }
else if (num>9)
  {
    float result = num / 10;  
    digit3 = 0;   // 
    digit2 = 0; 
    digit1 = result;
    digit0 = num % 10;  
  }
else
  {
    digit3 = 0;
    digit2 = 0;// 
    digit1 = 0;
    digit0 = num;  
  }
}

Thanks, Nick, for your thoughts. I set up my code like yours:

#include "LedControl.h"
LedControl lc=LedControl(12,11,10,1);

int delayTime = 25;
int tick = 500;
int thousands, hundreds, tens, ones;

void setup(){
  lc.shutdown(0,false);
  lc.setIntensity(0,5);
  lc.clearDisplay(0);
}

void loop(){
  calcDigits();
  
  if(tick >= 0){
    lc.setDigit(0,0,ones,false);
  }
  if(tick >= 10){
    lc.setDigit(0,1,tens,false);
  }
  if(tick >= 100){
    lc.setDigit(0,2,hundreds,true);
  }
  if(tick >= 1000){
    lc.setDigit(0,3,thousands,false);
  }
  delay(delayTime);
  tick++;
}

void calcDigits(){
  thousands = tick/1000;
  hundreds = tick/100;
  hundreds = hundreds - ((hundreds/10)*10);
  tens = tick/10;
  tens = tens - ((tens/10)*10);
  ones = tick - ((tick/10)*10);
}

And the video: http://youtu.be/-L7aHTatJLg

Still no decimal point. Why would setting the digit2 (hundreds in my case) to true give me the dp when all the others are false? I guess my big questions is this: Why do the digits light up when I use false? I thought false was supposed to turn them off. The counter works when all were set to true. The counter also works when all are set to false. Why?

I know I'm close, and the answer is probably something obvious, but it has not revealed itself to me yet.

One other thing. Sometimes, but not always, when I load my sketch or add power to the arduino, all four digits flash 8's. I do not want this. Thanks again for your time and patience.

mauimark: Still no decimal point. Why would setting the digit2 (hundreds in my case) to true give me the dp when all the others are false? I guess my big questions is this: Why do the digits light up when I use false? I thought false was supposed to turn them off. The counter works when all were set to true. The counter also works when all are set to false. Why?

Because that parameter - if you look at the reference - is specifically to control the decimal, has nothing to do whether the digit appears or not. That would be another function in the library. Basically, the digits are all blanked when you assert "lc.clearDisplay()", and switched on the first time you invoke "lc.setDigit()".

My suspicion at this point is that the decimal does not appear because you have not wired it to the MAX7219. :astonished:

mauimark: One other thing. Sometimes, but not always, when I load my sketch or add power to the arduino, all four digits flash 8's. I do not want this. Thanks again for your time and patience.

Ah, that's easy - though I have never bothered about it until now (but did notice it and ignored it) - and haven't seen it mentioned before either. Just put a 47k resistor from the Chip Select of the MAX7219 to Vcc. I just did this on my rig and it is a nice idea. :D

mauimark: Still no decimal point. Why would setting the digit2 (hundreds in my case) to true give me the dp when all the others are false? I guess my big questions is this: Why do the digits light up when I use false? I thought false was supposed to turn them off. The counter works when all were set to true. The counter also works when all are set to false. Why?

I know I'm close, and the answer is probably something obvious, but it has not revealed itself to me yet.

One other thing. Sometimes, but not always, when I load my sketch or add power to the arduino, all four digits flash 8's. I do not want this. Thanks again for your time and patience.

I'm afraid I can't comment much as my 4x7 was a breadboard lashup some months ago and I haven't proceeded with it. I'm of the same view as Paul about the missing DP!

Note that I use a 7221 but I don't think it makes any difference to the procedure. For the hardware, I rigorously followed the playground article http://playground.arduino.cc/Main/MAX72XXHardware with which you are probably familiar, but the software left a lot to be desired.

The end result worked exactly as it should, including the DP. I don't recall all segments flashing at the start, but it would not have concerned me if they had.

Basically, the digits are all blanked when you assert "lc.clearDisplay()", and switched on the first time you invoke "lc.setDigit()".

Ah.

...you have not wired it to the MAX7219.

Oh.

Just put a 47k resistor from the Chip Select of the MAX7219 to Vcc.

Thanks for the tip. I still get a very dim blink on digits 0 and 1 at startup, but it's not noticeable enough for me to worry about. Good explanations and easy fixes. Thank you both for your input.