0

16x32 RGB LED Matrix -- Alt High Performance Library
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

16x32 RGB LED Matrix -- Alt High Performance Library

by pburgess on Tue Oct 11, 2011 7:06 pm

itsalive2.jpg
itsalive2.jpg (79.24 KiB) Viewed 7035 times


Huge disclaimer up front, so it doesn't get lost in the shuffle: this currently works ONLY with ATmega328P-based Arduinos such as the Uno and Duemilanove; no love for the Mega or 32u4. It also requires a VERY SPECIFIC PINOUT to the board...if you've already wired something up to use with the standard RGBmatrixPanel library, that won't work here...a couple wires need to be moved around, and CANNOT be changed as with that library. Between that and some syntax differences, this is NOT a drop-in replacement for the standard library.

AltRGBMatrixPanel.zip
Arduino library for 16x32 RGB LED Matrix
(19.82 KiB) Downloaded 1107 times


What we've got here is a library for the 16x32 RGB LED Matrix that achieves both better refresh rates and lower CPU usage -- producing steadier images and allowing more processing time for your own code. It also handles tiling of multiple panels, and the bit depth (maximum number of colors) is configurable. That's the good news.

The bad news...as previously mentioned, it's tied to a very specific hardware configuration. It relies on a few dirty tricks (or as a friend of mine says, "things that would get you an 'F' in a programming class"), and my concern is that the timing might be so delicate as to require tweaking if someone's using even a different version of the compiler. So I'm hoping there might be a couple willing guinea pigs. :)

This is admittedly not a very practical thing. These panels really do demand something with a lot more RAM and horsepower, but there's an idea I'd been wanting to try before going off to the PIC32 or some such...

SPI on the Arduino is great and fast for things with a serial interface...the hardware handles all that shifting out and the clock signal and such. The RGB panel has a 6-bit parallel interface, so the SPI hardware won't help here...instead, in the standard RGBmatrixPanel library, a full PORT register is written for the parallel data out, and then the clock and additional signals are bit-banged in code.

Chips like the PIC32 have a feature called a 'Parallel Master Port.' When data is written to this port (typically 8 or 16 output lines), the chip automatically generates a 'write strobe' on another pin...in much the same way that the Arduino SPI hardware generates a clock signal without software intervention. Less code and less time is spent fiddling bits, allowing greater throughput...and it's throughput that ultimately determines how quickly the panel can be refreshed (see the README with the library for an explanation of this).

The dirty trick then is to copy data from RAM to the PORT as fast as possible. With loop unrolling and a bit of inline assembly, one byte can be transferred in two instructions (three clock cycles)...and then hardware PWM is used to generate the write strobe in sync with the bytes out, no extra bit-banging instructions needed. Getting the latter just right required an oscilloscope and a fair bit of trial and error! End result, the Arduino can pump out data in short bursts at 5.33 MHz (times six bits wide...or even eight, if you don't need the serial port). This might also have applications for some of the LCD panels with parallel interfaces.

Blah blah blah. So...higher refresh rates, CPU use typically 10 to 20 percent.

RAM on the Arduino is so limited that I'm not sure this is anything more than a novelty. One panel can be driven at 6 bits depth (x RGB, or 18 bits total, 256K colors -- enough for some much-needed gamma correction), or two panels at 3 bits depth, etc. Thing is, at this size/depth, scant few bytes are left for one's own code, so you might actually want to use something less than those figures. There are example programs included for both one and two panel configurations.

So...as mentioned...the timing is very fussy, and my concern is that different compiler versions could affect that. If anyone wants to try it out, I'd appreciate feedback. If you run it and get gobbledygook on the matrix, try the following:

In the library source file 'AltRGBmatrixPanel.cpp', around line 29:

Code: Select all | TOGGLE FULL SIZE
#define INTERRUPT_OVERHEAD 85 // avr-g++ -Os (Arduino lib default)

Try changing this number to 100 or more, recompile the sketches, and see if that helps.

Lemme know if that works (or not). If there's interest, I might also do a Mega-specific version (the code there could be a bit simpler, and might eke out a couple extra % CPU time).

pburgess
 
Posts: 3882
Joined: Sun Oct 26, 2008 2:29 am

Re: 16x32 RGB LED Matrix -- Alt High Performance Library

by len17 on Tue Oct 11, 2011 7:50 pm

pburgess wrote:The dirty trick then is to copy data from RAM to the PORT as fast as possible. With loop unrolling and a bit of inline assembly, one byte can be transferred in two instructions (three clock cycles)...and then hardware PWM is used to generate the write strobe in sync with the bytes out

Wow, that's hardcore. 8)

len17
 
Posts: 393
Joined: Sat Mar 14, 2009 7:20 pm

Re: 16x32 RGB LED Matrix -- Alt High Performance Library

by douglasmauro on Thu Oct 13, 2011 1:21 pm

Sheesh and I wrote code to switch size & fonts and thought I was awesome ... this *is* hardcore!
douglasmauro
 
Posts: 14
Joined: Fri Feb 19, 2010 4:41 pm

Re: 16x32 RGB LED Matrix -- Alt High Performance Library

by sparr on Mon Oct 17, 2011 8:02 pm

I haven't looked at your code (a sin, I know), but I wanted to ask if you're aware that you can free up more processing cycles for other code by using power-of-two delays for the PWM and turning the LED on at times and durations that match the set bits in the brightness.

That is, for 8-bit PWM, instead of this:

led_on();
for(i=0;i<256;i++) {
if(brightness==i) led_off();
delay(1);
}

you can do this:

for(i=0;i<8;i++) {
if(brightness & 1<<i) {
led_on();
delay(1<<i);
led_off();
}
}

(sorry for any pseudocode mistakes, I'm not in the right place to test or look up the proper implementation)

Obviously this is over-simplified since you're sending data to the display in batches and turning a lot of LEDs off and on each cycle, but I hope I got the idea across.
sparr
 
Posts: 196
Joined: Tue Nov 04, 2008 5:21 pm

Re: 16x32 RGB LED Matrix -- Alt High Performance Library

by pburgess on Tue Oct 18, 2011 1:03 am

sparr wrote:I wanted to ask if you're aware that you can free up more processing cycles [...] using power-of-two delays for the PWM


Indeed! Binary code modulation was probably the biggest single performance-improving factor...all the other optimizations are frosting on the BCM cake. There's a README.txt file included with the library that explains some of the shenanigans.

pburgess
 
Posts: 3882
Joined: Sun Oct 26, 2008 2:29 am

Re: 16x32 RGB LED Matrix -- Alt High Performance Library

by tbitson on Sat Oct 29, 2011 6:25 pm

Works great with 2 panels in a 32 x 32 configuration. I stripped out the text drawing functions, and have it working with the plasma demo with plenty of code space left.

However, I have not been able to get more than 3 bit color depth (planes). I only get about 20 puxels lit with modtly static patterns. Any suggestions?

tbitson
 
Posts: 24
Joined: Sat Sep 03, 2011 8:34 am
Location: Tucson, AZ

Re: 16x32 RGB LED Matrix -- Alt High Performance Library

by pburgess on Sat Oct 29, 2011 7:14 pm

Nope. Graphics are a memory hog, and the Arduino is just plain FULL at that point...fewer than 100 bytes RAM remain for one's own program use. This really begs for a beefier microcontroller, but I was curious to try wringing blood from the proverbial stone. :)

Glad it's working for you, and thanks for the update!

pburgess
 
Posts: 3882
Joined: Sun Oct 26, 2008 2:29 am

Re: 16x32 RGB LED Matrix -- Alt High Performance Library

by avriot on Tue Nov 15, 2011 4:58 pm

I was curious how the pic32 code was coming? I've been playing around with it a bit, but any hints would be awesome :)

avriot
 
Posts: 15
Joined: Tue Nov 15, 2011 4:55 pm

Re: 16x32 RGB LED Matrix -- Alt High Performance Library

by pburgess on Wed Nov 16, 2011 1:50 am

No substantive progress there yet, I'm afraid...some other stuff in the pipeline has taken precedence. Still on the agenda, I just couldn't tell you exactly when.

pburgess
 
Posts: 3882
Joined: Sun Oct 26, 2008 2:29 am

Re: 16x32 RGB LED Matrix -- Alt High Performance Library

by avriot on Sat Nov 26, 2011 7:56 pm

FYI, I've posted what I have for a pic32 lib so far here: viewtopic.php?f=47&t=24429

Any comments would be most welcome! I'm afraid there is no magic in this code like there is in yours, but it does work :)

avriot
 
Posts: 15
Joined: Tue Nov 15, 2011 4:55 pm

Re: 16x32 RGB LED Matrix -- Alt High Performance Library

by tbitson on Tue Jan 17, 2012 3:15 pm

Can this be adapted to the new 32x32 matrix?

tbitson
 
Posts: 24
Joined: Sat Sep 03, 2011 8:34 am
Location: Tucson, AZ

Re: 16x32 RGB LED Matrix -- Alt High Performance Library

by pburgess on Tue Jan 17, 2012 7:34 pm

tbitson: the 32x32 panel uses 16-row strobing, and as a result will cut the refresh rate in half...I don't think the end result would be very pleasing.

The good news is that most of the techniques here have since been implemented in the "official" RGB matrix library, and while it doesn't achieve the same bit depth (4 bits x RGB vs 6 bits x RGB), overall I think it strikes a more favorable balance between RAM use, CPU load and image quality without having to resort to all of the really dirty tricks done here.

pburgess
 
Posts: 3882
Joined: Sun Oct 26, 2008 2:29 am

Please be positive and constructive with your questions and comments.