Max7219 stops displaying data

Hi Everyone!

This is my first post to this forum--I am a complete newbie and need a little help. I'm a tinkerer, but I've got no coding experience...

I have an application that'll send a number to the serial port on my machine a specified number of times per second at a specified baud rate. I'd like to display that number on an 8-digit, 7 segment display driven by a max7219 chip. I'd also like to be able to update that number as I change it in the application--when I change it, the application will start sending the new number.

I added the max7219 library to the web editor, and lo-and-behold, one of the included examples allows a person to type in a number and send it to the display using the serial monitor--it works almost flawlessly. When I fired up my application, however, it would display the number, but it wouldn't update it. I've been messing around with it for days, and I finally discovered that if I remove the delay in the code, it works. But only for a minute. After that, the rx and tx lights stop blinking and become solid and the display seems to display a variation of the last string it received.

After some Googling, I thought it might be an issue with the buffers getting full, but I've tried every method I can find for clearing them without success--nothing I try makes it work for more than a minute or two. I'm hoping there's a simple fix to this. Does anyone have any ideas?

I'm not sure whether this matters, but I'm running Ubuntu 16.04. Here's a copy of the sketch I'm using denoting the change in the delay:

/***********************************************************
 * 
 * MAX7219 and 8x7 Segment LED Display
 * 
 * by Chris Rouse November 2015
 * 
 Connections
 pin 12 is connected to the DataIn 
 pin 11 is connected to the CLK 
 pin 10 is connected to LOAD 
 We have a single MAX7219. 
 * 
 * The number to display is read from the Serial Input
 * either type the number in the Serial Monitor
 * or via, for example, Bluetooth.
 * 
 * Only numbers are displayed, but negative 
 * and decimal fractions can be displayedz
 * 
 * For numbers less than zero, for example 0.125
 * must have a leading zero, ie 0.125 and not .125
 * 
 * The LED display can be cleared by sending any letter
 * 
 **********************************************************/
#include "LedControl.h" 
LedControl lc=LedControl(12,11,10,1);
int number[8];
int numLength = 0; // number of digitss
int i = 0;
int dp = 0; // position of decimal point, if any
int j = 0;
boolean minusSign = false; // false if negative number
boolean valid = false;
double displayNumber = 0;
String stringNumber;
void setup() {
  /*
   The MAX7219 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);
  /* Start Serial Monitor */
  Serial.begin(4800);
}

void printDigits() {
  lc.clearDisplay(0);
  for(i=0;i<numLength;i++) {
    if( dp == numLength-i){
     lc.setDigit(0,i,number[numLength-(i+1)],true);
    }
    else{
      lc.setDigit(0,i,number[numLength-(i+1)],false);
    }
  }
}
//
void loop() {
  if(Serial.available() > 0){
    j = 0;
    numLength = 0;
    dp=0;
    stringNumber ="";
  }
  // get number to display
  while (Serial.available()){
    int a = Serial.read();
//there was originally a delay of 10 here.
    stringNumber = stringNumber + char(a);
    if((a>47 && a< 58) || a == 45){ // ignore line end and decimal point
      a = a - 48;
      number[j] = a;
      numLength=numLength+1;
      if(numLength > 8){
        numLength = 8; // stop overflow
      }
      j = j +1;
    }
    if(a == 46) { // decimal point
      dp = numLength;
    }
    printDigits();
    valid = true;
  }      
  // check for a minus
  if (number[0] == -3){
    lc.setRow(0,numLength-1,B00000001); // print a minus sign
  }
  if(valid == true){
    Serial.println(stringNumber); // this is the string sent to the Serial Port.
    valid = false;
    }
    }

You have two main problems in the sketch:

  • You have no delimiter character. So the only way to recognize the beginning of the number string on the serial interface is a short pause but by removing the delay you don't even have that anymore. So define a delimiter code (carriage return might be a good choice) and start a new number if you receive that character.

  • You're using the String class. That might be responsible for the freeze you see after a few minutes. That class is not designed for embedded computers like the Arduino because it fragments the memory and soon enough you'll end with no large enough block available. The Arduino then reacts unpredictable, most often it's simply freezing. As you don't use the constructed string other than returning it to the serial interface, you can delete that completely and return the contents of your numbers array.