¿Qué tan preciso es el tiempo de pulseIn ()?

8

He estado usando la pulseIn()función para procesar la codificación de datos binarios basada en PWM. Funciona bien para distinguir pulsos que tienen longitudes significativamente diferentes, por ejemplo, 500us vs. 1500us. Eso lo hace más que suficiente para manejar controles remotos IR típicos.

Sin embargo, quiero hacer mi propio sistema IR que pueda usar más de 2 longitudes de pulso, para que la transferencia de datos pueda ocurrir más rápido. Idealmente, me gustaría usar 8 longitudes de pulso diferentes para la codificación octal (por ejemplo, 200us, 400us, 600us, etc.).

Sin pulseIn()embargo, he notado variaciones bastante significativas en los valores devueltos (+/- 10%). Espero que al menos una parte sea introducida por los módulos de transmisor y receptor IR, pero no tengo el equipo lo suficientemente bueno como para verificar eso.

Suponiendo que pueda mitigar ese error externo, ¿es pulseIn()probable que sea lo suficientemente preciso como para distinguir pulsos similares?

Peter Bloomfield
fuente

Respuestas:

11

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.

  1. encuestas en un evento Timer (por ejemplo, 50uS)
  2. captura los micros () en un PinChangeInterrupt
  3. usa interrupciones de captura de entrada para capturar el tiempo exacto
mpflaga
fuente
1
Brillante respuesta. El Arduino-IRremote es una biblioteca de muy alta calidad. Fácil de leer y tiene un diseño muy bien pensado que significa que es muy confiable.
Cybergibbons
2

Aquí hay algunos datos de pulseInprueba de una prueba. Un Arduino envió lo que se suponía que eran pulsos 14us, y el otro escupió estos datos:

18,18,18,12,18,18,18,18,18,18,18,18,18,18,18,18,18,24,19,18,18,18,18,18,24, 18,18,18,19,18,18,12,18,18,19,18,18,18,18,18,18,18,18,18,18,18,19,18,19,24, 18,18,18,18,18,18,18,24,18,18,18,18,18,18,18,18,18,18,18,18,18,19,18,18,18, 18,18,18,18,18,18,18,19,18,18,18,11,18

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.

TheDoctor
fuente