sexta-feira, 27 de março de 2015

Controle remoto com PIC - Parte 1

             Olá, hoje vou demonstrar como montar um controle remoto com o PIC e também como montar um receptor de controle remoto, a ideia inicial era montar apenas o decodificador(receptor do controle remoto) mas para isso eu precisava simular um controle remoto a medida que montava todo o firmware então acabei montando também o simulador de controle remoto(codificador), mas eu também queria que meu circuito reconhecesse pelo menos uns 4 tipos de marcas para que vocês pudessem testar em casa sem grandes dificuldades, então peguei 4 marcas mais vistas no mercado: LG, PHILIPS, SAMSUNG e SONY.Então comecei a ver a forma de ondas no osciloscópio e levantar informações(o que não é tão simples de encontrar), dai encontrei sobre a Sony e a Lg(protocolo NEC) embora o padrão da Samsung é o mesmo mas com diferença no tamanho do pulsos, o padrão Philips deu um pouco mais de trabalho pois não possuem um bit de "start".
               A característica do padrão NEC é a presença de um bit de inicio(start bit) e outro de fim(stop bit) e mais 1 ou 2 bits após o "stop bit", sendo que antes do "stop bit" existe um espaço de 46ms(padrão samsung) ou 44ms(LG), ao todo são 33bits, no padrão Sony existe um "start bit" e em seguida 12 bits(mas no circuito montado foi lido somente 11 mas deve ser devido ao fato de eu estar ignorando os espaços entre os bits mas isso não atrapalha o reconhecimento) que é enviado 3 vezes em intervalos de 27ms . Já o padrão Philips não tem "stop bit" e nem "start bit" ao todo dá 10bits. Veja como é a onda gerada pelo controle remoto do PIC:
               veja que não coloquei  a onda inteira do padrão NEC (LG e Samsung) para facilitar a visualização mas abaixo coloquei a onda completa do padrão samsung para dar uma idéia, a diferença entre Samsung e LG é o tamanho do "start bit":

           Os bits "0" e "1" se diferenciam pelo tempo em que dura o nível alto e o nível baixo, se tempo iguais vale 0 se os tempos forem diferentes nível alto,mas para facilitar a decodificação eu peguei o valor do período do sinal ou seja na borda de subida do sinal, o valor desses períodos não são padrões cada fabricante escolhe o seu, mas o da Samsung e LG são iguais os bits "0" e "1"(talvez por usar o mesmo protocolo e com diferença apenas no "start bit").
         Vamos agora ao código fonte do codificador de controle remoto, vale lembrar que colocando um led infravermelho ele deve acionar uma tv, bastando para isso fazer pequenas alterações neste código fonte(não testei na TV ainda pois gerei ele só pra testar o decodificador):

O código fonte:

/*
 *                               Emulando um controle remoto de TV no MPlab XC8
 *
 * Compilador : MPlabXC8
 * Microcontrolador: 16F628A
 * Autor: aguivone
 * Versão: 1
 * Data :  16 de março de 2015
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h> //para usar funçoes de string deve se adicionar este header
#define _XTAL_FREQ 4000000    // oscilador interno de 4 Mhz
#include <xc.h>
#include <delays.h>
/////////////////////////////////////////////////////////configuraçôes//////////////////////////////////////////////////
#define LED_STATUS RB0
#define LED_STATUS RB0


#pragma config FOSC = INTOSCIO  // Oscillator Selection bits (INTOSC oscillator: I/O function on RA6/OSC2/CLKOUT pin, I/O function on RA7/OSC1/CLKIN)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = OFF      // RA5/MCLR/VPP Pin Function Select bit (RA5/MCLR/VPP pin function is digital input, MCLR internally tied to VDD)
#pragma config BOREN = ON       // Brown-out Detect Enable bit (BOD enabled)
#pragma config LVP = OFF        // Low-Voltage Programming Enable bit (RB4/PGM pin has digital I/O function, HV on MCLR must be used for programming)
#pragma config CPD = OFF        // Data EE Memory Code Protection bit (Data memory code protection off)
#pragma config CP = OFF         // Flash Program Memory Code Protection bit (Code protection off)

long tempo_us1=0;

void interrupt interrupcao(void)//vetor de interrupção
 {
    if(T0IF)
    {//interrupção do timer0 - estoura quando atinge 255(0XFF)- estoura a cada 62.5us
        if(tempo_us1>0)
        {
            tempo_us1--;
        }
        TMR0 = 254;//reinicia timer com o valor calculado
        T0IF = 0;
        //62.5us + os delay da rotinas  = 75us
    }
 }

void inicializa_timer0()
{
    OPTION_REG = 0X03;//timer0 com prescaler dividido por 16
    T0IE = 1;//habilita interrupção do timer0
    TMR0 = 254;//zera registrador de contagem
}

void envia_bit(char protocolo,int val)
{
    switch(protocolo)
    {
        case 'G'://Samsung
        {
             if(val == 0)
            {//bit 0
             LED_STATUS = 1;
             __delay_us(560);
             LED_STATUS = 0;
             __delay_us(560);
            }
            else
            {//bit 1
             LED_STATUS = 1;
             __delay_us(560);
             LED_STATUS = 0;
             __delay_ms(1);
             __delay_us(680);
            }

        }break;
        case 'L'://LG 
        {
             if(val == 0)
            {//bit 0
             LED_STATUS = 1;
             __delay_us(560);
             LED_STATUS = 0;
             __delay_us(560);
            }
            else
            {//bit 1
             LED_STATUS = 1;
             __delay_us(560);
             LED_STATUS = 0;
             __delay_ms(1);
             __delay_us(680);
            }

        }break;
        case 'S'://sony
        {
                        if(val == 0)
            {//bit 0
             LED_STATUS = 1;
             __delay_us(600);
             LED_STATUS = 0;
             __delay_us(600);
            }
            else
            {//bit 1
             LED_STATUS = 1;
             __delay_ms(1);
             __delay_us(200);
             LED_STATUS = 0;
             __delay_us(600);
            }
        }break;
        case 'P'://
        {
           if(val == 0)
            {//bit 0
             LED_STATUS = 1;
             __delay_us(890);
             LED_STATUS = 0;
             __delay_us(890);
            }
            else
            {//bit 1
             LED_STATUS = 1;
             __delay_ms(1);
             __delay_us(800);
             LED_STATUS = 0;
             __delay_us(890);
            }

        }break;
    }
   
}

void envia_start_bit(char proto)
{
    switch(proto)
    {
    case 'L'://LG
    {
        LED_STATUS = 1;
        __delay_ms(9);
        LED_STATUS = 0;
        __delay_ms(4);
        __delay_us(500);
    }break;
   case 'G'://samsung
    {
        LED_STATUS = 1;
        __delay_ms(4);
        __delay_us(500);
        LED_STATUS = 0;
        __delay_ms(4);
        __delay_us(500);
    }break;
    case 'S'://sony
    {
        LED_STATUS = 1;
        __delay_ms(2);
        __delay_us(400);
        LED_STATUS = 0;
        __delay_us(600);
    }break;
    case 'P'://philips
    {
        LED_STATUS = 1;
        __delay_ms(1);
        __delay_us(800);
        LED_STATUS = 0;
        __delay_ms(1);
        __delay_us(800);
    }break;
}
}
void simula_pacote(char protocolo)
{
    switch(protocolo)
    {
        case 'L'://LG
        {
           envia_start_bit(protocolo);
           int temp = 0;
           while(temp<=10)//envia 10 bits 0
           {
              envia_bit(protocolo,0);
              temp++;
           }
           while(temp<=33)//envia 23 bit 1
           {
              envia_bit( protocolo,1);
              temp++;
           }
           __delay_ms(44);
           envia_start_bit(protocolo);
           envia_bit(protocolo,0);
           envia_bit(protocolo,1);
        }break;
       case 'G'://samsung
        {
           envia_start_bit(protocolo);
           int temp = 0;
           while(temp<=10)//envia 10 bits 0
           {
              envia_bit(protocolo,0);
              temp++;
           }
           while(temp<=33)//envia 23 bit 1
           {
              envia_bit( protocolo,1);
              temp++;
           }
           __delay_ms(46);
           envia_start_bit(protocolo);
           envia_bit(protocolo,0);
           envia_bit(protocolo,0);
        }break;
       case 'S'://sony
        {
           int envio = 0;
           while(envio<3)
           {
           envia_start_bit(protocolo);
           int temp = 0;
           while(temp<=6)//envia 6 bits 0
           {
              envia_bit(protocolo,0);
              temp++;
           }
           while(temp<=13)//envia 6 bit 1
           {
              envia_bit( protocolo,1);
              temp++;
           }
           __delay_ms(27);
           envio++;
           }
        }break;
        case 'P'://philips
        {
           int temp = 0;
           while(temp<3)//envia 2 bits 0
           {
              envia_bit(protocolo,0);
              temp++;
           }
           while(temp<7)//envia 4 bit 1
           {
              envia_bit( protocolo,1);
              temp++;
           }
           envia_start_bit(protocolo);
           while(temp<11)//envia 3 bit 1
           {
              envia_bit( protocolo,1);
              temp++;
           }
        }break;
    }
}
//////////////////////////////////////////////////////Rotina principal///////////////////////////////////////////////////////////////

void main(void) {
    TRISB = 0;//configura portB  como saida
    PORTB = 0;  // limpar as portas que estão configuradas como saidas
   // inicializa_timer0();
    PEIE = 1;//habilita interrupção de perifericos do pic
    GIE = 1; //GIE: Global Interrupt Enable bit
    for(;;)
    {
         simula_pacote('L');//simula um sinal de controle remoto LG
         __delay_ms(2000);//minimo de 100ms entre cada pacote mas para os teste vou colocar 5s
         simula_pacote('G');//simula um sinal de controle remoto Samsung
         __delay_ms(2000);//minimo de 100ms entre cada pacote mas para os teste vou colocar 5s
         simula_pacote('S');//simula um sinal de controle remoto Sony
         __delay_ms(2000);//minimo de 100ms entre cada pacote mas para os teste vou colocar 5s
         simula_pacote('P');//simula um sinal de controle remoto Philips
         __delay_ms(2000);//minimo de 100ms entre cada pacote mas para os teste vou colocar 5s

    }//loop infinito

}


Na segunda parte vou mostrar o código do receptor e mais algumas informações.


2 comentários :

olá,digite aqui seu comentário!