How to simplify led matrix code

Hello arduino community today i completed the code for my 5x5 led matix. its very simple and it works its just that every time i want to display a letter i have to say show(letter, delay). If I wanted to display a 50 character long message this would be inefficient. i tried to come up with my own solution but for some reason it doesn’t work and i have no idea why.
ill post the original code and the solution i tried.
Any help would be appreciated.

original code

``````/* Hopefully the last LED matrix code I ever make

BY: Chris Yambo
*/

int CPR = 8;  // clock pin row
int DPR = 10; // data pin row
int CPC = 11; // clock pin column
int DPC = 12; // data pin column
int LP = 9;   // combined the latch pins so theres only one

byte RA[] = { B10000000, B01000000, B00100000, B00010000, B00001000,}; // way to address rows individually
byte SMILEFACE[] = {B01110000, B10001000, B00000000, B01010000, B0101000};
byte SPACE[] = {B00000000, B00000000, B00000000, B00000000, B00000000};
byte A[] = {B10001000, B10001000, B11111000, B10001000, B11111000};
byte B[] = {B11111000, B10001000, B11110000, B10001000, B11111000};
byte C[] = {B11111000, B10001000, B10000000, B10001000, B11111000};
byte D[] = {B11110000, B10001000, B10001000, B10001000, B11110000};
byte E[] = {B11111000, B10000000, B11110000, B10000000, B11111000};
byte F[] = {B10000000, B10000000, B11110000, B10000000, B11111000};
byte G[] = {B11111000, B10001000, B10011000, B10000000, B11111000};
byte H[] = {B10001000, B10001000, B11111000, B10001000, B10001000};
byte I[] = {B01000000, B01000000, B01000000, B01000000, B01000000};
byte J[] = {B11111000, B10001000, B00001000, B00001000, B00001000};
byte K[] = {B10001000, B10010000, B11100000, B10010000, B10001000};
byte L[] = {B11111000, B10000000, B10000000, B10000000, B10000000};
byte M[] = {B10101000, B10101000, B10101000, B10101000, B11011000};
byte N[] = {B10001000, B10011000, B10101000, B11001000, B10001000};
byte O[] = {B11111000, B10001000, B10001000, B10001000, B11111000};
byte P[] = {B10000000, B10000000, B11111000, B10001000, B11111000};
byte Q[] = {B11111000, B10011000, B10001000, B10001000, B11111000};
byte R[] = {B10001000, B10010000, B11111000, B10001000, B11111000};
byte S[] = {B11111000, B00001000, B11111000, B10000000, B11111000};
byte T[] = {B00100000, B00100000, B00100000, B00100000, B11111000};
byte U[] = {B11111000, B10001000, B10001000, B10001000, B10001000};
byte V[] = {B00100000, B01010000, B10001000, B10001000, B10001000};
byte W[] = {B11011000, B10101000, B10101000, B10101000, B10101000};
byte X[] = {B10001000, B01010000, B00100000, B01010000, B10001000};
byte Y[] = {B11111000, B00001000, B11111000, B10001000, B10001000};
byte Z[] = {B11111000, B01000000, B00100000, B00010000, B11111000};

void setup() {

pinMode(CPR, OUTPUT);
pinMode(DPR, OUTPUT);
pinMode(CPC, OUTPUT); // setting pins as outputs
pinMode(DPC, OUTPUT);
pinMode(LP, OUTPUT);

for (int allOn = 0; allOn < 256; allOn++)
{
digitalWrite(LP, LOW);
shiftOut(DPR, CPR, LSBFIRST, allOn); // count up on rows and columns in binary
shiftOut(DPC, CPC, LSBFIRST, allOn); // cool effect to start it out every ime
digitalWrite(LP, HIGH);
delay(5);
}

if(int allOn = 255)
{
digitalWrite(LP, LOW);
shiftOut(DPR, CPR, LSBFIRST, 255); // give a second of everything on after counting sequence
shiftOut(DPC, CPC, LSBFIRST, 255); // then it's on to the main loop baby!!!
digitalWrite(LP, HIGH);
delay(1000); // wait a second of all on
}

int letter;
int row;
int timePassed; // just setting some int's in case i need them
int delayTime = 1000;
boolean pixel;
Serial.begin(9600);

}

void loop(){
show(A, 650);
show(B, 650);
show(C, 650);
show(D, 650);
show(E, 650);
show(F, 650);
show(G, 650);
show(H, 650);
show(I, 650);
show(J, 650);
show(K, 650);
show(L, 650);
show(M, 650);
show(N, 650);
show(O, 650);
show(P, 650);
show(Q, 650);
show(R, 650);
show(S, 650);
show(T, 650);
show(U, 650);
show(V, 650);
show(W, 650);
show(X, 650);
show(Y, 650);
show(Z, 650);

}

void show(byte * character, unsigned long duration){
unsigned long start = millis();
while(start + duration > millis()) //SINCE THIS WILL ALWAYS HAPPEN IT WILL ALWAYS DISPLAY THE LETTERS
{
for(int j=0; j<5; j++) // STARTS A COUT FRROM 0-4 AND MAKES IT THE INT 'J'
{
digitalWrite(LP, LOW); // PUT LATCH PIN LOW
shiftOut(DPR, CPR, LSBFIRST, RA[j]); // SHIFTT OUT ROW NUMBER 'J'
shiftOut(DPC, CPC, LSBFIRST, character[j]); //character[j]); SHIFT OUT COULMN 'J' FROM THE ARRAY OF WHATEVER CHARACTER WE CHOSE TO SHOW
digitalWrite(LP, HIGH); // PUT LATCH PIN HIGH DISPLAYING WHAT WE JUST SHIFTED
}
}
}
``````

my solution. i’m only posting the loop here since everything else is the same

`````` void loop(){
for(int g=0; g<4; g++)
{
byte text[] = {"test"};
byte letter[] = {text[g]};
byte test[] = {letter[0]};
show(test, 800);

}
}

void show(byte * character, unsigned long duration){
unsigned long start = millis();
while(start + duration > millis()) //SINCE THIS WILL ALWAYS HAPPEN IT WILL ALWAYS DISPLAY THE LETTERS
{
for(int j=0; j<5; j++) // STARTS A COUT FRROM 0-4 AND MAKES IT THE INT 'J'
{
digitalWrite(LP, LOW); // PUT LATCH PIN LOW
shiftOut(DPR, CPR, LSBFIRST, RA[j]); // SHIFTT OUT ROW NUMBER 'J'
shiftOut(DPC, CPC, LSBFIRST, character[j]); //character[j]); SHIFT OUT COULMN 'J' FROM THE ARRAY OF WHATEVER CHARACTER WE CHOSE TO SHOW
digitalWrite(LP, HIGH); // PUT LATCH PIN HIGH DISPLAYING WHAT WE JUST SHIFTED
}
}
}
``````

First of all, you would like to be able to call show() like this...

``````show('A',650);
``````

by passing the actual letter you want to display rather than an array that has the same name as the letter.

The first step is to rework your data structure to be addressable by character...

``````byte letters[26][5] = {
{B10001000, B10001000, B11111000, B10001000, B11111000},   // A
{B11111000, B10001000, B11110000, B10001000, B11111000},    // B
// the rest go here
};
``````

And then this...

``````void show(byte * character, unsigned long duration){
...
...
...
shiftOut(DPC, CPC, LSBFIRST, character[j]);
``````

becomes this...

``````void show(byte  character, unsigned long duration){
...
...
...
shiftOut(DPC, CPC, LSBFIRST, letters[character-'A'][j]);
``````

Thanks!!! :). Making one array instead of 26 makes sense but what do i put in the void loop area (not the part that's declaring show).

And what does this line of code mean like whats the difference of having the multiplication sign versus not having it an for character - A what does that mean specifically. Also if i use this method could i just declare a char and make it a string and my matrix would display whatever text the string was?

``````void show(byte  character, unsigned long duration){
...
...
...
shiftOut(DPC, CPC, LSBFIRST, letters[character-'A'][j]);
``````

sorry for all the noobish questions i'm not the est with coding as you can see

byte * character; declares a pointer to a byte and byte character; declares a byte. Suggest you read up on pointers in C/C++, they are important to know.

In loop(), instead of this... show(A, 650); do this... show('A', 650);

You could also define a showString() function that might look something like this...

``````void showString(char *myString, int delay) {
while (*myString) {
show(*myString++,delay);
}
}

// and somewhere inside loop call it like this...
showString("cabyambo",650);
``````

But if i have one array how do i call out the specific letters to shift out from that array? And would all the changes being made be made in the definition of the show function or would some have to be in the area of the loop where i actually say the show function?

You have one array but it is a two dimensional array. Or an array of arrays, one array for each letter. Declared like this... byte letters[26][5] = { // letter arrays };

Since the array has two dimensions, you need to provide two indexes to access one of the bytes...

letters[2][3] refers to the fourth byte of data for the letter C. As previously mentioned, you need to modify the show function to use this new array layout like this... shiftOut(DPC, CPC, LSBFIRST, letters[character-'A'][j]);

Notice for the first index we use character - 'A'. This will give zero for the letter A, 1 for B, 2 for C and so on.

Hello well I’ve done what you’ve said and it works and i understand it (just not the timing aspect of it i guess i got lucky lol).
But i was trying to make it work for strings and i just don’t understand what you suggested for that at all =( . Like why is the string a pointer now.

Pleas help!!! i really wana understand the string code and be able to say messages without saying the show command and then every letter

well here’s what i have that works to display the characters

``````/* Hopefully the last LED matrix code I ever make LOL
columns are positive and rows are negative
there is a transistor on the rows for current with a 2.something K resistor on the base
and a 3.3 ohm resistor on each column
uses 2 74HC595 shift registers one for column and one for rows
for columns Q1 goes to the leftmost column and for rows Q1 goes to lowest row
probably wouldnt do this in the future since i have to make the pics in the array uside down

to update the matrix i shift in the data for the columns then make its corresponding row high
so it goes row by row really fast sarting at the top
should probably switch this around and update it the opposite way
BY: Chris Yambo
*/

int CPR = 8;  // clock pin row
int DPR = 10; // data pin row
int CPC = 11; // clock pin column
int DPC = 12; // data pin column
int LP = 9;   // combined the latch pins so theres only one

byte RA[] = { B10000000, B01000000, B00100000, B00010000, B00001000,}; // way to address rows individually
byte letters[28][5] = {
{B10001000, B10001000, B11111000, B10001000, B11111000}, // A
{B11111000, B10001000, B11110000, B10001000, B11111000}, // B
{B11111000, B10001000, B10000000, B10001000, B11111000}, // C
{B11110000, B10001000, B10001000, B10001000, B11110000}, // D
{B11111000, B10000000, B11110000, B10000000, B11111000}, // E
{B10000000, B10000000, B11110000, B10000000, B11111000}, // F
{B11111000, B10001000, B10011000, B10000000, B11111000}, // G
{B10001000, B10001000, B11111000, B10001000, B10001000}, // H
{B01000000, B01000000, B01000000, B01000000, B01000000}, // I
{B11111000, B10001000, B00001000, B00001000, B00001000}, // J
{B10001000, B10010000, B11100000, B10010000, B10001000}, // K
{B11111000, B10000000, B10000000, B10000000, B10000000}, // L
{B10101000, B10101000, B10101000, B10101000, B11011000}, // M  everything must be made upside down!!!
{B10001000, B10011000, B10101000, B11001000, B10001000}, // N  to work with my hardware configuration
{B11111000, B10001000, B10001000, B10001000, B11111000}, // O  and the way I do the code
{B10000000, B10000000, B11111000, B10001000, B11111000}, // P
{B11111000, B10011000, B10001000, B10001000, B11111000}, // Q
{B10001000, B10010000, B11111000, B10001000, B11111000}, // R
{B11111000, B00001000, B11111000, B10000000, B11111000}, // S
{B00100000, B00100000, B00100000, B00100000, B11111000}, // T
{B11111000, B10001000, B10001000, B10001000, B10001000}, // U
{B00100000, B01010000, B10001000, B10001000, B10001000}, // V
{B11011000, B10101000, B10101000, B10101000, B10101000}, // W
{B10001000, B01010000, B00100000, B01010000, B10001000}, // X
{B11111000, B00001000, B11111000, B10001000, B10001000}, // Y
{B11111000, B01000000, B00100000, B00010000, B11111000}, // Z
};

void setup() {

pinMode(CPR, OUTPUT);
pinMode(DPR, OUTPUT);
pinMode(CPC, OUTPUT); // setting pins as outputs
pinMode(DPC, OUTPUT);
pinMode(LP, OUTPUT);

for (int allOn = 0; allOn < 256; allOn++)
{
digitalWrite(LP, LOW);
shiftOut(DPR, CPR, LSBFIRST, allOn); // count up on rows and columns in binary
shiftOut(DPC, CPC, LSBFIRST, allOn); // cool effect to start it out every ime
digitalWrite(LP, HIGH);
delay(5);
}

int letter;
int row;
int timePassed; // just setting some int's in case i need them
int delayTime = 1000;
boolean pixel;
Serial.begin(9600);

}

void loop(){
show('H',650);
show('I',650);

}

void show(char character, unsigned long duration){
unsigned long start = millis();
while(start + duration > millis()) //SINCE THIS WILL ALWAYS HAPPEN IT WILL ALWAYS DISPLAY THE LETTERS
{
for(int j=0; j<5; j++) // STARTS A COUT FRROM 0-4 AND MAKES IT THE INT 'J'
{
digitalWrite(LP, LOW); // PUT LATCH PIN LOW
shiftOut(DPR, CPR, LSBFIRST, RA[j]); // SHIFTT OUT ROW NUMBER 'J'
shiftOut(DPC, CPC, LSBFIRST, letters[character - 'A'][j]); //character[j]); SHIFT OUT COULMN 'J' FROM THE ARRAY OF WHATEVER CHARACTER WE CHOSE TO SHOW
digitalWrite(LP, HIGH);
delay(2); // PUT LATCH PIN HIGH DISPLAYING WHAT WE JUST SHIFTED

}

}

}
``````

Ok well I’ve made some code to display strings but i think for some reason the timing isn’t working. on the matrix it has all the letters displayed but all at once so all the pixels that would correspond to the letters in the string are on. if you have any suggestions on how to make each letter display for the delay the i set in the function i would be very appreciative

``````/* Hopefully the last LED matrix code I ever make

BY: Chris Yambo
*/

int CPR = 8;  // clock pin row
int DPR = 10; // data pin row
int CPC = 11; // clock pin column
int DPC = 12; // data pin column
int LP = 9;   // combined the latch pins so theres only one

byte RA[] = { B10000000, B01000000, B00100000, B00010000, B00001000,}; // way to address rows individually
byte letters[26][5] = {
{B10001000, B10001000, B11111000, B10001000, B11111000}, // A
{B11111000, B10001000, B11110000, B10001000, B11111000}, // B
{B11111000, B10001000, B10000000, B10001000, B11111000}, // C
{B11110000, B10001000, B10001000, B10001000, B11110000}, // D
{B11111000, B10000000, B11110000, B10000000, B11111000}, // E
{B10000000, B10000000, B11110000, B10000000, B11111000}, // F
{B11111000, B10001000, B10011000, B10000000, B11111000}, // G
{B10001000, B10001000, B11111000, B10001000, B10001000}, // H
{B01000000, B01000000, B01000000, B01000000, B01000000}, // I
{B11111000, B10001000, B00001000, B00001000, B00001000}, // J
{B10001000, B10010000, B11100000, B10010000, B10001000}, // K
{B11111000, B10000000, B10000000, B10000000, B10000000}, // L
{B10101000, B10101000, B10101000, B10101000, B11011000}, // M
{B10001000, B10011000, B10101000, B11001000, B10001000}, // N
{B11111000, B10001000, B10001000, B10001000, B11111000}, // O
{B10000000, B10000000, B11111000, B10001000, B11111000}, // P
{B11111000, B10011000, B10001000, B10001000, B11111000}, // Q
{B10001000, B10010000, B11111000, B10001000, B11111000}, // R
{B11111000, B00001000, B11111000, B10000000, B11111000}, // S
{B00100000, B00100000, B00100000, B00100000, B11111000}, // T
{B11111000, B10001000, B10001000, B10001000, B10001000}, // U
{B00100000, B01010000, B10001000, B10001000, B10001000}, // V
{B11011000, B10101000, B10101000, B10101000, B10101000}, // W
{B10001000, B01010000, B00100000, B01010000, B10001000}, // X
{B11111000, B00001000, B11111000, B10001000, B10001000}, // Y
{B11111000, B01000000, B00100000, B00010000, B11111000}, // Z
};

void setup() {

pinMode(CPR, OUTPUT);
pinMode(DPR, OUTPUT);
pinMode(CPC, OUTPUT); // setting pins as outputs
pinMode(DPC, OUTPUT);
pinMode(LP, OUTPUT);

for (int allOn = 0; allOn < 256; allOn++)
{
digitalWrite(LP, LOW);
shiftOut(DPR, CPR, LSBFIRST, allOn); // count up on rows and columns in binary
shiftOut(DPC, CPC, LSBFIRST, allOn); // cool effect to start it out every ime
digitalWrite(LP, HIGH);
delay(5);
}

if(int allOn = 255)
{
digitalWrite(LP, LOW);
shiftOut(DPR, CPR, LSBFIRST, 255); // give a second of everything on after counting sequence
shiftOut(DPC, CPC, LSBFIRST, 255); // then it's on to the main loop baby!!!
digitalWrite(LP, HIGH);
delay(1000); // wait a second of all on
}

int letter;
int row;
int timePassed; // just setting some int's in case i need them
int delayTime = 1000;
boolean pixel;
Serial.begin(9600);

}

void loop(){
show("CHRIS", 650);

}

void show(char *character, unsigned long duration){
unsigned long start = millis();
while(start + duration > millis()) //SINCE THIS WILL ALWAYS HAPPEN IT WILL ALWAYS DISPLAY THE LETTERS
{
for(int x=0; x<5; x++)
{
String message = character;
int SL = message.charAt(x);
Serial.println(SL);

for(int j=0; j<5; j++) // STARTS A COUT FRROM 0-4 AND MAKES IT THE INT 'J'
{
digitalWrite(LP, LOW); // PUT LATCH PIN LOW
shiftOut(DPR, CPR, LSBFIRST, RA[j]); // SHIFTT OUT ROW NUMBER 'J'
shiftOut(DPC, CPC, LSBFIRST, letters[SL - 'A'][j]); //character[j]); SHIFT OUT COULMN 'J' FROM THE ARRAY OF WHATEVER CHARACTER WE CHOSE TO SHOW
digitalWrite(LP, HIGH); // PUT LATCH PIN HIGH DISPLAYING WHAT WE JUST SHIFTED
}
}
}
}
``````