Scroll a 5X5 LED matrix that is row scanned

Hello Arduino community. I recently built a 5X5 LED matrix that was column scanned and that made it very easy for me to create a scrolling function. Someone on the forums actually told me the best way to do it. But now I,m realizing that if i wanted to make a matrix that had a longer width I'd need to row scan instead of column scan and that,s where the problem is. I made a code to try and scroll the matrix using using row scanning but it just scrolls from the top down , so a vertical scroll as appose to the desired horizontal one. I know where the problem is in the code but just can't figure out a work around.

The scrolling part is in the scroll function towards the bottom

The problem is that since i"m writing the entire message to be scrolled into a new array and then displaying 0-4, 1-5, 2-6... etc of that array it isn't scrolling left to right. Since in row scanning the LED's are turned on one row at a time its just going up and down not left to right like it did when i column scanned it.

Any help/ advice would be appreciated
Thanks in advance:Chris

//DOESNT WORK INSTEAD OF SCROLLING LEFT TO RIGHT IT SCROLLS TOP TO BOTTOM
//REV 2.0
//By: Christopher Beharry Yambo with help from the arduino community @www.forum.arduino.cc

/*
 * Controls a 5X5 LED matrix consisting of two 8bit shift registers
 * It's row scanned meaning that one row comes on at a time from top to bottom 
 * hopefully i can creat scrollin using row scanning!
 */
 
//constants for data pin, clock pin, and latch pin
const int CPR = 8;
const int LP = 9;
const int DPR = 10;
const int CPC = 11;
const int DPC = 12;

byte rowActivator[] = {B10000000, B01000000, B00100000, B00010000, B00001000,}; // way to address rows individually
byte letters[27][5] = {
    
  {B10001000, B10001000, B11111000, B10001000, B11111000}, // A 0          
  {B11110000, B10001000, B11110000, B10001000, B11110000}, // B 1
  {B11111000, B10001000, B10000000, B10001000, B11111000}, // C 2 
  {B11110000, B10001000, B10001000, B10001000, B11110000}, // D 3
  {B11111000, B10000000, B11110000, B10000000, B11111000}, // E 4
  {B10000000, B10000000, B11110000, B10000000, B11111000}, // F 5
  {B11111000, B10001000, B10011000, B10000000, B11111000}, // G 6
  {B10001000, B10001000, B11111000, B10001000, B10001000}, // H 7
  {B01000000, B01000000, B01000000, B01000000, B01000000}, // I 8
  {B11111000, B10001000, B00001000, B00001000, B00001000}, // J 9
  {B10001000, B10010000, B11100000, B10010000, B10001000}, // K 10
  {B11111000, B10000000, B10000000, B10000000, B10000000}, // L 11
  {B10101000, B10101000, B10101000, B10101000, B11011000}, // M 12
  {B10001000, B10011000, B10101000, B11001000, B10001000}, // N 13                    
  {B11111000, B10001000, B10001000, B10001000, B11111000}, // O 14
  {B10000000, B10000000, B11111000, B10001000, B11111000}, // P 15
  {B11111000, B10011000, B10001000, B10001000, B11111000}, // Q 16
  {B10001000, B10010000, B11111000, B10001000, B11111000}, // R 17
  {B11111000, B00001000, B11111000, B10000000, B11111000}, // S 18 
  {B00100000, B00100000, B00100000, B00100000, B11111000}, // T 19
  {B11111000, B10001000, B10001000, B10001000, B10001000}, // U 20
  {B00100000, B01010000, B10001000, B10001000, B10001000}, // V 21
  {B11011000, B10101000, B10101000, B10101000, B10101000}, // W 22
  {B10001000, B01010000, B00100000, B01010000, B10001000}, // X 23
  {B11111000, B00001000, B11111000, B10001000, B10001000}, // Y 24
  {B11111000, B01000000, B00100000, B00010000, B11111000}, // Z 25
  {B00000000, B00000000, B00000000, B00000000, B00000000}, // Space to shift out use number 91
};

//array the message in the scroll function is placed in
byte scrollArray[160];

void setup() {
  Serial.begin(9600);
  for(int x=8; x<=12; x++)
  {
    pinMode(x, OUTPUT);
  }
}
 
void loop() {
  scrollMessage("AX");
}

//funvtion to show a singular letter
void showLetter(char letter) {                         
  for(int A=0; A<5; A++)
  {
    digitalWrite(LP, LOW);                                      
    shiftOut(DPR, CPR, LSBFIRST, rowActivator[A]);                        
    shiftOut(DPC, CPC, LSBFIRST, letters[letter - 'A'][A]);       
    digitalWrite(LP, HIGH); 
  }
}                              

//function to display a message one letter at a time
void showMessage(String message) {
  int messageLength = message.length();
  int characterDelay = 650;
  
  for(int B=0; B<messageLength; B++)                  
  {
    int character = message.charAt(B);            
    unsigned long start = millis();               
    while((start + characterDelay) > millis())            
    {
      //if the character is a space shiftout the space character on the letters array
      if(character == 32)
      showLetter(91);                             

      //else shiftout the letter as usual
      else                                        
      showLetter(character); 
    }

    //puts a small space between two of the same letter
    if(character == message.charAt(B + 1))
    {
      unsigned long timer = millis();
      int doubleDelay = 125;

      while((timer + doubleDelay) > millis())
      {
        showLetter(91);
      }
    } 
  }
}                     

//function to scroll a message from left to right
void scrollMessage(String message){ 
  int scrollDelay = 250;
  int y = 0;
  int messageLength = message.length();

  //puts mesag einto the scroll array
  for(int C=0; C<messageLength; C++)
  {
    for(int D=0; D<5; D++)
    {
      scrollArray[(C*5) + D] = letters[(message.charAt(C)) - 'A'][D];
    }
  }

  // scrolls out the scroll array
  int X = 0;
  for(int E=0; E<=(messageLength*5); E++)
  {
    unsigned long timer = millis();
    while((timer + scrollDelay) > millis())
    {
      for(int F=0; F<5; F++)
      {
        digitalWrite(LP, LOW);
        shiftOut(DPR, CPR, LSBFIRST, rowActivator[F]);
        shiftOut(DPC, CPC, LSBFIRST, scrollArray[F + X]);
        digitalWrite(LP, HIGH);        
      }
    }
    X++;
  }    
}

Why not just turn the matrix sideways?

odometer:
Why not just turn the matrix sideways?

Problem solved!

If I turned it sideways the letters would also be sideways. It scrolls up and down so turning it sideways would just pt the letters on their side.

Hi, try this change. It compiles but I can not test it.

//function to scroll a message from left to right
void scrollMessage(String message){ 
  int scrollDelay = 250;
  int y = 0;
  int messageLength = message.length();

  //puts mesag einto the scroll array
  for(int C=0; C<messageLength; C++)
  {
    for(int D=0; D<5; D++)
    {
      scrollArray[(C*5) + D] = letters[(message.charAt(C)) - 'A'][D];
    }
  }

  // scrolls out the scroll array
  int X = 0;
  for(int E=0; E<=(messageLength*5); E++)
  {
    int Xl = X % 5;
    int Xr = 5 - Xl;
    byte rowData[8];
    for(int F=0; F<5; F++)
      {
        rowData[F] = scrollArray[F + X - Xl] << Xl | scrollArray[F + X + Xr] >> Xr;
      }
    unsigned long timer = millis();
    while((timer + scrollDelay) > millis())
    {
      for(int F=0; F<5; F++)
      {
        digitalWrite(LP, LOW);
        shiftOut(DPR, CPR, LSBFIRST, rowActivator[F]);
        shiftOut(DPC, CPC, LSBFIRST, rowData[F]);
        digitalWrite(LP, HIGH);        
      }
    }
    X++;
  }    
}

Paul

cabyambo:
If I turned it sideways the letters would also be sideways. It scrolls up and down so turning it sideways would just pt the letters on their side.

Then you change the font so that the letters appear the other way round. Perfectly obvious if you take a moment to think about it.

OK, it happens to be a trifle inconvenient only as the patterns now appear on their side in the source code but so what? It turns out to be far more practical as if each byte corresponds to a row, then you are constrained to use characters that are eight bits wide including the space between characters - because each byte to load to the display contains all eight bits wide.

Once you have bytes oriented vertically on the display, you only use as many bytes as your characters are wide - you do not even need to include the character spacing (and can even use a proportional font).

It's all in the programming - a simple adjustment in the code makes it much cleaner than what you were proposing.

@PaulRB Thank you so much!! Your solution worked perfectly i just currently don't understand it at all. Also, sorry for replying so late I just honestly got bummed that i couldn't get it to work so i had put the matrix on hold for a bit but thanks to you it works. You've already done more than enough but if you could explain what makes this work I'd be more than appreciative.

Thanks so much: Chris

Hi Chris. Yes, it is difficult code for a beginner to understand. What Paul__B says is true, it would have been much cleaner and simpler to rotate your matrix and font. But because you did not want that, the code is more complicated. It now has to perform manipulations on the individual bits, instead of whole bytes. It uses bit-shifting (<< and >>) to get some bits from one character and other bits from the neighbouring character. These are then merged into one byte with the bitwise-OR function (|).