El problema aquí tiene que ver con la sincronización, ¡así que salgamos nuestros osciloscopios! Básicamente (y un poco más simplificado) la mayoría de las declaraciones de control de flujo de C estándar no pueden hacer garantías de tiempo en un microcontrolador. Las interrupciones basadas en hardware garantizan que el código comenzará a ejecutarse dentro de un número fijo de ciclos de reloj.
El Arduino (más específicamente, el Arduino Uno con un ATmega328) tiene muchas formas de activar interrupciones de hardware, llamadas a veces "vectores de interrupción" (pág. 57 de la Hoja de datos de ATmega). ¿Cuál queremos? Queremos ejecutar el código inmediatamente después de la transición del pin de la polla, por lo que estamos buscando una Interrupción de Cambio de Pin o una interrupción externa. La sección 12 en la hoja de datos entra en demasiados detalles sobre esto, pero la clave es que cada puerto de 8 pines comparte un vector de interrupción. (arduino.cc/en/Hacking/PinMapping168) Esto lo hace complicado, especialmente si eres nuevo en microcontroladores. La comunidad Arduino creó una gran biblioteca para tal situación, llamada PinChangeInt . (Descargo de responsabilidad: contribuí a PinChangeInt)
La función integrada del creador de interrupciones Arduino (attachInterrupt (interrupt, ISR, mode)) y el creador de interrupciones de PinChangeInt (PCintPort :: attachInterrupt (PIN1, & ISRfunc, EDGE)) tienen argumentos muy similares. Los argumentos pin y edge / mode son autoexplicativos: el pin en el que desea que se active la interrupción y el edge en el que está interesado (lo más probable es que suba, pero verifique el diagrama de tiempo de su reloj). El nombre de la función que especifique se adjunta como la rutina de servicio de interrupción (ISR). Cada vez que el hardware ve esa interrupción, el ISR comienza a ejecutarse. Esta función (ISRfunct () anterior) no toma argumentos y no devuelve ningún valor (escriba VOID). Puede acceder a variables globales y otras de alcance como cualquier función. Para implementar la lógica que está describiendo, necesitará una variable global para sus datos y una para el "índice de transmisión" o el último bit enviado.
Para obtener más información sobre las interrupciones en Arduino, consulte los enlaces a continuación:
ATmega168 Subsystem Diagrams
uchobby.com/index.php/2007/11/24/arduino-interrupts/
gonium.net/md/2006/12/20/handling-external-interrupts-with-arduino/