Need help with multiple instances of LedControl for 32x32 LED array

Trying to use the LedControl library. I have 16 8x8 LED arrays driven by MAX7219 chips. The units I'm using are found here:

http://www.ebay.com/itm/231109763431?ssPageName=STRK:MEWNX:IT&_trksid=p3984.m1497.l2649

The arrangement is to use four LedControl objects, each with four 8x8 displays daisy chained. I tried creating instances like this:

LedControl lc1=LedControl(12,11,10,numarrays);
LedControl lc2=LedControl(12,11,9,numarrays);
LedControl lc3=LedControl(12,11,8,numarrays);
LedControl lc4=LedControl(12,11,7,numarrays);

but this doesn't work. The row with lc1 works OK, but not the others. So it looks like I need completely different pins for all three lines, data, clock and cs. So I try this with just the first two rows:

LedControl lc1=LedControl(12,11,10,numarrays);
LedControl lc2=LedControl(36,34,9,numarrays);

I'm using a Mega 2560 because I need the larger SRAM. This also doesn't work.

What am I doing wrong?

Thanks, Theron Wierenga

Hi twiereng,

According to the library page for LEDControl, you can chain up to 8 chips per instance, so you should only need to create 2 instances.

I think we will need to see your whole sketch if we are to help. Don’t forget to use code tags when you post it.

OK, here’s the code. The Game of Life code appears to be working OK, and it is displayed correctly in the top row of 4 8x8 displays. I chose to go with four instances of LedControl so that the ripple through would only have to go through four displays across.

This is a work in progress, later I’ll add RTC to the display as well.


// 8x8 Matrix Test

//We always have to include the libraries
#include "LedControl.h"
#include <dht.h>
#include <SPI.h>

/* we always wait a bit between updates of the display */
int delaytime = 2000;
int numarrays = 4;
int indexym1, indexy, indexyp1;
byte aray[1024];
byte newaray[1024];
byte lastaray[1024];
//byte thirdaray[1024];
byte sum = 0;
byte lastsecond = 0;
byte second, minute, hour, ampm, dayOfWeek, dayOfMonth, month, year, f1224, t1, t2, f100, f10, f1;
double lasttemp = 0, currenttemp = 0, humidity = 0;

LedControl lc1=LedControl(12,11,10,numarrays); // These have to be here because of scope
LedControl lc2=LedControl(36,34,9,numarrays);
LedControl lc3=LedControl(32,30,8,numarrays);
LedControl lc4=LedControl(28,27,7,numarrays);

dht DHT;                                       // The DHT22 Temperature Humidity sensor
#define DHT22_PIN 41


void setup() 
{
  f1224 = 1;
  RTC_init_DS3234();
  //day(1-31), month(1-12), year(0-99), dayofweek (1-7), ampm (0-1), hour(0-23), minute(0-59), second(0-59), 12/24 hr (0-1)
  //                                    Sun = 1          0 = am, 1 = pm                                      0 = 24 hr.
  //SetTimeDate_DS3234(19,12,13,5,1,3,51,30,1); 
  
  /*
   The MAX72XX is in power-saving mode on startup,
   we have to do a wakeup call
   */
   for (int i=0;i < numarrays; i++)
   {
      lc1.shutdown(i,false);
      lc2.shutdown(i,false);
      lc3.shutdown(i,false);
      lc4.shutdown(i,false);
      /* Set the brightness to a low values */
      lc1.setIntensity(i,1);
      lc2.setIntensity(i,1);
      lc3.setIntensity(i,1);
      lc4.setIntensity(i,1);
      /* and clear the display */
      lc1.clearDisplay(i);
      lc2.clearDisplay(i);
      lc3.clearDisplay(i);
      lc4.clearDisplay(i);
   }
  
  for (int i=0; i < 1024; i++)
  {
     aray[i] = 0; 
     newaray[i] = 0;
     lastaray[i] = 0;
  }

  SeedArray();
  Display_8x8(); 
  delay(delaytime);
//  Serial.begin(9600);
 
}

void loop()
{
Game_of_Life();
//  lc1.clearDisplay(0);
//  lc1.clearDisplay(1);
//  lc1.clearDisplay(2);
//  lc1.clearDisplay(3);
//  delay(1000);
//  for (int j=0; j<18;j++)
//  {
//      for (int i=0;i<5;i++)
//      {
//        lc1.setColumn(0,i,alpha[i+j*5]);
//        lc1.setColumn(1,i,alpha[i+j*5]);
//        lc1.setColumn(2,i,alpha[i+j*5]);
//      }
//      delay(1000);
//  }

//  for (int i=4; i< 7; i++)
//  {
//      Show_Number(0,i-4,i);
//      // Show_DayofWeek(i);
//      
//     delay(1500);
//  }

//for (int i=0;i<8;i++)
//      {
//        lc2.setColumn(0,i,255);
//        lc2.setColumn(1,i,255);
//        lc2.setColumn(2,i,255);
//        lc2.setColumn(3,i,255);
//      }
//delay(1000);
}

void Game_of_Life()
{
   for (int y = 1; y <= 30; y++)
  {
      indexym1 = (y-1) * 32;
      indexy = y * 32;
      indexyp1 = (y+1) * 32;
      for (int x = 1; x <= 30; x++)
      {
         sum = aray[indexym1+x-1] + aray[indexym1+x] + aray[indexym1+x+1] + aray[indexy+x-1] + aray[indexy+x+1] + aray[indexyp1+x-1] + aray[indexyp1+x] + aray[indexyp1+x+1];
         if (aray[indexy+x] == 1)
         {
            if ((sum < 2) || (sum > 3))
            {
               newaray[indexy+x] = 0;  // LED could be changed here
            } 
            else 
            {
               newaray[indexy+x] = 1;
            }
         }
         else
         //if (aray[indexy+x] == 0)
         {
             if (sum == 3) 
             {
               newaray[indexy+x] = 1;  // LED could be changed here
             } 
             else 
             {
               newaray[indexy+x] = 0;
             }
         }
      }
  }
  CheckState();
  Display_8x8();
  delay(delaytime); 
}
void Display_8x8()
{
  for (int i=0;i < numarrays; i++)
   {
      /* Clear the display */
      lc1.clearDisplay(i);
      lc2.clearDisplay(i);
      lc3.clearDisplay(i);
      lc4.clearDisplay(i);
   }
  for (int y = 0; y < 8; y++)  // Only the top 8 rows are checked
  {
      indexy = y * 32;
      for (int x = 0; x < 8; x++)
      {
          if (aray[indexy+x] == 1)
          {
               lc1.setLed(0, y, x, true);
          }
      }
      
      for (int x = 8; x < 16; x++)
      {
          if (aray[indexy+x] == 1)
          {
               lc1.setLed(1, y, x-8, true);
          }
      }
      
      for (int x = 16; x < 24; x++)
      {
          if (aray[indexy+x] == 1)
          {
               lc1.setLed(2, y, x-16, true);
          }
      }
      
      for (int x = 24; x < 32; x++)
      {
          if (aray[indexy+x] == 1)
          {
               lc1.setLed(3, y, x-24, true);
          }
      }
  }

  for (int y = 8; y < 16; y++)  // second eight rows
  {
      indexy = y * 32;
      for (int x = 0; x < 8; x++)
      {
          if (aray[indexy+x] == 1)
          {
               lc2.setLed(0, y, x, true);
          }
      }
      
      for (int x = 8; x < 16; x++)
      {
          if (aray[indexy+x] == 1)
          {
               lc2.setLed(1, y, x-8, true);
          }
      }
      
      for (int x = 16; x < 24; x++)
      {
          if (aray[indexy+x] == 1)
          {
               lc2.setLed(2, y, x-16, true);
          }
      }
      
      for (int x = 24; x < 32; x++)
      {
          if (aray[indexy+x] == 1)
          {
               lc2.setLed(3, y, x-24, true);
          }
      }
  }   

  for (int y = 16; y < 24; y++)  // third eight rows
  {
      indexy = y * 32;
      for (int x = 0; x < 8; x++)
      {
          if (aray[indexy+x] == 1)
          {
               lc3.setLed(0, y, x, true);
          }
      }
      
      for (int x = 8; x < 16; x++)
      {
          if (aray[indexy+x] == 1)
          {
               lc3.setLed(1, y, x-8, true);
          }
      }
      
      for (int x = 16; x < 24; x++)
      {
          if (aray[indexy+x] == 1)
          {
               lc3.setLed(2, y, x-16, true);
          }
      }
      
      for (int x = 24; x < 32; x++)
      {
          if (aray[indexy+x] == 1)
          {
               lc3.setLed(3, y, x-24, true);
          }
      }
  }   

  for (int y = 24; y < 32; y++)  // fourth eight rows
  {
      indexy = y * 32;
      for (int x = 0; x < 8; x++)
      {
          if (aray[indexy+x] == 1)
          {
               lc4.setLed(0, y, x, true);
          }
      }
      
      for (int x = 8; x < 16; x++)
      {
          if (aray[indexy+x] == 1)
          {
               lc4.setLed(1, y, x-8, true);
          }
      }
      
      for (int x = 16; x < 24; x++)
      {
          if (aray[indexy+x] == 1)
          {
               lc4.setLed(2, y, x-16, true);
          }
      }
      
      for (int x = 24; x < 32; x++)
      {
          if (aray[indexy+x] == 1)
          {
               lc4.setLed(3, y, x-24, true);
          }
      }
  }     
}

void SeedArray()
{
    randomSeed(analogRead(0));
 //   for (int i=0; i < 576; i++) {aray[i] = 0;}
    for (int a=0; a < 500; a++)
    {
       int y = random(1, 32);
       int x = random(1, 32); 
       aray[y*32+x] = 1;
    }
}

void CheckState()
{
  bool flag = true;
  for (int i=0; i < 1024; i++)
  {
    if (aray[i] != newaray[i]) 
    {
        flag = false;
    }
    lastaray[i] = aray[i];
    aray[i] = newaray[i];
  }
  
  if (flag)
  {
    SeedArray();
  }
  else
  {
       flag = true;
       for (int i=0; i < 1024; i++)
       {
          if (lastaray[i] != newaray[i])
          {
             flag = false;
            
          }
       }
       if (flag) {SeedArray();}
  }
}

I did ask you to "Don't forget to use code tags when you post it." Its part of the forum rules, you should have read them before posting. Please edit your post and put them in. The button on the edit page has a # symbol on it.

twiereng:
I chose to go with four instances of LedControl so that the ripple through would only have to go through four displays across.

If you use the arduino's SPI hardware, you should be able to chain all 16 displays with no speed problems. If the LED control library can't be changed to manage 16 chained chips and use SPI, I would remove it and have your code talk directly to the max7219s more directly with the SPI library.

I too am fascinated by Conway's Game of Life. I used a bare ATmega328 driving a 128 x 64 graphic LCD to make a desk ornament. Here's a video: Conway's Game of Life Arduino (digitalWriteFast) - YouTube

Paul

OK, I think I have the code marked correctly. Sorry I missed that.

My idea was to use a 4x4 array of 8x8 LED displays. I purchased the 8x8 displays from China, they come with a little board, the MAX 7219 IC and the display - very inexpensive and decent quality. My only complaint was that the pin spacing on the board was 1.16 inches instead of 1.1, making layout of a motherboard for all 16 units a little difficult, but the results were OK.

I then wanted to create 4 instances of the LedControl, one for each row of four 8x8 displays. This helps a little with symmetry going from a 32x32 array for Conway's Game of Life to the individual 8x8 displays. The documentation at LedControl shows this example.

/* we have to include the library */
#include "LedControl.h"

// Create a new LedControl for 8 devices... 
LedControl lc1=LedControl(12,11,10,8); 

// ... and another one, now we control 1024 Leds's from an arduino, not bad!
// The second one must use different pins!
LedControl lc2=LedControl(9,8,7,8);

And here's what I've done.

LedControl lc1=LedControl(12,11,10,numarrays); 
LedControl lc2=LedControl(4,3,9,numarrays);
LedControl lc3=LedControl(32,30,8,numarrays);
LedControl lc4=LedControl(28,27,7,numarrays);

Unfortunately, it doesn't work.

I've enjoyed Conway's Game of Life also. This little device was something I wanted to make for my son's desk. I have also programed a 3D version in Microsoft WPF.

Thanks, Theron

Hi,
I've read through your code but can't spot anything obvious, but I'm not an expert with this library.
I would try swapping things around to see what happens.
What happens if you swap the wiring around? Do thed other rows work ok if they are connected to the lines that the 1st row is currently hooked up to?
What if you swap the arduino ouput numbers around in the sketch? Is it always the row hooked up to led1 that works?

Paul

OK, I reduced instances to just two

LedControl lc1=LedControl(12,11,10,numarrays); 
LedControl lc2=LedControl(4,3,9,numarrays);

where numarrays = 4 and lc1 is wired to the first row and lc2 is wired to the second row. If I place an 8x8 LED array in the first row, with nothing in the second row, it works. If I place and 8x8 LED array in the second row, with nothing in the first row, it works. If I place an 8x8 LED array in both first and second rows only the first row works.

This library appears to have been written predominately for use with 7 segment displays. My next step is writing my own library.

Thanks, Theron

twiereng:
If I place an 8x8 LED array in the first row, with nothing in the second row, it works. If I place and 8x8 LED array in the second row, with nothing in the first row, it works. If I place an 8x8 LED array in both first and second rows only the first row works.

Is that with no changes to the sketch? If so, that doesn't sound like a software issue, the s/w does not know which lines you connect the matrices to. Are you powering all the matrices from the Arduino's 5V output? Could you be overloading it with two rows, pulling the voltage down so far that some of the displays are not responding?

twiereng:
My next step is writing my own library.

I wouldn't bother unless you plan to re-use the code on other projects. Just write your code to talk to the 7219s directly using the ShiftOut() function. Or better still, see my earlier advice.

My 128x64 lcd Game Of Life code has a much faster algorithm (~10 generations per second, on a grid size 8 times larger), and runs on a Atmega328, which only has 2K RAM (same as an UNO). I'll share the code if you like.

If you want to try a different library look at my MD_MAX72xx library in the code repository linked below. It is designed to deal with pixels from the start and can easily handle 20+ LED modules.