La función pulsein () es muy con pérdida, ya que es un bucle duro y devuelve un número * los ciclos de reloj supuestos que toma por bucle
...
// wait for the pulse to stop
while ((*portInputRegister(port) & bit) == stateMask) {
if (numloops++ == maxloops)
return 0;
width++;
}
// convert the reading to microseconds. The loop has been determined
// to be 20 clock cycles long and have about 16 clocks between the edge
// and the start of the loop. There will be some error introduced by
// the interrupt handlers.
return clockCyclesToMicroseconds(width * 21 + 16);
El método más preciso para capturar la sincronización de un PIN es usar la FUNCIÓN DE CAPTURA DE ENTRADA. Mira el este ejemplo . Permite la captura de entrada a 1x de la CPU para una resolución máxima y cada borde del pin de entrada captura el valor del reloj del temporizador para leer desde el servicio de interrupción generado. También permite la interrupción de desbordamiento del temporizador para mantener un tiempo absoluto grande y capturarse. Dado que el 1x rodará bastante rápido. Las capturas almacenan el tiempo en una matriz para leer por el bucle principal.
Donde para las señales sobre IR, la biblioteca típica para usar es la biblioteca shirriff / Arduino-IRremote . Donde tiene varias demostraciones que leerán y enviarán el IR desde una señal demodulada. Permitir a uno construir un boceto de su propio diseño. Este código originalmente crea una interrupción del temporizador que sondea el pin de entrada a una velocidad determinada por
#define USECPERTICK 50 // microseconds per clock interrupt tick
en el archivo IRremote.h. Para mis propósitos, lo he cambiado a 25 us. Donde encuentro esto todavía pueden faltar intermitentemente flujos de pulso.
Tenga en cuenta que la demodulación se realiza mejor dentro del receptor IR, que a su vez emite esta señal de interés. Dónde agregar un poco de fondo. Usando la modulación típica de 38KHz, equivale a una resolución mínima de 26.3uS por ciclo de pulso. La biblioteca de Sheriff muestra típicamente que la mayoría de los baudios o bits están en el orden de más de 10 pulsos. Que parecen cumplir con los tiempos deseados.
La bifurcación microtherion / Arduino-IRremote del trabajo de shirriff mejora la recepción al reemplazar el sondeo de interrupción del temporizador del pin con el uso de PinChangeInterrupts. Que he fusionado con mi propia bifurcación mpflaga / Arduino-IRremote , que agrega varias otras características.
Entonces podría usar cualquiera de las bibliotecas anteriores. O cree su propia aplicación que use cualquiera de los siguientes para capturar bordes.
- encuestas en un evento Timer (por ejemplo, 50uS)
- captura los micros () en un PinChangeInterrupt
- usa interrupciones de captura de entrada para capturar el tiempo exacto
Aquí hay algunos datos de
pulseIn
prueba de una prueba. Un Arduino envió lo que se suponía que eran pulsos 14us, y el otro escupió estos datos:Como puede ver, los pulsos de ninguna manera son precisos. El tiempo sería más preciso si los extremos de envío y recepción se escribieran en ensamblado, o incluso se descargaran en sus propios procesadores.
fuente