non standad LED matrix with MAX7219s

I have made a display with a clock and three lines of " days since " plus the previous '24 jul 19' type display using 34 MAX7219 chips
.
I tried a modified LedControl sketch to run the displays ( the pin numbers are different to the standard LED blocks, but I can edit a character table if I can see it )

By the time I had got to just the display in 5 lines of 7 characters, it was already telling me I was short of memory, and I hadn't even started counting the "days since" yet.

Here is the crude way I was trying, this is for just showing a demo of all displays showing numbers.

I cannot work out how to make the character into an array inside the character pattern, or how to switch between lc1 and lc2 without repeating everything.

The parola library might be easier for me by making each of the 5 seven character lines into a string and send it ( and work out how to not have it scrolling ) but I can't see the character table file to modify for my displays.

My displays are separate 5x7 so I guess I would have the kerning to make up all 5? 8? columns?

Can anyone suggest the best way to do this please, I am using a promini 328, 5v.

This is my overcomplicated code for just the demo numbers :-

#include <TinyGPS++.h>
        #include "LedControl.h"
     //   #include <VirtualWire.h>
        #include <EEPROM.h>
        #include <TimeLib.h>
    #include <SoftwareSerial.h>
       // Configure SoftSerial library
     SoftwareSerial SoftSerial(4,13); 
    TinyGPSPlus gps;
        
        int addr = 0;
    int displayArrayA[5] = {  63,63,136,72,72};
    int displayArrayB[5] = {  108,254,146,146,146}; 
    int displayArrayC[5] = {  68,124,130,130,130}; 
    int displayArrayD[5] = {  124,254,130,130,130};
    int displayArrayE[5] = {  130,254,146,146,146};
    int displayArrayF[5] = {  128,254,144,144,144};
    int displayArrayG[5] = {  76,124,130,130,138 };
    int displayArrayH[5] = {  254,254,16,16,16};
    int displayArrayI[5] = {  0,0,254,130,130};
    int displayArrayJ[5] = {  0,4,252,130,128};
    int displayArrayK[5] = {  130,254,40,16,68};
    int displayArrayL[5] = {  2,254,2,2,2};
    int displayArrayM[5] = {  254,254,32,64,64};
    int displayArrayN[5] = {  254,254,16,32,8};
    int displayArrayO[5] = {  124,124,130,130,130};
    int displayArrayP[5] = { 112,254,136,136,136};
    int displayArrayQ[5] = {  126,124,138,130,134};
    int displayArrayR[5] = {  98,254,152,144,148};
    int displayArrayS[5] = {  76,100,146,146,146};
    int displayArrayT[5] = {  128,128,254,128,128};
    int displayArrayU[5] = {  252,252,2,2,2};
    int displayArrayV[5] = {  248,248,2,4,4};
    int displayArrayW[5] = {  252,252,12,2,2};
    int displayArrayX[5] = {  198,198,16,40,40};
    int displayArrayY[5] = {   192,192,30,32,32};
    int displayArrayZ[5] = {  194,134,146,138,162};
    int displayArray0[5] = {  124,124,146,138,162};
    int displayArray1[5] = {  0,0,254,66,2};
    int displayArray2[5] = {  98,66,138,134,146};
    int displayArray3[5] = {   108,68,146,130,146};
    int displayArray4[5] = { 8,24,72,40,254 };
    int displayArray5[5] = { 156,228,162,162,162 };
    int displayArray6[5] = {  76,124,146,146,146};
    int displayArray7[5] = {  192,134,144,136,160};
    int displayArray8[5] = {  108,108,146,146,146};
    int displayArray9[5] = {  124,100,146,146,146};
    int displayArrayDOT[5] = {  0,0,6,6,0};
    int displayArraySPACE[5] = {  0,0,0,0,0};
    int displayArrayDASH[5] = {  16,16,16,16,16};
    int displayArrayCOMMA[5] = {  0,0,12,10,0 };
       
     
        int activenumber;
        int x;
    
        LedControl lc0=LedControl(3,2,18,7); // A   clock + A since
        LedControl lc1=LedControl(3,2,15,7); // B   middle date
        LedControl lc2=LedControl(3,2,17,7); //C   top date
        LedControl lc3=LedControl(3,2,14,7);  // D   bottom date
        LedControl lc4=LedControl(3,2,16,7);  // E   Bsince + Csince
        
        /* we always wait a bit between updates of the display */
    
        byte dig[34];
        int brightness = 2; 
        int standby = HIGH; 
        int activeletter;
 
    
    
      //=========================================================
        void setup() {   
    
             Serial.begin(9600);	// Debugging only
              SoftSerial.begin(9600);
      Serial.println("setup");
   
      for ( int j=0; j <=7; j++ )   
        { lc0.shutdown(j,false);
        lc0.setIntensity(j,brightness);
        lc0.clearDisplay(j);
        lc0.setScanLimit(j,5);
        }
     
      
         for ( int j=0; j <=7; j++ )   
     { lc1.shutdown(j,false);
     lc1.setIntensity(j,brightness);
      lc1.clearDisplay(j);
        lc1.setScanLimit(j,5);
         }
    
           for ( int j=0; j <=7; j++ )   
         {
          lc2.shutdown(j,false);
            lc2.setIntensity(j,brightness);
          lc2.clearDisplay(j);
          lc2.setScanLimit(j,5);
         } 
    
            for ( int j=0; j <=7; j++ )   
       {
          lc3.shutdown(j,false);
            lc3.setIntensity(j,brightness);
          lc3.clearDisplay(j);
         lc3.setScanLimit(j,5);
         }
          for ( int j=0; j <=7; j++ )   
        {
          lc4.shutdown(j,false);
           lc4.setIntensity(j,brightness);
          lc4.clearDisplay(j);
          lc4.setScanLimit(j,5);
         }
blankall ();

 x=0;
    for (byte z=0; z<=4; z++ ) { lc0.setRow(x,z,displayArray1[z]); }   x++;   //  A  clock and B sincedays
    for (byte z=0; z<=4; z++ ) { lc0.setRow(x,z,displayArray0[z]); }   x++;
    for (byte z=0; z<=4; z++ ) { lc0.setRow(x,z,displayArray3[z]); }   x++;
    for (byte z=0; z<=4; z++ ) { lc0.setRow(x,z,displayArray2[z]); }   x++;
    for (byte z=0; z<=4; z++ ) { lc0.setRow(x,z,displayArray4[z]); }   x++;
    for (byte z=0; z<=4; z++ ) { lc0.setRow(x,z,displayArray3[z]); }   x++;
    for (byte z=0; z<=4; z++ ) { lc0.setRow(x,z,displayArray5[z]); }   x++;
 x=0;   
    for (byte z=0; z<=4; z++ ) { lc1.setRow(x,z,displayArray9[z]); }   x++;   //  B date YY-month DD
    for (byte z=0; z<=4; z++ ) { lc1.setRow(x,z,displayArray1[z]); }   x++;
    for (byte z=0; z<=4; z++ ) { lc1.setRow(x,z,displayArrayN[z]); }   x++;
    for (byte z=0; z<=4; z++ ) { lc1.setRow(x,z,displayArrayA[z]); }   x++;
    for (byte z=0; z<=4; z++ ) { lc1.setRow(x,z,displayArrayJ[z]); }   x++;
    for (byte z=0; z<=4; z++ ) { lc1.setRow(x,z,displayArray3[z]); }   x++;
    for (byte z=0; z<=4; z++ ) { lc1.setRow(x,z,displayArray2[z]); }   x++;
 x=0;
    for (byte z=0; z<=4; z++ ) { lc2.setRow(x,z,displayArray0[z]); }   x++;    //  C date  YY-month DD
    for (byte z=0; z<=4; z++ ) { lc2.setRow(x,z,displayArray2[z]); }   x++;
    for (byte z=0; z<=4; z++ ) { lc2.setRow(x,z,displayArrayB[z]); }   x++;
    for (byte z=0; z<=4; z++ ) { lc2.setRow(x,z,displayArrayE[z]); }   x++;
    for (byte z=0; z<=4; z++ ) { lc2.setRow(x,z,displayArrayF[z]); }   x++;
    for (byte z=0; z<=4; z++ ) { lc2.setRow(x,z,displayArray0[z]); }   x++;
    for (byte z=0; z<=4; z++ ) { lc2.setRow(x,z,displayArray1[z]); }   x++;
 x=0;   
    for (byte z=0; z<=4; z++ ) { lc3.setRow(x,z,displayArray8[z]); }   x++;    //  D date  YY-month DD
    for (byte z=0; z<=4; z++ ) { lc3.setRow(x,z,displayArray1[z]); }   x++;
    for (byte z=0; z<=4; z++ ) { lc3.setRow(x,z,displayArrayG[z]); }   x++;
    for (byte z=0; z<=4; z++ ) { lc3.setRow(x,z,displayArrayU[z]); }   x++;
    for (byte z=0; z<=4; z++ ) { lc3.setRow(x,z,displayArrayA[z]); }   x++;
    for (byte z=0; z<=4; z++ ) { lc3.setRow(x,z,displayArray3[z]); }   x++;
    for (byte z=0; z<=4; z++ ) { lc3.setRow(x,z,displayArray1[z]); }   x++;
x=0;   
    for (byte z=0; z<=4; z++ ) { lc4.setRow(x,z,displayArray1[z]); }   x++;  //  C since ( 3# and D since ( 4# )
    for (byte z=0; z<=4; z++ ) { lc4.setRow(x,z,displayArray5[z]); }   x++;
    for (byte z=0; z<=4; z++ ) { lc4.setRow(x,z,displayArray1[z]); }   x++;
    for (byte z=0; z<=4; z++ ) { lc4.setRow(x,z,displayArray7[z]); }   x++;
    for (byte z=0; z<=4; z++ ) { lc4.setRow(x,z,displayArray9[z]); }   x++;
    for (byte z=0; z<=4; z++ ) { lc4.setRow(x,z,displayArray6[z]); }   x++;
    for (byte z=0; z<=4; z++ ) { lc4.setRow(x,z,displayArraySPACE[z]); }   x++;
   
        }
        //=========================================
        void loop() { 
    x=0;    
}

    int displayArrayA[5] = {  63,63,136,72,72};
    int displayArrayB[5] = {  108,254,146,146,146};
    int displayArrayC[5] = {  68,124,130,130,130};
    int displayArrayD[5] = {  124,254,130,130,130};
etc, etc

Start by declaring this lot as byte instead of int. While you are at it declare them as const as they will never change

Thanks, good point.

LedControl lc0 = LedControl(3, 2, 18, 7); // A   clock + A since
LedControl lc1 = LedControl(3, 2, 15, 7); // B   middle date
LedControl lc2 = LedControl(3, 2, 17, 7); //C   top date
LedControl lc3 = LedControl(3, 2, 14, 7); // D   bottom date
LedControl lc4 = LedControl(3, 2, 16, 7); // E   Bsince + Csince

Can you create an array of lc objects ?

If so, then this lot

  for ( int j = 0; j <= 7; j++ )
  {
    lc0.shutdown(j, false);
    lc0.setIntensity(j, brightness);
    lc0.clearDisplay(j);
    lc0.setScanLimit(j, 5);
  }
  for ( int j = 0; j <= 7; j++ )
  {
    lc1.shutdown(j, false);
    lc1.setIntensity(j, brightness);
    lc1.clearDisplay(j);
    lc1.setScanLimit(j, 5);
  }
  for ( int j = 0; j <= 7; j++ )
  {
    lc2.shutdown(j, false);
    lc2.setIntensity(j, brightness);
    lc2.clearDisplay(j);
    lc2.setScanLimit(j, 5);
  }
  for ( int j = 0; j <= 7; j++ )
  {
    lc3.shutdown(j, false);
    lc3.setIntensity(j, brightness);
    lc3.clearDisplay(j);
    lc3.setScanLimit(j, 5);
  }
  for ( int j = 0; j <= 7; j++ )
  {
    lc4.shutdown(j, false);
    lc4.setIntensity(j, brightness);
    lc4.clearDisplay(j);
    lc4.setScanLimit(j, 5);
  }

could be reduced by nesting two for loops

I tried that but the library wouldn't let me change to lc[t] or whatever, but I was probably trying it wrong.

I was probably trying it wrong.

Quite possibly not. The way that some libraries are written does not allow an array of instances to be created.

By the time I had got to just the display in 5 lines of 7 characters, it was already telling me I was short of memory, and I hadn't even started counting the "days since" yet.

put your character table as multidimensional byte array in PROGMEM/flash
https://www.arduino.cc/en/pmwiki.php?n=Reference/PROGMEM

Thanks noiasca,

I have been trying but am messed with strings I think

#include <avr/pgmspace.h>
const char string_0[] PROGMEM = "00000000";   // "String 0" etc are strings to store - change to suit.
const char string_1[] PROGMEM = "00000000";
const char string_2[] PROGMEM = "00000000";  //  this is my ( sideways as it comes out ) number "1"
const char string_3[] PROGMEM = "11111110";
const char string_4[] PROGMEM = "10000010";
const char string_5[] PROGMEM = "00000000";
const char string_6[] PROGMEM = "00000000";

// Then set up a table to refer to your strings.

const char* const string_table[] PROGMEM = {string_0, string_1, string_2, string_3, string_4, string_5};

they suggest reading that into a buffer, but I am not sure how to send that to the MAX7219, either using the LedControl library, or directly with MAX7219 packets?

I thought of something like this:

/*
  by noiasca
*/

const byte bytesPerDigit = 5;
const byte displayArray[][bytesPerDigit] PROGMEM =
{
  {  63, 63, 136, 72, 72},
  {  108, 254, 146, 146, 146},
  {  68, 124, 130, 130, 130},
  {  124, 254, 130, 130, 130},
  {  130, 254, 146, 146, 146},
  {  128, 254, 144, 144, 144},
  {  76, 124, 130, 130, 138 }
  // and so on
};

void read(byte index)  // just a demo function how to read a specific index position:
{
  byte out;
  for (byte i = 0 ; i < bytesPerDigit; i++)
  {
    out = pgm_read_byte(&(displayArray[index][i]));
    Serial.print(out);
    Serial.print(" ");
  }
  Serial.println();
}


void setup() {
  Serial.begin(115200);
  Serial.println(F("\nStart"));

  read(0);
  read(1);
  read(2);
}

void loop() {

}

will give you:

09:33:59.938 -> Start
09:33:59.938 -> 63 63 136 72 72 
09:33:59.938 -> 108 254 146 146 146 
09:33:59.938 -> 68 124 130 130 130

ok?

and by the way, I suggest to order your character table

0 - 9 --> numbers 0 - 9
10 ... --> letters (an offset to ASCII 65 ... so 'A' will be ASCII-55 = your index 10)
nn ... --> special characters (will need some If's anyway)

printing of number 4 will be just a simple
myPrint(4);

Boffin3:
I tried that but the library wouldn't let me change to lc[t] or whatever, but I was probably trying it wrong.

I cannot test this because I don't have the hardware, but this compiles

LedControl lc0 = LedControl((3, 2, 18, 7);
LedControl lc1 = LedControl(3, 2, 15, 7);
//etc

LedControl displays[] = {lc0, lc1};

In the code you can refer to display[0], display[1] etc which would allow you to use a for loop to iterate through them

That works UKHeliBob, thanks

 for ( int u=0; u<=4; u++){
   
      for ( int j=0; j <=7; j++ )   
        { displays[u].shutdown(j,false);
        displays[u].setIntensity(j,brightness);
        displays[u].clearDisplay(j);
        displays[u].setScanLimit(j,5);
        }
      }

I am now going to try noiasca's suggestions with the flash memory and logical order of tables, ( it is still on 75% of static mem )

OK noiasca,

I have tried your suggestion, and the memory is down to 66% , thank you, and I have reordered the table as you suggested.
It prints out the table samples fine, but how do I get it from the progmem into the MAX7219s ?

myPrint(4); just tells me myPrint in the loop just tells me that myPrint is not declared in this scope.

#include <TinyGPS++.h>
#include "LedControl.h"
//   #include <VirtualWire.h>
#include <EEPROM.h>
#include <TimeLib.h>
#include <SoftwareSerial.h>
// Configure SoftSerial library
SoftwareSerial SoftSerial(4, 13);
TinyGPSPlus gps;

const byte bytesPerDigit = 5;
const byte displayArray[][bytesPerDigit] PROGMEM =
{
  {  63, 63, 136, 72, 72},
  {  124, 124, 146, 138, 162},
  {  0, 0, 254, 66, 2},
  {  98, 66, 138, 134, 146},
  {   108, 68, 146, 130, 146},
  { 8, 24, 72, 40, 254 },
  { 156, 228, 162, 162, 162 },
  {  76, 124, 146, 146, 146},
  {  192, 134, 144, 136, 160},
  {  108, 108, 146, 146, 146},
  {  124, 100, 146, 146, 146},
  {  63, 63, 136, 72, 72},
  {  108, 254, 146, 146, 146},
  {  68, 124, 130, 130, 130},
  {  124, 254, 130, 130, 130},
  {  130, 254, 146, 146, 146},
  {  128, 254, 144, 144, 144},
  {  76, 124, 130, 130, 138 },
  {  254, 254, 16, 16, 16},
  {  0, 0, 254, 130, 130},
  {  0, 4, 252, 130, 128},
  {  130, 254, 40, 16, 68},
  {  2, 254, 2, 2, 2},
  {  254, 254, 32, 64, 64},
  {  254, 254, 16, 32, 8},
  {  124, 124, 130, 130, 130},
  { 112, 254, 136, 136, 136},
  {  126, 124, 138, 130, 134},
  {  98, 254, 152, 144, 148},
  {  76, 100, 146, 146, 146},
  {  128, 128, 254, 128, 128},
  {  252, 252, 2, 2, 2},
  {  248, 248, 2, 4, 4},
  {  252, 252, 12, 2, 2},
  {  198, 198, 16, 40, 40},
  {   192, 192, 30, 32, 32},
  {  194, 134, 146, 138, 162},
  {  0, 0, 6, 6, 0}, // displayArrayDOT[5]
  {  0, 0, 0, 0, 0}, //displayArraySPACE[5] =
  {  16, 16, 16, 16, 16}, //  displayArrayDASH[5] =
  {  0, 0, 12, 10, 0 } //  displayArrayCOMMA[5] =

  //  const byte  displayArrayDOT[5] = {  0,0,6,6,0},
  //  const byte  displayArraySPACE[5] = {  0,0,0,0,0},
  //  const byte  displayArrayDASH[5] = {  16,16,16,16,16},
  //  const byte  displayArrayCOMMA[5] = {  0,0,12,10,0 },
};


int  x;


LedControl lc0 = LedControl(3, 2, 18, 7); // A   clock + A since
LedControl lc1 = LedControl(3, 2, 15, 7); // B   middle date
LedControl lc2 = LedControl(3, 2, 17, 7); //C   top date
LedControl lc3 = LedControl(3, 2, 14, 7); // D   bottom date
LedControl lc4 = LedControl(3, 2, 16, 7); // E   Bsince + Csince

LedControl displays[] = {lc0, lc1, lc2, lc3, lc4};

/* we always wait a bit between updates of the display */

byte dig[34];
const byte  brightness = 5;
const byte  standby = HIGH;
const byte  activeletter;




void read(byte index)  // just a demo function how to read a specific index position:
{
  byte out;
  for (byte i = 0 ; i < bytesPerDigit; i++)
  {
    out = pgm_read_byte(&(displayArray[index][i]));
    Serial.print(out);
    Serial.print(" ");
  }
  Serial.println();
}


//}


//=========================================================
void setup() {

  Serial.begin(9600);	// Debugging only
  SoftSerial.begin(9600);
  Serial.println("setup");

  Serial.println(F("\nStart"));

  read(0);
  read(1);
  read(2);



  for ( byte u = 0; u <= 4; u++) {

    for ( byte j = 0; j <= 7; j++ )
    { displays[u].shutdown(j, false);
      displays[u].setIntensity(j, brightness);
      displays[u].clearDisplay(j);
      displays[u].setScanLimit(j, 5);
    }
  }
  blankall ();
}
//=========================================
void loop() {
  x = 0;
  myPrint(4);
}

I guess I must send to the max data with something like the example for printing

byte out;
  for (byte i = 0 ; i < bytesPerDigit; i++)
  {
    out = pgm_read_byte(&(displayArray[index][i]));
    Serial.print(out);
    Serial.print(" ");

with the i being the led column...?

OK I have it working with the code below. Thank you guys only 58% 0f memory used now.

It displays the 7 digits in the row, but the last 3 digits in the first line are flickering and going off, ( which doesnt happen with the other test display that had the lack of memory ? )

Seems to be the 5th chip faulty, the other rows are fine.
I am going to swap that pcb with the end one and hope ( no spare chips ! )

Now to sort out the " days since " and the gps clock.

#include <TinyGPS++.h>
#include "LedControl.h"
#include <EEPROM.h>
#include <TimeLib.h>
#include <SoftwareSerial.h>
// Configure SoftSerial library
SoftwareSerial SoftSerial(4, 13);
//TinyGPSPlus gps;
byte delaytime = 0;
const byte bytesPerDigit = 5;
const byte displayArray[][bytesPerDigit] PROGMEM =
{
  {  63, 63, 136, 72, 72},
  {  124, 124, 146, 138, 162},
  {  0, 0, 254, 66, 2},
  {  98, 66, 138, 134, 146},
  {   108, 68, 146, 130, 146},
  { 8, 24, 72, 40, 254 },
  { 156, 228, 162, 162, 162 },
  {  76, 124, 146, 146, 146},
  {  192, 134, 144, 136, 160},
  {  108, 108, 146, 146, 146},
  {  124, 100, 146, 146, 146},
  {  63, 63, 136, 72, 72},
  {  108, 254, 146, 146, 146},
  {  68, 124, 130, 130, 130},
  {  124, 254, 130, 130, 130},
  {  130, 254, 146, 146, 146},
  {  128, 254, 144, 144, 144},
  {  76, 124, 130, 130, 138 },
  {  254, 254, 16, 16, 16},
  {  0, 0, 254, 130, 130},
  {  0, 4, 252, 130, 128},
  {  130, 254, 40, 16, 68},
  {  2, 254, 2, 2, 2},
  {  254, 254, 32, 64, 64},
  {  254, 254, 16, 32, 8},
  {  124, 124, 130, 130, 130},
  { 112, 254, 136, 136, 136},
  {  126, 124, 138, 130, 134},
  {  98, 254, 152, 144, 148},
  {  76, 100, 146, 146, 146},
  {  128, 128, 254, 128, 128},
  {  252, 252, 2, 2, 2},
  {  248, 248, 2, 4, 4},
  {  252, 252, 12, 2, 2},
  {  198, 198, 16, 40, 40},
  {   192, 192, 30, 32, 32},
  {  194, 134, 146, 138, 162},
  {  0, 0, 6, 6, 0}, // displayArrayDOT[5]
  {  0, 0, 0, 0, 0}, //displayArraySPACE[5] =
  {  16, 16, 16, 16, 16}, //  displayArrayDASH[5] =
  {  0, 0, 12, 10, 0 } //  displayArrayCOMMA[5] =

  //  const byte  displayArrayDOT[5] = {  0,0,6,6,0},
  //  const byte  displayArraySPACE[5] = {  0,0,0,0,0},
  //  const byte  displayArrayDASH[5] = {  16,16,16,16,16},
  //  const byte  displayArrayCOMMA[5] = {  0,0,12,10,0 },
};
byte  x;
LedControl lc0 = LedControl(3, 2, 18, 7); // A   clock + A since
LedControl lc1 = LedControl(3, 2, 15, 7); // B   middle date
LedControl lc2 = LedControl(3, 2, 17, 7); //C   top date
LedControl lc3 = LedControl(3, 2, 14, 7); // D   bottom date
LedControl lc4 = LedControl(3, 2, 16, 7); // E   Bsince + Csince

LedControl displays[] = {lc0, lc1, lc2, lc3, lc4};
/* we always wait a bit between updates of the display */

byte dig[34];
const byte  brightness =15;
const byte  standby = HIGH;
const byte  activeletter;

void read(byte index)  // just a demo function how to read a specific index position:
{
  byte out;
  for (byte i = 0 ; i < bytesPerDigit; i++)
  {
    out = pgm_read_byte(&(displayArray[index][i]));
    Serial.print(out);
    Serial.print(" ");
  }
  Serial.println();
}
//=========================================================
void setup() {

  Serial.begin(9600);	// Debugging only
  SoftSerial.begin(9600);
  Serial.println("setup");


  for ( byte u = 0; u <= 4; u++) {

    for ( byte j = 0; j <= 7; j++ )
    { displays[u].shutdown(j, false);
      displays[u].setIntensity(j, brightness);
      displays[u].clearDisplay(j);
      displays[u].setScanLimit(j, 5);
    }
  }
  blankall ();
}
//=========================================
void loop() {

  x = 0;
  delay ( delaytime );

  for (byte z = 0; z <= 4; z++ ) {
    lc0.setRow(x, z, pgm_read_byte(&(displayArray[1][z])) );
  }
  x++;
  delay ( delaytime );
  for (byte z = 0; z <= 4; z++ ) {
    lc0.setRow(x, z, pgm_read_byte(&(displayArray[2][z])) );
  }
  x++;
  delay ( delaytime );
  for (byte z = 0; z <= 4; z++ ) {
    lc0.setRow(x, z, pgm_read_byte(&(displayArray[3][z])) );
  }
  x++;
  delay ( delaytime );
  for (byte z = 0; z <= 4; z++ ) {
    lc0.setRow(x, z, pgm_read_byte(&(displayArray[4][z])) );
  }
  x++;
  delay ( delaytime );
  for (byte z = 0; z <= 4; z++ ) {
    lc0.setRow(x, z, pgm_read_byte(&(displayArray[5][z])) );
  }
  x++;
  delay ( delaytime );
  for (byte z = 0; z <= 4; z++ ) {
    lc0.setRow(x, z, pgm_read_byte(&(displayArray[6][z])) );
  }
  x++;
  delay ( delaytime );
  for (byte z = 0; z <= 4; z++ ) {
    lc0.setRow(x, z, pgm_read_byte(&(displayArray[7][z])) );
  }
  x = 0;
  delay ( delaytime );

}

I doubt that to be a program error. I suspect your hardware, lack of current...

Speaking about your program, you should avoid that code duplicates and make generic functions.
Also I don't see, what your delay is for.
And finally, you should consider Hardware SPI instead of the software bitbang of LedControl.
Hardware SPI for the MAX7219 is approx. 7 times faster than software bitbang.

Yes the delay was just a test to see why the digits were flashing ( which is the faulty chip ) that will be gone when I tidy it up later.
I first have to work out the days since bit ( which is why I called Time.h to try )

If I get time I will make it hardware SPI, and also go through the very rough display routine ( I want to generate digit[35] from the gps and " days since" functions during the night, also update every minute ( with unix dates in eeprom, and a remote control to adjust the previous dates )

It is going to be another busy night, I want to get this out by Monday to avoid disappointing a pal.

dank je voor je hulp , Karma to you :slight_smile:

Hi noiasca,

I have got the gps clock going, but now I want to try to get rid of code duplicates and make generic functions as you suggest. ( I am back to over 70% memory again )

I can almost see a general way to do it with the display part below.
I am selecting the character with its digit[] number ( 35 of them )

The days since calc becomes dig [x]

For the 3 identical rows of 7 digits, I can renumber the digits to be say 8 apart, and for each of the 3 lc rows, have dig + 8 ?

  x = 0;
  for (byte z = 0; z <= 4; z++ ) {
    lc0.setRow(x, z, pgm_read_byte(&(displayArray[dig[0]][z])) );
  }
  x++;
  for (byte z = 0; z <= 4; z++ ) {
    lc0.setRow(x, z, pgm_read_byte(&(displayArray[dig[1]][z])) );
  }
  x++;
  for (byte z = 0; z <= 4; z++ ) {
    lc0.setRow(x, z, pgm_read_byte(&(displayArray[dig[2]][z])) );
  }
  x++;
  for (byte z = 0; z <= 4; z++ ) {
    lc0.setRow(x, z, pgm_read_byte(&(displayArray[dig[3]][z])) );
  }
  x++;
  for (byte z = 0; z <= 4; z++ ) {
    lc0.setRow(x, z, pgm_read_byte(&(displayArray[5][z])) );
  }
  x++;
  for (byte z = 0; z <= 4; z++ ) {
    lc0.setRow(x, z, pgm_read_byte(&(displayArray[6][z])) );
  }
  x++;
  for (byte z = 0; z <= 4; z++ ) {
    lc0.setRow(x, z, pgm_read_byte(&(displayArray[7][z])) );
  }
  x = 0;

  // ===========================================================================

  x = 0;
  for (byte z = 0; z <= 4; z++ ) {
    lc1.setRow(x, z, pgm_read_byte(&(displayArray[1][z])) );
  }
  x++;
  for (byte z = 0; z <= 4; z++ ) {
    lc1.setRow(x, z, pgm_read_byte(&(displayArray[2][z])) );
  }
  x++;
  for (byte z = 0; z <= 4; z++ ) {
    lc1.setRow(x, z, pgm_read_byte(&(displayArray[3][z])) );
  }
  x++;
  for (byte z = 0; z <= 4; z++ ) {
    lc1.setRow(x, z, pgm_read_byte(&(displayArray[4][z])) );
  }
  x++;
  for (byte z = 0; z <= 4; z++ ) {
    lc1.setRow(x, z, pgm_read_byte(&(displayArray[5][z])) );
  }
  x++;
  for (byte z = 0; z <= 4; z++ ) {
    lc1.setRow(x, z, pgm_read_byte(&(displayArray[6][z])) );
  }
  x++;
  for (byte z = 0; z <= 4; z++ ) {
    lc1.setRow(x, z, pgm_read_byte(&(displayArray[7][z])) );
  }
  x = 0;
  // ===========================================================================

  x = 0;
  for (byte z = 0; z <= 4; z++ ) {
    lc2.setRow(x, z, pgm_read_byte(&(displayArray[1][z])) );
  }
  x++;
  for (byte z = 0; z <= 4; z++ ) {
    lc2.setRow(x, z, pgm_read_byte(&(displayArray[2][z])) );
  }
  x++;
  for (byte z = 0; z <= 4; z++ ) {
    lc2.setRow(x, z, pgm_read_byte(&(displayArray[3][z])) );
  }
  x++;
  for (byte z = 0; z <= 4; z++ ) {
    lc2.setRow(x, z, pgm_read_byte(&(displayArray[4][z])) );
  }
  x++;
  for (byte z = 0; z <= 4; z++ ) {
    lc2.setRow(x, z, pgm_read_byte(&(displayArray[5][z])) );
  }
  x++;
  for (byte z = 0; z <= 4; z++ ) {
    lc2.setRow(x, z, pgm_read_byte(&(displayArray[6][z])) );
  }
  x++;
  for (byte z = 0; z <= 4; z++ ) {
    lc2.setRow(x, z, pgm_read_byte(&(displayArray[7][z])) );
  }
  x = 0;
  // ===========================================================================

  x = 0;
  for (byte z = 0; z <= 4; z++ ) {
    lc3.setRow(x, z, pgm_read_byte(&(displayArray[1][z])) );
  }
  x++;
  for (byte z = 0; z <= 4; z++ ) {
    lc3.setRow(x, z, pgm_read_byte(&(displayArray[2][z])) );
  }
  x++;
  for (byte z = 0; z <= 4; z++ ) {
    lc3.setRow(x, z, pgm_read_byte(&(displayArray[3][z])) );
  }
  x++;
  for (byte z = 0; z <= 4; z++ ) {
    lc3.setRow(x, z, pgm_read_byte(&(displayArray[4][z])) );
  }
  x++;
  for (byte z = 0; z <= 4; z++ ) {
    lc3.setRow(x, z, pgm_read_byte(&(displayArray[5][z])) );
  }
  x++;
  for (byte z = 0; z <= 4; z++ ) {
    lc3.setRow(x, z, pgm_read_byte(&(displayArray[6][z])) );
  }
  x++;
  for (byte z = 0; z <= 4; z++ ) {
    lc3.setRow(x, z, pgm_read_byte(&(displayArray[7][z])) );
  }
  x = 0;
  // ===========================================================================

  x = 0;
  for (byte z = 0; z <= 4; z++ ) {
    lc4.setRow(x, z, pgm_read_byte(&(displayArray[1][z])) );
  }
  x++;
  for (byte z = 0; z <= 4; z++ ) {
    lc4.setRow(x, z, pgm_read_byte(&(displayArray[2][z])) );
  }
  x++;
  for (byte z = 0; z <= 4; z++ ) {
    lc4.setRow(x, z, pgm_read_byte(&(displayArray[3][z])) );
  }
  x++;
  for (byte z = 0; z <= 4; z++ ) {
    lc4.setRow(x, z, pgm_read_byte(&(displayArray[4][z])) );
  }
  x++;
  for (byte z = 0; z <= 4; z++ ) {
    lc4.setRow(x, z, pgm_read_byte(&(displayArray[5][z])) );
  }
  x++;
  for (byte z = 0; z <= 4; z++ ) {
    lc4.setRow(x, z, pgm_read_byte(&(displayArray[6][z])) );
  }
  x++;
  for (byte z = 0; z <= 4; z++ ) {
    lc4.setRow(x, z, pgm_read_byte(&(displayArray[7][z])) );
  }
  x = 0;
}

I'm not shure what you want to tell me. But the answer might be yes.

By the way, for others it would make it far more easier to understand your wiring if you draw a schematic where we can see which object (which slave select) is used for which digit row and how you number your digits (left to right, right to left).

edit:
start with a "simple" sketch from scratch and only take care of your display and your write methods.
I cannot test without your hardware.
This might guide you to the direction you should go.

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

const uint8_t LEDCS_PIN = 8;           // 8 LED CS or LOAD -  8 CS
const uint8_t LEDCLK_PIN = 13;         // 7 LED Clock      - 13 CLK on UNO/NANO
const uint8_t LEDDATA_PIN = 11;        // 9 LED DATA IN    - 11 MOSI on UNO/NANO
const uint8_t LED_MODULES = 7;

const uint8_t LEDCS1_PIN = 9;
const uint8_t LEDCS2_PIN = 8;

LedControl display[] = {
  {LEDDATA_PIN, LEDCLK_PIN, LEDCS_PIN, LED_MODULES},      // lc display object 0
  {LEDDATA_PIN, LEDCLK_PIN, LEDCS1_PIN, LED_MODULES},     // lc object 1
  {LEDDATA_PIN, LEDCLK_PIN, LEDCS2_PIN, LED_MODULES}      // lc object 2
};

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


const byte bytesPerDigit = 5;
const byte displayArray[][bytesPerDigit] PROGMEM =
{
  {  63, 63, 136, 72, 72},
  {  124, 124, 146, 138, 162},
  {  0, 0, 254, 66, 2},
  {  98, 66, 138, 134, 146},
  {   108, 68, 146, 130, 146},
  { 8, 24, 72, 40, 254 },
  { 156, 228, 162, 162, 162 },
  {  76, 124, 146, 146, 146},
  {  192, 134, 144, 136, 160},
  {  108, 108, 146, 146, 146}
};


void myWrite( uint8_t displayNr, uint8_t addr, uint8_t character)
{
  //displayNr     the index of the object
  //addr          the single MAX72xx within your display Object
  //character     the character (index) you want to print
  //this is what the library method expects:
  //void LedControl::setRow(uint8_t addr, uint8_t row, uint8_t value)
  //therefore you
  for (byte i = 0; i < bytesPerDigit; i++)
  {
    display[displayNr].setRow(addr, i, pgm_read_byte(&(displayArray[character][i])) );
  }
}




void setup() {
  /* The MAX72XX needs to initialize hardware */
  for (auto & obj : display)
  {
    obj.begin();
    obj.shutdown(0, false);     /* Set the brightness to a medium values */
    obj.setIntensity(0, 8);     /* and clear the display */
    obj.clearDisplay(0);
  }

  //examples:

  // myWrite( uint8_t displayNr, uint8_t addr, uint8_t character)
  myWrite(0, 0, 0); // displayNr 0, module adress 0, character 0
  myWrite(1, 2, 3); // displayNr 1, module adress 2 , character 3
  myWrite(2, 0, 8); // displayNr 2, switch on
  myWrite(2, 1, 8);
  myWrite(2, 2, 8);
  myWrite(2, 3, 8);
  myWrite(2, 4, 8);
  myWrite(2, 5, 8);
  myWrite(2, 6, 8);
  myWrite(2, 7, 8);
}

void loop() {
}

there's probably an error in

display[displayNr].setRow(addr, i, pgm_read_byte(&(displayArray[character][i])) );

order/number/index, but you should be able to do that alone with your hardware.
If the displays only show garbish, start to add serial.prints so that you can see, what numbers are getting used.

Thanks noiasca,

I have attached a sketch of how I have reordered the digits to try and address them more logically ( and describe the functions )

I have no idea what the days represent, or why the bottom one has 4 digits !

The three identical rows have digit[] numbers 7 apart, so hopefully it should make it easier, I will try it tonight.

If the memory problem persists after I calculate dates etc, I have found I have a Bobuino 1284 mini which perhaps will be better .

I will also need to input the remote control as well as the gps so it might help there ?

I have no experience with it and will read up a bit.

tileorder.jpg

I am canfused with calling characters from the eeprom, can you please give me an example for calling "HW 25 "

jOHN

and by the way, I suggest to order your character table

0 - 9 --> numbers 0 - 9
10 ... --> letters (an offset to ASCII 65 ... so 'A' will be ASCII-55 = your index 10)
nn ... --> special characters (will need some If's anyway)

printing of number 4 will be just a simple
myPrint(4);