29 de set de 2013

Interface PPM - Usando rádio controle de modelismo

 

E ai pessoal, tudo certo?  estou voltando aos post’s e gostaria de apresentar a vocês um projeto bacana para quem pretende conciliar duas áreas distintas porém que trazem muitas alegrias a quem lhes concede tempo e empenho, são elas a eletrônica embarcada e o modelismo!

 

foto

 

Que tal desenvolvermos um software para agregarmos funções aos nossos modelos? ou quem sabe incrementarmos aquele robô em desenvolvimento para que possamos obter distâncias maiores além de podermos utilizar vários rádios disponíveis no mercado a preço atraentes… bora lá!!!

Bom para tanto precisamos entender como funciona o sistema de rádio controle destes utilizados no modelismo, não importando qual área de modelismo se aplica, tanto auto, aero ou helimodelismo utilizam a mesma técnica de controle que se dá através de controle PPM.

Controle PPM

PPM (Pulse Position Modulation) é a técnica de controle de servos e outros dispositivos utilizados em modelismo que consiste da modulação por posicionamento de pulso, esta técnica já foi vista anteriormente no blog quando abordamos o  controle de servomotores e mostramos como gerar os pulsos para controlarmos os dispositivos atuadores (servos).

 

servo-pwm_w400

 

A abordagem desta vez será inversa, ou seja, iremos aprender a ler um pulso proveniente de um receptor de aeromodelismo a fim de criarmos nossos próprios atuadores, que podem ser chaves digitais On-Off, saídas de tensão proporcionais aos valores dos Sticks do rádio, sistemas de iluminação, automáticos para trens de pouso, sequenciadores de portas, enfim, o que sua imaginação lhe proporcionar!

 

Rádios e Receptores

Atualmente os sistemas de radio controle para modelismo sofreram uma merecida atualização no que diz respeito ao meio de comunicação entre rádio e receptor, várias técnicas já foram utilizadas, sendo elas AM(Amplitude Modulada), FM (Frequência Modulada) muito comum até então e por fim a mais utilizada atualmente, a 2.4GHz que utiliza um protocolo baseado em salto de frequência, mais isso no momento não é o foco do nosso projeto, iremos nos concentrar apenas no sinal PPM já processado pelo receptor.

 

SPM18800-GAL01

 

Neste exemplo vamos utilizar um receptor DSMX2 da marca Orange, que possui uma taxa de repetição de frames a cada 22ms, cada frame varia então de 1ms a 2ms correspondentes a posição do Stick do rádio, a alimentação do receptor é de 5V sendo alimentado pela própria placa PK2Lab.

 

70170

 

 

Processamento do sinal PPM

Para efetuarmos a análise do sinal PPM pelo microcontrolador podemos efetuar a medição do tempo em que o sinal permanece em nível alto, para isto vamos utilizar o recurso CAPTURE do modulo CCP1 do PIC 16F887.

 

Sinal captura com Stick centrado

 

Bom, temos agora que começar configurando o TMR1 do PIC16F887 para incremento a cada 1us,  e a borda de interrupção do módulo CCP1 para captura na borda de subida, assim que este evento for detectado, zeramos os contadores de 16 bits do TMR1 e alteramos a borda de captura para detectar o momento exato em que esse sinal volta a nível baixo, quando isso ocorrer os registradores do TMR1 irão conter o valor exato correspondente diretamente ao tempo em que o sinal permaneceu alto, esse tempo é um espelho do posicionamento do stick do controle.

Vale observar que a mudança de sensibilidade de borda do módulo CCP1 gera o disparo errôneo desta interrupção, portanto, temos que tomar a precaução de manter desabilitada essa interrupção durante esta mudança de borda.

 

Programa

 

/******************************************************************************

                      JL Audio Manutenção Eletrônica

Data: 09/2013
Autor: Jean Carlos
Projeto: Decodificador de sinais PPM
Microprocessador: PIC16F887
Clock do processador: 8MHz
Estação de desenvolvimento: PK2Lab
Compilador: MikroC PRO V4.60.0.0
Versão atual:  1.0
Descrição:

              Este projeto consiste em decodificar os sinais PPM
              provenientes da saída de um receptor de rádio controle


*******************************************************************************/
// Configuração do LCD da placa PK2Lab V.1.1

sbit LCD_RS at RB2_bit;
sbit LCD_EN at RB3_bit;
sbit LCD_D4 at RB4_bit;
sbit LCD_D5 at RB5_bit;
sbit LCD_D6 at RB6_bit;
sbit LCD_D7 at RB7_bit;

sbit LCD_RS_Direction at TRISB2_bit;
sbit LCD_EN_Direction at TRISB3_bit;
sbit LCD_D4_Direction at TRISB4_bit;
sbit LCD_D5_Direction at TRISB5_bit;
sbit LCD_D6_Direction at TRISB6_bit;
sbit LCD_D7_Direction at TRISB7_bit;


//Variáveis Globais

char txt[7];
unsigned int Tempo_L, Tempo_H, Pulso;

//Interrupções

void interrupt()
{
if(CCP1IF_bit && CCP1CON.B0)  // Captura por CCP1 e borda como subida...
{
  CCP1IF_bit  = 0;            // Limpa a flag para nova captura
  CCP1IE_bit  = 0;            // Desabilita interrupção por periféricos(CCP1)
  CCP1CON     = 4;          // Configura a borda de captura para DESCIDA.
  CCP1IE_bit  = 1;            // Habilita interrupção por periféricos(CCP1)
  TMR1H       = 0;             // Zera registradores do TMR1 para contagem de tempo
  TMR1L       = 0;
  TMR1ON_bit  = 1;          // Habilita contagem de tempo.
}

else if(CCP1IF_bit)
      {
       CCP1IF_bit  = 0;       // Limpa a flag para nova captura
       TMR1ON_bit  = 0;     // Desabilita contagem de tempo.
       CCP1IE_bit  = 0;       // Desabilita interrupção por periféricos(CCP1)
       CCP1CON     = 5;     // Configura a borda de captura para SUBIDA.
       CCP1IE_bit  = 1;       // Habilita interrupção por periféricos(CCP1)
       Tempo_H     = CCPR1H; 

       Tempo_L     = CCPR1L;  // Carrega valores de tempo   capturado           
      }

}

//Rotina Principal

void main()
{
TRISD  = 0b00000000;
TRISE  = 0b00000000;
TRISC  = 0b00000100;         // Entrada CCP1
PORTC  = 0b00000000;
ANSEL  = 0b00000000;       // Entradas digitais.
ANSELH = 0b00000000;      // Entradas digitais.
INTCON = 0b11000000;       // Liga interruptores GIE e PEIE
TMR1IE_bit = 0;                 // Desabilita interrpções de TMR1
CCP1IE_Bit = 1;                 // Habilita interrupções por CAPTURA(CCP1)
CCP1CON    = 5;                // CCP1 para CAPTURA borda de SUBIDA.

T1CKPS1_bit = 0;               // Prescaller TMR1 2:1
T1CKPS0_bit = 1;
TMR1CS_bit  = 0;               // Clock selecionado -> OSC/4
TMR1ON_bit  = 0;               // Timer -> 1 = Habilita contagem


Lcd_Init();
Lcd_Cmd(_Lcd_Cursor_Off);
Lcd_Cmd(_LCD_CLEAR);
Lcd_Out(1,1,"***  PK2Lab  ***");
Lcd_Out(2,1,"Pulso us:       ");
Delay_ms(100);

while(1)
{
Delay_ms(100);                               // Intervalo entre leituras.
Pulso = (Tempo_H<<8)+ Tempo_L;   // Obtenção do pulso PPM
IntToStr(Pulso, txt);                         // Converte texto para impressão
Lcd_Out(2,11,txt);                           // Mostra Pulso em us no display

if(Pulso > 1600) PORTE.B1 = 1;
    else          PORTE.B1 = 0;

if(Pulso > 1100) PORTD.B0 = 1;
    else          PORTD.B0 = 0;

if(Pulso > 1200) PORTD.B1 = 1;
    else          PORTD.B1 = 0;

if(Pulso > 1300) PORTD.B2 = 1;
    else          PORTD.B2 = 0;
   
if(Pulso > 1400) PORTD.B3 = 1;
    else          PORTD.B3 = 0;

if(Pulso > 1500) PORTD.B4 = 1;
    else          PORTD.B4 = 0;

if(Pulso > 1600) PORTD.B5 = 1;
    else          PORTD.B5 = 0;

if(Pulso > 1700) PORTD.B6 = 1;
    else          PORTD.B6 = 0;

if(Pulso > 1800) PORTD.B7 = 1;
    else          PORTD.B7 = 0;
   
   
}//while(1)
}//main

/******************************************************************************

 

Vídeo do projeto