Arduino - descodificación basada en descodificación de datos en serie, carrera entre ISR y bucle ()

1

Intentando decodificar datos seriales (codificados usando un método patentado) desde un módulo de RF.

Habiendo alternado entre muestreo rápido (4x el más rápido) y últimamente un método basado en interrupciones, he llegado a un punto muerto y no estoy seguro de lo que estoy haciendo mal, porque aparentemente las personas han tenido éxito en la decodificación de datos de RF de banda ISM (Manchester, NRZ , VirtualWire y HT12E / PT2260-62 codificado), en software.

En mi caso, el AGC de los módulos de RF (que no tengo idea de cómo apagar, ya que no hay hoja de datos, y la compañía no responde a los correos electrónicos ... una marca barata del este de Asia) capta el ruido y tiene las transiciones de nivel más rápidas en duraciones ~ 40us, aunque las transiciones válidas (datos codificados) no son menores que 400us. Mi ISR tiene la tarea elemental de medir la duración del último estado para rechazar el ruido no esencial y guardar solo las transiciones que podrían ser parte de los datos codificados. Hasta ahora, no he usado una cola circular (que es lo que planeo como el siguiente paso), pero antes de hacer eso, hice un pequeño experimento. En el ISR compruebo el estado de una bandera para ver si es verdadera, y si es verdad, hago Serial.print ("x"), de lo contrario, la configuro como verdadera. En el bucle (), compruebo si el indicador es verdadero, luego hago Serial.print ("-") y lo configuro como falso. La bandera se declara volátil. Encuentro que tengo flujos continuos muy largos de "x" s y muy raros "-". Mi ISR se está activando en cada transición del pin-2 (es decir, la interrupción externa # 0).

Ahora mi pregunta es, si agregar una cola realmente solucionaría mi problema, porque aparentemente el ISR se está ejecutando con demasiada frecuencia y por lo tanto está matando a mi ciclo () de ciclos. Al contar la distancia entre la "x" y "-", esperaba encontrar la longitud de cola ideal, pero no puedo encontrar un patrón. ¿Hay algo intrínsecamente incorrecto en mi enfoque?

Aquí encontrará un resumen del código fuente .

    
pregunta icarus74

2 respuestas

1

Es probable que desee tomar en cuenta el tiempo de transmisión (y los métodos de administración de software UART) de la rutina Serial.print ().

Si tiene acceso a un ámbito, alternar los pines de E / S sería mucho más rápido. Podría alternar uno en el ISR y el otro en el bucle.

O puede incrementar un contador en el ISR y muestrearlo / borrarlo en el bucle (dentro de una interrupción, desactivar / volver a habilitar) y luego imprimirlo (después de volver a habilitar las interrupciones). Más sofisticado sería imprimir solo el número si supera el máximo anterior.

Sin embargo, tales pruebas son fundamentalmente defectuosas, a menos que el código de prueba constituya una pequeña fracción de las operaciones de bucle, simplemente descifrar cuántas interrupciones pueden ocurrir durante una rutina de verificación / impresión máxima no tiene sentido en términos de la operación final que presumiblemente estar haciendo algo más en el bucle.

En general, deseará utilizar un búfer circular si está adquiriendo datos a través de una interrupción que debe agregarse en un ensamblaje más grande (bits en bytes o bytes en búferes) y luego actuar de una manera que sea siempre consumidor. No debería ser demasiado difícil cambiar el tamaño de su búfer más tarde para optimizar el consumo de memoria, especialmente si mantiene el tamaño de la potencia de dos. Es posible que desee crear alarmas de desbordamiento e intentar ejecutar el sistema terminado con un tamaño de búfer reducido artificialmente.

Preste mucha atención para asegurarse de que el ISR no pueda saltar en el medio del bucle que intenta actualizar las variables de seguimiento del búfer. Si realiza una lectura-modificación-escritura, deberá protegerlo.

    
respondido por el Chris Stratton
1

Muchos módulos de IR y RF están diseñados para producir resultados óptimos con una señal que tiene un ciclo de trabajo particular, y establecerán su umbral de conmutación en aproximadamente el nivel_recibido_de_desarrollado / (función_duty_duty_cycle * 2). Por ejemplo, si un dispositivo está diseñado para recibir una señal con un ciclo de trabajo de 1/3, el nivel de señal promedio recibido sería 1/3 del nivel de transmisión, por lo que la fórmula establecería un umbral de 1/2 del nivel de transmisión (dejando un margen de ruido de +/- la mitad del nivel de transmisión). Si se enviara a un dispositivo de este tipo una señal con un ciclo de trabajo de 1/2, establecería el umbral en 2/3 del nivel de transmisión, dejando solo 1/3 del nivel de transmisión como margen de ruido. Si un receptor está diseñado para datos codificados en Manchester (ciclo de trabajo del 50%), el umbral será simplemente el nivel de recepción promedio. Si está recibiendo más ruido de un lado o del otro, podría valer la pena averiguar si su receptor está diseñado para el ciclo de trabajo que se está enviando.

También sugeriría tomar la salida del receptor y alimentarla a través de un filtro RC. Esto puede generar un rechazo de fallos mucho mejor de lo que podría lograrse con el software solo. Si, por ejemplo, durante el intervalo en que se está transmitiendo un cero, la señal del receptor es baja el 99% del tiempo, pero ocurre que hay fallas en los momentos en que la CPU las muestra, la CPU puede pensar falsamente que es alta todo durante ese tiempo, pero el circuito del filtro RC emitiría correctamente una baja continua. Si usa un circuito de filtro RC, puede ser bueno usar una resistencia de polarización para asegurar que el retraso en los flancos ascendentes y descendentes sea aproximadamente igual. Si la entrada del procesador cambia a 1/3 de carril, por ejemplo, agregue una resistencia de polarización a Vss para que aparezca un "alto" de la radio como 2/3 VDD.

    
respondido por el supercat

Lea otras preguntas en las etiquetas