Scrolling Display using Arduino 24x8

In this Project, we will see about how to Make a simple 24x8 Scrolling LED Matrix in Home.

Circuit Diagram:



Arduino Code:
scrolling_led_matrix_24x8.ino
//Change your Name at Line.115

#define BA{B00111100,B01000010,B01000010,B01000010,B01111110,B01000010,B01000010,B01000010}
#define BB{B01111100,B01000010,B01000010,B01111100,B01000010,B01000010,B01000010,B01111100}
#define BC{B00111100,B01000010,B01000000,B01000000,B01000000,B01000000,B01000010,B00111100}
#define BD{B01111000,B01000100,B01000010,B01000010,B01000010,B01000010,B01000100,B01111000}
#define BE{B01111110,B01000000,B01000000,B01111100,B01000000,B01000000,B01000000,B01111110}
#define BF{B01111110,B01000000,B01000000,B01111100,B01000000,B01000000,B01000000,B01000000}
#define BG{B00111100,B01000010,B01000000,B01000000,B01001110,B01000010,B01000010,B00111100}
#define BH{B01000010,B01000010,B01000010,B01111110,B01000010,B01000010,B01000010,B01000010}
#define BI{B01111100,B00010000,B00010000,B00010000,B00010000,B00010000,B00010000,B01111100}
#define BJ{B00111110,B00001000,B00001000,B00001000,B00001000,B00001000,B01001000,B00110000}
#define BK{B01000100,B01001000,B01010000,B01100000,B01100000,B01010000,B01001000,B01000100}
#define BL{B01000000,B01000000,B01000000,B01000000,B01000000,B01000000,B01000000,B01111110}
#define BM{B10000010,B11000110,B10101010,B10101010,B10010010,B10010010,B10000010,B10000010}
#define BN{B01000010,B01100010,B01010010,B01010010,B01001010,B01001010,B01000110,B01000010}
#define BO{B00111100,B01000010,B01000010,B01000010,B01000010,B01000010,B01000010,B00111100}
#define BP{B01111100,B01000010,B01000010,B01000010,B01111100,B01000000,B01000000,B01000000}
#define BQ{B00111100,B01000010,B01000010,B01000010,B01000010,B01000010,B01000100,B00111010}
#define BR{B01111100,B01000010,B01000010,B01111100,B01010000,B01001000,B01000100,B01000010}
#define BS{B00111100,B01000010,B01000000,B00110000,B00001100,B00000010,B01000010,B00111100}
#define BT{B01111100,B00010000,B00010000,B00010000,B00010000,B00010000,B00010000,B00010000}
#define BU{B01000010,B01000010,B01000010,B01000010,B01000010,B01000010,B01000010,B00111100}
#define BV{B01000100,B01000100,B01000100,B01000100,B01000100,B01000100,B00101000,B00010000}
#define BW{B10000010,B10000010,B10000010,B10000010,B10010010,B10010010,B10101010,B01101100}
#define BX{B10000010,B10000010,B01000100,B00101000,B00010000,B00101000,B01000100,B10000010}
#define BY{B10000010,B10000010,B01000100,B00101000,B00010000,B00010000,B00010000,B00010000}
#define BZ{B01111110,B00000010,B00000100,B00001000,B00010000,B00100000,B01000000,B01111110}

#define LA{B00000000,B00000000,B00000000,B00111000,B00000100,B00111100,B01000100,B00111000}
#define LB{B01000000,B01000000,B01000000,B01000000,B01111000,B01000100,B01000100,B01111000}
#define LC{B00000000,B00000000,B00000000,B00111100,B01000000,B01000000,B01000000,B00111100}
#define LD{B00000100,B00000100,B00000100,B00000100,B00111100,B01000100,B01000100,B00111100}
#define LE{B00000000,B00000000,B00000000,B00111000,B01000100,B01011000,B01000000,B00111100}
#define LF{B00111000,B01000100,B01000000,B01000000,B01111000,B01000000,B01000000,B01000000}
#define LG{B00111000,B01000100,B01000100,B01000100,B00111000,B00000100,B00000100,B01111000}
#define LH{B01000000,B01000000,B01000000,B01111000,B01000100,B01000100,B01000100,B01000100}
#define LI{B00000000,B00000000,B00010000,B00000000,B00010000,B00010000,B00010000,B00010000}
#define LJ{B00000000,B00001000,B00000000,B00001000,B00001000,B00001000,B01001000,B00110000}
#define LK{B00000000,B01000000,B01000000,B01001000,B01010000,B01100000,B01010000,B01001000}
#define LL{B00100000,B00100000,B00100000,B00100000,B00100000,B00100000,B00100000,B00011000}
#define LM{B00000000,B00000000,B00000000,B01000000,B01101100,B01010100,B01000100,B01000100}
#define LN{B00000000,B00000000,B00000000,B01000000,B01111000,B01000100,B01000100,B01000100}
#define LO{B00000000,B00000000,B00000000,B00111000,B01000100,B01000100,B01000100,B00111000}
#define LP{B00000000,B00000000,B00111000,B01000100,B01000100,B01111000,B01000000,B01000000}
#define LQ{B00000000,B00000000,B00111000,B01000100,B01000100,B00111100,B00000100,B00000100}
#define LR{B00000000,B00000000,B00111000,B01000100,B01000000,B01000000,B01000000,B01000000}
#define LS{B00000000,B00000000,B00111000,B01000100,B01100000,B00011100,B01000100,B00111000}
#define LT{B00100000,B00100000,B00100000,B01111000,B00100000,B00100000,B00100000,B00011000}
#define LU{B00000000,B00000000,B00000000,B01000100,B01000100,B01000100,B01000100,B00111100}
#define LV{B00000000,B00000000,B00000000,B01000100,B01000100,B01000100,B00101000,B00010000}
#define LW{B00000000,B00000000,B00000000,B01000100,B01000100,B01010100,B01010100,B00111000}
#define LX{B00000000,B00000000,B00000000,B01000100,B00101000,B00010000,B00101000,B01000100}
#define LY{B00000000,B00000000,B00000000,B01000100,B01000100,B00111100,B00000100,B01111000}
#define LZ{B00000000,B00000000,B00000000,B01111100,B00000100,B00111000,B01000000,B01111100}

#define SPACE{B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000}
#define NUM0{B00111100,B01000010,B01000110,B01001010,B01010010,B01100010,B01000010,B00111100}
#define NUM1{B00011000,B00111000,B00011000,B00011000,B00011000,B00011000,B00011000,B00111100}
#define NUM2{B00111100,B01000010,B00000010,B00000010,B00001100,B00110000,B01000000,B01111110}
#define NUM3{B00111100,B01000010,B00000010,B00000010,B00011100,B00000010,B01000010,B00111100}
#define NUM4{B01000010,B01000010,B01000010,B01000010,B00111110,B00000010,B00000010,B00000010}
#define NUM5{B01111110,B01000000,B01000000,B01111100,B00000010,B00000010,B01000010,B00111100}
#define NUM6{B01111110,B01000000,B01000000,B01000000,B01111110,B01000010,B01000010,B01111110}
#define NUM7{B01111110,B00000010,B00000100,B00000100,B00001000,B00001000,B00010000,B00010000}
#define NUM8{B00111100,B01000010,B01000010,B01111110,B01000010,B01000010,B01000010,B00111100}
#define NUM9{B01111110,B01000010,B01000010,B01111110,B00000010,B00000010,B01000010,B01111110}
#define DEVIDE{B00000100,B00000100,B00001000,B00001000,B00010000,B00010000,B00100000,B00100000}
#define TWODOTS{B00000000,B00011000,B00011000,B00000000,B00000000,B00011000,B00011000,B00000000}
#define DOT{B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B01100000,B01100000}
#define COMA{B00000000,B00000000,B00000000,B00000000,B00000000,B00110000,B00110000,B01100000}
#define LINE{B00000000,B00000000,B00000000,B01111110,B01111110,B00000000,B00000000,B00000000}
#define QUASTION{B00111000,B01000100,B00000100,B00000100,B00001000,B00010000,B00000000,B00010000}
#define MARK{B00011000,B00011000,B00011000,B00011000,B00011000,B00000000,B00011000,B00011000}
/*
#define LESSTHAN
#define GRATTHAN
#define AT
#define POUND
#define DOLLAR
#define PERCENT
#define CARAT
#define AND
#define ASTERISK
#define LPARENTH
#define RPARENTH
#define HYPHEN
#define UNSCORE
#define PLUS
#define EQUALS
#define DASH
#define LBRACKET
#define RBRACKET
#define SYM[
#define SYM]
#define SYM|
#define SYM\
#define SYM`
#define SYM~
#define SYM;
#define SYM:
*/

int latchPin = 10;
int clockPin = 13;
int dataPin = 11;
int clock = 9;
int Reset = 8;
int latchPinPORTB = latchPin - 8;
int clockPinPORTB = clockPin - 8;
int dataPinPORTB = dataPin - 8;
int i = 0;
long scrolling_word[16];
int array_turn=0;
byte your_text[60][8]={BS,BD,LE,LV,SPACE,BE,LL,LE,LC,LT,LR,LO,LN,LI,LC,LS};//CHANGE YOUR TEXT HERE


void setup(){
  Serial.begin(9600);
  pinMode(dataPin,OUTPUT);
  pinMode(clockPin,OUTPUT);
  pinMode(latchPin,OUTPUT);
  pinMode(clock,OUTPUT);
  pinMode(Reset,OUTPUT);
  digitalWrite(Reset,HIGH);
  digitalWrite(Reset,LOW);
  setupSPI();
}

void display_word(int loops,byte word_print[][8],int num_patterns,int delay_langth){// this function displays your symbols
  i = 0;// resets the counter fot the 4017
  for(int g=0;g<8;g++)//resets the the long int where your word goes
    scrolling_word[g] = 0;
  for(int x=0;x<num_patterns;x++){//main loop, goes over your symbols
   // you will need to find a better way to make the symbols scroll my way is limited for 24 columns

   for(int r=0;r<8;r++)//puts the buildes the first symbol (also controls how many columns are displayed)
      scrolling_word[r] |= word_print[x][r]; 
    for (int z=0;z<8;z++){//the scrolling action (Z is also pretty much a kerning variable- larger vale = more space between letters)
        for(int p=0;p<8;p++)
          scrolling_word[p] = scrolling_word[p] << 1;
// end of the scrolling funcion
      for(int t=0;t<delay_langth;t++){// delay function, it just loops over the same display
        for(int y=0;y<8;y++){// scaning the display
          if(i == 8){// counting up to 8 with the 4017
            digitalWrite(Reset,HIGH);
            digitalWrite(Reset,LOW);
            i = 0;
          }
          latchOff();
          spi_transfer(make_word(0x01000000,y));// sending the data
          spi_transfer(make_word(0x00010000,y));
          spi_transfer(make_word(0x00000100,y));
          latchOn();
          delayMicroseconds(800);//waiting a bit
          latchOff();
          spi_transfer(0);// clearing the data
          spi_transfer(0);
          spi_transfer(0);
          latchOn();
          digitalWrite(clock,HIGH);//counting up with the 4017
          digitalWrite(clock,LOW);
          i++;
        }
      }
    }
  }
  finish_scroll(delay_langth);
}

void finish_scroll(int delay_scroll){// this function is the same as the funcion above, it just finishing scrolling
  for (int n=0;n<24;n++){
        for(int h=0;h<8;h++)
          scrolling_word[h] = scrolling_word[h] << 1;
      for(int w=0;w<delay_scroll;w++){
        for(int k=0;k<8;k++){
          if(i == 8){
            digitalWrite(Reset,HIGH);
            digitalWrite(Reset,LOW);
            i = 0;
          }
          latchOff();
          spi_transfer(make_word(0x01000000,k));
          spi_transfer(make_word(0x00010000,k));
          spi_transfer(make_word(0x00000100,k));
          latchOn();
          delayMicroseconds(800);
          latchOff();
          spi_transfer(0);
          spi_transfer(0);
          spi_transfer(0);
          latchOn();
          digitalWrite(clock,HIGH);
          digitalWrite(clock,LOW);
          i++;
        }
      }
    }
}

byte make_word (long posistion,byte turn){
  byte dummy_word = 0;
  for(int q=0;q<8;q++){
    if(scrolling_word[turn] & (posistion<<q))
      dummy_word |= 0x01<<q;
  }
  return dummy_word;
}   


  void loop() {

        display_word(1,your_text,20,15);// calls for the display_pattern function and says that int loop = 15(if you do more loop the pattern whould scrole slower).
   // the seconds variable in this (20 in this case), controls how many letters your display can hold at one time.
       }
  
  

void latchOn(){
  bitSet(PORTB,latchPinPORTB);
}

void latchOff(){
  bitClear(PORTB,latchPinPORTB);
}


void setupSPI(){
  byte clr;
  SPCR |= ( (1<<SPE) | (1<<MSTR) ); // enable SPI as master
  //SPCR |= ( (1<<SPR1) | (1<<SPR0) ); // set prescaler bits
  SPCR &= ~( (1<<SPR1) | (1<<SPR0) ); // clear prescaler bits
  clr=SPSR; // clear SPI status reg
  clr=SPDR; // clear SPI data reg
  SPSR |= (1<<SPI2X); // set prescaler bits
  //SPSR &= ~(1<<SPI2X); // clear prescaler bits
  delay(10);
}
byte spi_transfer(byte data){
  SPDR = data;			  // Start the transmission
  while (!(SPSR & (1<<SPIF))){};     // Wait the end of the transmission
  return SPDR;			  // return the received byte, we don't need that
}

Youtube Video Tutorial:




Download our official Android App in PlayStore. Click Here
You can get the all the required files (like Circuit Diagram, Arduino.ino file, Libraries Used, and others) for the project  in ZIP format and much more...

18 comments:

  1. if i want to define a word 7 rows wide and 5 column long what should be change in code?

    ReplyDelete
    Replies
    1. Pixels for every Letter are defined in starting part of the code. You can change here

      Delete
  2. Hai sir iam biggner 24*8 led panal Other led code be will working this diagram or not..Same modal panal extra added is it code changed or not? How to download adriuno code most downloading site..? Suppose rgb color led use is it how to video playing in outdoor please answer this question...

    ReplyDelete
  3. Reply pls. Can i ask what if my led is 5x30? How will I change the code? Thanks. Asap reply just needed

    ReplyDelete
  4. What is the use of oscillator 16 mkz

    Where it need to be connect.

    And also capacitor connection..

    ReplyDelete
  5. can you please send the clear circuit diagram.

    ReplyDelete
  6. Great Work , please can you send me fritzing PCB !

    ReplyDelete
  7. how many characters, it can display in one scrolling line

    ReplyDelete
  8. Hi staysay, Ihave been trying put my text in where it said to go but it keeps giving me errors can you give me a little more info on how to put my text into the code. please and thank you.

    ReplyDelete
  9. im the one who sent the above message

    ReplyDelete
  10. can the number of columns be increased?

    ReplyDelete
  11. sir, how I update this code for 10*48 led display?

    ReplyDelete