Skip to content

06_Decodificador PPM

José Fernando Picó Antolí edited this page Jan 22, 2022 · 39 revisions

Decodificador PPM

  • Podemos encontrar el código en el repositorio Código fuente Decodificador

  • Vamos a realizar un pequeño circuito digital que se encargará de decodificar los pulsos PPM que se recibirían por ejemplo de un mando de Radio Control, en el ejemplo, haremos la decodificación de una trama de pulsos donde hay 8 canales codificados.

  • En la siguiente figura mostramos una trama de pulsos PPM ( 8 canales ) que recibirá el sistema digital encargado de decodificarlos y haremos una pequeña explicación de dicha trama.

Trama PPM 8 Canales

  • En la parte de arriba podemos ver la trama (8 canales) que se recibirá, como se trata de una trama de 8 canales, tendremos un total de 9 pulsos seguidos de una pausa y luego se repetirá la trama ( 9 pulsos + pausa ... ). La codificación de cada canal viene dada por el tiempo que transcurre entre pulsos, por lo que el primer canal se codifica por el tiempo que transcurre desde el primer pulso al segundo pulso, el segundo canal por el tiempo que transcurre desde el segundo pulso al tercero... y el canal 8 por el tiempo que transcurre desde el 8º pulso al 9º, y tras una pausa determinada se volverá a inyectar otra trama de pulsos nuevos con la codificación de los 8 canales.

  • En la parte del medio vemos la trama invertida, esta suele ser la forma real como se recibirían las tramas ya que es más eficiente la transmisión RC con la señal invertida.

  • En la parte inferior se pretende mostrar que con cada pulso recibido nuestro sistema digital recibirá un pulso de entrada (flanco positivo) con el cual gestionará la máquina de estados adecuada. Se empleará por lo tanto un detector de flancos negativos para crear dichos pulsos.

  • Como la distancia entre pulsos será un valor bajo ( entre [0.8-2.5 ms] en sistemas de radio control normales ), utilizaremos ese tiempo máximo para saber si estamos en la pausa de la trama o no, digamos que lo utilizaremos para sincronizar la señal y saber donde nos encontramos ya que la señal se podría perder momentáneamente, o algún pulso se podría perder y se estaría decodificando el canal incorrecto ( corrimiento de los canales) por lo cual se hará uso de un contador de overflow/sincronismo para detectar cuando hay una pausa mayor de 4 ms y así poder llevar la máquina de estados a su punto de partida inicial y saber que el próximo pulso entrante será el inicio del canal 1. Los pulsos PPM recibidos se usarán a su vez para resetear el contador de overflow/sincronismo de forma que entre los pulsos PPM recibidos nunca se desbordará el contador ya que nunca pasarán más de 4 ms y solo cuando aparezca la pausa entre tramas se reseteará llevando la máquina al estado inicial.

  • En la siguiente figura mostramos un esquema del sistema digital a crear.

Decodificador PPM 8 Canales

  • En la figura podemos distinguir el Datapath que estará formado por todos los recursos que nuestro sistema digital necesita y que serán controlados por nuestra máquina de estados que se realizará a partir de un diagrama de estados ASMD usando así los conceptos vistos hasta aquí.

  • El DATAPATH estará formado por:

    • Módulo de sincronismo. Como el sistema digital es controlado al ritmo de un reloj de sistema común que gobierna a golpe de flancos de reloj el sistema digital y la señal que se recibe es una señal asícrona ( que llega en cualquier momento), esta se debe sincronizar con la señal de reloj del sistema, este módulo sincronizador está basado en dos biestables D en cascada.
    • Detector de flanco negativos. Dicho Módulo se encargará de crear un pulso positivo con la llegada de cada flanco negativo al sistema, este pulso será el que gobierne el ritmo de la máquina de estados.
    • Contador de Overflow (4ms). Dicho contador es el encargado de la sincronización entre trasmas PPM.
    • Varias puertas OR. Encargadas de resetear la máquina de estado cuando el sistema recibe una señal de reset o el reseteo del contador de overflow con la llegada de cada pulso PPM y reseteo de la máquina de estados si el contador se desborda ( sincronismo entre tramas PPM ).
  • La Máquina de ESTADOS encargada de controlar el DATAPATH se puede ver como una caja negra en la siguiente figura que contendrá la máquina ASMD propiamente dicha.

Máquina de ESTADOS

DATAPATH

  • El SINCRONIZADOR será el mostrado en las siguientes figuras:

CajaNegra_Sinc Sincronizador

  • El DETECTOR DE FLANCO NEGATIVO sería:

Detector_FlancoNeg Detector_FlancoNeg

  • El CONTADOR DE OVERFLOW DE 4ms sería:

Overflow 4ms Overflow 4ms

MÁQUINA ASMD

  • Siguiendo lo visto hasta este punto vamos a crear el Algoritmo ASMD necesario para implementar la máquina de estados deseada para controlar el DATAPATH que compone nuestro sistema digital, para ello recordamos la composición de un bloque ASMD en la siguiente figura:

Bloque ASMD

ALGORITMO ASMD

  • Para realizar nuestro ALGORITMO ASMD nos basamos en el tren de pulsos PPM que recibe el sistema, podemos ver el algoritmo creado en la siguente figura:

ASMD

  • Explicación del Algoritmo:

    • Vamos a crear un bloque que cumplirá el Algoritmo ASMD que desarrollaremos, este bloque tiene 3 entradas ( reloj del sistema, In_PPM_neg por donde se reciben los pulsos de PPM, reset resetear la máquina y llevarla al estado inicial S0) y 8 salidas por donde se crean los pulsos decodificados de cada canal ( estos atacarían a 8 servos distintos ).

    • El Algoritmo está formado por 9 bloques ASDM que corresponderá con cada uno de los estados por los que se compone el sistema y donde hay que tener en cuenta que el contenido de cada bloque ( cambios de señales/decisiones, etc) se realiza al completo en cada ciclo de reloj del sistema ( 12MHz en nuestra Alhambra II ) .

    • El algoritmo parte del estado S0 al cual se llega al iniciar el sistema o al sufrir este un reset, estando en el estado S0 con cada ciclo de reloj se irán realizando las comprobaciones pertinentes para saber si nos mantenemos o no en dicho estado, mientras no se reciba ningún pulso PPM de entrada el sistema se mantiene en el estado S0 y cuando se recibe un pulso PPM se activará la señal del canal 1 (CH1) y se pasará al estado siguiente S1 donde por el hecho de estar en el estado S1 el canal CH1 se mantiene a 1 mientras no llegue otro pulso PPM, en el momento que llegue otro pulso PPM la señal CH1 se desactiva y se activa la señal del canal 2 (CH2) y se pasará al estado S2 donde se mantiene el canal 2 a 1 mientras no se reciba otro pulso PPM, así sucesivamente se irá pasando de un estado a otro con la llegada de cada uno de los pulso PPM y con la llegada el 9º pulso PPM se finalizará la trama completa de los pulsos PPM y se volverá al estado inicial S0 esperando el inicio de una nueva trama de pulsos PPM.

    • Por la señal de reset se lleva la máquina de estado al estado inicial y si recordamos lo dicho antes, hay un componente del DATAPATH ( contador de overflow) que se encargará de llevar la máquina de estado inicial si hay un desbordamiento pudiendo sincronizar las señales de los canales con el sistema digital en caso de pérdida de señal momentánea.

Codificación del ALGORITMO ASMD a VERILOG

  • Una vez realizado el Algoritmo ASMD vamos a traducirlo a verilog, para ello vamos a realizarlo usando el **ESTILO B" explicado en este repositorio. ESTILO B

  • Mostramos el código en la siguiente caja de código.

  • El bloque resultante sería:

ASMD

  • Por InPPM_neg recibimos los pulsos PPM en modo invertido ( la tramsmisión en modo invertido es más eficaz)
  • Por el pin reset podemos volver al estado inicial
  • clk reloj del sistema
  • Por los pines de salida CH1, CH2, CH3, CH4, CH5, CH6, CH7 y CH8 obtenemos la señal decodificada de cada canal que será un pulso de amplitud equivalente al tiempo entre dos pulsos PPM. valor entre 0.2-0.3 ms a unos 2.2-2.3 ms que puede atacar a un servo.
  • (Estos valores dependen del servo)
parameter [3:0] S0=0, S1=1, S2=2, S3=3, S4=4, S5=5, S6=6, S7=7, S8=8;              //Poner nombres a los estados

reg Ch1=0, Ch2=0, Ch3=0, Ch4=0, Ch5=0, Ch6=0, Ch7=0, Ch8=0;                        //Inicializo canales

reg [3:0]  estadoActual=0, estadoNext=0;                                           //Inicializo estados

// bloque secuencial. Capturar estado Actual

always @(posedge clk )
if(reset) estadoActual <= S0; 
else estadoActual <= estadoNext;



// Bloque combinacional. Calculamos estado siguiente y valor de las
// salidas en función de las entradas y del estado actual.

always @(reset or InPPM_neg or estadoActual)  //  estado siguiente = función ( entradas y estado actual)
begin

  //valores por defecto. justo antes del case pongo valores por defecto y en el case solo cambiamos
  //la salida que se ve afectada y las demás tomarán los valores por defecto

  Ch1   = 0;   Ch2   = 0;   Ch3   = 0;   Ch4   = 0; 
  Ch5   = 0;   Ch6   = 0;   Ch7   = 0;   Ch8   = 0;
  estadoNext   = 'bx; 
  
  case(estadoActual)  //Evaluación del estado actual
     S0:begin                                   
        if( InPPM_neg  )  begin   estadoNext = S1;   Ch1 = 1'b1;   end 
        else                      estadoNext = S0;  
        end
     S1:begin                                   
        if( InPPM_neg  )  begin   estadoNext = S2;   Ch2 = 1'b1;   end 
        else              begin   estadoNext = S1;   Ch1 = 1'b1;   end
        end
     S2:begin                                   
        if( InPPM_neg  )  begin   estadoNext = S3;   Ch3 = 1'b1;   end 
        else              begin   estadoNext = S2;   Ch2 = 1'b1;   end
        end
     S3:begin                                   
        if( InPPM_neg  )  begin   estadoNext = S4;   Ch4 = 1'b1;   end 
        else              begin   estadoNext = S3;   Ch3 = 1'b1;   end
        end
     S4:begin                                   
        if( InPPM_neg  )  begin   estadoNext = S5;   Ch5 = 1'b1;   end 
        else              begin   estadoNext = S4;   Ch4 = 1'b1;   end
        end
     S5:begin                                   
        if( InPPM_neg  )  begin   estadoNext = S6;   Ch6 = 1'b1;   end 
        else              begin   estadoNext = S5;   Ch5 = 1'b1;   end
        end
     S6:begin                                   
        if( InPPM_neg  )  begin   estadoNext = S7;   Ch7 = 1'b1;   end 
        else              begin   estadoNext = S6;   Ch6 = 1'b1;   end
        end
     S7:begin                                   
        if( InPPM_neg  )  begin   estadoNext = S8;   Ch8 = 1'b1;   end 
        else              begin   estadoNext = S7;   Ch7 = 1'b1;   end
        end
     S8:begin                                   
        if( InPPM_neg  )          estadoNext = S0;
        else              begin   estadoNext = S8;   Ch8 = 1'b1;  end
        end
     default:                     estadoNext = S0;
   endcase
end

CONCLUSIONES

  • Se ha realizado un Decodificador PPM siguiendo la metodología mostrada en este repositorio para crear sistemas digitales usando la creación de algoritmos ASMD para intentar clarificar un poco más la teoría con un caso práctico implementado y probado en la FPGA Alhambra II.

  • Podemos encontrar el código en el repositorio Código fuente Decodificador

  • Aquí un pequeño gif de una prueba donde se inyectaban 8 canales PPM distintos de forma repetitiva ( solo uso 5 Servos porque no tenía más pero se probaron en las 8 posiciones de salida ).

Vídeo

Clone this wiki locally