LED DOT MATRIX 64x16

Instead I make a dot matrix LED display, I decided to payment already made ??display.

http://www.canton-electronics.com/375mm-64x16-dot-matrix-led-display-for-arduino-uno-r3-mega2560-mcu-sign-project-p-753.html

I trusted the seller's promises: "With the display you get full documentantion and example sketch".

So far I have found that complete documentation is only one demo program which shows the pre-generated text. At my request the seller for additional documentation is a response "that is it".

//Author: cantone-electonics
//More information welcome to : http://www.canton-electronics.com 
//Arduino 1.0.4
//Arduino uno R3
//64x16 Matrix LED

#define COL_PIXEL     64
#define ROW_PIXEL     16

int latchPin=8; //LT
int clockPin=12;//SK
int dataPin=11; //R1

int en_74138 = 2;
int la_74138 = 3;
int lb_74138 = 4;
int lc_74138 = 5;
int ld_74138 = 6;
 
unsigned int ROW_xPixel;
unsigned int ROW_num;
unsigned char Col_num_1;
unsigned char Col_num_2;
unsigned char Col_num_3;
unsigned char Col_num_4;
unsigned char Col_num_5;
unsigned char Col_num_6;
unsigned char Col_num_7;
unsigned char Col_num_8;


//Data code: Horizontal modulus ,Bytes reverse order
unsigned char  Bmp1[]=
{
/*------------------------------------------------------------------------------
;  Width X height (pixels): 64X16
;I Love You
------------------------------------------------------------------------------*/
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0, 0xff, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0xc0, 0x0, 0x0, 0x0,
0x0, 0x0, 0xc, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x0, 0x3, 0x0, 0x0, 
0x0, 0x0, 0x0, 0x0, 0x30, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x0, 0x3, 0xc0, 0x3, 0x3, 0x30, 0xf0, 0x0, 0xc0, 0xc, 
0xf0, 0xc0, 0x0, 0x3, 0x0, 0xc, 0x0, 0x3, 0x30, 0xc, 0x3, 0x30, 0xc, 0x3, 0x0, 0x3, 0xc, 0xc3, 0x0, 0x3, 0x0, 0xc,
0x0, 0x3, 0xc, 0x30, 0x3, 0x30, 0x3, 0xc, 0x0, 0x3, 0x3, 0xcc, 0x0, 0x3, 0x0, 0xc, 0x0, 0x3, 0xc, 0x30, 0x3, 0x30,
0x3, 0xc, 0x0, 0x3, 0x3, 0xcc, 0x0, 0x3, 0x0, 0xc, 0x0, 0x3, 0xc, 0x30, 0x3, 0x30, 0xf, 0xc, 0x0, 0x3, 0x3, 0xcc, 
0x0, 0x3, 0x0, 0xc, 0x0, 0x3, 0xc, 0x30, 0x3, 0x30, 0xf3, 0x3, 0x0, 0x3, 0x3, 0xcc, 0x0, 0x3, 0x0, 0xc, 0x0, 0x3, 
0xc, 0x30, 0xc, 0xc, 0x3, 0x0, 0x0, 0x3, 0x3, 0xcc, 0x0, 0x3, 0x0, 0xc, 0x0, 0xc3, 0x30, 0xc, 0x30, 0x3, 0x3, 0xc, 
0x0, 0x3, 0xc, 0xc3, 0x0, 0x3, 0xc0, 0xff, 0x0, 0xff, 0xc0, 0x3, 0xc0, 0x0, 0xfc, 0x3, 0x0, 0x3, 0xf0, 0x0, 0xff, 
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 
};



unsigned char  Bmp2[]=
{
/*------------------------------------------------------------------------------
; Width X height (pixels): 16X16
;WELCOME 64 16
------------------------------------------------------------------------------*/
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3c, 0x30, 0xf0, 0xfc, 0xff, 0x3c, 0x0, 
0xf0, 0x3f, 0xf0, 0xf, 0x3c, 0x0, 0xcf, 0xff, 0x3f, 0x3c, 0xf0, 0xf0, 0xfc, 0xff, 0x3c, 0x0, 0xfc, 0x3f, 0xfc, 0x3f, 0x3c, 
0x0, 0xcf, 0xff, 0x3f, 0x3c, 0xf0, 0xf0, 0x3c, 0x0, 0x3c, 0x0, 0xf, 0x0, 0xf, 0xf0, 0x3c, 0x0, 0xcf, 0x3, 0x0, 0x3c, 0xfc,
0xf0, 0x3c, 0x0, 0x3c, 0x0, 0xf, 0x0, 0xf, 0xf0, 0xfc, 0xc0, 0xcf, 0x3, 0x0, 0x3c, 0xfc, 0xf0, 0x3c, 0x0, 0x3c, 0x0, 0xf, 
0x0, 0xf, 0xf0, 0xfc, 0xf0, 0xcf, 0x3, 0x0, 0xfc, 0xfc, 0xfc, 0xfc, 0xff, 0x3c, 0x0, 0xf, 0x0, 0xf, 0xf0, 0xfc, 0xf3, 0xcf,
0xff, 0x3f, 0xf0, 0xfc, 0x3c, 0xfc, 0xff, 0x3c, 0x0, 0xf, 0x0, 0xf, 0xf0, 0x3c, 0x3f, 0xcf, 0xff, 0x3f, 0xf0, 0xfc, 0x3c, 
0x3c, 0x0, 0x3c, 0x0, 0xf, 0x0, 0xf, 0xf0, 0x3c, 0x3f, 0xcf, 0x3, 0x0, 0xf0, 0xfc, 0x3c, 0x3c, 0x0, 0x3c, 0x0, 0xf, 0x0,
0xf, 0xf0, 0x3c, 0x3f, 0xcf, 0x3, 0x0, 0xf0, 0xff, 0x3f, 0x3c, 0x0, 0x3c, 0x0, 0xf, 0x0, 0xf, 0xf0, 0x3c, 0x3f, 0xcf, 0x3,
0x0, 0xf0, 0xff, 0x3f, 0x3c, 0x0, 0x3c, 0x0, 0xf, 0x0, 0xf, 0xf0, 0x3c, 0x3f, 0xcf, 0x3, 0x0, 0xc0, 0xcf, 0xf, 0x3c, 0x0, 
0x3c, 0x0, 0xf, 0x0, 0xf, 0xf0, 0x3c, 0xf, 0xcf, 0x3, 0x0, 0xc0, 0xcf, 0xf, 0xfc, 0xff, 0xfc, 0xff, 0xfc, 0x3f, 0xfc, 0x3f, 
0x3c, 0xc, 0xcf, 0xff, 0x3f, 0x0, 0x3, 0x3, 0xfc, 0xff, 0xfc, 0xff, 0xf0, 0x3f, 0xf0, 0xf, 0x3c, 0xc, 0xcf, 0xff, 0x3f, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
};


void shiftOut(unsigned char dataOut)
{
  
    for(int i=0;i<=7;i++)
   {
      PORTB &=~(1<<(clockPin-8));//equate digitalWrite(clockPin,LOW);
       
     if(dataOut & (0x01<<i))  PORTB |=1<<(dataPin-8); //equate digitalWrite(dataPin,HIGH);
     else  PORTB &=~(1<<(dataPin-8));//equate digitalWrite(dataPin,LOW);
     
     PORTB |=1<<(clockPin-8);//equate digitalWrite(clockPin,HIGH);
     
   }
}

//Combine 2 bits/pixel to 1 bits/pixel 
unsigned char Combine_2BitsTo1Bit(unsigned char num,unsigned char *BMP)
{
  
  unsigned char Col_num_tem_1;
  unsigned char Col_num_tem_2;
  unsigned int Col_num_tem = 0;
  unsigned char i=0;
  unsigned char Col_num_1bit = 0x00;
  
  Col_num_tem_1 = *(BMP+num);
  Col_num_tem_2 = *(BMP+num+1);
  
  Col_num_tem = Col_num_tem_1;
  Col_num_tem |= (Col_num_tem_2 << 8);
  
 for(i=0;i<8;i++)
  {   
    if(Col_num_tem&(0x0003<<i*2)) Col_num_1bit |= (0x01<<i);
  }
  return ~Col_num_1bit;
}

//display one picture 
void display_martix(unsigned char *BMP)
{
  //Display count
  unsigned int dis_cnt=256;
  unsigned int i;
  
   for(i=0;i<dis_cnt*16;i++)
   {
     
     digitalWrite(en_74138, HIGH);//Turn off display
  
     //Col scanning
    shiftOut(Col_num_1);
    shiftOut(Col_num_2);
    shiftOut(Col_num_3);
    shiftOut(Col_num_4);
    shiftOut(Col_num_5);
    shiftOut(Col_num_6);
    shiftOut(Col_num_7);
    shiftOut(Col_num_8);
  
    digitalWrite(latchPin, LOW);
    digitalWrite(latchPin, HIGH);
  
    //Row scanning
    // AVR Port Operation 
    PORTD = ((ROW_xPixel << 3 ) & 0X78) | (PORTD & 0X87);//Write PIN 3 4 5 6 la_74138 lb_74138 lc_74138 ld_74138
     
    digitalWrite(en_74138, LOW);//Turn on display
  

     
    if(ROW_xPixel==15) ROW_xPixel=0; else ROW_xPixel++;
  
   /*
   // Single color,1 bits/pixel
   Col_num_1=~BMP[(COL_PIXEL/8)*ROW_xPixel];
   Col_num_2=~BMP[(COL_PIXEL/8)*ROW_xPixel+1];
   Col_num_3=~BMP[(COL_PIXEL/8)*ROW_xPixel+2];
   Col_num_4=~BMP[(COL_PIXEL/8)*ROW_xPixel+3];
   Col_num_5=~BMP[(COL_PIXEL/8)*ROW_xPixel+4];
   Col_num_6=~BMP[(COL_PIXEL/8)*ROW_xPixel+5];
   Col_num_7=~BMP[(COL_PIXEL/8)*ROW_xPixel+6];
   Col_num_8=~BMP[(COL_PIXEL/8)*ROW_xPixel+7];
 */
   
   //Single color,2 bits/pixel 
   Col_num_1 = Combine_2BitsTo1Bit((COL_PIXEL/8)*ROW_xPixel*2,BMP);
   Col_num_2 = Combine_2BitsTo1Bit((COL_PIXEL/8)*ROW_xPixel*2+2,BMP);
   Col_num_3 = Combine_2BitsTo1Bit((COL_PIXEL/8)*ROW_xPixel*2+4,BMP);
   Col_num_4 = Combine_2BitsTo1Bit((COL_PIXEL/8)*ROW_xPixel*2+6,BMP);
   Col_num_5 = Combine_2BitsTo1Bit((COL_PIXEL/8)*ROW_xPixel*2+8,BMP);
   Col_num_6 = Combine_2BitsTo1Bit((COL_PIXEL/8)*ROW_xPixel*2+10,BMP);
   Col_num_7 = Combine_2BitsTo1Bit((COL_PIXEL/8)*ROW_xPixel*2+12,BMP);
   Col_num_8 = Combine_2BitsTo1Bit((COL_PIXEL/8)*ROW_xPixel*2+14,BMP);
  
  // delayMicroseconds(1000); 
   
  }
  
}

void setup()
{
  pinMode(latchPin,OUTPUT);
  pinMode(clockPin,OUTPUT);
  pinMode(dataPin,OUTPUT);
  
  pinMode(en_74138,OUTPUT);
  pinMode(la_74138,OUTPUT);
  pinMode(lb_74138,OUTPUT);
  pinMode(lc_74138,OUTPUT);
  pinMode(ld_74138,OUTPUT);
  
  
  digitalWrite(en_74138, LOW);
  
  // AVR Port Settings
  DDRD |= 0x78; //Set PIN 3 4 5 6 output  
  
  
  
  
}




void loop()
{

  
 display_martix(Bmp1);

 display_martix(Bmp2);

 
 
 
}

I wanted to display date/time and temperature (with DS3231 AT24C32 IIC module precision Real Time Clock modules and DHT22/AM2302 Digital Temperature And Humidity Sensor). No idea how. =(

Unfortunately, later found that other sellers (similar products) added library for easier operation (programming).

I was wondering if anyone has used this display similar purposes and in what way?
Any help is welcome.

Nobody ?
=(

Hi limel,

If you do not get a response from someone who was purchased the display from another seller with better software, perhaps you should consider writing a new sketch. Experts on this forum will help if you show that you are willing to learn and do not ask for someone else to write the sketch for you.

The sketch you have been given is useful as a demonstration for how to drive the display, but not very useful for your application.

Here are my suggestions:

  • Consider the display as 2 lines of 16 characters. Plan how you would want to display time, date etc. on this grid
  • Consider what characters you will need: "0".."9" "/" "c" "%" etc.
  • Consider using the SPI pins on the Arduino and the SPI library for best performance
  • Consider using the timer2 library for refreshing the display, so that your main loop() code can use libraries to read the time, temp, humidity etc and use delay() while the display continues to be refreshed without flickering.

I hope these suggestions give you some ideas.

Paul

@Paul,

First of all, thanks for the reply and your suggestions.

To clarify, I'm not looking for someone else to write the sketch for me.
I'm just looking for a library which would be easier to write sketch.

For example, when I write a sketch for TFT touch dispay I first find an appropriate library.
Then I start writing me sketch. I never start from "zero", I'm not expert. :wink:

With the help of uncle "Google" I finally found the appropriate library for my led dot matrix diplay !
Is a library with a few simple functions to begin with display.
So if anyone needs a library for "Driver IC : 74HC245 74HC595 74HC138 74HC04 APM4953" look here:

Hi limel!.
Firs of all, sorry for my English.

Could you manage the matrix with success?

Here in spain the adafruit are very expensive and i don't need colors. This matrix is ideal for me.
In your last link, i can see a better libraries with drawPoint, drawrect and drawimage functions but the product is diferent, only 16x32 matrix. it worked for "canton electronics" 16x64 display?
Can you scroll text?

Hi limel ,

I'm also like you. Few weeks ago I bought the same led matrix display from canton-electronics. and for me it is impossible to understand the documentationI recieved.
I'm trying to make a scoreboard with that matrix display but after two weeks I'm thinking to buy another matrix display that has better library.
¿Did you get any library for that matrix?

I need help and I think you are the only one u can do it.
P.D: sorry for my english

Hi Limel

Are you able to create animation for that board? I manage to create simple sketch for the board using an in house application. But, have not yet found a way to animate the text. If you have a sample sketch that animate some text, can you please share it with us?

If anyone is interested in in the application that I am using, please let me know.

Hi Gate-Keeper !

i'm trying to understand how it works, but i can't do it. The sample code is a pain, and i don't know how to paint individual pixels.
Please, your code would help me!.

i'm writting a library (or something like that) to print text in this led matrix.
I'm new in arduino, and the result won't be the best and quick code, but will work.
The "hello world" is done....when finished i'll post it here..

Hi petabyte,

I' also have that matrix display but I still trying to print something. I would be gratefull to show your code.

I'll do the code a little more readable and i'll post it here this weekend, i hope.

here it is!.

It's not a library, and i'm new in arduino and c languaje. Therefore the code will not be the best, i'm sure, but it works and display text with diferents fonts, in the desired position.

The problem with the "canton electronic" function is that it sends to the matrix a buffer matrix with two bits per pixel and reversed bit weight. I can't understand it enough to modify it for working with a bit per pixel and non reversed bytes.
Therefore, i paint the text (and another effects) in a more confortable matrix called "canvas" with the function:

textToCanvas(unsigned char *font,int fontHeight, int fontWidth, String message, int row, int column)

only one function to all the text sizes. (only tried with 6x5, 8x8 and 16x16, could be errors with other measures).

After that, i translate the canvas to reversed doble bit with translateCanvasToBuffer(). It moves and translate the canvas to the buffer before send it to the matrix.
And finally i send the buffer to the matrix with the original "canton electronics" function. I have added two params to this function, and the setup code, moved to a function for calling it from the main ino project.

There are two versions of this function , one for the arduino One, and another one for the arduino Mega. I only have an arduino mega, therefore i only tried the Mega version.
Despite this, you shouldn't have any problems with the UNO version. My code is equal in two cases, and i have done the same changes to the two "display_matrix" funtion versions.

I hope it works for you, and the code gives you ideas to paint another things to the matrix.

Dropbox link:

Dropbox - 404?

Hi petabyte,

Your code is very clear and it look well but I would like to know when write any word if that word can remain printed untill I want to print other word.

Thanks for your code.

display_matrix(unsigned char *BMP, int delay_refresco, int sustain)

The sustain parameter is the time text will be visible in the matrix.
If you want to do another things with your code while the text is displayed......it's another question...and i think that you can't do that....

Seems that the matrix haven't persistence itself.The canton electronic function does a loop for mantain the send picture.
You could simulate it by using interrupts, or some thing like that , but the refresh will do for sure flickering problems.
I think this can be the reason for the very low price. Even so, we can buy a cheap 15$ arduino uno only to control the matrix, (sending texts from the main arduino via serial) and still get a very good total cost for a 64x16 matrix.
Now i don't need to do this, because my arduino will only display text and some draws and will not do another things, but may be an idea for you.

OK, I will try to creat a library to make my project.
Thanks for your code.

I've been playing around with this display a bit and I agree that the code supplied has limited functionality.
However I've created an interrupt driven version of the code that constantly scans an 8x32 byte array to address each pixel on the board with ease. Please use any part of this code you guys like.

Matrix_LED_6432_PK.ino (26.9 KB)

Hi
Thank you petabyte and kaziewip for your interesting libraries.
I have my led 64x16 dot matrix from aliexpress.com
http://www.aliexpress.com/item/Indoor-F3-75-P4-75-Single-Red-color-LED-dot-matrix-module-304-76mm-64-16/1721794648.html

Based on petabyte's code I've created an timer/interrupt based version, which runs the matrix in background. In main loop I download data from internet with an ethernetshield an update it on the matrix in fixed time intervals.

Beside the matrix display mechanisme, which could in my opinion be improved, I'm not shure, how the current-limiting could be donne right:

  1. I search more data(sheets) of the matrix it selfe. (led peak current, and for how long the peak max shoud last)

  2. The colum drivers (shift register 74HC595) seem not to be the right thing for their job: max 35mA current per output, total max 70mA current output for the hole IC, 0.5W max Power disipation
    In multiplexing mode, there are much higher peak currents.
    http://www.nxp.com/documents/data_sheet/74HC_HCT595.pdf

  3. The row drivers look much more stronger: p-chanel mosfet FDS4953: 5A contiuos current, 20A peak
    -> each row is only on for 1/16 time.
    Intelligent Power and Sensing Technologies | onsemi

  4. according to this website, i bought the matrix, it's driven 1/16 constant current. But how should the current be constant when in each row a different count of led's are shining?

  5. if one led consumts 10 to 20mA in constant current, it could be peak 100 to 200mA (16x multiplex) a normal led accepts max 10x times the constant current as peak.
    The whole matrix is on: 64x 100mA = 6.4A per row, always only one row on. -> 8 shift registers for the whole row: 6.4A/8 = 0.8A continous through ONE shift register. In my opinion something doesnt work right here.

Pleas correct me, if me suggestions are wrong.

conclusen: 1. the shift registers are too weak.
2. the current should be limited individually per row, according to the count of led's on in this row.

Hey kaziewip.
Nice code for shift registry led matrix displays. :slight_smile:

I am very new to (trying to) code arduino. Just need to make a led matrix display to hang in the window of my wifes massage salon and have been searching high and low for useful sketches to "borrow" ideas from and learn how the darn language works.

Your sketch is by FAR the best one I've found.

But with my very limited knowledge of coding I have run into some problems.
The scrolling text thingie does not scroll onto the screen. The first letter magically appears in the far right part of the display but then scrolls out like it should on the left end.

Have tried to edit every variable I could think of to try to make it have a smooth scroll into the display but no such luck. :confused:

Could you direct me to where abouts in your code I should edit that?

And my display is 64x16 and I have no idea how to make the top half of my display useful.
I tried to switch to big font, but the top part of the font does not scroll, just the bottom part. :confused:

Also, if anyone can give me tips on how to edit this code so I can use both red and green (and orange) I'd appreciate it.
Oh, and anyone know if there is a possibility to dim the display? I only have 2amp psu for it, so might need to lower the intensity to stay within limits.

Thanks for the compliments! :slight_smile:

The code I posted is for a 64x32 LED matrix display and so it doesn't surprise me that it'll misbehave on a 64x16 display.

However just after I posted the earlier code, I made some adjustments to drive a 128x16 display (two 64x16 displays connected in series). It should work for just one 64x16 display but it'll just show LEDs addressed between 64 <= x <= 127.
(It's a bit inefficient to use this code for just one display but never mind.)

Anyhow, the 128x16 code is attached.

(BlackMajj: in answer to your specific questions, the delay(15) at the end of the code governs the scrolling timing (you'll need to fiddle with this to get the right answer for your needs) and the moveLeft(1,8,15) only scrolls lines 8 to 15 to the left. If you want the whole thing to scroll then you'd use moveLeft(1,0,15).)

Matrix_LED_12816_PK.ino (27.1 KB)

BlackMajj:

This code in general won't work for an RG LED matrix, since the software frame buffer in my code only stores the pixels as zeros (off) and ones (on). It would need to be adjusted to use 2 bits per pixel (0=off, 1=red, 2=green, 3=amber).

I also imagine that the electronic addressing of an RG display will also be somewhat different so the "shiftOut" routine would need to be adjusted to take care of this.

Maybe I'll get hold of an RG display and play around with it!

Using a scanning approach like the one I've pursued keeps the power requirements down as much as possible, since you're only displaying one (or two in the case of the 64x32 display) lines of LEDs at a time. You can make the screen dimmer or brighter in software by playing with the interrupt timer variable OCR2A in the "setup" routine (the default value is 97). Note that as it gets dimmer you'll start to see a flicker though :frowning: