Autor Tema: Mando a distancia infrarrojo  (Leído 2938 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado micro_pepe

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3206
Mando a distancia infrarrojo
« en: 03 de Diciembre de 2008, 20:39:56 »
Buenas, pretendo hacer un control de volumen digital con mando a distancia. De momento estoy programando el mando a distancia, tengo este programa de prueba, es muy parecido al dimmer con mando de Nocturno, en el cual pongo dos led de prueba para encenderlos y apagarlos.

El problema es que despues de memorizar las teclas del mando, se encienden o apagan los dos led al mismo tiempo con casi cualquier tecla del mando.

Código: [Seleccionar]
//****************************************************************************//
// Version CCS 3.242
//****************************************************************************//
# include <16F84a.h>
# use delay(clock=4000000)
# fuses XT,NOWDT,NOPUT,NOPROTECT

#byte PORTA                = 0x05
#byte PORTB                = 0x06
#bit  GRABAR               = PORTA.0
#bit  ZUMBADOR             = PORTA.1
#bit  SALIDA_1             = PORTA.2
#bit  SALIDA_2             = PORTA.3
#bit  MANDO                = PORTB.0

#define Periodo            190
#define SI                 1
#define NO                 0
#define ON                 1
#define OFF                0
//********************************* VARIABLES ********************************//
int1 PermisoLeer;//Impide la lectura de una tecla despues de acabar de leerla.

int8 Pasos;//se incrementa cada vuelta del timer, capturando un bit del mando.

int32 LecturaMando;//Almacena la lectura de una tecla pulsada.

int32 LecturaMandoTemporal;//Almacena temporalmente la lectura de una tecla
                           //pulsada, para su posterior comprobación.

int8 EstadoProceso;//Cuando se pulsa la tecla GRABAR, va pasando por todas las
                   //teclas que se están programando, en primera pasada se
                   //captura la tecla; en segunda pasada se captura de nuevo y
                   //se comprueba.
int8 Direccion;//Almacena la dirección de la EEPROM donde se guardan las teclas.

int32 IncVol;//Tecla incrementar volumen.

int32 DecVol;//Tecla decrementar volumen.

int32 CanalSel;//Tecla seleccion del canal.

int32 Bal_L;//Tecla balance hacia el canal L.

int32 Bal_R;//Tecla balance hacia el canal R.
//****************************************************************************//
//****************************************************************************//
//Lee de la EEPROM los códigos de mando que se hayan memorizado               //
//****************************************************************************//
void LeerCodigosMando(void){
int8 i;
IncVol=read_eeprom(3);
DecVol=read_eeprom(7);
CanalSel=read_eeprom(11);
Bal_L=read_eeprom(15);
Bal_R=read_eeprom(19);
for(i=2;i!=0xFF;i--){
   IncVol=IncVol*256+read_eeprom(i);
   DecVol=DecVol*256+read_eeprom(i+4);
   CanalSel=CanalSel*256+read_eeprom(i+8);
   Bal_L=Bal_L*256+read_eeprom(i+12);
   Bal_R=Bal_R*256+read_eeprom(i+16);
}
}
//****************************************************************************//
//Reproduce un pitido corto de 200msg.                                        //
//****************************************************************************//
void PitidoCorto(void){
int8 i;
for(i=0;i<200;i++){
   ZUMBADOR=ON;
   delay_us(500);
   ZUMBADOR=OFF;
   delay_us(500);
}
}
//****************************************************************************//
//Reproduce un pitido corto de 600msg.                                        //
//****************************************************************************//
void PitidoLargo(void){
int16 i;
for(i=0;i<600;i++){
   ZUMBADOR=ON;
   delay_us(500);
   ZUMBADOR=OFF;
   delay_us(500);
}
}
//****************************************************************************//
//Graba las cinco teclas: Subir volumen, bajar volumen, seleccion del canal,  //
//balance L, balance R.                                                       //
//****************************************************************************//
void AlmacenaTecla(void){
int8 cont;
if(EstadoProceso%2==1){//Paso impar.
   //Captura de tecla.
   LecturaMandoTemporal=LecturaMando;
   EstadoProceso++;
   PitidoCorto();//Indica tecla leida.
}else{//Paso par.
   //Comprobacion de tecla.
   if(LecturaMandoTemporal==LecturaMando){
   //Tecla correcta.
   Direccion=EstadoProceso*2-4;
   write_eeprom(Direccion,LecturaMando%256);//Parte baja
   LecturaMando=LecturaMando/256;
   write_eeprom(Direccion+1,LecturaMando%256);
   LecturaMando=LecturaMando/256;
   write_eeprom(Direccion+2,LecturaMando%256);
   LecturaMando=LecturaMando/256;
   write_eeprom(Direccion+3,LecturaMando%256);//Parte alta.
   EstadoProceso++;
   PitidoLargo();//Indica tecla almacenada correctamente.
   }else{//Comprobacion fallida.
   EstadoProceso--;
   LecturaMandoTemporal=0;
   for(cont=0;cont<4;cont++){//Indica fallo de lectura, se repite esa tecla.
       PitidoCorto();
       Delay_ms(200);
   }
   }
}
if(EstadoProceso==11){//5 teclas grabadas correctamente.
      LeerCodigosMando();
      EstadoProceso=1;
      for(cont=0;cont<4;cont++){//Indica fin de teclas almacenadas.
         PitidoLargo();
         Delay_ms(200);
      }
      Delay_ms(4000);
}
}
//****************************************************************************//
//Procesa las pulsaciones de las teclas del mando.                            //
//****************************************************************************//
void ProcesaTecla(void){

if(LecturaMando==IncVol){
      if(SALIDA_1==ON)
            SALIDA_1=OFF;
      else
            SALIDA_1=ON;
      Delay_ms(100);
}
if(LecturaMando==DecVol){
      if(SALIDA_2==ON)
            SALIDA_2=OFF;
      else
            SALIDA_2=ON;
      Delay_ms(100);
}
}
//****************************************************************************//
//En esta interrupción se interpretan y se programan las teclas del mando.    //
//En cada pasada de la interrupción se toma una muestra del mando, al llegar  //
//a 32 muestras se interpretan o programan las teclas.                        //
//****************************************************************************//
#INT_TIMER0
void tempo(){
set_timer0(Periodo);
if(PermisoLeer==SI){
   Pasos++;
   LecturaMando=LecturaMando*2+MANDO;
   if(Pasos==32){//Fin de la captura.
      PermisoLeer=NO;
      if((LecturaMando!=0xEFFFFFFF)&&(LecturaMando!=0)){
      //Con esto eliminamos el ruido.
         if(GRABAR){
            AlmacenaTecla();
         }else{
            ProcesaTecla();
         }
       }
       Delay_ms(1200);
       enable_interrupts(INT_EXT);
   }
}
}
//****************************************************************************//
//Esta interrupción detecta que una tecla del mando se ha pulsado y se prepara//
//el timer0 para leer la tecla.                                               //
//****************************************************************************//
#INT_EXT
void CrucePor0(){
set_timer0(Periodo);
disable_interrupts(INT_EXT);
PermisoLeer=SI;
Pasos=0;
}
//****************************************************************************//
//****************************************************************************//
void main(){

set_tris_A(0b11110001);
setup_timer_0(RTCC_INTERNAL | RTCC_DIV_8);
enable_interrupts(INT_TIMER0);
enable_interrupts(INT_EXT);
ext_int_edge(H_TO_L);
enable_interrupts(GLOBAL);

EstadoProceso=1;
LeerCodigosMando();

while(1);
}

Un saludo.
« Última modificación: 03 de Diciembre de 2008, 20:43:39 por micro_pepe »
Se obtiene más en dos meses interesandose por los demás, que en dos años tratando de que los demás se interesen por ti.

新年快乐     的好奇心的猫死亡

Desconectado micro_pepe

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3206
Re: Mando a distancia infrarrojo
« Respuesta #1 en: 04 de Diciembre de 2008, 12:37:13 »
Buenas. Creo que la forma de capturar las teclas no puede funcionar bien, pues de una tecla a otra es posible que solo cambien unos pocos bits, y puede dar la casualidad que esa diferencia no sea muestreada. He pensado en utilizar algun codigo estandar como el RC5, pero esto tiene el inconveniente de que si el amplificador lo pongo por ejemplo en el salón, las teclas coincidan con el televisor y al pulsar el mando actue sobre el TV y el amplificador al tiempo.

Pero no se me ocurre otra forma de poder programar las teclas de un mando ¿Alguna idea?

Un saludo.
Se obtiene más en dos meses interesandose por los demás, que en dos años tratando de que los demás se interesen por ti.

新年快乐     的好奇心的猫死亡

Desconectado gera

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2188
Re: Mando a distancia infrarrojo
« Respuesta #2 en: 04 de Diciembre de 2008, 13:42:36 »
Buenas!! Una pregunta, no podemos "decodificar" un protocolo infrarrojo capturando una trama y guardandola, para luego compararla? Independientemente si el bit esta dado por flanco ascendente o descendente. El unico problema aca seria identificar la unidad de comando, porque el mando emite varias veces la misma señal.
saludos!

"conozco dos cosas infinitas: el universo y la estupidez humana. Y no estoy muy seguro del primero." A.Einstein

Desconectado oliver8520

  • PIC10
  • *
  • Mensajes: 3
Re: Mando a distancia infrarrojo
« Respuesta #3 en: 01 de Junio de 2009, 14:46:22 »
podria poner el esquema de todo yo tambien quiero hacer uno haci bajar y subir el volumen a distancia pero tambien digital con pulsadores en el control y pulsadores en el circuito aqui hay una pagina donde lo manejan con un pic pero no se como programarlo y tiene un potenciometro morizado lo que quiero son pulsadores para bajar y subir volumen  y pues si se pudiera tambien dejar ese potenciometro

http://sound.westhost.com/project110.htm
esta es otra pero es mas compleja
http://www.mhennessy.f9.co.uk/preamp/schematics.htm?Control.gif

agradesco inmensamente sus ayudas