¿Es una buena idea actualizar una pantalla (matriz de 8x8 LED en este caso) dentro de un controlador de interrupciones?

4

Digamos que tengo un Arduino conectado a un 8x8 LED matrix .

En mi caso, la matriz de LED se controla utilizando dos registros de desplazamiento 74HC595 (uno para las filas y otro para las columnas).

Dado que solo puede establecer el estado de 8 LED a la vez (una fila), la idea es actualizar las filas lo suficientemente rápido para que el ojo humano no note el parpadeo.

Esto generalmente se hace en el método loop() :

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.   
}

Aquí hay un problema potencial: ¿qué pasa si la CPU tiene que hacer un proceso que consume mucho tiempo en el método de bucle (por ejemplo: matemáticas pesadas)? Se llamará al método display () con algún retraso que podría ser perceptible (el led comenzará a parpadear o, lo que es peor, se detendrá en una fila).

Una posible solución que se me ocurre es actualizar la matriz de LED en un controlador de interrupciones:

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

¿Es esta una buena idea? De esa manera, no importa cuánto tiempo se invierta en el método loop (), la pantalla se actualizará tan rápido como sea necesario. El problema potencial que puedo ver es que ahora se pasa mucho tiempo en la interrupción, lo que generalmente es algo malo (el controlador de interrupciones debe ser lo más corto posible).

Otra solución es usar un controlador de controlador LED separado (por ejemplo: conectado a Arduino mediante el bus I2C) pero esto requiere cambiar la lista de componentes.

    
pregunta tigrou

2 respuestas

3

Sí, ese es el enfoque correcto: actualice la pantalla en un ISR.

Incluso los cambios leves en el tiempo pueden resultar en artefactos visuales, por lo que es necesario mantener el tiempo bastante ajustado si desea una apariencia de alta calidad en la pantalla.

Si es posible, use hardware (por ejemplo, el periférico SPI) para escribir en los registros de desplazamiento y, por supuesto, use una velocidad de reloj relativamente alta. Si lo hace, el tiempo total empleado en el ISR debería ser solo un pequeño porcentaje del ancho de banda del procesador, y dado que se toma en pequeños "trozos", el procesamiento en segundo plano procederá casi como si tuviera un procesador funcionando a, por ejemplo, 12MHz En lugar de 16MHz.

Los procesos simples y (relativamente) críticos para el tiempo, como actualizar una pantalla, son exactamente para lo que sirven los ISR. También es un buen momento (mientras está en un ISR periódico) para escanear los interruptores de entrada para el rebote, por ejemplo.

    
respondido por el Spehro Pefhany
2

Normalmente, los controladores de interrupción se utilizan para acciones cortas. La razón es que el programa principal bloquea.

Sin embargo, si el controlador principal no realiza acciones críticas de tiempo, es un problema menor.

Asegúrese de que el controlador de interrupciones no demore más que la siguiente llamada de interrupción. De lo que recibe una llamada de interrupción dentro de una llamada de interrupción, etc.

En su caso, su función de actualización probablemente siempre esté tomando el mismo tiempo. Puede medirlo (haga una prueba con 1000 iteraciones y divida el tiempo entre 1000, o 1M si no puede medirlo). Y ya sabes la frecuencia de actualización. Usted sabe cuánto le queda a usted un porcentaje (menos algunos gastos generales) para su programa principal.

Personalmente, creo que escribir 64 pines GPIO, incluso con los registros de desplazamiento se debe hacer muy rápidamente, pero la prueba es mejor que suponer.

    
respondido por el Michel Keijzers

Lea otras preguntas en las etiquetas