How to scroll text Arduino UNO, 8x8 LED matrix and 74HC595 shift registers

const uint8_t IMAGES[][8] = {
{
0b00000000,
0b00111100,
0b01100110,
0b01100110,
0b01111110,
0b01100110,
0b01100110,
0b01100110
},{
0b00000000,
0b01111100,
0b01100110,
0b01100110,
0b01111100,
0b01100110,
0b01100110,
0b01111100
},{
0b00000000,
0b00111100,
0b01100110,
0b01100000,
0b01100000,
0b01100000,
0b01100110,
0b00111100
},{
0b00000000,
0b01111100,
0b01100110,
0b01100110,
0b01100110,
0b01100110,
0b01100110,
0b01111100
},{
0b00000000,
0b01111110,
0b01100000,
0b01100000,
0b01111100,
0b01100000,
0b01100000,
0b01111110
},{
0b00000000,
0b01111110,
0b01100000,
0b01100000,
0b01111100,
0b01100000,
0b01100000,
0b01100000
},{
0b00000000,
0b00111100,
0b01100110,
0b01100000,
0b01100000,
0b01101110,
0b01100110,
0b00111100
},{
0b00000000,
0b01100110,
0b01100110,
0b01100110,
0b01111110,
0b01100110,
0b01100110,
0b01100110
},{
0b00000000,
0b00111100,
0b00011000,
0b00011000,
0b00011000,
0b00011000,
0b00011000,
0b00111100
},{
0b00000000,
0b00011110,
0b00001100,
0b00001100,
0b00001100,
0b01101100,
0b01101100,
0b00111000
},{
0b00000000,
0b01100110,
0b01101100,
0b01111000,
0b01110000,
0b01111000,
0b01101100,
0b01100110
},{
0b00000000,
0b01100000,
0b01100000,
0b01100000,
0b01100000,
0b01100000,
0b01100000,
0b01111110
},{
0b00000000,
0b01100011,
0b01110111,
0b01111111,
0b01101011,
0b01100011,
0b01100011,
0b01100011
},{
0b00000000,
0b01100011,
0b01110011,
0b01111011,
0b01101111,
0b01100111,
0b01100011,
0b01100011
},{
0b00000000,
0b00111100,
0b01100110,
0b01100110,
0b01100110,
0b01100110,
0b01100110,
0b00111100
},{
0b00000000,
0b01111100,
0b01100110,
0b01100110,
0b01100110,
0b01111100,
0b01100000,
0b01100000
},{
0b00000000,
0b00111100,
0b01100110,
0b01100110,
0b01100110,
0b01101110,
0b00111100,
0b00000110
},{
0b00000000,
0b01111100,
0b01100110,
0b01100110,
0b01111100,
0b01111000,
0b01101100,
0b01100110
},{
0b00000000,
0b00111100,
0b01100110,
0b01100000,
0b00111100,
0b00000110,
0b01100110,
0b00111100
},{
0b00000000,
0b01111110,
0b01011010,
0b00011000,
0b00011000,
0b00011000,
0b00011000,
0b00011000
},{
0b00000000,
0b01100110,
0b01100110,
0b01100110,
0b01100110,
0b01100110,
0b01100110,
0b00111110
},{
0b00000000,
0b01100110,
0b01100110,
0b01100110,
0b01100110,
0b01100110,
0b00111100,
0b00011000
},{
0b00000000,
0b01100011,
0b01100011,
0b01100011,
0b01101011,
0b01111111,
0b01110111,
0b01100011
},{
0b00000000,
0b01100011,
0b01100011,
0b00110110,
0b00011100,
0b00110110,
0b01100011,
0b01100011
},{
0b00000000,
0b01100110,
0b01100110,
0b01100110,
0b00111100,
0b00011000,
0b00011000,
0b00011000
},{
0b00000000,
0b01111110,
0b00000110,
0b00001100,
0b00011000,
0b00110000,
0b01100000,
0b01111110
},{
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000
},{
0b00000000,
0b00000000,
0b00000000,
0b00111100,
0b00000110,
0b00111110,
0b01100110,
0b00111110
},{
0b00000000,
0b01100000,
0b01100000,
0b01100000,
0b01111100,
0b01100110,
0b01100110,
0b01111100
},{
0b00000000,
0b00000000,
0b00000000,
0b00111100,
0b01100110,
0b01100000,
0b01100110,
0b00111100
},{
0b00000000,
0b00000110,
0b00000110,
0b00000110,
0b00111110,
0b01100110,
0b01100110,
0b00111110
},{
0b00000000,
0b00000000,
0b00000000,
0b00111100,
0b01100110,
0b01111110,
0b01100000,
0b00111100
},{
0b00000000,
0b00011100,
0b00110110,
0b00110000,
0b00110000,
0b01111100,
0b00110000,
0b00110000
},{
0b00000000,
0b00000000,
0b00111110,
0b01100110,
0b01100110,
0b00111110,
0b00000110,
0b00111100
},{
0b00000000,
0b01100000,
0b01100000,
0b01100000,
0b01111100,
0b01100110,
0b01100110,
0b01100110
},{
0b00000000,
0b00000000,
0b00011000,
0b00000000,
0b00011000,
0b00011000,
0b00011000,
0b00111100
},{
0b00000000,
0b00001100,
0b00000000,
0b00001100,
0b00001100,
0b01101100,
0b01101100,
0b00111000
},{
0b00000000,
0b01100000,
0b01100000,
0b01100110,
0b01101100,
0b01111000,
0b01101100,
0b01100110
},{
0b00000000,
0b00011000,
0b00011000,
0b00011000,
0b00011000,
0b00011000,
0b00011000,
0b00011000
},{
0b00000000,
0b00000000,
0b00000000,
0b01100011,
0b01110111,
0b01111111,
0b01101011,
0b01101011
},{
0b00000000,
0b00000000,
0b00000000,
0b01111100,
0b01111110,
0b01100110,
0b01100110,
0b01100110
},{
0b00000000,
0b00000000,
0b00000000,
0b00111100,
0b01100110,
0b01100110,
0b01100110,
0b00111100
},{
0b00000000,
0b00000000,
0b01111100,
0b01100110,
0b01100110,
0b01111100,
0b01100000,
0b01100000
},{
0b00000000,
0b00000000,
0b00111100,
0b01101100,
0b01101100,
0b00111100,
0b00001101,
0b00001111
},{
0b00000000,
0b00000000,
0b00000000,
0b01111100,
0b01100110,
0b01100110,
0b01100000,
0b01100000
},{
0b00000000,
0b00000000,
0b00000000,
0b00111110,
0b01000000,
0b00111100,
0b00000010,
0b01111100
},{
0b00000000,
0b00000000,
0b00011000,
0b00011000,
0b01111110,
0b00011000,
0b00011000,
0b00011000
},{
0b00000000,
0b00000000,
0b00000000,
0b01100110,
0b01100110,
0b01100110,
0b01100110,
0b00111110
},{
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b01100110,
0b01100110,
0b00111100,
0b00011000
},{
0b00000000,
0b00000000,
0b00000000,
0b01100011,
0b01101011,
0b01101011,
0b01101011,
0b00111110
},{
0b00000000,
0b00000000,
0b00000000,
0b01100110,
0b00111100,
0b00011000,
0b00111100,
0b01100110
},{
0b00000000,
0b00000000,
0b00000000,
0b01100110,
0b01100110,
0b00111110,
0b00000110,
0b00111100
},{
0b00000000,
0b00000000,
0b00000000,
0b00111100,
0b00001100,
0b00011000,
0b00110000,
0b00111100
}};
const int IMAGES_LEN = sizeof(IMAGES)/8;

uint8_t colPins[8] = { 2, 3, 4, 5, 6, 7, 8, 9};

#define SER_PIN 10
#define SCK_PIN 11
#define RCK_PIN 12

void setup() {
for (int i = 0; i < 8; i++) {
pinMode(colPins[i], OUTPUT);
}
pinMode(SER_PIN, OUTPUT);
pinMode(SCK_PIN, OUTPUT);
pinMode(RCK_PIN, OUTPUT);
Serial.begin(9600);
}

void loop() {
// iterate each row
for (int i = 0; i < IMAGES_LEN; i++) {
for (int j = 0; j < 100; j++) {
int rowbits = 0x80;
for (int row = 0; row < 8; row++) {
for (int k = 0; k < 8; k++)
digitalWrite(colPins[k], LOW); // Cleanup cols
writeData(rowbits); // prepare to write the row
for (int col = 0; col < 8; col++)
digitalWrite(colPins[7 - col], IMAGES[i][row] & 1 << col ? HIGH : LOW );
delay(1);
writeData(0);
rowbits >>= 1;
}
}
}
}
void writeData(byte data) {
digitalWrite(RCK_PIN, LOW);
shiftOut(SER_PIN, SCK_PIN, LSBFIRST, data);
digitalWrite(RCK_PIN, HIGH);
}

Anyone can help me to make scroll this text

Like this?

yes but i dont know the code . im beginner

This is a very old project of mine from my early days with Arduino. I would advise you to use MAX7219 instead of 74HC595.

/*
примерна програма с демонстрация управлението на
светодиодна матрица 8х8 чрез регистри и драйвер
масив с кадрите
8 байта за кадър
*/

/*
const byte matrix [] = 
{
  0, 0, 0, 0, 0, 0, 0, 0,
  B00000000, B00000000, B00000000, B00011000, B00100100, B00000000, B00000000, B00000000,
  B11111110, B00010001, B00010001, B00010001, B00010001, B11111110, B00000000, B00000000,
  B11111111, B00010001, B00010001, B00110001, B01010001, B10001110, B00000000, B00000000,
  B11111111, B10000001, B10000001, B10000001, B10000001, B01111110, B00000000, B00000000,
  B01111111, B10000000, B10000000, B10000000, B10000000, B01111111, B00000000, B00000000,
  B00000000, B10000001, B11111111, B11111111, B10000001, B00000000, B00000000, B00000000,
  B11111111, B00000010, B00000100, B00111000, B01000000, B11111111, B00000000, B00000000,
  B01111110, B10000001, B10000001, B10000001, B10000001, B01111110, B00000000, B00000000,
  B00000000, B00000000, B00000000, B00100100, B00011000, B00000000, B00000000, B00000000,
  0, 0, 0, 0, 0, 0, 0, 0
};
// масива описва < A R D U I N O > като кадър 0 е празен т.е. изпълнява ролята на SPACE
*/

const byte matrix [] = 
{
  0, 0, 0, 0, 0, 0, 0, 0,
  B11111111, B00000010, B00000100, B00001000, B00000100, B00000010, B11111111, B00000000,
  B11111111, B01000000, B00100000, B00011000, B00000100, B00000010, B11111111, B00000000,
  B00000001, B00000001, B00000001, B11111111, B00000001, B00000001, B00000001, B00000000,
  B11111111, B00010000, B00011000, B00010100, B00100010, B01000001, B10000000, B00000000,
  B00111100, B01000010, B10000001, B10000001, B10000001, B01000010, B00111100, B00000000,
  0, 0, 0, 0, 0, 0, 0, 0
};

byte SframeS [ 8 ]; // масив за временно съхранение на текущия кадър
const word DIM = sizeof ( matrix ); // размер на масива

// пинове за контрол на регистрите 74HC595
const byte
SH_CP = 5,
ST_CP = 4,
OE = 3, // OE може да не се ползва а да се свърже директно към GND и всички маркирани с * редове да се изтрият като излишни
DS = 2
;


// времеви променливи
unsigned long
cycle,
timer
;
// технологично времезадържане в микросекунди - стойността е определена опитно  при еквивалентното му задаване в милисекунди се получи слабо но забележимо и дразнещо примигаване ако е зададена прекалено малка стойност започва да оказва влияние инертността на елементите като ефекта се проявява в по-слабото светене на светодиодите
const word PAUSE = 240;
// помощни променливи и масив за определяне на посоката
word sec = 80;
const char drctn [] = "LURD";
byte
change,
chng,
Hmirror,
Vmirror
;


void Sframe ( word duration ) // процедура за визуализиране на текущия кадър
{
  cycle = millis ();
  do
  {
    timer = millis () - cycle;
    for ( byte n = 0; n < 8; n++ )
    {
      digitalWrite ( ST_CP, LOW );
      shiftOut ( DS, SH_CP, LSBFIRST, 1 << n ); // изреждане на колоните
      shiftOut ( DS, SH_CP, LSBFIRST, SframeS [ n ] ); // задаване на редовете в избраната колона
      digitalWrite ( ST_CP, HIGH );
      digitalWrite ( OE, LOW ); // *
      delayMicroseconds ( PAUSE );
      digitalWrite ( OE, HIGH ); // *
    }
  }
  while ( duration > timer );
}

void frame ( word fb, word fe, char dir, byte DIRstep ) // процедура за генериране на текущия кадър
{
  switch ( dir )
  {
    case 'L':
    for ( byte MOVEstep = 0; MOVEstep < 8; MOVEstep ++ )
    {
      if ( MOVEstep + DIRstep < 8 )
      {
        SframeS [ MOVEstep ] = matrix [ fb * 8 + MOVEstep + DIRstep ];
      }
      else
      {
        SframeS [ MOVEstep ] = matrix [ fe * 8 + MOVEstep + DIRstep - 8 ];
      }
    }
    break;
    case 'U':
    for ( byte f = 0; f < 8; f ++ )
    {
      SframeS [ f ] = ( matrix [ fb * 8 + f ] >> DIRstep ) | ( matrix [ fe * 8 + f ] << ( 8 - DIRstep ) );
    }
    break;
    case 'R':
    for ( byte MOVEstep = 0; MOVEstep < 8; MOVEstep ++ )
    {
      if ( MOVEstep - DIRstep < 0 )
      {
        SframeS [ MOVEstep ] = matrix [ fe * 8 + MOVEstep - DIRstep + 8 ];
      }
      else
      {
        SframeS [ MOVEstep ] = matrix [ fb * 8 + MOVEstep - DIRstep ];
      }
    }
    break;
    case 'D':
    for ( byte f = 0; f < 8; f ++ )
    {
      SframeS [ f ] = ( matrix [ fb * 8 + f ] << DIRstep ) | ( matrix [ fe * 8 + f ] >> ( 8 - DIRstep ) );
    }
    break;
  }
}

void frm ( byte HM, byte VM, byte INV ) // процедура за модифициране текущия кадър - хоризонтално/вертикално огледало + инверсия
{
  if ( HM | VM | INV < 2 )
  {
    if ( HM == 1 )
    {
      for ( byte n = 0; n < 4; n ++ )
      {
        change = SframeS [ n ];
        SframeS [ n ] = SframeS [ 7 - n ];
        SframeS [ 7 - n ] = change;
      }
    }
    if ( VM == 1 )
    {
      for ( byte n = 0; n < 8; n ++ )
      {
        change = SframeS [ n ];
        for ( byte b = 0; b < 8; b ++ )
        {
          bitWrite ( chng, b, bitRead ( change, 7 - b ) );
        }
        SframeS [ n ] = chng;
      }
    }
    if ( INV == 1 )
    {
      for ( byte n = 0; n < 8; n ++ )
      {
        SframeS [ n ] = ~ SframeS [ n ];
      }
    }
  }
}

void frames ( word fb, word fe, char dir, word drtn, byte HM, byte VM, byte INV ) // процедура за визуализиране плавен преход м/у 2 кадъра или статичен кадър
{
  if ( fb < DIM / 8 && fe < DIM / 8 && ( dir == 'L' || dir == 'U' || dir == 'R' || dir == 'D' ) )
  {
    if ( fb == fe )
    {
      frame ( fb, fe, dir, 0 );
      frm ( HM, VM, INV );
      Sframe ( drtn );
    }
    else
    {
      for ( byte s = 0; s < 8; s ++ )
      {
        frame ( fb, fe, dir, s );
        frm ( HM, VM, INV );
        Sframe ( drtn );
      }
    }
  }
}

void setup ()
{
  pinMode ( OE, OUTPUT ); // *
  digitalWrite ( OE, HIGH ); // *
  pinMode ( ST_CP, OUTPUT );
  digitalWrite ( ST_CP, HIGH );
  pinMode ( DS, OUTPUT );
  pinMode ( SH_CP, OUTPUT );
  
  pinMode ( A0, OUTPUT );
  pinMode ( A2, OUTPUT );
  digitalWrite ( A2, HIGH );
}

void loop ()
{
/*
параметри на процедура frames ( word b, word e, char 
dir, word time, byte hm, byte vm, byte inv )
b - начален кадър
e - краен кадър
dir - посока на прехода м/у началния и крайния кадри - 
'L' ляво,'U' горе, 'R' дясно или 'D' долу
time - 10...65000 време в милисекунди като има 2 случая
 1) при b=e означава времето за показване на кадъра
 2) иначе е времетраенето на всеки от общо преходи 0...7 
т.е. от началния кадър до -1 на крайния кадър
hm, vm - 0 и 1 определя хоризонтално и вертикално огледало съответно
 понеже се инвертира резултатния кадър може да изглежда, 
че посоката на преход е обратна
inv - 0 и 1 определя позитивно/негативно състояние на 
кадъра за визуализиране
по принцип се прави някаква проверка на входните данни и 
ако не са допустими
процедурата не се изпълнява изобщо или се изпълнява 
частично като
резултата вероятно ще е странен и по-добре да се избягва 
некоректно задаване
некоректно задаване
*/
  for ( byte n = 0; n < 4; n ++ )
  {
    Hmirror = n & 1;
    Vmirror = ( n & 2 ) >> 1;
    for ( byte rpt = 1; rpt < DIM / 8 - 1; rpt ++ )
    {
      sec = analogRead ( A1 ) / 2 + 20;
      // sec = map ( sec, 0, 1023, 20, 400 );
      frames ( 0, rpt, drctn [ n ], sec, Hmirror, Vmirror, n % 2 );
      frames ( rpt, 0, drctn [ n ], sec, Hmirror, Vmirror, n % 2 );
    }
    frames ( 0, 0, drctn [ n ], sec, Hmirror, Vmirror, n % 2 );
  }
}



This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.