32x16 LED Matrix Panel and Arduino

67,919

80

92

Introduction: 32x16 LED Matrix Panel and Arduino

The Story of Project

In short, this project is the result of a challenge. One day, a friend who was visiting me, saw my experiments with some led matrix and ask me if I can control many of these. I answered "yes certainly", using auxiliary integrated circuits can be controlled a large number of LEDs.

I started doing research and after I saw many projects I have concluded I need a ready-made panel and start my experiments from there. Also I wanted to skip monochrome panels and try with multicolor LEDs.

I observed that RGB panels are a little more expensive than dual color panels (the price difference is noticed especially when you plan to buy many).

So I decided to start with this panel: http://www.gearbest.com/development-boards/pp_65373.html which I think would best fit my future plans.

Priced at $ 13.91 is the best price that I could find (at the time I made the order).

I must say that this panel is why I "landed" at this store in the first place. Meanwhile I made several orders (from "Development Board" section)... and I will return with other articles if I manage to do interesting things with them.

Step 1: Components

The panel came as a kit. I guess that panel is used to make large displays available as finished product at some specialized vendors/manufacturers.

However, this panel assembly requires soldering of many SMD components. This requires careful planning of the sequence in which components will be soldered.

In the next steps I will show sequence that worked for me.

Step 2: PCB

PCB is very well done, the markings are visible and useful. Identifying the place for each component is easy.

The most important thing is to finish with SMD components before proceeding with thru-hole components.
Also it is necessary to mount bolts and nuts before soldering LED matrix.

Step 3: Soldering SMD Components

I soldered components in the following order:

  1. SMD Capacitors
  2. 74HC138
  3. 4953
  4. 74HC595

Step 4: Soldering Thru-hole Components

Not much to say at this step

Step 5: LED Matrix

Do not forget to double check orientation of LED matrix before soldering. There are two positions posible and only one is correct.

Note: I change bolts with others longer and put spacers for safety.

Step 6: Data Connector

A, B, C, D - row select with 74HC138

OE - 74HC595 Ouput Enable(Active Low)

STB - 74HC595 Strobe / Data Latch

CLK - 74HC595 Clock Input

R - data input for 74HC595 (RED section / 4*74HC595)

G - data input for 74HC595 (GREEN section / 4*74HC595)

Step 7: Arduino Library and Demo Code

I had to write this Arduino library from scratch because I have not found anything compatible with this panel.

I found souces / libraries for monochrome panels and for RGB panels but nothing to fit exactly this type of panel.

So I give up searching and start coding :) I named the library myMATRIX (sorry for the lack of inspiration).

After installing the library you can run the example myMATRIX_Demo.

This library should work with any ATmega - based Arduino boards. I tested with: Arduino Mega 2560, ATmega32, ATmega1284, ATmega8. It does not depend on other libraries and use timer2 for refreshing purpose.

Here is an example of using the library:

#include "myMATRIX.h"
#define RowAPin 2
#define RowBPin 3
#define RowCPin 4
#define RowDPin 5 
#define OE_Pin 6  
#define RedPin 7  
#define Green_pin 8  
#define CLK_Pin 9  
#define STB_Pin 10 

void setup () {
myMatrix.Init(Red_Pin,Green_Pin,CLK_Pin,RowA_Pin,RowB_Pin,RowC_Pin,RowD_Pin,OE_Pin,STB_Pin);
myMatrix.fillRectangle(0,0,31,4,red);
myMatrix.fillRectangle(0,5,31,10,green);
myMatrix.fillRectangle(0,11,31,15,yellow);
}

void loop(){
}

This example has the result from second image of this step.

Step 8: Another Example

#include "myMATRIX.h"
#define RowA_Pin 2
#define RowB_Pin 3
#define RowC_Pin 4
#define RowD_Pin 5 
#define OE_Pin 6  
#define Red_Pin 7  
#define Green_Pin 8  
#define CLK_Pin 9  
#define STB_Pin 10 

void setup (){
myMatrix.Init(Red_Pin,Green_Pin,CLK_Pin,RowA_Pin,RowB_Pin,RowC_Pin,RowD_Pin,OE_Pin,STB_Pin);
}

void loop(){
 myMatrix.clearScreen();
 char scrolltext_1[]="     * <a href="http://www.OpenHardware.Ro" rel="nofollow"> www.OpenHardware.Ro </a> *      ";
 char scrolltext_2[]="     * Numbers * 1234567890      ";
 char scrolltext_3[]="     * Capital Letters * ABCDEFGHIJKLMNOPQRSTUVXYZ      ";
 char scrolltext_4[]="     * Small Letters * abcdefghijklmnopqrstuvxyz      ";
 myMatrix.fillRectangle(0,0,31,15,red); delay(1000);
 myMatrix.fillRectangle(0,0,31,15,green); delay(1000);
 myMatrix.fillRectangle(0,0,31,15,yellow); delay(1000);
 myMatrix.drawRectangle(0,0,31,15,red); delay(1000);
 myMatrix.fillRectangle(10,3,21,12,green); delay(1000); 
 myMatrix.clearScreen();
 myMatrix.drawHLine(0,31,7,green);
 myMatrix.drawHLine(0,31,15,green);
 myMatrix.drawVLine(0,0,15,yellow);
 myMatrix.drawVLine(31,0,15,yellow);
 myMatrix.printString(5,8,yellow,black,"Demo");
 myMatrix.hScroll(0,red,black,scrolltext_1);
 myMatrix.hScroll(0,black,green,scrolltext_1);
 myMatrix.hScroll(0,red,black,scrolltext_2);
 myMatrix.hScroll(0,red,black,scrolltext_3);
 myMatrix.hScroll(0,red,black,scrolltext_4);
}

Step 9: More About MyMatrix Library

myMatrix library is very simple but has the advantage of being lightweight and easy to use.

All pins can be configured by the user.

Were implemented only basic functions :

void Init(uint8_t pinRed, uint8_t pinGreen, uint8_t pinClock, 
                 uint8_t pinRowA, uint8_t pinRowB, uint8_t pinRowC, uint8_t pinRowD,
                 uint8_t pinOE, uint8_t pinSTB);
void setPixel(uint8_t x ,uint8_t y, uint8_t color);
void fillRectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint8_t color);
void drawRectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint8_t color);
void clearScreen();
void printChar(uint8_t x,uint8_t y, uint8_t For_color, uint8_t Bk_color, char ch);
void printString(uint8_t x, uint8_t y, uint8_t For_color, uint8_t Bk_color,char *p);
void drawVLine(uint16_t x, uint16_t y1, uint16_t y2, uint8_t color);
void drawHLine(uint16_t x1, uint16_t x2, uint16_t y, uint8_t color);
void hScroll(uint8_t y, uint8_t For_color, uint8_t Bk_color,char *p);

This library is still in early stage. It will be maintained here: http://openhardware.ro/mymatrix

No need to check there to see if any updates. I'll post here by a comment any major change.

myMatrix library is released under the MIT license http://opensource.org/licenses/MIT nice explained here http://choosealicense.com/

There are plans in the future to update the library to support multiple panels (as I will have those panels).

I will also try other types of panels available on the market (same as above).

Thanks for reading!

UPDATE:

I attached here (at this step) version 1.1. Solve the compiling (in fact linking) problem in newer version of Arduino.

5 People Made This Project!

Recommendations

  • Game Design: Student Design Challenge

    Game Design: Student Design Challenge
  • Make It Bridge

    Make It Bridge
  • For the Home Contest

    For the Home Contest

92 Comments

0
joshcliffejones
joshcliffejones

Question 2 years ago on Step 9

Hi Silvius,
Firstly, MANY thanks for your tutorial, this is the only thing that has gotten me even close to what i wanted to achieve!

I have a couple of 16x80 LED panels that in themselves are LED signs, but with crappy built in controllers you have to program with a remote control. I want to modernise this and run them using an Arduino or ideally an ESP32 NodeMCU.

My issue that i hope someone can help me with is driving all 80 lines instead of just the 32 that your library is currently programmed for. When i change the values within the sketch from 31 to 79, it doesnt work, so i assume i am missing something more and the library needs to be modified?

I really really hope that yourself or someone can help me with this as its something ive attempted myself and unfortunately fail at.

Kind Regards,
Josh

0
dancopy
dancopy

3 years ago

Hi Silvius, if you can take a look at this attached sketch, it is a clock with a static text at the bottom but I would like to scroll this text but I have no idea because the author does not seem to have used any library for the module of matrix. Thank you

0
1413
1413

Reply 3 years ago

A quick hack to do that is replace this part

ClearBuffer();
printLetter(1,10,'H',COLOR_RED);
printLetter(1+6,10,'E',COLOR_RED);
printLetter(1+6+6,10,'L',COLOR_RED);
printLetter(1+6+6+6,10,'L',COLOR_RED);
printLetter(1+6+6+6+6,10,'O',COLOR_RED);

with a function that scrolls your text. Your function would do the same but change the position of each character base on step and time like this:

//global var
int scroll_max_step; // set in setup(), it can be your text length
int scroll_step; // set in setup(), scroll_step = -scroll_max_step;
unsigned long scroll_delay; // set in setup(), it can be 100ms or 500ms
unsigned long scroll_timestamp_old;

void print_text(int x, int y)
{
printLetter(x,y,'H',COLOR_RED);
printLetter(x+6,y,'E',COLOR_RED);
printLetter(x+6+6,y,'L',COLOR_RED);
printLetter(x+6+6+6,y,'L',COLOR_RED);
printLetter(x+6+6+6+6,y,'O',COLOR_RED);
}

void scrolling()
{
if (millis() - scroll_delay >= scroll_timestamp_old)
{
// this will scroll from left to right
scroll_timestamp_old = millis();
scroll_step++;
if (scroll_step >= scroll_max_step) scroll_step = -scroll_max_step;
}
ClearBuffer();
print_text(scroll_step, 10);
}

The only problem is void SetPixel(byte x, byte y, byte val) does not accept negative value, so you have to modify it to accept negative value and do nothing if it is negative value like this

void SetPixel(int x, int y, byte val)
{
if (x<0 || y<0) return;
if(val & COLOR_RED)
{
pbuffer_r[x/byte(8)][y] &= ~(1 << 7 >> (x%8));
}
if(val & COLOR_GREEN)
{
pbuffer_g[x/byte(8)][y] &= ~(1 << 7 >> (x%8));
}
}

Good luck!

0
dancopy
dancopy

Reply 3 years ago

Hi Silvius, sorry, you want to help me but I could not understand how the replacement of the sketch is, that is, the part that you added to replace, where do you go from where to in the sketch?
1) By kindness, could you put here for me the modified complete sketch?
2) Did you get to try the sketch I sent you?
For me, the LEDs show with a little weak intensity, you noticed?
I leave here my gratitude to you,
Daniel Fernandes

0
Silvius
Silvius

Reply 3 years ago

Hello! Unfortunately I have a busy schedule these days, and I can not properly handle this requirement.
I looked at the code you sent me. It's like my library. But there are also great differences in performance, and because of this is weak intensity.

The principle is the same: there is a buffer that is sent quickly to the module. Im my code I use a timer interrupt and send one line at every interrupt.
In the code you send to me the buffer is send in main loop. Also in my library I use an optimized version of shiftOut and digitalWrite to speed up things.

So... this code is good to understand the principle... in my library things are somewhat hidden, but are big differences when it comes to speed.

I would like to try to explain the code in an article/instructable separately... It's too much to write to solve this in a comment.

0
dancopy
dancopy

Reply 3 years ago

I understand your occupation, each one has yours. I am retired from my service (I am 52 years old) and I would like to understand some of these codes and, in general, about the Arduino codes, but I have enough difficulties. I just want to fit (I do not understand where to fit) your adaptation in that sketch I sent you, but I'll try again. Thank you very much

0
1413
1413

Reply 3 years ago

Silvius, I am sorry if I hijack your instructable or something. But since I am here, I think I should give Dan a hand.

Hi Daniel,
I couldn't try your code on the display for a number of reasons, such as I don't have RTC module and I hard wired my panel to a project... But I tried to compile the modified one. If your code runs OK then the modified code should work too.

You can find the complete "sketch" in attachment. You can change the brightness by changing number 80 to higher number such as 2000

[code]
// draw the screen ====
draw_buffer(80); // <-------
// END draw the screen ===
[/code]

80 in your code is for 80 microseconds which is, sort of, how long each row stays lit. So to make it brighter, increase this number to around 2000 or 2600. The math behind it is simple. You have 24 frame/s, each frame has 16 rows, therefore each row has to stay lit for 1/(24*16) second = approx 2.6 ms or 2600 microseconds.

I agree with Silvius that this code is not optimized. If it works for you and you are pleased with its performance, I say just use it. If you want to do it properly, use a timer to "redraw" the panel instead of put in main loop.

This guy has some good info on how to drive LED matrix http://ceezblog.info/2019/04/09/understanding-led-matrix-scanning-method/ in case you want to read more about it.

0
dancopy
dancopy

Reply 3 years ago

Hi friend (1413)! I did not expect you would help me! Thank you very much!
In draw_buffer (80); changing to, for example, draw_buffer (1000); shows a great flickering, so I left it like this: draw_buffer (250); It's kind of erased, but at least it does not have Flickering.
But, two problems:
1) The colon (clock) is not flashing (in the original code they blink).
2) The text scrolls to the end of the array module and restarts.
I'll be posting a little video on youtube for you to see.
Here: https://www.youtube.com/watch?v=kg5kJvEs_CY&feature=youtu.be
Thanks again

0
1413
1413

Reply 3 years ago

Ahh, silly me. I made mistakes.
- On scrolling step, it was supposed to be in pixel not in character length, so 5 chars => it would be 5 char * 6 pixel = 30. Try 30 or higher

Change in setup:
//---------------------------------------
scroll_max_step = 32; // or 40 for example
scroll_step = -32; // = negative of scroll_max_step

- On the colon symbol, changing delay of each row, we mess up timing for blinking colon for a tick indication, so after period of time it will blink eventually but not sure how long. This can be fixed by changing how to display the colon.

One more thing, I changed the scrolling code from only "left to right" to "left to right then right to left".

You can find the complete code in attachment.

0
dancopy
dancopy

Reply 3 years ago

Greetings 1413!
Maybe you thought I did not like the sketch you adapted for me; I liked it and, quite, with the text coming and going!
But I wanted the whole matrix to shine brighter, and then Silvius updated its library, myMATRIX_1.2, and an internet friend adapted the RTC in Silvius sketch for me.
So I'd like to let you know that I was grateful to you.
Now I want to try to scroll text with different colors, one after the other.
Thanks again to you and Silvius,
Daniel Fernandes

0
Silvius
Silvius

Reply 3 years ago

You're welcome!
...to scroll text with different colors, I think ... library should be modified again ... hScroll_nb function must return a value to see when an iteration is complete...
and change colour between iterations.... I will try to do this in the coming days
Regards!

0
dancopy
dancopy

Reply 3 years ago

Hi Silvius!
Remembering the subject, were you able to add the 3 colors to your library and use my sample clock with text scrolling sketch?
Thanks

0
dancopy
dancopy

Reply 3 years ago

Hi Silvius!
Were you able to do something in your library for Scrolling Text in different colors?
Greetings

0
dancopy
dancopy

Reply 3 years ago

Greetings Silvius! Thanks for the reply.
Is that the previous project, say, the original, made by another person, was in 3 colors:

COLOR_RED = 1,
COLOR_GREEN = 2,
COLOR_ORANGE = 3,

But, not necessarily in scrolling the text.
It was a color for the clock numbers,
another color for the colon of the clock (two flashing dots),
and another color for scrolling the text.
But if you can adapt your library to these 3 colors, I will be very grateful to you. When can I know?
Daniel Fernandes

0
dancopy
dancopy

Reply 3 years ago

Hi friend! (1413)
Very cool your idea of scrolling the text left-right and right-left; But, one thing, the colon is still not blinking!
In fact, the colon does not even appear on the display.

PS. Another thing: I would like, if possible, your name to, if I may post the code, I want to put in addition to the name of the author of the original code, his name and Silvius, as credit in the header of the sketch...
Thanks++

0
Silvius
Silvius

Reply 3 years ago

Silvius, I am sorry if I hijack your instructable or something. But since I am here, I think I should give Dan a hand
I have no problem with that. On the contrary. I think it's very nice to try to help him. On this occasion, we will all learn something ... And I got a boost to work on this library ... to solve something that seems a challenge ...
So I'm glad you're here.
Keep in touch!

0
Silvius
Silvius

Reply 3 years ago

I started working on your request ... and I noticed a problem.
The h_scroll function blocks the main loop, so it is not possible to display anything until it is over.
Now I'm looking for a solution either by modifying the library or by building a scroll function that allows for parallel execution of other instructions.
...Or both?

0
dancopy
dancopy

Reply 3 years ago

Thank you Silvius,
I do not want to be taking away your precious time and not bothering you; But if you want and can help me, I'll be very grateful,
Daniel

0
Silvius
Silvius

Reply 3 years ago

Problem solved. In a maximum of one day I will come back with an updated version of the library and a new example. I need a little more time to put them in order.

0
Silvius
Silvius

Reply 3 years ago


That was what you wanted ... I think