Parola and LedControl

Has anyone have experience using the Parola (Scrolling LED matrix display) and LedControl libraries in the same code?

They work fine independently but as soon as you initiate Parola's "P.Begin()", LedControl no longer works.

I am not the most experienced programmer and I don't fully understand what P.Begin() does ... but is there such a thing of P.end() ? (tried it but no luck) ... looks like I'm stuck :-(

I have used both libraries but not together.

Parola has way more capabilities than I use.

Why do you need both libraries?

.

Alright here's the code:

// Overall ==================
int MessagesOrMIDI = 2; // 1 = Scrolling Messages, 2 = MIDI
unsigned long time;
unsigned long interval = 5000;
unsigned long intervalStep = 5000;
int doneFlag;
// ==========================

// MIDI Stuff ===============
byte incomingByte; 
int ledCounter=1;
int switchbit=0;
// ==========================

// LED Control Stuff ========================================================================
#include 

LedControl lc=LedControl(11,13,10,4);

byte sqBox8[8]={B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111}; // Full Square 64 Leds ON
byte sqBox6[8]={B00000000,B01111110,B01111110,B01111110,B01111110,B01111110,B01111110,B00000000}; // Square 36 Leds ON
byte sqBox4[8]={B00000000,B00000000,B00111100,B00111100,B00111100,B00111100,B00000000,B00000000}; // Square 16 Leds ON
byte sqBox2[8]={B00000000,B00000000,B00000000,B00011000,B00011000,B00000000,B00000000,B00000000}; // Square 4 Leds ON


int displayPosition;
int randomSymbol;
// =========================================================================

// Parola stuff =========================================================================
#include 
#include 
#include 

// Define the number of devices we have in the chain and the hardware interface
// NOTE: These pin numbers will probably not work with your hardware and may
// need to be adapted
#define HARDWARE_TYPE MD_MAX72XX::FC16_HW
#define MAX_DEVICES 4
#define CLK_PIN   13
#define DATA_PIN  11
#define CS_PIN    10

// Hardware SPI connection
MD_Parola P = MD_Parola(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);

#define BUF_SIZE 100
char Message_1[BUF_SIZE] = { "Message 1" };
char Message_2[BUF_SIZE] = { "Message 2" };
char Message_3[BUF_SIZE] = { "Message 3" };

int messageSelect = 0;
int switchInputA1;
int switchInputA2;
// =======================================================================





void setup() {

// MIDI Stuff ===============
Serial.begin(31250); // MIDI
// ==========================

// LED Control Stuff ==================================================================================
lc.shutdown(0,false); lc.setIntensity(0,8); lc.clearDisplay(0); 
lc.shutdown(1,false); lc.setIntensity(1,8); lc.clearDisplay(1);
lc.shutdown(2,false); lc.setIntensity(2,8); lc.clearDisplay(2);
lc.shutdown(3,false); lc.setIntensity(3,8); lc.clearDisplay(3); 
// =========================================================================

// Parola stuff =========================================================================
pinMode(A1, INPUT); // Switch to select scrolling text message 1/2
pinMode(A2, INPUT); // Switch to select scrolling text message 2/2

 if ( MessagesOrMIDI == 1 )
 {
      P.begin();
             
      if (messageSelect == 1 )
      {
      P.displayText(Message_1,0, 30, 0, PA_SCROLL_LEFT, PA_SCROLL_LEFT);
      }
    
      if (messageSelect == 2 )
      {
      P.displayText(Message_2,0, 30, 0, PA_SCROLL_LEFT, PA_SCROLL_LEFT);
      }
    
      if (messageSelect == 3 )
      {
      P.displayText(Message_3,0, 30, 0, PA_SCROLL_LEFT, PA_SCROLL_LEFT);
      }
  }
    
// =========================================================================
  
}




void loop() {

  time = millis(); // Switch back and forth, every 10 seconds, between MIDI controlled LED effects (LedControl) and scrolling (Parola)
  if ( time > interval )
  {
  doneFlag = 0;
   
  if ( (MessagesOrMIDI % 2) == 0 && doneFlag == 0 ) { MessagesOrMIDI = 1; doneFlag = 1; setup(); }

  if ( (MessagesOrMIDI % 2) != 0 && doneFlag == 0 ) { MessagesOrMIDI = 2;  } 
   
  interval = interval + intervalStep;
  }


    if ( MessagesOrMIDI == 1 ) // Text Scrolling
    {
        // Scroll Text =======================================================================
        P.displayAnimate();
      
        if (P.displayAnimate()) // If finished displaying message, check out switch to see what text message needs displying and (re-)run
        {
        switchInputA1 = analogRead(A1);
        switchInputA2 = analogRead(A2);
      
        if ( switchInputA1 > 500 && switchInputA2 < 500 ) { messageSelect = 1; }
        if ( switchInputA1 > 500 && switchInputA2 > 500 ) { messageSelect = 2; }
        if ( switchInputA1 < 500 && switchInputA2 > 500 ) { messageSelect = 3; }
  
        setup();
        
        }
        // ========================================================================= 
    }



  if ( MessagesOrMIDI == 2 )
  {
     // MIDI Stuff =========================================================================  
      if (Serial.available() > 0) {
      
         incomingByte = Serial.read();
        
          //if ( incomingByte == 250 )
          //{
                 
        
              if ( incomingByte == 248 )
              {  
                  
                  // Drive LEDs
                  if ( ledCounter == 1 ) { displayPosition = random(0,4); MatrixOnOff();  }
                  //if ( ledCounter == 13 ) { display = random(0,4); MatrixOnOff();  }
                  if ( ledCounter == 25 ) { displayPosition = random(0,4); MatrixOnOff();  }
                  //if ( ledCounter == 37 ) { display = random(0,4); MatrixOnOff();  }
                  if ( ledCounter == 49 ) { displayPosition = random(0,4); MatrixOnOff();  }
                  //if ( ledCounter == 61 ) { display = random(0,4); MatrixOnOff();  }
                  if ( ledCounter == 73 ) { displayPosition = random(0,4); MatrixOnOff();  }
                  //if ( ledCounter == 85 ) { display = random(0,4); MatrixOnOff();  }
                  ledCounter++;
                  if ( ledCounter == 97 ) { ledCounter = 1; }
      
               }
    
            //}
    
                   // if ( incomingByte == 252 )
                   // {
                   // asm volatile ("jmp 0");           
                   // }
      
        }
        // ========================================================================= 
    }

}    





// Functions =======================================================================

void MatrixOnOff()
{

  randomSymbol = random(1,5);
  
  if ( randomSymbol == 1 )
  {  
  lc.setRow(displayPosition,0,sqBox8[0]);
  lc.setRow(displayPosition,1,sqBox8[1]);
  lc.setRow(displayPosition,2,sqBox8[2]);
  lc.setRow(displayPosition,3,sqBox8[3]);
  lc.setRow(displayPosition,4,sqBox8[4]);
  lc.setRow(displayPosition,5,sqBox8[5]);
  lc.setRow(displayPosition,6,sqBox8[6]);
  lc.setRow(displayPosition,7,sqBox8[7]);
  }


if ( randomSymbol == 2 )
  {  
  lc.setRow(displayPosition,0,sqBox6[0]);
  lc.setRow(displayPosition,1,sqBox6[1]);
  lc.setRow(displayPosition,2,sqBox6[2]);
  lc.setRow(displayPosition,3,sqBox6[3]);
  lc.setRow(displayPosition,4,sqBox6[4]);
  lc.setRow(displayPosition,5,sqBox6[5]);
  lc.setRow(displayPosition,6,sqBox6[6]);
  lc.setRow(displayPosition,7,sqBox6[7]);
  }


if ( randomSymbol == 3 )
  {  
  lc.setRow(displayPosition,0,sqBox4[0]);
  lc.setRow(displayPosition,1,sqBox4[1]);
  lc.setRow(displayPosition,2,sqBox4[2]);
  lc.setRow(displayPosition,3,sqBox4[3]);
  lc.setRow(displayPosition,4,sqBox4[4]);
  lc.setRow(displayPosition,5,sqBox4[5]);
  lc.setRow(displayPosition,6,sqBox4[6]);
  lc.setRow(displayPosition,7,sqBox4[7]);
  }

if ( randomSymbol == 4 )
  {  
  lc.setRow(displayPosition,0,sqBox2[0]);
  lc.setRow(displayPosition,1,sqBox2[1]);
  lc.setRow(displayPosition,2,sqBox2[2]);
  lc.setRow(displayPosition,3,sqBox2[3]);
  lc.setRow(displayPosition,4,sqBox2[4]);
  lc.setRow(displayPosition,5,sqBox2[5]);
  lc.setRow(displayPosition,6,sqBox2[6]);
  lc.setRow(displayPosition,7,sqBox2[7]);
  }
  
  delay(200);
  lc.clearDisplay(displayPosition);

Cont. posting ------- The circuit has a MIDI in and I use the MIDI clock to display squares (and more if I get it to work) in sync with the music. After 5 seconds (or whatever duration) the display will read something like “you are listening to etc.” … then after a certain amount of time it goes back to showing effects in sync with the music … and back to scrolling text etc.

Have a look here on youtube to see it in action:

Link

After reset of the Nano, you can see blinking squares (this is in sync with an incoming midi clock) … this is using LedControl … all fine, happy with that. Then after 5 seconds, it switches to a scrolling text (I can select different text messages with the switch bottom left) … again, all fine. 5 seconds later, it is supposed to switch back to the blinking squares … but that’s not working. When you wait another 5 seconds you can see the scrolling starting again … … … so, somehow Parola ‘blocks’ LedControl. I’ve done a few Arduino projects and usually I can work things out but not this time. I could reset the Arduino externally with a 555 circuit, but I’d imagine it must be possible through code.

OK, so I was a bit vague about this.

So the LedControl library is used to control matrix displays then. :astonished: I did not realise this as I have only ever used my own code or Parola.

And that is exactly what Parola is for.

You are attempting to use two different libraries to access the same displays. It should be obvious that it is not going to work. Probably because MD_MAX72xx reconfigures the hardware SPI, or because you would have to re-initialise LedControl - I haven't had time to look just now.

So, the obvious answer is to "lose" LedControl. You should not need it. Use MD_MAX72xx to do whatever you were doing with it. Read the instructions. :grinning:

Appreciate your feedback.

Yes, I have already started looking into what other stuff Parola can do to provide effects in sync with the MIDI clock.

I did try to re-initialize LedControl but Paraola seems to overrule things - it’s got a good grip over the HW.

I could of course add another screen; one for LedControl and one for Parola - they cost pennies :slight_smile:

I could be wrong, but I presume that MD_MAX72xx and LedControl do basically the same thing, but MD_MAX72xx is probably much more versatile.

Waiting for Marco to chip in. :grinning:

Got it all up and running

https://youtu.be/fUTcd5c1eOQ

Design, diagram, code etc to follow

Good you got it working, but you don't describe how (to follow?).

In general you should not mix two libraries that control the same hardware. You should either use one or the other.

If you want to just use Parola and MD_MAX72xx, then you can do the MIDI effects by calling MD_MAX72xx library directly - you get the library (object) handle from the Parola library. This avoids contention issues between the two libraries when accessing the hardware.

Cant comment about LedControl, as I don't use it.

marco_c: Cant comment about LedControl, as I don't use it.

Obviously! :grinning: :grinning: :grinning:

Here’s the end result of what I was working on (called MidiMatrix):

Diagram, PCB, Sketch, Components etc. can be found here:

MIDI Synced LED Matrix (MidiMatrix) by Erik Oostveen

Looks neat and professionally done. Good job!

Cheers!