Let's say I have an Arduino connected to a 8x8 LED matrix
.
In my case, the LED matrix is driven using two 74HC595
shift registers (one for the rows and one for the columns).
Since it can only set the status of 8 LEDs at a time (one row), idea is to refresh the rows fast enough so that the human eye will not notice the blinking.
This is usually done in the loop()
method :
int led_status[8]; //contains LED status (which is on/off) for each row
void loop() {
process_otherstuff(); //eg: key inputs,...
display(); //shift led_status[] to shift register and latch result.
}
Here is potential issue : what if CPU has to do some time consuming process in the loop method (eg: heavy math) ? The display() method will be called with some delay which might be noticeable (led will start blinking or even worse : stop refreshed, appears to be stuck on one row).
A possible solution I can think of is the refresh the LED matrix in an interrupt handler :
void setup()
{
analogWrite(3, 100);
attachInterrupt(1, refreshdisplay, RISING);
}
int row = 0;
void refreshdisplay()
{
//refresh one single row
refreshrow(row++);
if(row > 7) row = 0;
}
Is this a good idea ? That way, no matter how much time is spend in loop() method, display will be refreshed as fast as needed.
Potential issue I can see is a lot of time is now spent in the interrupt, which is usually a bad thing (interrupts handler should be as short as possible).
Another solution is to use a separate LED controller driver (eg : connected to Arduino using I2C bus) but this require changing components list.
Best Answer
Yes, that is the correct approach- refresh the display in an ISR.
Even slight timing changes can result in visual artifacts, so keeping the timing fairly tight is necessary if you want a high-quality appearance to the display.
If possible, use hardware (eg. the SPI peripheral) to write to the shift registers, and of course use a relatively high clock speed. If you do that, the total time spent in the ISR should only be a few percent of the processor bandwidth, and since it's taken in small "chunks" the background processing will proceed almost as if you had a processor running at, say, 12MHz rather than 16MHz.
Simple and (relatively) timing-critical processes like refreshing a display are exactly what ISRs are good for. It's also a good time (while you are in a periodic ISR) to scan input switches for debouncing, for example.