# Timing of an led matrix

Helo arduino community i made simple code for my led matrix but the timing portion i took out of an arduino book i had . I really don’t understand it and would be appreciative if you could help. Its the first two lines after i start defining the show function. What i don’t understand is that I have a while loop that’s supposed to display a letter while the int start which is the total time that’s passed so far plus the duration i set is > than the total time that passed. How can this work? Start + duration will never be less than millis (the total time passed) so why does it switch from letter to letter and not just display the first letter continuously?

Please help . I would be grateful for any explanation you could give me.

`````` void loop(){
show('C', 650);
show('A', 650);
show('B', 650);
show('Y', 650);
show('A', 650);
show('M', 650);
show('B', 650);
show('O', 650);

}

void show(char character, unsigned long duration){
unsigned long start = millis(); //Begin timing the animation
while(start + duration > millis()) //loop untill duration period. still dont understand this but oh well
{
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); // PUT LATCH PIN HIGH DISPLAYING WHAT WE JUST SHIFTED

}

}

}
``````

I will answer your question three days from today. Today is the 27th so on the 30th you will have your answer. Check your calendar each day, and when it says 30th come back here for your answer.

@cabyambo, How many topics are you going to have on this? This is like the 4th one now.

@Cross Roads I just really want to understand how this led matrix code works but i'm not really having any luck. The code you showed me uses an SPI library which i don't understand which is why i decided to make functions.

shiftOut, SPI.transfer, just 2 ways to toggle a clock line while the databit goes high low. SPI uses dedicated hardware and is really fast - clock line can be up to 8 MHZ. shiftout uses code to: drive data bit clock high clock low drive next data bit clock high clock low repeat 6 more times.

What you don't seem to be getting is the need to control 2 timing loops. One runs every 2mS for example, with data sent out for a column every 2 mS for persistence of vision. The second runs once a second to change the data to be displayed. Blink-without-delay is a simple way to get that: Simplified:

``````currentTime = millis();
elapsedTime1 = currentTime - previousTime1;
elapsedTime2 = currentTime - previousTime2;
if (elapsedTime1 >= duration1){
previousTime1 = previousTime1 + duration1; // set up for next interval
// do task 1
// say, move next letter into the display array
// use a counter to keep track of which letter is being displayed

/* want scrolling? Use a large array for the message, say 32 bytes, 64 bytes, 100 bytes,
whatever you decide, and every 100mS move the next 5 columns to be shown into the display
array. So 0-4, 1-5, 2-6, 3-7, etc until reach the end, 95-9 for example. When at the end, load
the message array with more data (if desired) and reset the pointer to 0.
My scrolling display, I used 1000 bytes because I experimented to find out how  big I could go
without crashing. */
} // end task 1
if (elapsedTme2 >= duration2){
previousTime2 = previousTIme2 + duration2; // set up fo next interval
// do task 2
// say, send out data from the display array for the next column
// use a counter to keep track ow column you are on
} // end task 2
} // end loop
``````

Oh - I used 1020 bytes but I was storing the message in EEPROM, and used 2 bytes to indicate if there was a message, 2 bytes to store where the end of the message was. When using SRAM, it was actually bigger because there was more SRAM free, and I had myself pretty confused when I went to EEPROM because address 1024 wrapped around to address 0, 1025 = 1, 1026 = 2 and my results were pretty flakey until I figured out was happening; or rather, had it pointed out to me 8)

Thanks so much!!! what your saying makes a lot of sense but jut to be clear on the first timing loop i shift out the data and on the second I make the latch pins high to display what i shifted out

And the piece of code that controls your if loops I don't understand. Are those the 1ms and 2ms delays or is that how long to display a letter. If you explain this to me I think ill be able to have the best matrix ever lol :)

@ DavidOConnar hey man can you tell me the answer?

27th is start, 3 days is the duration and check the calendar is millis.

Now you know that "Start + duration will never be less than millis" is not the case. :)

lol thanks. Cool explanation 8)

Dear arduino community i have a working code for an LED matrix but much of it was derived from help I recieved on the forums. I understand almost all of it accept for the part that keeps the letter displayed for the time specified. To be specific in the part of code I don’t understand wouldn’t start + duration always be greater than millis? This makes no sense to me. If anyone could explain it to me i would be very appreciative.

P.S. it’s a 5X5 matrix

Specific piece of code I don’t understand

``````unsigned long start = millis(); //Begin timing the animation
while(start + duration > millis()) //loop untill duration period. still dont understand this but oh well
``````

Entire 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 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
};

byte space[1][5] = {
{B00000000, B00000000, B00000000, B00000000, B00000000}, // Space
};

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('E', 650);
show('L', 650);
show('L', 650);
show('O', 650);
show(' ', 650);
show('W', 650);
show('O', 650);
show('R', 650);
show('L', 650);
show('D', 650);
show(' ', 650);

}

void show(char character, unsigned long duration){
unsigned long start = millis(); //Begin timing the animation
while(start + duration > millis()) //loop untill duration period. still dont understand this but oh well
{
if(character == 32) // if loop for letters
{
digitalWrite(LP, LOW); // PUT LATCH PIN LOW
shiftOut(DPR, CPR, LSBFIRST, 0); // shift out ruw number 'J'
shiftOut(DPC, CPC, LSBFIRST, 0); //SHIFT OUT COULMN 'J' FROM THE ARRAY OF WHATEVER CHARACTER WE CHOSE TO SHOW
digitalWrite(LP, HIGH); // Put latch pin high displayig everything shifted in
delay(2);
}

if(character == 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90) // if loop for letters
{
for(int j=0; j<5; j++) // starts a count from 0- 4 and makes it j
{
int y = character - 'A';
digitalWrite(LP, LOW); // PUT LATCH PIN LOW
shiftOut(DPR, CPR, LSBFIRST, RA[j]); // shift out ruw number 'J'
shiftOut(DPC, CPC, LSBFIRST, letters[y][j]); //SHIFT OUT COULMN 'J' FROM THE ARRAY OF WHATEVER CHARACTER WE CHOSE TO SHOW
digitalWrite(LP, HIGH); // Put latch pin high displayig everything shifted in
delay(2);
}
}

}
}
``````

From the Reference page on while():

while loops will loop continuously, and infinitely, until the expression inside the parenthesis, () becomes false. Something must change the tested variable, or the while loop will never exit. This could be in your code, such as an incremented variable, or an external condition, such as testing a sensor.

So when the function is called:

unsigned long start = millis(); //Begin timing the animation while(start + duration > millis()) //loop untill duration period.

start +duration will be greater than millis() because start was just given the value millis, and the stuff in the following { } brackets will run. Then millis() will increase as time goes on, while start+duration is fixed; and at some point start + duration will not be greater (i.e. the condition becomes false) and the while exits.

Oh, now i understand it. I thought start was continually increasing the same as millis. I didn’t realize it wasn’t. Thank you so much