16x32 RGB LED Matrix, Arduino Due
Moderators: adafruit_support_bill, adafruit
Please be positive and constructive with your questions and comments.
-
- Posts: 2
- Joined: Thu Feb 21, 2013 2:59 am
16x32 RGB LED Matrix, Arduino Due
Hi, I found less information about this.
Will the 16x32 or 32x32 RGB LED-Matrix work with the Arduino Due? Is someone porting the library for the Arduino Due.
Another Question will the library for the digitally controlled pwm led stripes, work with the Due?
Thanks in advance
Will the 16x32 or 32x32 RGB LED-Matrix work with the Arduino Due? Is someone porting the library for the Arduino Due.
Another Question will the library for the digitally controlled pwm led stripes, work with the Due?
Thanks in advance
-
- Posts: 33
- Joined: Thu Dec 20, 2012 9:33 am
Re: 16x32 RGB LED Matrix, Arduino Due
There doesn't seem to be many people here with Due's yet. There was a shortage, so hopefully now that is sorted out, more people here will get them.
I've ported Adafruit's WS2801 and LBD8806 libraries to the Due. There were quite a few things I needed to do, but it is possible.
I'd encourage you to try it yourself, if it doesn't work straight away.
I've ported Adafruit's WS2801 and LBD8806 libraries to the Due. There were quite a few things I needed to do, but it is possible.
I'd encourage you to try it yourself, if it doesn't work straight away.
- pburgess
- Posts: 4161
- Joined: Sun Oct 26, 2008 2:29 am
Re: 16x32 RGB LED Matrix, Arduino Due
Hardwarily, there's no reason this couldn't work. The Due would be great for this.
Softwarily, the library hasn't been ported yet. There are some hardware differences that would need to be dealt with (timers, etc.) that make this a non-trivial effort. But it seems likely it'll happen...just no ETA right now.
Softwarily, the library hasn't been ported yet. There are some hardware differences that would need to be dealt with (timers, etc.) that make this a non-trivial effort. But it seems likely it'll happen...just no ETA right now.
- avriot
- Posts: 15
- Joined: Tue Nov 15, 2011 4:55 pm
Re: 16x32 RGB LED Matrix, Arduino Due
Is there any eta on a port of the LED matrix library for the Due? I've got something mostly working, but there is a bit of ghosting going on so I thought I'd check in to see if anybody else is working on this. If not, I can post what I have if others have any ideas.
- avriot
- Posts: 15
- Joined: Tue Nov 15, 2011 4:55 pm
Re: 16x32 RGB LED Matrix, Arduino Due
Since nobody has responded, I assume nobody has gotten further then my blundering about 
So, this is as far as I've gotten with porting stuff from the Adafruit RGB library:
It works mostly, but I get ghosties:

One thing I can think of is a a possible misunderstanding about how the timer interrupts work. I grabbed code from http://forum.arduino.cc/index.php?topic=130423.0 which seemed to work ok, but I'm a bit confused. Specifically, about these few lines:
and
I'm using this combo because any higher frequency and not all the points are plotted, but any lower frequency, and the ghosties get worse. I would think this combo would lead to an interrupt at (84 Mhz)/2/80000 = 525 Hz or clock cycles (which would be 0.16 Hz)? Either way, it is way lower than the 40-50 Mhz I would need. It is possible that I'm just not understanding how all of the variables work, but I've played with different values of the "frequency" and its hard to find a sweet spot.
Furthermore, if I do other things in the code, like update the display based on input from an analog pin or two, then the value of the optimum frequency changes.
So, any ideas on this would be thankfully appreciated!
Edit: Also, I realized I'm also a little fishy on the setting of the registers (so, basically, the whole code!
), as in, how the toggling of bits in the original Arduino code translates to simply setting registers in the new Due code (for example: do A, B, C pins need to be low when the clock is toggled or their original values?)

So, this is as far as I've gotten with porting stuff from the Adafruit RGB library:
Code: Select all
#include <Arduino.h>
#define APIN 33
#define BPIN 34
#define CPIN 35
#define LAT 38
#define OE 36
#define CLK 37
#define R1 32
#define G1 29
#define B1 27
#define R2 30
#define G2 28
#define B2 26
#define PWMBITS 3 // 3 = 3 bit color per LED, 9-bit total pixel color
#define PWMMAX ((1 << PWMBITS) - 1)
#define WIDTH 96 // = 32 X number of panels
#define HEIGHT 16 // = height of each panel
#define NUMBYTES (WIDTH * HEIGHT / 2) * 3 // use 1.5 bytes (12 bits) per pixel
#define maxScan 8 // number of sections that are scanned - 8 rows for each RGB-123
uint8_t matrixbuff[NUMBYTES]; // 768 bytes for 16x32
volatile uint8_t pwmcounter=0;
volatile uint8_t scansection=0;
//----------------------------
void matrix_begin() {
pinMode(APIN, OUTPUT);
digitalWrite(APIN, LOW);
pinMode(BPIN, OUTPUT);
digitalWrite(BPIN, LOW);
pinMode(CPIN, OUTPUT);
digitalWrite(CPIN, LOW);
pinMode(LAT, OUTPUT);
digitalWrite(LAT, LOW);
pinMode(CLK, OUTPUT);
digitalWrite(CLK, HIGH);
pinMode(OE, OUTPUT);
digitalWrite(OE, LOW);
pinMode(R1,OUTPUT);
pinMode(R2,OUTPUT);
pinMode(G1,OUTPUT);
pinMode(G2,OUTPUT);
pinMode(B1,OUTPUT);
pinMode(B2,OUTPUT);
digitalWrite(R1,LOW);
digitalWrite(R2,LOW);
digitalWrite(G1,LOW);
digitalWrite(G2,LOW);
digitalWrite(B1,LOW);
digitalWrite(B2,LOW);
}
// construct a color from an r,g,b value
uint16_t matrix_Color444(uint8_t r, uint8_t g, uint8_t b) {
uint16_t c;
c = r;
c <<= 4;
c |= g & 0xF;
c <<= 4;
c |= b & 0xF;
return c;
}
// draw a pixel at the x & y coords with a specific color
void matrix_drawPixel(uint8_t x, uint8_t y, uint16_t c) {
uint16_t index = 0;
uint8_t old;
uint8_t red, green, blue, panel, ysave, ii;
// extract the 12 bits of color
red = (c >> 8) & 0xF;
green = (c >> 4) & 0xF;
blue = c & 0xF;
panel = (y - y%16)/16;
// both top and bottom are stored in same byte
if (y%16 < 8)
index = y%16;
else
index = y%16-8;
// now multiply this y by the # of pixels in a row
index *= WIDTH;
index += 32*panel;
// now, add the x value of the row
index += x;
// then multiply by 3 bytes per color (12 bit * High and Low = 24 bit = 3 byte)
index *= 3;
old = matrixbuff[index];
if (y%16 < 8) {
// we're going to replace the high nybbles only
// red first!
matrixbuff[index] &= ~0xF0; // mask off top 4 bits
matrixbuff[index] |= (red << 4);
index++;
// then green
matrixbuff[index] &= ~0xF0; // mask off top 4 bits
matrixbuff[index] |= (green << 4);
index++;
// finally blue
matrixbuff[index] &= ~0xF0; // mask off top 4 bits
matrixbuff[index] |= (blue << 4);
} else {
// we're going to replace the low nybbles only
// red first!
matrixbuff[index] &= ~0x0F; // mask off bottom 4 bits
matrixbuff[index] |= red;
index++;
// then green
matrixbuff[index] &= ~0x0F; // mask off bottom 4 bits
matrixbuff[index] |= green;
index++;
// finally blue
matrixbuff[index] &= ~0x0F; // mask off bottom 4 bits
matrixbuff[index] |= blue;
}
}
// output your filled matrix
void matrix_writeSection(uint8_t secn, uint8_t *buffptr) {
//digitalWrite(OE, HIGH);
uint16_t portCstatus_nonclk = 0x0080; // CLK = low
uint16_t portCstatus = 0x0080; // OE = HIGH
portCstatus |= 0x0020; // clk is high here too
REG_PIOC_ODSR = portCstatus; // set OE, CLK to high
// set A, B, C pins
if (secn & 0x1){ // Apin
portCstatus |= 0x0002;
portCstatus_nonclk |= 0x0002;
}
if (secn & 0x2){ // Bpin
portCstatus |= 0x0004;
portCstatus_nonclk |= 0x0004;
}
if (secn & 0x4){ // Cpin
portCstatus |= 0x0008;
portCstatus_nonclk |= 0x0008;
}
REG_PIOC_ODSR = portCstatus; // set A, B, C pins
// if (secn & 0x1) {
// digitalWrite(APIN, HIGH);
// } else {
// digitalWrite(APIN, LOW);
// }
// if (secn & 0x2) {
// digitalWrite(BPIN, HIGH);
// } else {
// digitalWrite(BPIN, LOW);
// }
// if (secn & 0x4) {
// digitalWrite(CPIN, HIGH);
// } else {
// digitalWrite(CPIN, LOW);
// }
uint8_t low, high;
uint16_t out = 0x0000;
uint8_t i;
for ( i=0; i<WIDTH; i++) {
out = 0x0000;
// red
low = *buffptr++;
high = low >> 4;
low &= 0x0F;
//if (low > pwmcounter) {
// digitalWrite(R2,HIGH);
//} else {
// digitalWrite(R2,LOW);
//}
if (low > pwmcounter) out |= 0x0200; // R2, pin 30, PD9
//if (high > pwmcounter){
// digitalWrite(R1,HIGH);
//} else {
// digitalWrite(R1,LOW);
//}
if (high > pwmcounter) out |= 0x0400; // R1, pin 32, PD10
// green
low = *buffptr++;
high = low >> 4;
low &= 0x0F;
//if (low > pwmcounter) {
// digitalWrite(G2,HIGH);
//} else {
// digitalWrite(G2,LOW);
//}
if (low > pwmcounter) out |= 0x0008; // G2, pin 28, PD3
//if (high > pwmcounter){
// digitalWrite(G1,HIGH);
//} else {
// digitalWrite(G1,LOW);
//}
if (high > pwmcounter) out |= 0x0040; // G1, pin 29, PD6
// blue
low = *buffptr++;
high = low >> 4;
low &= 0x0F;
//if (low > pwmcounter) {
// digitalWrite(B2,HIGH);
//} else {
// digitalWrite(B2,LOW);
//}
if (low > pwmcounter) out |= 0x0002; // B2, pin 26, PD1
//if (high > pwmcounter){
// digitalWrite(B1,HIGH);
//} else {
// digitalWrite(B1,LOW);
// }
if (high > pwmcounter) out |= 0x0004; // B1, pin 27, PD2
//digitalWrite(CLK, LOW);
REG_PIOC_ODSR = portCstatus_nonclk; // set clock to low, OE, A, B, C stay the same
REG_PIOD_ODSR = out;
//digitalWrite(CLK, HIGH);
REG_PIOC_ODSR = portCstatus; // set clock to high, OE, A, B, C stay the same
}
// latch it!
//digitalWrite(LAT, HIGH);
REG_PIOC_ODSR = 0x0070; // LAT = HIGH, OE = HIGH, CLK = HIGH, A, B, C = LOW
//digitalWrite(LAT, LOW);
REG_PIOC_ODSR = 0x0030; // only OE = HIGH and CLK = HIGH, LAT = LOW, A, B, C = LOW
// digitalWrite(OE, LOW);
REG_PIOC_ODSR = 0x0020; // only clk is high, OE, LAT, A, B, C are low
}
void matrix_updateDisplay(void) {
matrix_writeSection(scansection, matrixbuff + (3*WIDTH*scansection));
scansection++;
if (scansection == maxScan) {
scansection = 0;
pwmcounter++;
if (pwmcounter == PWMMAX) { pwmcounter = 0; }
}
}
//TC1 ch 0
void TC3_Handler()
{
TC_GetStatus(TC1, 0);
matrix_updateDisplay();
}
void startTimer(Tc *tc, uint32_t channel, IRQn_Type irq, uint32_t frequency) {
pmc_set_writeprotect(false);
pmc_enable_periph_clk((uint32_t)irq);
TC_Configure(tc, channel, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK1);
uint32_t rc = VARIANT_MCK/2/frequency; //2 because we selected TIMER_CLOCK1 above
//TC_Configure(tc, channel, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK4);
//// VARIANT_MCK = 84000000, I guess timer4 is every 1/4 or something?
//uint32_t rc = VARIANT_MCK/128/frequency; //128 because we selected TIMER_CLOCK4 above
TC_SetRA(tc, channel, rc/2); //50% high, 50% low
TC_SetRC(tc, channel, rc);
TC_Start(tc, channel);
tc->TC_CHANNEL[channel].TC_IER=TC_IER_CPCS;
tc->TC_CHANNEL[channel].TC_IDR=~TC_IER_CPCS;
NVIC_EnableIRQ(irq);
}
void setup(){
matrix_begin();
startTimer(TC1, 0, TC3_IRQn, 150000); //TC1 channel 0, the IRQ for that channel and the desired frequency
}
void loop(){
matrix_drawPixel(0, 2, matrix_Color444(2, 0, 0));
matrix_drawPixel(1, 2, matrix_Color444(2, 0, 0));
matrix_drawPixel(2, 2, matrix_Color444(2, 0, 0));
matrix_drawPixel(3, 2, matrix_Color444(2, 0, 0));
matrix_drawPixel(4, 2, matrix_Color444(2, 0, 0));
}
One thing I can think of is a a possible misunderstanding about how the timer interrupts work. I grabbed code from http://forum.arduino.cc/index.php?topic=130423.0 which seemed to work ok, but I'm a bit confused. Specifically, about these few lines:
Code: Select all
TC_Configure(tc, channel, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK1);
uint32_t rc = VARIANT_MCK/2/frequency; //2 because we selected TIMER_CLOCK1 above
Code: Select all
startTimer(TC1, 0, TC3_IRQn, 80000); //TC1 channel 0, the IRQ for that channel and the desired frequency
Furthermore, if I do other things in the code, like update the display based on input from an analog pin or two, then the value of the optimum frequency changes.
So, any ideas on this would be thankfully appreciated!
Edit: Also, I realized I'm also a little fishy on the setting of the registers (so, basically, the whole code!

- avriot
- Posts: 15
- Joined: Tue Nov 15, 2011 4:55 pm
Re: 16x32 RGB LED Matrix, Arduino Due
Ok, so, I've narrowed down one problem which is basically a typo * looks sheepish *
Changing the lines:
to
leads me to actually set the OE on the right pin and removes the ghosting. Hurray!
I still don't quite get the timer update frequency as it seems to be very low numbers still, and I still can't get exactly the pattern I want to print out... but one crisis at a time... sigh.
Changing the lines:
Code: Select all
uint16_t portCstatus_nonclk = 0x0080; // OE high, CLK = low
uint16_t portCstatus = 0x0080; // OE = HIGH
Code: Select all
uint16_t portCstatus_nonclk = 0x0010; // OE high, CLK = low
uint16_t portCstatus = 0x0010; // OE = HIGH
I still don't quite get the timer update frequency as it seems to be very low numbers still, and I still can't get exactly the pattern I want to print out... but one crisis at a time... sigh.

- avriot
- Posts: 15
- Joined: Tue Nov 15, 2011 4:55 pm
Re: 16x32 RGB LED Matrix, Arduino Due
So, I do feel a little silly posting again since I think I'm just talking to myself (Hi self! *waves*). But, on the off chance that someone else wants to try to drive more panels with a Due some time in the future, I've managed to get a little library working with a few standard examples. Link is found in this post: http://avriot.com/?p=393. Right now I've just got the library doing the math for 1 panel, but the Due can definitely drive more. On that blog post I show a pic of 3 panels which don't flicker in the slightest, but there are some funny lines in the 2 trailing panels because of poor math. More info can be found at that page, since I think I've blathered on and on enough here 

- hiduino
- Posts: 862
- Joined: Sat Sep 01, 2012 7:05 pm
Re: 16x32 RGB LED Matrix, Arduino Due
I've been wanting to try using my Due also, but just haven't the time. But I'll take a look at what you have and see if I can make a go of it also. I have 4 panels to play with so we'll see how well it can do or not.
- adafruit_support_rick
- Posts: 35092
- Joined: Tue Mar 15, 2011 11:42 am
Re: 16x32 RGB LED Matrix, Arduino Due
My apologies. We in support usually look for unanswered topics. When you tag on to an old thread, it often goes unnoticed. It usually better to start a new topic than resurrect an old one.avriot wrote:Since nobody has responded, I assume nobody has gotten further then my blundering about
We aren't really doing much work on porting libraries to the Due. A major reason for this is that Arduino 1.5.2 is quite incomplete and unstable, and it hasn't been updated for over 6 months. We have decided to focus our efforts elsewhere until such time as a usable version of Arduino for the Due is released.
That said, we don't discourage our customers from making their own attempts at porting our libraries!

- avriot
- Posts: 15
- Joined: Tue Nov 15, 2011 4:55 pm
Re: 16x32 RGB LED Matrix, Arduino Due
No worries! I'll know better next time. In the end, it worked out well since I just had to work on it a bit more myself and I learned something new. Got some new brain folds.My apologies. We in support usually look for unanswered topics. When you tag on to an old thread, it often goes unnoticed. It usually better to start a new topic than resurrect an old one.

Now that you mention it, I did have to make a few changes to the hardware stuff for Arduino 1.5.2, but I think it was all for another application. If anybody has issues with the matrix library I posted, please let me know and I'll post the hardware changes I made.We aren't really doing much work on porting libraries to the Due. A major reason for this is that Arduino 1.5.2 is quite incomplete and unstable, and it hasn't been updated for over 6 months. We have decided to focus our efforts elsewhere until such time as a usable version of Arduino for the Due is released.
- avriot
- Posts: 15
- Joined: Tue Nov 15, 2011 4:55 pm
Re: 16x32 RGB LED Matrix, Arduino Due
Hi all! Just wanted to give you a quick update that a new library with multiple panel support and examples has been posted. I was able to do 6 panels with some simple animations, but had to play around a bit with the "frequency" input in matrix.begin. The character writing isn't working at the moment with multiple y-panels, but other stuff is. Also, seems like the plasma example has a slow refresh rate do draw new pixels, which I'll hopefully get around to checking up with in the next few weeks, but probably not until then. Check out some of the examples for a better idea of how to implement different panels, and there is a diagram of different panel layouts on the website.
- adafruit_support_rick
- Posts: 35092
- Joined: Tue Mar 15, 2011 11:42 am
Re: 16x32 RGB LED Matrix, Arduino Due
Cool - We'll have to give it a try 

-
- Posts: 15
- Joined: Tue Apr 23, 2013 6:19 pm
Re: 16x32 RGB LED Matrix, Arduino Due
I've bought the same display. Could you post you working library to try something ? I've 2 display
Thank you so much
Daniele
Thank you so much
Daniele
-
- Posts: 2
- Joined: Sun Jan 12, 2014 11:12 am
Re: 16x32 RGB LED Matrix, Arduino Due
I've expanded avriot's library a bit to work with the 32x32 matrix as well as the 16x32 one.
It works pretty well, but I too am having some timing troubles stemming, I think, from using SerialUSB on the native port. I'm pushing frames to the panel over serial, which works nicely in about 30fps with 16bit colors, but I think the timers for usb and the matrix interfere with each other. (I'm using SerialUSB because as far as I can tell using hardware serial through the programming port is basically impossible over 200,000 kbaud.)
As long as I'm pushing new data, the display flickers randomly, resulting in some lines being brighter than other lines. If I set the matrix frequency to something ludicrously high (like 20,000), the problem goes away, but unsurprisingly the frame rate goes down. As soon as I stop sending new frames, the matrix displays the last frame completely flicker-free. Maybe somebody here who understands these timers properly has some idea.
Side note: If I do use serial via the programming port the flicker completely goes away, but I can't get more than about 9fps. So that's not a solution, but it does lead me to think the issue must be timer/interrupt-related.
I've put my changes to the library on github at https://github.com/kirberich/RGBmatrixPanelDue
The python module and arduino sketches for sending frames over serial is here: https://github.com/kirberich/matrix-controller
It works pretty well, but I too am having some timing troubles stemming, I think, from using SerialUSB on the native port. I'm pushing frames to the panel over serial, which works nicely in about 30fps with 16bit colors, but I think the timers for usb and the matrix interfere with each other. (I'm using SerialUSB because as far as I can tell using hardware serial through the programming port is basically impossible over 200,000 kbaud.)
As long as I'm pushing new data, the display flickers randomly, resulting in some lines being brighter than other lines. If I set the matrix frequency to something ludicrously high (like 20,000), the problem goes away, but unsurprisingly the frame rate goes down. As soon as I stop sending new frames, the matrix displays the last frame completely flicker-free. Maybe somebody here who understands these timers properly has some idea.
Side note: If I do use serial via the programming port the flicker completely goes away, but I can't get more than about 9fps. So that's not a solution, but it does lead me to think the issue must be timer/interrupt-related.
I've put my changes to the library on github at https://github.com/kirberich/RGBmatrixPanelDue
The python module and arduino sketches for sending frames over serial is here: https://github.com/kirberich/matrix-controller
-
- Posts: 6
- Joined: Tue Jun 14, 2011 12:06 pm
Re: 16x32 RGB LED Matrix, Arduino Due
Just wanted to say thanks for all the hard work! I have this panel and Due and I've been waiting for someone smarter than me to put all the pieces together! Thanks for all your hard work!
Please be positive and constructive with your questions and comments.