Electronic – arduino – Is it a good idea to refresh a display (8×8 LED matrix in this case) inside an interrupt handler

arduinointerruptsled-matrixshift-register

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.