Tiled Neomatrix on different pins - only first defined works

I'm trying to run two Adafruit NeoMatrices in a 2x1 'group' on 2 different GPIOs (2&4) on the same Uno. Only one lights up: whichever one is declared first. If matrix1 is first, those matrices are lit. If matrix2 is first, those light up. In the current setup below, matrix2 lights up in blue.

#include <Adafruit_GFX.h>
#include <Adafruit_NeoMatrix.h>
#include <Adafruit_NeoPixel.h>

#define matrixWidth 16
#define matrixHeight  16
#define tilesX  2
#define tilesY  1

Adafruit_NeoMatrix matrix2 =  Adafruit_NeoMatrix(matrixWidth,matrixHeight, tilesX, tilesY, 4,  
  NEO_MATRIX_TOP   + NEO_MATRIX_RIGHT   + NEO_MATRIX_ROWS   + NEO_MATRIX_ZIGZAG +
  NEO_TILE_TOP + NEO_TILE_RIGHT + NEO_TILE_ROWS,
  NEO_GRB + NEO_KHZ800);
    
Adafruit_NeoMatrix matrix1 =  Adafruit_NeoMatrix(matrixWidth,matrixHeight, tilesX, tilesY, 2,  
  NEO_MATRIX_TOP   + NEO_MATRIX_RIGHT   + NEO_MATRIX_ROWS   + NEO_MATRIX_ZIGZAG +
  NEO_TILE_TOP + NEO_TILE_RIGHT + NEO_TILE_ROWS,
  NEO_GRB + NEO_KHZ800);
  


void setup() {

  matrix1.begin();
  matrix1.setTextWrap(false);
  matrix1.setBrightness(5);

  
  matrix2.begin();
  matrix2.setTextWrap(false);
  matrix2.setBrightness(5);

}
 
 
void loop() {

showTop();
showBottom();

}

void showTop() {
  
  matrix1.fillScreen(matrix1.Color(0,128,0));
  matrix1.show();

}

void showBottom() {
  
  matrix2.fillScreen(matrix2.Color(0,0,128));
  matrix2.show();

}

I found where someone else seemed to have the same problem a few years ago, but no one ever helped them. Adafruit NeoMatrix Serial Begin Issue

Any help is appreciated!
Thanks!
Blair

A glance at the code and it looks like it should work. I'd go to github, find the neomatrix page. Check out the issues page to see if your thingy is an open issue. If not open an issue, posting your code, and an adafruity programmer can give you some feedback on why their cht don't work.

Try using the numPixels() function to see if the NeoPixel memory for the second matrix is actually allocated. From Adafruit_NeoPixel.h:

uint16_t numPixels(void) const { return numLEDs; }

Good call, @gfvalvo.

When compiled for Arduino UNO this sketch has enough RAM for 440 pixels (10x11x4) but not 484 (11x11x4). For 1024 pixels (16x16x4) you are going to need an Arduino with more RAM.

Thanks, gfvalvo and everyone else! At least I'm not crazy...

I couldn't get that exact line to work (probably mostly because I don't know where to define matrix1 or matrix2 in that), and presumably numLEDs is defined in a different line. The Adafruit_NeoPixel.h docs don't mention where they got numLEDs from....but I ended up doing this and get 0 for both matrix1 and matrix2:

uint16_t numLEDs = matrix1.numPixels();

void setup() {

  // Start the serial interface
  Serial.begin(57600);

  Serial.print(numLEDs);

Getting the same value for both is suspicious, so probably my workaround isn't valid. Any thoughts on what I'm doing wrong?

Thanks!

Not posting the complete code that you tried.

A zero for .numPixels() means that there wasn't enough memory available to create the object.

In what way is it suspicious? If both are zero it means there wasn't room for either matrix. If both are 512 (16x16x2) it means there was room for both. If the first one is 512 and the second one is 0 it means there was room for the first but not the second.

I suspect that the problem is the location of the numPixels() call relative to where the memory allocation attempt actually takes place. But, need to see the code to tell. Hence, the hint in Post #6.

Here's the whole code. The output to the serial monitor is "⸮L⸮Number of LEDs: 0" (I'm swapping out matrix1 & matrix2 on the numLEDs declaration between runs)

#include <Adafruit_GFX.h>
#include <Adafruit_NeoMatrix.h>
#include <Adafruit_NeoPixel.h>


#define matrixWidth 16
#define matrixHeight  16
#define tilesX  2
#define tilesY  1

Adafruit_NeoMatrix matrix2 =  Adafruit_NeoMatrix(matrixWidth,matrixHeight, tilesX, tilesY, 4,  
  NEO_MATRIX_TOP   + NEO_MATRIX_RIGHT   + NEO_MATRIX_ROWS   + NEO_MATRIX_ZIGZAG +
  NEO_TILE_TOP + NEO_TILE_RIGHT + NEO_TILE_ROWS,
  NEO_GRB + NEO_KHZ800);
    
Adafruit_NeoMatrix matrix1 =  Adafruit_NeoMatrix(matrixWidth,matrixHeight, tilesX, tilesY, 2,  
  NEO_MATRIX_TOP   + NEO_MATRIX_RIGHT   + NEO_MATRIX_ROWS   + NEO_MATRIX_ZIGZAG +
  NEO_TILE_TOP + NEO_TILE_RIGHT + NEO_TILE_ROWS,
  NEO_GRB + NEO_KHZ800);





void setup() {

  // Start the serial interface
  Serial.begin(57600);


  
  matrix1.begin();
  matrix1.setTextWrap(false);
  matrix1.setBrightness(5);

  
  matrix2.begin();
  matrix2.setTextWrap(false);
  matrix2.setBrightness(5);

  uint16_t numLEDs = matrix2.numPixels();
  Serial.print("Number of LEDs: ");
  Serial.print(numLEDs);
}
 
 
void loop() {



showTop();
showBottom();

}

void showTop() {
  
  matrix1.fillScreen(matrix1.Color(0,128,0));
  matrix1.show();

}

void showBottom() {
  
  matrix2.fillScreen(matrix2.Color(0,0,128));
  matrix2.show();

}

Why not check the size of both matrices? And, get rid of excessive white space at the same time.

#include <Adafruit_GFX.h>
#include <Adafruit_NeoMatrix.h>
#include <Adafruit_NeoPixel.h>

#define matrixWidth 16
#define matrixHeight  16
#define tilesX  2
#define tilesY  1

Adafruit_NeoMatrix matrix2 =  Adafruit_NeoMatrix(matrixWidth, matrixHeight, tilesX, tilesY, 4,
                              NEO_MATRIX_TOP   + NEO_MATRIX_RIGHT   + NEO_MATRIX_ROWS   + NEO_MATRIX_ZIGZAG +
                              NEO_TILE_TOP + NEO_TILE_RIGHT + NEO_TILE_ROWS,
                              NEO_GRB + NEO_KHZ800);

Adafruit_NeoMatrix matrix1 =  Adafruit_NeoMatrix(matrixWidth, matrixHeight, tilesX, tilesY, 2,
                              NEO_MATRIX_TOP   + NEO_MATRIX_RIGHT   + NEO_MATRIX_ROWS   + NEO_MATRIX_ZIGZAG +
                              NEO_TILE_TOP + NEO_TILE_RIGHT + NEO_TILE_ROWS,
                              NEO_GRB + NEO_KHZ800);

void setup() {
  // Start the serial interface
  Serial.begin(57600);

  uint16_t numLEDs1 = matrix1.numPixels();
  uint16_t numLEDs2 = matrix2.numPixels();
  Serial.print("Number of LEDs Matrix 1: ");
  Serial.println(numLEDs1);
  Serial.print("Number of LEDs Matrix 2: ");
  Serial.println(numLEDs2);

  matrix1.begin();
  matrix1.setTextWrap(false);
  matrix1.setBrightness(5);

  matrix2.begin();
  matrix2.setTextWrap(false);
  matrix2.setBrightness(5);
}

void loop() {
  showTop();
  showBottom();
}

void showTop() {
  matrix1.fillScreen(matrix1.Color(0, 128, 0));
  matrix1.show();
}

void showBottom() {
  matrix2.fillScreen(matrix2.Color(0, 0, 128));
  matrix2.show();
}

New result with less whitespace and both LED counts printing:

Number of LEDs in matrix1: 0 Number of LEDs in matrix2: 0

#include <Adafruit_GFX.h>
#include <Adafruit_NeoMatrix.h>
#include <Adafruit_NeoPixel.h>


#define matrixWidth 16
#define matrixHeight  16
#define tilesX  2
#define tilesY  1

Adafruit_NeoMatrix matrix2 =  Adafruit_NeoMatrix(matrixWidth,matrixHeight, tilesX, tilesY, 4,  
  NEO_MATRIX_TOP   + NEO_MATRIX_RIGHT   + NEO_MATRIX_ROWS   + NEO_MATRIX_ZIGZAG +
  NEO_TILE_TOP + NEO_TILE_RIGHT + NEO_TILE_ROWS,
  NEO_GRB + NEO_KHZ800);
    
Adafruit_NeoMatrix matrix1 =  Adafruit_NeoMatrix(matrixWidth,matrixHeight, tilesX, tilesY, 2,  
  NEO_MATRIX_TOP   + NEO_MATRIX_RIGHT   + NEO_MATRIX_ROWS   + NEO_MATRIX_ZIGZAG +
  NEO_TILE_TOP + NEO_TILE_RIGHT + NEO_TILE_ROWS,
  NEO_GRB + NEO_KHZ800);

void setup() {

  // Start the serial interface
  Serial.begin(57600);
  
  matrix1.begin();
  matrix1.setTextWrap(false);
  matrix1.setBrightness(5);
  
  matrix2.begin();
  matrix2.setTextWrap(false);
  matrix2.setBrightness(5);

  uint16_t numLEDs1 = matrix1.numPixels();
  Serial.print("Number of LEDs in matrix1: ");
  Serial.print(numLEDs1);
  
  uint16_t numLEDs2 = matrix2.numPixels();
  Serial.print(" Number of LEDs in matrix2: ");
  Serial.print(numLEDs2);
}
 
void loop() {

showTop();
showBottom();

}

void showTop() {
  
  matrix1.fillScreen(matrix1.Color(0,128,0));
  matrix1.show();

}

void showBottom() {
  
  matrix2.fillScreen(matrix2.Color(0,0,128));
  matrix2.show();

}

And, do either of the matrices show anything?

Well, it used to. Let me see what I inadvertently changed....

I undid things one by one and found that when I added the Serial.begin, it stopped lighting up. That seems like the complete opposite of what you would want, since that would be for debugging...

But whichever matrix I define first is the one that lights up. They both report 0 to the serial interface in numPixels (when serial is enabled), but perhaps that's because they don't actually light up if I have the serial turned on?

Is there a way to print to the console below the code window instead of specifically turning on the serial console? I mean the one where the errors display, just below the code. My Google Fu has failed me in this search so far, but I'm still looking...

Only at compile time. Since the failure to allocate memory doesn't happen until runtime, you can't detect and report the failure at compile time.

1 Like

I tried adding a Serial.end() in the setup and then again in the loop after printing numLEDs in the setup, but they didn't light up. Serial seems to kill the ability to light the LEDs. This makes no sense to me. Here's the Serial.end() in the setup:

#include <Adafruit_GFX.h>
#include <Adafruit_NeoMatrix.h>
#include <Adafruit_NeoPixel.h>

#define matrixWidth 16
#define matrixHeight  16
#define tilesX  2
#define tilesY  1

Adafruit_NeoMatrix matrix2 =  Adafruit_NeoMatrix(matrixWidth,matrixHeight, tilesX, tilesY, 4,  
  NEO_MATRIX_TOP   + NEO_MATRIX_RIGHT   + NEO_MATRIX_ROWS   + NEO_MATRIX_ZIGZAG +
  NEO_TILE_TOP + NEO_TILE_RIGHT + NEO_TILE_ROWS,
  NEO_GRB + NEO_KHZ800);

Adafruit_NeoMatrix matrix1 =  Adafruit_NeoMatrix(matrixWidth,matrixHeight, tilesX, tilesY, 2,  
  NEO_MATRIX_TOP   + NEO_MATRIX_RIGHT   + NEO_MATRIX_ROWS   + NEO_MATRIX_ZIGZAG +
  NEO_TILE_TOP + NEO_TILE_RIGHT + NEO_TILE_ROWS,
  NEO_GRB + NEO_KHZ800);
  
void setup() {
  
  matrix1.begin();
  matrix1.setTextWrap(false);
  matrix1.setBrightness(5);

  matrix2.begin();
  matrix2.setTextWrap(false);
  matrix2.setBrightness(5);
  
  // Start the serial interface
  Serial.begin(57600);

  uint16_t numLEDs1 = matrix1.numPixels();
  Serial.print("Number of LEDs in matrix1: ");
  Serial.print(numLEDs1);
  
  uint16_t numLEDs2 = matrix2.numPixels();
  Serial.print(" Number of LEDs in matrix2: ");
  Serial.print(numLEDs2);
  Serial.end();
    
}
 
void loop() {
  
  showTop();
  showBottom();

}

void showTop() {
  
  matrix1.fillScreen(matrix1.Color(0,128,0));
  matrix1.show();

}

void showBottom() {
  
  matrix2.fillScreen(matrix2.Color(0,0,128));
  matrix2.show();

}

Serial requires a buffer in memory. You are very short on memory. If you DON'T use Serial you can fit one 16x16x2 matrix but not two. If you DO use Serial you can't even fit one. Makes sense to me

Try defining smaller matrices (say 2x2) just to see if the memory gets allocated. Get rid of Serial.end. It won't do anything for you.

I did that experiment. I was able to fit two 10x11x2 matrices but not two 11x11x2. (See Reply #4)

I saw it. BTW, you assumed 4 bytes / pixel. So these are RGBW devices?

But, it would be illustrative for nifty950 to print the numPixels value of each matrix for small sizes. Then, increase the sizes until the second one is no longer allocated. Then keep increasing until the first one is is no longer allocated.