Lógica de decodificación RF (no codificada por Manchester) - Arduino

0

Continuando desde mi publicación anterior , estoy intentando decodificar los datos RF codificados directamente en Arduino. Adopté el enfoque de "muestreo" en comparación con el enfoque basado en "interrupción", por lo que creo que la línea de interrupción se usará para otros fines.

Después de haberlo escrito, y pasar un buen día tratando de depurarlo (la falta de un verdadero depurador es realmente revelador, ya que la consola de serie println () está realmente limitada debido a su lentitud), pero aún no puede parecer. a trabajar.

Aquí comparto la lógica (pseudocódigo), con la esperanza de que alguien pueda ayudarnos a detectar cualquier error obvio, o tal vez un problema de tiempo complejo menos obvio (que sospecho que es más probable).

En primer lugar, cómo se codifican los datos (que estoy tratando de decodificar): -

bit-0: IIII ---- ---- ---- IIII ---- ---- ----
bit-1: IIII IIII IIII ---- IIII IIII IIII ----
bit-F: IIII ---- ---- ---- IIII IIII IIII ---- ('Floating', used only in Addr-part)
bit-S: IIII ---- ---- ---- ---- ---- ---- ---- (sync-bit)

Cada I (alto) o - (bajo) es ~ 120 us (micro-seg) [en realidad oscila entre 118-121 us].

Entonces, decidí muestrear a intervalos de 30 us, es decir, 4 veces la frecuencia de la señal. En Arduino, uso delayMicroseconds (30) para obtener este efecto, aunque la lógica dentro del loop () es bastante pesada, ~ 150 líneas de código y hasta 4 niveles de if-nesting (solo para indicar la complejidad) de la lógica de transición de nivel, de la máquina de estado, de la técnica de patrones. El boceto Arduino compilado tiene un tamaño de ~ 2KB, solo para dar una indicación de la complejidad.

La transmisión de datos es una secuencia de 'Palabras en clave', donde cada palabra en clave es -

[ Addr(8-bits: 0/1/F) | Data (4-bits: 0/1) | Sync-bit ]

Y, un mínimo de 2 palabras en clave con la misma dirección se utilizan para algunas verificaciones de errores rudimentarias.

Entre 2 palabras de código sucesivas, hay un tiempo de todas las señales bajas.

También, la transmisión anterior a / válida es un ruido significativo en la línea, y mi observación es que las características del ruido son tales que no hubo un período continuo alto en el ruido que estuviera cerca del representación de máximos en el bit-1 codificado, pero hubo bastantes patrones en el ruido, cuyo período alto continuo coincidió con el del periodo alto para el bit-0 o la primera parte del bit-F / bit-S, es decir, podemos (con seguridad) asuma que estos patrones no existen en el ruido ...

---- ---- ----
IIII IIII IIII

pero estos hacen ...

----
IIII

Y, ahora mi lógica -

Decodificando la máquina de estados:     INICIAL - > DEC_CW1 - > DONE_CW1 - > DEC_CW2 - > DONE_CW2 - > INICIAL

Pseudocódigo de alto nivel:

1) Detect RF-data pin state
2) Check if there is a transition
3) If no transition, then just increment count of samples in same state (say SampleCount)
4) If transition, then 
4.1) Check, If SampleCount is in valid range to qualify towards an encoded bit
4.1.1) And, If CurrentState is INITIAL (i.e. before finding start of CW1)
4.1.1.1) Set CurrentState = DEC_CW1 (i.e. found start of CW1, potentially)
4.2.1) Or, If CurrentState is DONE_CW1 (i.e. before finding start of CW2)
4.1.1.1) Set CurrentState = DEC_CW2 (i.e. found start of CW2, potentially)
4.3.1) Or, If CurrentState is DEC_CW1 (i.e. already decoding CW1)
4.3.1.1) Is SamplePatternFor1Bit length enough to decode Bit
4.3.1.1.1) Yes, does it match 1BitPattern for 0 | 1 | F | S ?
4.3.1.1.1.1) Yes, then add it to CW1
4.3.1.1.1.2) No, then invalid pattern/error, discard all under-construction buffers, reset all counters and states & return from loop()
4.3.1.1.2) No, then continue loop()
4.4.1) Or, If CurrentState is DEC_CW2 (i.e. already decoding CW2)
4.4.1.1) Is SamplePatternFor1Bit length enough to decode Bit
4.4.1.1.1) Yes, does it match 1BitPattern for 0 | 1 | F | S ?
4.4.1.1.1.1) Yes, then add it to CW1
4.4.1.1.1.2) No, then invalid pattern/error, discard all under-construction buffers, reset all counters and states & return from loop()
4.4.1.1.2) No, then continue loop()
5) No transition,
5.1) Increment SampleCount (i.e. yet another sample in same state as before)
5.2) If SampleCount is 95-97 samples, all LOW then it indicates trailing end of S-bit pattern
5.2.1) Yes, If CurrentState is INITIAL (i.e. already decoding CW1)
5.2.1.1) Yes, means CW1 is complete, so Set CurrentState = DONE_CW1
5.2.1.2) Move under-construction CW, into saved CW1
5.2.2) Yes, If CurrentState is DEC_CW2 (i.e. already decoding CW2)
5.2.2.1) Yes, means CW1 is complete, so Set CurrentState = DONE_CW2
5.2.2.2) Move under-construction CW, into saved CW2
5.2.2.3) If CW1.Addr = CW2.Addr (same pattern) ?
5.2.2.3.1) Yes, then CW match, return CW2.data as the decoded Data from CW2.Addr as Addr
5.2.2.3.2) No, then discard all under-construction buffers, reset all counters and states & return from loop()
    
pregunta icarus74

1 respuesta

0

Mientras que la nota de la aplicación Atmel sobre las conversaciones de codificación / decodificación de Manchester de 2 enfoques - 1. Muestreo rápido 2. Usando interrupciones

Mi primer intento, como se muestra en esta pregunta, fue usar el método de muestreo rápido, pero no pudiendo hacer un progreso razonable, y la creciente complejidad de la lógica de muestreo, descodificación, análisis de comandos, cambié al método de interrupción. . Si uno sigue las "Preguntas vinculadas", encontrará cómo finalmente lo resolví. En pocas palabras, encontré que el método de interrupción es mucho más simple, y también creo que es algo más confiable y robusto contra los problemas de tiempo.

    
respondido por el icarus74

Lea otras preguntas en las etiquetas