Example Code for Arduino-Pattern Animation and Rolling

Last revision 2025/12/17

The article offers a detailed guide on using Arduino for pattern animation and rolling effects with RGB LED modules. It includes hardware setup, wiring diagrams, and sample code, allowing users to create dynamic and visually appealing animations on their Arduino projects. The tutorial also covers manipulating channels and colors through code, making it a valuable resource for those looking to enhance their Arduino projects with creative LED displays.

Hardware Preparation

  • Arduino Board: Any Arduino-compatible board, 1
  • DFR0124 4x4 RGB LED Module: 2
  • IDC2x5 Cables (if using Interface shield): 1
  • F/M Cables (if connecting directly to Arduino): 1

Wiring Diagram

ARDUINO ARDUINO u u u u
13 -> SCLK (pin 25) OUT1 1 28 OUT channel 0
12 OUT2 2 27 -> GND (VPRG)
11 -> SIN (pin 26) OUT3 3 26 -> SIN (pin 11)
10 -> BLANK (pin 23) OUT4 4 25 -> SCLK (pin 13)
9 -> XLAT (pin 24) . 5 24 -> XLAT (pin 9)
8 . 6 23 -> BLANK (pin 10)
7 . 7 22 -> GND
6 . 8 21 -> VCC (+5V)
5 . 9 20 -> 2K Resistor -> GND
4 . 10 19 -> +5V (DCPRG)
3 -> GSCLK (pin 18) . 11 18 -> GSCLK (pin 3)
2 . 12 17 -> SOUT
1 . 13 16 -> XERR
0 OUT14 14 15 OUT channel 15

If you are daisy-chaining more than one TLC, connect the SOUT of the first TLC to the SIN of the next.All the other pins should just be connected together:

BLANK on Arduino -> BLANK of TLC1 -> BLANK of TLC2 -> ...

XLAT on Arduino -> XLAT of TLC1 -> XLAT of TLC2 -> ...

Other Preparation Work

  1. Change the value of defined invariable NUM_TLCS from 3 to 6( In the file: "tlc_config.h" incuded in the library folder: "Tlc5940".) since we need two modules for this demo.
  2. The order of channel is determined by the order of TLC microcontroller. channnel 0-15 are 16 red LEDs controlled by the first TLC microcontroller. channel 16-31 are 16 green LEDs, channel 32-47 are 16 blue LEDs. One RGB modules has 3 TLC microcontrollers and if you want to use two RGB LED modules, channel 48-63 are 16 red LEDS of second module, and so on.
  3. "basicProcess.h" is mapping the channel into a more friendly structure so that you can use x,y axis location to process the data.
  4. "message.h" includes the message of word: love. You can change the word to whatever you want(any word, pattern, shape) by creating x,y axis location information first.
  5. The library uses the PWM output ability of digital pins 3, 9, 10, and 11. Do not use analogWrite(...) on these pins.

Sample Code

Arduino code

/*
Description:    This is a demo of using 4*4 RGB LED written by Arduino 1.0. First, you will see a pattern of  face. Then, eyes are blinking. After that a red heart appears. Finally, you will see a rolling word: love.
 Guide:          1. You'd better read the example "basic use" in this library before trying to modify the code as your version.
 2. Put head files: basicProcess.h and message.h under the same folder of LEDArrayTEST2.
 3. The order of channel is determined by the order of TLC microcontroller. channnel 0-15 are 16 red LEDs controlled by the first TLC microcontroller. channel 16-31 are 16 green LEDs, channel 32-47 are
 16 blue LEDs. In our project, one RGB modules has 3 TLC microcontrollers and we use two RGB LED modules with 6 TLCS totally.Thus, channel 48-63 are 16 red LEDS of second module, and so on.
 4. Change the value of defined invariable NUM_TLCS from 3 to 6( In the file: "tlc_config.h" incuded in the library folder: "Tlc5940".) since we need two modules for this demo.
 5. "basicProcess.h" is mapping the channel into a more friendly structure so that you can use x,y axis location to process the data.
 6. "message.h"  includes the message of word: love. You can change the word to whatever you want(any word, pattern, shape) by creating x,y axis location information first.
 Author:         Michael from DFrobot
 Contact e-mail: [email protected]
 Date:           2012/02/08
 */
//#######include#######################################################################
#include "Tlc5940.h"
#include "basicProcess.h"
#include "message.h"

//######function declaration#######################################################################
void face(CHANNEL *ptr,int unit, int brightness, COLOR color); //face pattern (channel structureis defined in "basicProcess.h", unit is the shifting amount)
void heart(CHANNEL *ptr,COLOR color,int brightness);  //heart pattern

//#######setup############################################################################
void setup()
{
  /* Call Tlc.init() to setup the tlc.
   You can optionally pass an initial PWM value (0 - 4095) for all channels.*/
  Tlc.init();
  for (int channel=0;channel<NUM_TLCS*16;channel++)
  {
    mapping(channel);

  }
//########face###################################################################
  CHANNEL* ptr;
  for(int i=-1;i<10;i++) // -1 is the starting location and 10 is the ending location of moving face, you can change it to see what happens
  {
    for (ptr=array;ptr<array+NUM_TLCS*16;ptr++)
    {
      face(ptr,i,BLUE,1000,false);     //show moving face
    }
    Tlc.update();
    /* Tlc.update() sends the data to the TLCs.  This is when the LEDs will
     actually change. */
    delay(200);
    Tlc.clear();
  }

  for(int i=0;i<5;i++)   //5 is the time of eyes'blinking, change it to see the effects
  {
    for (ptr=array;ptr<array+NUM_TLCS*16;ptr++)
    {
      face(ptr,1,BLUE,1000,i%2);
    }
    Tlc.update();
    delay(1000);
    Tlc.clear();
  }

//########heart###################################################################
  for (ptr=array;ptr<array+NUM_TLCS*16;ptr++)
  {
    //heart(ptr,GREEN,100);
    heart(ptr,RED,3500);

  }
  Tlc.update();
  delay(2000);
  Tlc.clear();

  MessageInitialize();  //"defined in message.h"

}

//#########loop: word rolling ##########################################################
void loop()
{

  CHANNEL* ptr;
  for(int i=-15;i<9;i++)  //starting and ending position of word
  {
    for (ptr=array;ptr<array+NUM_TLCS*16;ptr++)
    {
      //heart(ptr,GREEN,100);
      loveMessage(ptr,i,200,BLUE);
      loveMessage(ptr,i,4000,RED);  //we blend red and blue to make purple, change the color whatever you want
    }
    Tlc.update();
    delay(200);
    Tlc.clear();
  }
}
//############################################################################
void face(CHANNEL *ptr,int unit,  COLOR color, int brightness, boolean blinking)
{

  if(ptr->X==1 && (ptr->Y-1+unit)%8+1==7 && ptr->color==color)
    Tlc.set(ptr->channel,brightness);
  if(ptr->X==1 && (ptr->Y-1+unit)%8+1==6 && ptr->color==color)
 Tlc.set(ptr->channel,brightness);
  if(ptr->X==1 && (ptr->Y-1+unit)%8+1==5 && ptr->color==color)
 Tlc.set(ptr->channel,brightness);
  if(ptr->X==2 && (ptr->Y-1+unit)%8+1==8 && ptr->color==color)
 Tlc.set(ptr->channel,brightness);
  if(ptr->X==2 && (ptr->Y-1+unit)%8+1==4 && ptr->color==color)
 Tlc.set(ptr->channel,brightness);
  if(ptr->X==3 && (ptr->Y-1+unit)%8+1==8 && ptr->color==color)
 Tlc.set(ptr->channel,brightness);
  if(ptr->X==3 && (ptr->Y-1+unit)%8+1==7 && ptr->color==color) //locaton of left eye
  {
    Tlc.set(ptr->channel,(!blinking)*brightness);
  }
  if(ptr->X==3 && (ptr->Y-1+unit)%8+1==5 && ptr->color==color)//location of right eye
  {
    Tlc.set(ptr->channel,(!blinking)*brightness);
  }
  if(ptr->X==3 && (ptr->Y-1+unit)%8+1==4 && ptr->color==color)
 Tlc.set(ptr->channel,brightness);
  if(ptr->X==4 && (ptr->Y-1+unit)%8+1==7 && ptr->color==color)
 Tlc.set(ptr->channel,brightness);
  if(ptr->X==4 && (ptr->Y-1+unit)%8+1==6 && ptr->color==color)
 Tlc.set(ptr->channel,brightness);
  if(ptr->X==4 && (ptr->Y-1+unit)%8+1==5 && ptr->color==color)
 Tlc.set(ptr->channel,brightness);
}
//#############################################################################

void heart(CHANNEL *ptr,COLOR color,int brightness)
{
  if(ptr->X==4 && ptr->Y==6 && ptr->color==color)
    Tlc.set(ptr->channel,brightness);
  if(ptr->X==4 && ptr->Y==4 && ptr->color==color)
    Tlc.set(ptr->channel,brightness);
  if(ptr->X==3 && ptr->Y==7 && ptr->color==color)
    Tlc.set(ptr->channel,brightness);
  if(ptr->X==3 && ptr->Y==6 && ptr->color==color)
    Tlc.set(ptr->channel,brightness);
  if(ptr->X==3 && ptr->Y==5 && ptr->color==color)
    Tlc.set(ptr->channel,brightness);
  if(ptr->X==3 && ptr->Y==4 && ptr->color==color)
    Tlc.set(ptr->channel,brightness);
  if(ptr->X==3 && ptr->Y==3 && ptr->color==color)
    Tlc.set(ptr->channel,brightness);
  if(ptr->X==2 && ptr->Y==6 && ptr->color==color)
    Tlc.set(ptr->channel,brightness);
  if(ptr->X==2 && ptr->Y==5 && ptr->color==color)
    Tlc.set(ptr->channel,brightness);
  if(ptr->X==2 && ptr->Y==4 && ptr->color==color)
    Tlc.set(ptr->channel,brightness);
  if(ptr->X==1 && ptr->Y==5 && ptr->color==color)
    Tlc.set(ptr->channel,brightness);

}

"basicProcess.h"

/*
This headfile transfer channel into two dimensional x,y axis location and corresponding color.
the x,y axis information is as follows:
(4,4) (4,3) (4,2) (4,1)
(3,4) (3,3) (3,2) (3,1)
(2,4) (2,3) (2,2) (2,1)
(1,4) (1,3) (1,2) (1,1)
if we have more than one module:
...(4,9)    (4,8) (4,7) (4,6) (4,5)    (4,4) (4,3) (4,2) (4,1)
...(3,9)    (3,8) (3,7) (3,6) (3,5)    (3,4) (3,3) (3,2) (3,1)
...(2,9)    (2,8) (2,7) (2,6) (2,5)    (2,4) (2,3) (2,2) (2,1)
...(1,9)    (1,8) (1,7) (1,6) (1,5)    (1,4) (1,3) (1,2) (1,1)
*/

#include "Tlc5940.h"

enum COLOR{RED,GREEN,BLUE};
struct CHANNEL
{
  int X;
  int Y;
  int channel;  //(0 - NUM_TLCS*16)
  COLOR color;

};

CHANNEL array[NUM_TLCS*16];


void mapping(int channel)
 {

  CHANNEL* value=array+channel;
  //red
 if((channel%48)<16)   //48 is used to determine whether one module or multi modules. ( One module has 3 colors and each color has 16 LEDs.)
 {
 value->Y=(channel%48)%4+channel/48*4+1;
 value->X=(channel%48)/4+1;
 value->color=RED;
 value->channel=channel;
}
 //green
if((channel%48)>=16&&(channel%48)<32)
  {
 value->Y=((channel%48)-16)%4+channel/48*4+1;
 value->X=((channel%48)-16)/4+1;
 value->color=GREEN;
 value->channel=channel;

 }
 //blue
 if((channel%48)>=32&&(channel%48)<48)
  {
 value->Y=((channel%48)-16*2)%4+channel/48*4+1;
 value->X=((channel%48)-16*2)/4+1;
 value->color=BLUE;
 value->channel=channel;

 }


 }

"message.h"


/*
This headfile is for message inputing. Here it is a word: love. Message is initialized using two dimensional array.
for example:
0 1 1 0
1 1 1 1
1 1 1 1
0 1 1 0  can be represented as a circle.
*/
int Message[4][15]; //the dimension is according to the message you want to input
void MessageInitialize()
{
  for(int i=0;i<4;i++)
  {
    for(int j=0;j<15;j++)
    {
      Message[i][j]=0;
    }
  }
    Message[3][14]=1;
  Message[3][9]=1;
  Message[3][6]=1;
  Message[3][4]=1;
  Message[3][1]=1;
  Message[2][14]=1;
  Message[2][10]=1;
  Message[2][8]=1;
  Message[2][6]=1;
  Message[2][4]=1;
  Message[2][2]=1;
  Message[2][1]=1;
  Message[2][0]=1;
  Message[1][14]=1;
  Message[1][10]=1;
  Message[1][8]=1;
  Message[1][6]=1;
  Message[1][4]=1;
  Message[1][2]=1;
  Message[0][14]=1;
  Message[0][13]=1;
  Message[0][12]=1;
  Message[0][9]=1;
  Message[0][5]=1;
  Message[0][1]=1;
}

void loveMessage(CHANNEL *ptr,int unit,int brightness, COLOR color)  //"unit" is for horizontal shifting
{
   for(int i=0;i<4;i++)
  {
    for(int j=0;j<15;j++)
    {
     if(Message[i][j]==1)
     {

       if(ptr->X==i+1 && ptr->Y==j+1+unit && ptr->color==color)
        Tlc.set(ptr->channel,brightness);
     }
    }
  }
}

Result

Additional Information

The library uses the PWM output ability of digital pins 3, 9, 10, and 11. Do not use analogWrite(...) on these pins.

Was this article helpful?

TOP