I've got 8 x 8x8 matrices chained all of which have a max7219 controller on board, I'm finding that the performance of updating all the pixels on all of these screens is very slow, probably takes 500ms to set the pixels of all 8 screens.
Just doing something as basic as this (purposefully simplistic example!):
for(int i=0;i<8;i++)
{
for(int y=0;y<8;y++)
{
lc.setRow(i,y,255);
}
}
Just wondering if this is an inherent problem with using matrices like this and if I wanted to do full screen animation across the 64x32 screen I'd need to be using a different controller that has more umph?
Obviously the Mega board I'm using has more than enough grunt to set the pixels fast enough so I can only assume the bottleneck is on the MAX7219 itself.
No, the bottleneck is not the Arduino or the max chips. It's the library. Don't get me wrong, the LED Control library is great for a beginner taking their first steps with max7219 chips. But every time your code calls lc.setRow(), it is only intending to update 8 LEDs, but the data that is sent each time probably updates at least 64 LEDs, maybe all 512, I'm not sure. Also, it may not be using the Arduino's SPI hardware, but using software "bit-banged" SPI, which is at least an order of magnitude slower.
So to summarize, an ordinary Arduino and Max chips can be used to update a display much larger than 8 times 8x8 very smoothly. But you must either use the right library or eschew libraries and write code yourself that interacts with the max chips more closely.
Hopefully forum member Marco will respond and advise!
Last time I looked (some time ago), LedControl was particularly inefficient, as mentioned above:
It did not use the SPI hardware and 'bit banged' the interface. This is much much slower to execute the comms.
It updated the while display every time one thing changed (eg, your call to setRow) rather than just the parts that changed.
Together these two aspects make it very clunky and slow for animations, or even just fast updates.
The MaxMatrix library works the same way, as far as I can tell.
You might want to try the MD_MAX72xx library to see if this works faster for you. If you are doing text animation (scrolling, etc) the MD_Parola would also be worth looking into. Links in the signature block below.
Right, looks like you are using a panel of matrices for text/graphics. For this application I would suggest you look at MD_MAXPanel. I wrote this one specifically to support 'game' type applications.
Awesome, I'll give that a shot. The idea was to have pinball table type animations, so basically store the graphics for each animation frame (probably a byte array) and be able to cycle through.
From your SPI pins it looks like you are not using the hardware SPI the. Have you changed the library constructor to be the version where you supply the pins?
Is your power supply separate from the Arduino? The Arduino board's power supply is not powerful enough for 8 matrices. You need a separate power supply and make sure the grounds are all connected together.
Are you sure your wiring is right? No shorts or incorrect paths?
Did you set serial monitor baud rate to match the baud rate set in the sketch?
No sure, I'll need to check that.
How are you powering the circuit? Did you overload the usb power with too many matrices?
Is your power supply separate from the Arduino? The Arduino board's power supply is not powerful enough for 8 matrices. You need a separate power supply and make sure the grounds are all connected together.
So the Matrices are all powered directly off the main board, this wasn't a problem before when I was using the LEDControl library, but I can certainly give it it's own power supply and test it again.
From your SPI pins it looks like you are not using the hardware SPI the. Have you changed the library constructor to be the version where you supply the pins?
I didn't know there was a difference in which pins you use, which pins are the best to use, and the only thing I changed were the consts at the beginning of the Panel_Test to assign the pins.
Are you sure your wiring is right? No shorts or incorrect paths?
It works perfectly with the LEDControl library, the wiring for the boards isn't identical to that in the documentation as this from what I understand just simplifies it for when you've got a lot of boards stacked up. I've only got two runs of 4 so the wiring comes out the end of one block of 4 and into the other end of the next block of 4.
The other thing is I've been looking at what this library does and it seems a little overly complex for what I actually need.
I've already got my fonts as bytes (an 8x14 and 3x5 font), and I'm happy to bit shift the bytes to do the 10s and the units in the little font, this stuff isn't scary to me. So I'm really comfortable dealing in bytes (takes me back to my spectrum coding days!). So ideally all I want is a library that essentially has two commands:
SetByte([displayno],[RowNo],[Byte]); // Prepare the display bytes
-- This essentially would probably set bytes in an array (disp1) meanwhile an array (disp2) is what is currently displayed on the screens
and
RefreshDisplays(); //Apply all the changes made to the displays
-- So this could compare the bytes in disp1 and disp2 and update the elements of the displays that have changed. From here the SetByte commands would then update disp2 rather than disp1 and then the refresh displays would flip to the other disp array (if all this makes sense), again this goes back to my previous coding days where you'd draw the screen then "flip" to it, and then you'd continue drawing on the other screen, then flip again to display it. I appreciate I'm rambling on a bit now!
I don't know how much of a big ask this is, I'm happy to write it myself if I understood the communication to the 7219s, but that's currently a bit beyond my knowledge right now. I had a look at the LEDControl.cpp to see if I could mod that to make it work as I wanted but ended up just making it even more inefficient (still worked though! just even slower!!)
That aside, this help you guys are providing is massively appreciated.
Actually thinking about this a bit more... So this is written directly into the browser, more pseudo code than code! Completely untested, not run, nothing! Just thinking out loud!!
So really the main bit I can't do is the {DoCleverStuffToUpdateTheActualDisplay;} of course, I've no idea how this should work, or indeed if you can just punch a byte at a row of a display... Anyway...
RobFarley:
So the Matrices are all powered directly off the main board, this wasn't a problem before when I was using the LEDControl library, but I can certainly give it it's own power supply and test it again.
What does "powered directly off the main board" mean? What is this "main board"?
I am always suspicious of such statements. An Arduino is not in any respect whatsoever a "power supply"; you supply power - at 5 V - to it via the 5 V pin it does not supply power to anything else.
I don't really want to argue this as I'm really not precious about how it's powered and happy to try it out on it's own power supply. However, it's connected as per the instructions I got with the starter kit, and subsequently I've now got the 8 matrices running off the same pin diagram which apparently isn't the greatest idea in the world and I'm happy to adjust what I'm doing accordingly...
If I'm doing something wrong tell me! I'm new to this and keen to learn from the more experienced members of this forum. I've simply wired stuff up as per the instructions I've got!
I'm fine with software, but very new to the hardware side of things.
I didn't know there was a difference in which pins you use, which pins are the best to use, and the only thing I changed were the consts at the beginning of the Panel_Test to assign the pins.
There is a hardware SPI interface that works really fast. This is on set pins, which depend on the type of Arduino you are using (normally marked MISO, MISO and SS pins). You can also do SPI by bit bashing any pins you like, but this will run slower. The MD_MAX72xx library allows you to use either type. If you use the constructor with no pins, then it will default to the hardware interface for your hardware, using the SPI library. If you specify the pins, then it will bit bash directly.
I don't know how much of a big ask this is, I'm happy to write it myself if I understood the communication to the 7219s, but that's currently a bit beyond my knowledge right now.
Not really that hard at all. You should be able to work it out from the two libraries you have. It will simplify things if you use the SPI library for the actual transmissions (with the default pins). There is lots out there describing how the SPI interface works and you can certainly use any of the generic code in MD_MAX72xx. The MAX72xx data sheet describes the command register codes you should use and how the supporting data byte is structured. Again, both libraries already do this, so I expect that if you read the data sheet and understand what SHOULD be done for comms, what the libraries ACTUALLY DO will become easier to understand.