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

19 de jan de 2013

Acelerômetro Digital via I²C

Olá pessoal… depois do jejum de post’s resolvi postar algo um pouco mais complexo para me redimir um pouco… se bem que acredito que a leitura será interessante e muito agradável pois se trata de uma tecnologia atual e que já faz parte do nosso cotidiano, vamos implementar o uso de um acelerômetro digital com comunicação via I²C.

Acelerômetro

O acelerômetro consiste em um dispositivo micro eletromecânico (MEMS) que utiliza-se de nanotecnologia para construção de sensores que medem a grandeza de aceleração em objetos.

Acelerometro_GLB

Para conseguir efetuar a leitura desta grandeza, este componente possui em seu interior uma massa móvel contendo várias placas que interagem com placas fixas ao ci, formando desta maneira um sistema capacitivo que altera o valor da capacitância conforme o movimento da massa móvel, ou seja, a cada movimento no componente temos uma informação disponível relacionada a um dos eixos.

Zoom de 1500x em um MEMS da ST

mems II

A empresa ST Microeletronics desenvolve a muitos anos essa tecnologia e hoje conta com seus MEMS instalados em muitos equipamentos, desde pequenos brinquedos e controle de video games até os telefones de ultima geração.

Para este post, vamos utilizar o LIS3LV02DL que possui muitos recursos embutidos além de medir aceleração em três eixos e possuir comunicação via barramento I²C que é um dos mais utilizados para comunicação entre microcontroladores e seus periféricos, além de ter duas escalas de medição, uma medindo até 2 g e outra medindo até 6 g, sendo 1.0025 g o equivalente a uma aceleração de 9.8310 m/s².

Este componente é fornecido pela ST Microeletronics em uma placa de avaliação comercializada pelo código STEVAL-MKI009V1.

image_steval-mki009v1

DSC01323

Abaixo podemos observar a foto do acelerômetro LIS331, utilizado no iPhone 3GS comparado a uma moeda.

LIS331

Os acelerômetros podem apresentar duas formas de interfaceamento, sendo, digital ou analógico, nos analógicos as saídas correspondentes aos eixos informam a grandeza variando o nível de tensão DC no pino correspondente ao seu eixo, já no caso dos acelerômetros digitais, esses valores são transferidos via comunicação serial, podendo ser utilizado I²C ou SPI.

mems3

Este componente ainda conta com uma interrupção por movimentos, sendo possível efetuar o ajuste do nível de sensibilidade.

Curiosidade!!!

Alguns computadores antigos da Apple, contam com uma função que detecta uma possível queda de nível, fazendo com que a agulha do HD fosse para a posição de descanso a fim de não danificar o disco antes do impacto acontecer, pois bem, como é possível efetuar a detecção de queda livre?

R. Como todos sabemos, todos os corpos na terra sofrem a ação da gravidade, portanto o acelerômetro sempre estará sofrendo esta força, quando em queda livre de maneira linear, esta força tende a se anular pois o corpo acelera em relação ao eixo da terra e é neste momento que se pode detectar a queda livre ou free fall.

free fall


Interfaceamento 

Para interfacear o acelerômetro, temos que atentar para o fato da tensão de alimentação do mesmo que é de 3.3V ser diferente da tensão de alimentação da placa, para isto vamos utilizar um regulador externo de 3.3V além de dois resistores de pull up, este é um diferencial da placa PK2Lab, pois foi construída com o intuito de trabalhar com periféricos I²C com tensões de 3.3V ou 5V de forma simples e direta.
 
Vale lembrar que os microcontroladores PIC quando alimentados com uma tensão de 5V, entendem como nível lógico alto uma tensão superior a 2V, portanto podemos conectar os pinos TX e RX do acelerômetro nos pinos do microcontrolador que os níveis lógicos serão entendidos.
 
Comunicação I²C
 
A comunicação foi estabelecida pelo protocolo I²C na frequência de 100Khz  a 3.3V sendo respeitado a tabela de tempos conforme datasheet.
 
Para efetuarmos as leituras referentes aos eixos, primeiro precisamos configurar o acelerômetro para informar como desejamos receber os dados, para isto devemos seguir a seguinte sequência.
 

# Inicializar o barramento

# Informar o comando de escrita para o LIS3LV02DL

# Escrever o conteúdo do registrador CTRL_REG1 (Já vem indexado)

# Escrever o conteúdo do registrador CTRL_REG2

 

Após este procedimento podemos efetuar as leituras propriamente ditas seguindo a sequência abaixo.

# Inicializar o barramento

# Informar o comando de escrita para o LIS3LV02DL

# Informar qual o endereço desejamos ler inicialmente

# Reinicializar o barramento novamente

# Informar o comando de leitura para o LIS3LV02DL

# Efetuar a leitura de forma sequencialmente dos eixos

Por fim, como a leitura do acelerômetro se dá em 12 bits, precisamos concatenar esses dois bytes para obtermos a informação desejada para enfim apresentarmos os resultados no display LCD  e via porta serial.

 
Alguns registradores internos ao Acelerômetro
  • WHO_AM_I
    Endereço padrão deste CI no barramento I²C…
  • CTRL_REG1
    Configurações para habilitação de leitura dos eixos, self test…
  • CTRL_REG2
    Seleção de escala, interrupções…
  • CTRL_REG3
    Ajuste de clock e filtros passa alta…

 


Software

O software para este exemplo mede a aceleração dos 3 eixos em 12 bits apresentando os valores lidos no display LCD, e envia os dados periodicamente via porta serial para o terminal serial do PC a 9600bps.

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

                      JL Audio Manutenção Eletrônica

Data: 23/04/2011
Autor: Jean Carlos
Projeto: MEMS ST - Acelerômetro  ( LIS3LV02DL )
Microprocessador: PIC18F4550
Clock do processador: 8MHz
Estação de desenvolvimento: PK2Lab V1.1
Versão atual:  V 1.0
Descrição:

          Este projeto demonstra o uso de um MEMS(Sistema Micro eletromecânico)
          da ST, modelo LIS3LV02DL que se trata de um acelerômetro digital
          de 3 eixos (2G e 6G)


*******************************************************************************/
//Variáveis Globais

unsigned char XL,XH,YL,YH,ZL,ZH;
unsigned int X,Y,J;
char txt[7];


//****************************************************************
//Rotinas Auxiliares

void Le_Acelerometro()
      {
      I2C_Start();
      I2C_Wr(0x3A);     // Endereço do acelerômetro para escrita.
      I2C_Wr(0xA8);     // Endereço do registrador Eixo X Lower (0x28), ainda foi setado o sétimo bit do registrador para indicar a indexação automática do endereço.
      I2C_Repeated_Start();
      I2C_Wr(0x3B);     // Endereço do acelerômetro para leitura.
      XL = I2C_Rd(1);
      XH = I2C_Rd(1);
      YL = I2C_Rd(1);
      YH = I2C_Rd(1);   // Carrega as informações referentes aos eixos
      ZL = I2C_Rd(1);
      ZH = I2C_Rd(0);
      I2C_Stop();
      }
     
     
void Envia_Serial()
     {
     Usart_Write(X);
     Usart_Write(Y);
     Usart_Write(J);
     }
    
//****************************************************************
//Rotina Principal

void main()                               // Início do programa principal
{
TRISA = 0b00000000;
PORTA = 0b00000000;
TRISB = 0b00000000;
PORTB = 0b00000000;
TRISC = 0b00000000;
PORTC = 0b00000000;
TRISD = 0b00000000;
PORTD = 0b00000000;
TRISE = 0b00000000;
PORTE = 0b00000000;
ADCON1 = 0X0F;          // Entradas digitais.

Lcd_Config(&PORTB,2,3,1,7,6,5,4);  // Configuração PK2Lab V.1.1
Lcd_Cmd(Lcd_Cursor_Off);
Lcd_Cmd(Lcd_Clear);
Lcd_Out(1,1,"***  PK2Lab  ***");
Lcd_Out(2,1,"  Acelerometro  ");
Delay_ms(3000);
Lcd_Cmd(Lcd_Clear);
Lcd_Out(1,1,"X:");
Lcd_Out(2,1,"Y:");
Lcd_Out(2,9,"Z:");

Usart_Init(9600);  // Inicia comunicação RS232
I2C_Init(100000);  // Inicia comunicação I2C


   I2C_Start();                          // Inicia comunicação I2C
   I2C_Wr(0x3A);                     // Endereço do LIS3LV02DL para escrita
   I2C_Wr(0xA0);                     // Primeira palavra de endereço inicia pelo registrador CTRL_REG1 (0x20) , escrita contínua…
   I2C_Wr(0xC7);                     // 11000111 ---> CTRL_REG1  C7
   I2C_Wr(0x04);                      // 00000100 ---> CTRL_REG2  04
   I2C_Stop();

 

while(1)
{
Le_Acelerometro();          // Efetua a leitura de aceleração dos 3 eixos
Delay_ms(100);

X = (XH);                         // Concatena as partes altas e baixas dos registradores.
X = (X<<8) + XL;

Y = (YH);
Y = (Y<<8) + YL;

J = (ZH);           // Foi usado J no lugar de Z pois Z o compilador usa como Zero
J = (J<<8) + ZL;

intToStr(X,txt);                
Lcd_Out(1,3,txt);
intToStr(Y,txt);
Lcd_Out(2,3,txt);
intToStr(J,txt);
Lcd_Out(2,11,txt);

Envia_serial();                // Envia os dados pela porta serial a 9600bps

}//while(1)
}//main


Vídeos do projeto

Neste vídeo podemos observar o projeto em funcionamento.

Neste outro vídeo, vemos o acelerômetro controlando um equipamento de iluminação profissional (Moving Head) onde controlamos PAN e TILT através da leitura dos eixos X e Y respectivamente.

 

Gostaria de agradecer imensamente ao Eng. André Braz, representante da empresa ST Microelectronics no Brasil, que gentilmente cedeu algumas peças destas incríveis máquinas assim como muita informação técnica! Valeu André!!!

Bom pessoal, por hoje é isto, grande abraço a todos e bons projetos!