Autor Tema: Decodificando un protocolo IR y obteniendo direcciones y comandos.  (Leído 23045 veces)

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

Desconectado RedPic

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 5538
    • Picmania by Redraven
Ya estoy aqui con otro invento. En este caso es una copia descarada del de Manolo Nocturno en su Interpretando mando infrarrojos con dsPIC pero a mi manera ...  :mrgreen:


Debemos empezar por describir el protocolo que deseamos decodificar. En mi caso, al enfrentarme a un nuevo protocolo, en principio desconocido, lo que hago es colgarle el TSOP1738 al Analizador lógico. Con él obtengo una serie de cronogramas que voy comparando con la información sobre protocolos de la que dispongo y mas pronto que tarde logro encontrar al que corresponde.



El mejor sitio donde encontrar información sobre los distintos protocolos es SB-Projects: IR remote control

Alternativamente un buen método de rastrear un protocolo consiste en hacer un programa para el PIC que registre sucesivamente los tiempos que separan dos flancos de bajada correlativos. Yo lo he realizado utilizando las interrupción externa de RB0 y guardando los valores de TIMER0 cada vez que llegaba un flanco de este tipo. Al registrar una serie suficientemente larga de ellos, entre 25 y 35 pulsos consecutivos, transmitía vía RS232 los valores de TIMER0 recogidos al PC y los veía sobre un Monitor Serie estilo HyperTerminal o Siow.



De un simple vistazo a los valores recibidos se puede deducir la estructura de los datos recogidos.
Una vez identificado el protocolo del que se trata podremos encarar la realización del software que lo interpreta. En el ejemplo que os brindo a continuación se trata del protocolo NEC-32 que lleva embebido el mando ANSONIC SDG-20H de mi decodificador de Televisión Digital Terrestre.


Fundamentos del Protocolo NEC-32:

1.- Longitud de 8 bits de dirección y 8 bits de comando.
2.- Tanto la dirección como el comando son enviados dos veces a modo de CRC.
3.- La primera vez los bits originales y la segunda los mismos pero negados.
4.- Los pulsos son por modulación de amplitud.
5.- La frecuencia portadora es de 38kHz (detectable por el TSOP1738).
6.- La longitud de un Bit "0" es de 1.12ms y la de un "1" es de 2.25ms.
7.- En total de transmiten un bit de Start de 9ms+4.5ms=13.5ms mas 32 bits de datos.





Desarrollo del software de decodificación:

Con el fin de mostrar claramente el funcionamiento de nuestro decodificador vamos a recoger los distintos bits uno a uno y guardarlos en una tabla de bits, posteriormente los trataremos para componer los bytes correspondientes.

La tabla de bits es char sbits[32] y la inicializamos (limpiamos) con '\0'. Cuando los hayamos recibidos todos los acumularemos sobre bytes[4] que son los valores a recoger.

Todo el software gira en torno a la Interrupción externa por RB0, que es donde recogemos los distintos Bits. En #int_ext podemos distinguir tres bloques distintos:

Código: C
  1. #int_ext
  2. void ext_isr() {
  3.  
  4.    // Obtengo datos de Timer0
  5.    tt = get_timer0();
  6.    t = tt-tti;
  7.    tti= tt;
  8.  
  9.    // Si he recibido el Start Bit puedo guardar
  10.    if(start_recived==1){
  11.       // Bit "0"
  12.       if(t>40 && t<50){ sbits[ntbits]='0'; }
  13.       // Bit "1"
  14.       if(t>85 && t<90){ sbits[ntbits]='1'; }
  15.       // Si he recibido 32 bits entonces hay dato
  16.       if(++ntbits==total_bits){
  17.          hay_dato=1;
  18.       }
  19.    }
  20.  
  21.    // Detecto Start Bit
  22.    if(t>525 && t<530){
  23.       start_recived=1;
  24.       limpia_bits();
  25.    }
  26. }

Para recoger cada bit, o mejor dicho el ancho de cada bit que es lo que nos interesa, lo que hacemos es guardar la diferencia entre el estado del TIMER0 en cada interrupción y el valor que tenía en la interrupción anterior. Esto es lo que hacemos en la primera parte donde el valor de t alcanza el valor de dicha diferencia.

Para comenzar a recoger los 32 bits correspondientes a los cuatro bytes de dirección y comando debemos esperar a recibir el bit de Start, a partir del cual comenzaremos a acumular valores de bits en sbits[ x ].

Para un Cristal de 20 Mhz y un Preescaler  de TIMER0 de RTCC_DIV_128 el bit de Start son unos 525 Ticks de TIMER0, así que solo tras haber recibido un bit de una amplitud aproximada, entre 525 y 530 ticks de ancho, habilitaremos la recepción de los demás mediante la variable de tipo flag start_recived.

Para un Cristal de 20 Mhz y un Preescaler  de TIMER0 de RTCC_DIV_128 un bit "0" son unos 44 Ticks de TIMER0, así que guardamos un '0' si recibimos un bit de una amplitud aproximada de entre 40 y 50 ticks de ancho, y como un bit "1" son unos 88 Ticks de TIMER0 guardamos un '1' si recibimos un bit de una amplitud de entre 85 y 90 ticks de ancho.

Una vez recogidos los 32 bits podemos pasar a convertirlos en los correspondientes 4 bytes de dirección y comando (recordad que según este protocolo en particular el primer byte es la dirección, el segundo es la misma dirección pero con todos los bits "invertidos", el tercero es el comando y el cuarto y último es el comando "invertido")

Código: C
  1. int bits[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
  2.  
  3. void convierte_bits_a_bytes(void){
  4.  
  5.   for(i=0;i<4;++i){
  6.     Bytes[i]=0x00;
  7.     for(j=0;j<8;++j){
  8.       if(sbits[(i*8)+j]=='1'){
  9.         bytes[i]=bytes[i]|Bits[j];
  10.       }
  11.     }
  12.   }
  13. }

Todo lo demás de programa es "paja" ... o sea habilitar que todo esto sea posible. El programa completo es:

Código: C
  1. // ir_capture ANSONIC SDG-20H (TDT) with NEC-32 Protocol
  2. //
  3.  
  4. #include <18f4550.h>
  5. #fuses HS,MCLR,NOWDT,NOPROTECT,NOPUT,NOBROWNOUT,NOPBADEN,NOLVP,NOCPD,NODEBUG,NOWRT,NOVREGEN
  6. #use delay(clock=20000000)
  7. #use rs232(baud=19200, xmit=PIN_C6, rcv=PIN_C7)
  8.  
  9.  
  10. const char Version[]="1.0.H\0";
  11.  
  12. const int total_bits=32;
  13. const int total_bytes=4;
  14.  
  15. char sbits[total_bits];
  16. int1 first_ext=0;
  17. int1 start_recived=0;
  18. int i,j,k;
  19. long tt,tti,t;
  20. int ntbits=0;
  21. int1 hay_dato=0;
  22. char sbit1;
  23. int bits[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
  24. int bytes[total_bytes]={0x00,0x00,0x00,0x00};
  25.  
  26. void limpia_bits(void);
  27.  
  28. // INTERRUPCION por RECEPCION SERIE -------------------------------------------
  29.  
  30. #int_rda
  31. void serial_isr() {
  32.   if(kbhit()){
  33.     putchar(getc());
  34.   }
  35. }
  36.  
  37. // INTERRUPCION EXT por RB0 --------------------------------------------------
  38.  
  39. #int_ext
  40. void ext_isr() {
  41.  
  42.   // Obtengo datos de Timer0
  43.   tt = get_timer0();
  44.   t = tt-tti;
  45.   tti= tt;
  46.  
  47.   // Si he recibido el Start Bit puedo guardar
  48.   if(start_recived==1){
  49.     // Bit "0"
  50.     if(t>40 && t<50){ sbits[ntbits]='0'; }
  51.     // Bit "1"
  52.     if(t>85 && t<90){ sbits[ntbits]='1'; }
  53.     // Si he recibido 32 bits entonces hay dato
  54.     if(++ntbits==total_bits){
  55.       hay_dato=1;
  56.     }
  57.   }
  58.  
  59.   // Detecto Start Bit
  60.   if(t>525 && t<530){
  61.     start_recived=1;
  62.     limpia_bits();
  63.   }
  64. }
  65.  
  66. //-----------------------------------------------------------------------------
  67.  
  68. void flash_porte(void){
  69.  
  70.   for(i=0;i<3;i++){
  71.     output_e(0x07);
  72.     delay_ms(75);
  73.     output_e(0x00);
  74.     delay_ms(75);
  75.   }
  76. }
  77.  
  78. void limpia_bits(void){
  79.  
  80.   for(i=0;i<total_bits;++i){
  81.     sbits[i]='\0';
  82.   }
  83.   ntbits=0;
  84. }
  85.  
  86. void convierte_bits_a_bytes(void){
  87.  
  88.   for(i=0;i<4;++i){
  89.     Bytes[i]=0x00;
  90.     for(j=0;j<8;++j){
  91.       if(sbits[(i*8)+j]=='1'){
  92.         bytes[i]=bytes[i]|Bits[j];
  93.       }
  94.     }
  95.   }
  96. }
  97.  
  98. void muestra_bits(void){
  99.  
  100.   printf("\r\nPULSO RECIBIDO -----------------------\r\n");
  101.  
  102.   for(i=0;i<4;++i){
  103.     printf("Byte %u = ",i+1);
  104.     for(k=0;k<2;++k){
  105.       if(k==1){
  106.         printf(" ",i+1);
  107.       }
  108.       for(j=0;j<8;++j){
  109.         switch(k){
  110.           case 0: printf("%2u ",(i*8)+j+1);
  111.                   break;
  112.           case 1: printf("%2c ",sbits[(i*8)+j]);
  113.                   break;
  114.         }
  115.       }
  116.       if(k==0){ printf("\r\n"); }
  117.     }
  118.     printf(" Valor = %u\r\n",Bytes[i]);
  119.   }
  120.   printf("Address = %u Command = %u\r\n",Bytes[0],Bytes[2]);
  121.  
  122.   ntbits=0;
  123. }
  124.  
  125. void main() {
  126.  
  127.   disable_interrupts(global);
  128.   setup_adc_ports(NO_ANALOGS);
  129.   setup_adc(ADC_OFF);
  130.   setup_spi(FALSE);
  131.   setup_psp(PSP_DISABLED);
  132.   setup_counters(RTCC_INTERNAL,RTCC_DIV_2);
  133.   setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
  134.   setup_timer_2(T2_DISABLED,0,1);
  135.   setup_timer_3(T3_DISABLED);
  136.   setup_comparator(NC_NC_NC_NC);
  137.   setup_vref(FALSE);
  138.   port_b_pullups(FALSE);
  139.  
  140.   setup_timer_0(RTCC_INTERNAL | RTCC_DIV_128);
  141.  
  142.   set_tris_b(0b00000001);
  143.   set_tris_c(0b10000000);
  144.   set_tris_e(0b00010000);
  145.   output_e(0x00);
  146.  
  147.   delay_ms(500);
  148.   printf("\r\n");
  149.   printf("[RRBOARD2] IR TSOP1738 Reader-Decoder version %s\r\n",version);
  150.   printf("for ANSONIC SDG-20H (TDT) with NEC-32 Protocol\r\n\n");
  151.   flash_porte();
  152.  
  153.   ext_int_edge(H_TO_L);
  154.   first_ext=0;
  155.   start_recived=0;
  156.   hay_dato=0;
  157.  
  158.   limpia_bits();
  159.  
  160.   enable_interrupts(int_rda);
  161.   enable_interrupts(int_ext);
  162.   enable_interrupts(global);
  163.  
  164.   do {
  165.  
  166.     if(hay_dato==1){
  167.        hay_dato=0;
  168.        convierte_bits_a_bytes();
  169.        muestra_bits();
  170.        limpia_bits();
  171.     }
  172.  
  173.   } while (TRUE);
  174. }

Y por supuesto el famoso ejemplo final. Que en este caso corresponde a lo trasmitido tras pulsar los cuatro cursores del mando:



Espero que os haya gustado.  :mrgreen:

« Última modificación: 16 de Agosto de 2010, 13:44:43 por RedPic »
Contra la estupidez los propios dioses luchan en vano. Schiller
Mi Güeb : Picmania

Desconectado ALE1973

  • Colaborador
  • PIC16
  • *****
  • Mensajes: 229
Re: Decodificando un protocolo IR y obteniendo direcciones y comandos.
« Respuesta #1 en: 27 de Julio de 2006, 15:21:17 »
Exelente... como anillo al dedo, justo estaba por comenzar a hacer un proyecto en que estoy necesitando interpretar comandos de un control remoto....

Saludos y felicitaciones por el trabajo.

Alejandro.

Desconectado piclord

  • PIC12
  • **
  • Mensajes: 52
Re: Decodificando un protocolo IR y obteniendo direcciones y comandos.
« Respuesta #2 en: 27 de Julio de 2006, 18:31:41 »
Hola muchachos
Hace un par de mese construí un decoder similar al que señala RedPIC..detecté que en el caso de mi mando infrarrojo (sony), no todas las teclas tiene en mismo largo en bits, entre 12, 15 y 20 bits es el largo de los codigos...asi...no podia dar un largo fijo de bits a recivir...otra cosa que sucedía era que a veces la trama se enviaba sin el start bit, e incluso se repetia la trama hasta 5 veces, de modo que opte por detectar primero la presencia del start bit y luego la llegada de un segundo start bit, si es que aplica, y de ese modo determiné el envío de un comando, ya sea en 12, 15 o 20 bits....ahora, no me preocupé de asignarle a cada trama recivida la tecla que le corresponde en el mando, sino que asigne dicha trama a una funcion especifica, onda el metodo de aprender que nos entregó nocturno con su dimmer infrarrojo.

Eso era, para tenerlo en cuenta tambien..

Saludos..

Desconectado RedPic

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 5538
    • Picmania by Redraven
Re: Decodificando un protocolo IR y obteniendo direcciones y comandos.
« Respuesta #3 en: 28 de Julio de 2006, 01:21:32 »
ALE1973:  Todo tuyo. Muchas gracias.

Piclord: Si, el SONY además tiene una portadora de 40 Khz, por lo que el TSOP1738 lo recibe pero mal. Lo suyo es detectarlo con el TSOP1740 que para eso está. Hasta que me di cuenta de esto anduve perplejo con falsos bits que aparecían de vez en cuando.

Contra la estupidez los propios dioses luchan en vano. Schiller
Mi Güeb : Picmania

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18271
    • MicroPIC
Re: Decodificando un protocolo IR y obteniendo direcciones y comandos.
« Respuesta #4 en: 28 de Julio de 2006, 01:28:50 »
Cuando empecé a leer y vi esas palabras "...a mi manera..." me eché a temblar.

Al terminar de leer he comprobado que mis temblores eran fundados. Menuda manera de documentar un proyecto, maestro Diego.

Desconectado RedPic

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 5538
    • Picmania by Redraven
Re: Decodificando un protocolo IR y obteniendo direcciones y comandos.
« Respuesta #5 en: 28 de Julio de 2006, 01:35:31 »
Frank Sinatra cantaba My Way, yo no puedo porque canto menos que un grillo enterrado en alquitrán.  :P

Manuelo, ya sabes que "a mi manera" es:

Escribiendo una novela, salpicada aquí y allá de algun comentario jocoso y festivo, con una cierta pátina de hablar para quien sabe poco o nada, o sea alguien como yo mismo, y con un estilo parafraseando a Groucho Marx que demuestre que me siento muy orgulloso de que empezando de la nada puedo alcanzar las mas altas cotas de la miseria ... ja ja ja  :D  :D  :D

Contra la estupidez los propios dioses luchan en vano. Schiller
Mi Güeb : Picmania

Desconectado Algec

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 974
Re: Decodificando un protocolo IR y obteniendo direcciones y comandos.
« Respuesta #6 en: 28 de Julio de 2006, 08:55:02 »
Sencillamente, de nuevo me dejas sin palabras.
Un 10 simple y llanamente no se puede mejorar, Gracias

Desconectado piclord

  • PIC12
  • **
  • Mensajes: 52
Re: Decodificando un protocolo IR y obteniendo direcciones y comandos.
« Respuesta #7 en: 28 de Julio de 2006, 11:56:13 »
ALE1973:  Todo tuyo. Muchas gracias.

Piclord: Si, el SONY además tiene una portadora de 40 Khz, por lo que el TSOP1738 lo recibe pero mal. Lo suyo es detectarlo con el TSOP1740 que para eso está. Hasta que me di cuenta de esto anduve perplejo con falsos bits que aparecían de vez en cuando.




Hola maestro RedPIC..
Si, efectivamente, el sony usa una portadora de 40 Khz, pero es es relativo, pues los IR receiver que he visto, la mayoria tiene la frecuencia central en 38Khz, y con ellos he podido capturar las trama sin problemas...Yo usé el IRM8601, que anduvo perfecto...
Notar otra cosa, este IR receiver, cuando no tiene señal de entrada, en su salida tiene un 1, osea, que invierte la señal entrante....De eso se desprende que si los flancos a detectar son de bajada, entonces se monitorea el tiempo bajo...Entonces, para los tiempos de 1200 us, corresponde un bit 1 enviado desde el mando, que tiene esa duracion, pero a la salida del receptor tenemos un 0....en definitiva, como dice redPIC, basta con medir los tiempos 1200us y 2250us...dando = si se trata de un 0 ó un 1, puesto que el largo de ese pulso determina de que bit se trata...
Tambien observar que la cantidad de ticks no simpre es fija...por tanto hay que dar un rango, el que puede ser determiando empíricamente.....

Muy buen proyecto...yo lo uso en la alarma de mi casa....chavela...

Modificado por Redpic para convertir "rago" en "rango".

Les dejo algo de lo que tengo aca en mi pc, informacion sobre las tramas capturadas

« Última modificación: 01 de Agosto de 2006, 17:44:53 por piclord »

Desconectado RedPic

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 5538
    • Picmania by Redraven
Re: Decodificando un protocolo IR y obteniendo direcciones y comandos.
« Respuesta #8 en: 28 de Julio de 2006, 14:49:03 »
Gracias ALE1973 .... Y ahora a continuar con los IR. Ahora mismo estoy haciendo un sistema "experto". Quiero definir unas funciones básicas y asociarla a comandos recibidos vía RS232 ... o con un mando IR, cualquier mando IR, asignar secuencialmente cada función a una pareja address/command, independiente de mando de que se trate y del protocolo que use .... ya ire posteando resultados.
Contra la estupidez los propios dioses luchan en vano. Schiller
Mi Güeb : Picmania

Desconectado RedPic

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 5538
    • Picmania by Redraven
Re: Decodificando un protocolo IR y obteniendo direcciones y comandos.
« Respuesta #9 en: 29 de Julio de 2006, 12:38:26 »
Buenoooo ... ya tenemos otro programa un poco mas avanzado.

Basandome en todo lo escrito anteriormente he construido un programa que realiza una serie de funciones básicas como activar o desactivar unos pines del PIC o incrementar o decrementar cierto valor.

Lo bonito de este programa es que los comandos para realizar estas funciones pueden enviarse al PIC vía RS232 como en tantos de mis ejemplos anteriores (vénase por ejemplo los Ejemplitos Recibiendo del RS232 sobre un Buffer y procesandolo posteriormente, Desde el PC a una EEPROM I2C y viseversa a través de mi PIC, Controlando un SERVO con el PIC desde nuestro PC y La EEPROM interna puesta a nuestro servicio.)

Pero ademas pueden enviarse vía IR utilizando el mando del televisor.

El rollo estaba en que para realizarlo había antes que leer los comandos que dicho mando IR envía con las teclas que nos interesaban y despues programar nuestro programa para que las recibiese y aceptase en cada caso. Pero esta forma de hacerla no es elegante.

Lo elegante y bonito es que el programa fuese capaz de leer comandos y asignarlos a cada función, guardandolos en la EEPROM durante lo que podríamos llamar como fase de aprendizaje o memorización.

A partir de ahí tendríamos guardados los comandos asignados a cada función y que podrían ser cambiados en cualquier momento con solo reprogramar los comandos de nuevo.

Además para hacerlo elegante del todo debería haber una manera de hacer todo esto sin hacer uso de hardware accesorio alguno, ningún botón, ni software externo, nada de enviar un comando RS232 para entrar en modo programación.

Para ello decidi que iba a tener disponibles 5 segundos tras el reset para que si en ese lapso recibía cualquier comando IR entonces entraba automáticamente en modo programación. Si transcurrido ese lapso de tiempo no recibía nada entonces recargaba desde la EEPROM los comandos configurados anteriormente y santas pascuas.

De cualquier forma le he dejado implementado el que cada ejecución que realiza lo monitoriza por la RS232 para que podamos seguir su funcionamiento.

Imagen de una programación completa tras un Reset:



Imagen de un funcionamiento normal fuera de la fase de programación:



« Última modificación: 29 de Julio de 2006, 12:54:36 por RedPic »
Contra la estupidez los propios dioses luchan en vano. Schiller
Mi Güeb : Picmania

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18271
    • MicroPIC
Re: Decodificando un protocolo IR y obteniendo direcciones y comandos.
« Respuesta #10 en: 29 de Julio de 2006, 12:42:57 »
Diego, en modo programación tuve que hacer que el Minidimmer solicitase cada tecla dos veces, porque a veces pillaba basura y de esta forma me aseguraba de que todo iba perfecto. ¿No te ha pasado a ti eso?

P.D.: has puesto las imágenes al revés, aunque se entiende tu artículo a la perfección

Desconectado RedPic

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 5538
    • Picmania by Redraven
Re: Decodificando un protocolo IR y obteniendo direcciones y comandos.
« Respuesta #11 en: 29 de Julio de 2006, 12:44:38 »
El programa de mi post anterior (no me ha dejado postearlo en el mismo porque me decía que exedía no se qué número de bytes por post)

Código: C
  1. // ir_command.c by Redpic
  2. // ANSONIC SDG-20H (TDT) supporting NEC-32 Protocol
  3. // With recording Command send function
  4. // and automode programing on reset
  5.  
  6. #include <18f4550.h>
  7. #fuses HS,MCLR,NOWDT,NOPROTECT,NOPUT,NOBROWNOUT,NOPBADEN,NOLVP,NOCPD,NODEBUG,NOWRT,NOVREGEN
  8. #use delay(clock=20000000)
  9. #use rs232(baud=19200, xmit=PIN_C6, rcv=PIN_C7)
  10.  
  11. #define PIN_FUNC1 PIN_E0
  12. #define PIN_FUNC2 PIN_E1
  13. #define PIN_FUNC3 PIN_E2
  14.  
  15. #define PIN_LED PIN_E0
  16.  
  17. // CONSTANTES -
  18.  
  19. const char Version[]="1.0.H\0";
  20.  
  21. const int total_bits  = 32;
  22. const int total_bytes =  4;
  23.  
  24. const char COMANDO232_MENU  = '?'; const char COMANDO232_TXT_MENU[]  = "Muestra menu de opciones RS232.";
  25. const char COMANDO232_MODO_PROG = 'p'; const char COMANDO232_TXT_MODO_PROG[] = "Entrar en modo Programación.";
  26. const char COMANDO232_FUNC_ON = 'o'; const char COMANDO232_TXT_FUNC_ON[] = " * 1 Activa/Desactiva procesar Comandos IR.";
  27. const char COMANDO232_FUNC_1  = '1'; const char COMANDO232_TXT_FUNC_1[]  = " * 2 Ejecutar Función 1";
  28. const char COMANDO232_FUNC_2  = '2'; const char COMANDO232_TXT_FUNC_2[]  = " * 3 Ejecutar Función 2";
  29. const char COMANDO232_FUNC_3  = '3'; const char COMANDO232_TXT_FUNC_3[]  = " * 4 Ejecutar Función 3";
  30. const char COMANDO232_FUNC_VEX  = 'f'; const char COMANDO232_TXT_FUNC_VEX[]  = " * 5 Ver Estado actual de funciones.";
  31. const char COMANDO232_FUNC_VER  = 'm'; const char COMANDO232_TXT_FUNC_VER[]  = " * 6 Ver Comandos almacenados por función.";
  32. const char COMANDO232_FUNC_RESET= 'r'; const char COMANDO232_TXT_FUNC_RESET[]= " * 7 Reset Hardware.";
  33. const char COMANDO232_FUNC_PLUS = '+'; const char COMANDO232_TXT_FUNC_PLUS[] = " * 8 Incrementa valor Ref.";
  34. const char COMANDO232_FUNC_Minus= '-'; const char COMANDO232_TXT_FUNC_MINUS[]= " * 9 Decrementa valor Ref.";
  35.  
  36. const int  MODO_INACTIVO    =  0;  const char MODO_TXT_INACTIVO[]    = "INACTIVO";
  37. const int  MODO_ACTIVO    =  1;  const char MODO_TXT_ACTIVO[]    = "ACTIVO";
  38. const int  MODO_PROGRAMACION  =  2;  const char MODO_TXT_PROGRAMACION[]  = "PROGRAMACIÓN";
  39.  
  40. const int  RTCCS_AUTOPROG = 3;
  41.  
  42. // VARIABLES EN RAM -
  43.  
  44. // De recepción IR y generales --
  45.  
  46. int1 first_ext=0;
  47. int1 start_recived=0;
  48. int1 hay_dato=0;
  49. int1 autoprog_enabled=0;
  50. int1 flag_flash_led=0;
  51. char sbits[total_bits];
  52. int  i,j,k;
  53. long tt,tti,t;
  54. int  ntbits=0;
  55. char sbit1;
  56. int  bits[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
  57. int  bytes[total_bytes]={0x00,0x00,0x00,0x00};
  58. int  nrtcc=0;
  59.  
  60. // De Comandos y Funciones --
  61.  
  62. char rec232=0x00;
  63. char opcion=0x00;
  64. int  Modo=MODO_INACTIVO;
  65. int  nextPROG=0;
  66.  
  67. int1 FUNC1=0;
  68. int1 FUNC2=0;
  69. int1 FUNC3=0;
  70. int  VALREF;
  71.  
  72. int ADDRESSDEV;
  73. int COMANDODEV_FUNC_ON;
  74. int COMANDODEV_FUNC_1;
  75. int COMANDODEV_FUNC_2;
  76. int COMANDODEV_FUNC_3;
  77. int COMANDODEV_FUNC_VEX;
  78. int COMANDODEV_FUNC_VER;
  79. int COMANDODEV_FUNC_RESET;
  80. int COMANDODEV_FUNC_PLUS;
  81. int COMANDODEV_FUNC_MINUS;
  82.  
  83. // Prototipos de funciones --
  84.  
  85. void flash_led(int n);
  86. void limpia_bits(void);
  87. void convierte_bits_a_bytes(void);
  88. void muestra_bits(void);
  89. void lee_config_desde_EEPROM(void);
  90. void programar_comandos(int funcion, int device_address, int device_command);
  91. void presenta_menu(void);
  92. void on_reset(void);
  93.  
  94. // INTERRUPCION por RECEPCION SERIE -
  95.  
  96. #int_rda
  97. void serial_isr() {
  98.  
  99.  rec232=0x00;
  100.  if(kbhit()){
  101.    rec232=getc();
  102.    if( rec232==COMANDO232_MENU   ||
  103.    rec232==COMANDO232_MODO_PROG  ||
  104.    rec232==COMANDO232_FUNC_ON  ||
  105.    rec232==COMANDO232_FUNC_1   ||
  106.    rec232==COMANDO232_FUNC_2   ||
  107.    rec232==COMANDO232_FUNC_3   ||
  108.    rec232==COMANDO232_FUNC_PLUS  ||
  109.    rec232==COMANDO232_FUNC_MINUS ||
  110.    rec232==COMANDO232_FUNC_RESET ||
  111.    rec232==COMANDO232_FUNC_VEX ||
  112.    rec232==COMANDO232_FUNC_VER){
  113.    opcion=rec232;
  114.    }
  115.  }
  116. }
  117.  
  118. // INTERRUPCION EXT por RB0 --
  119.  
  120. #int_ext
  121. void ext_isr() {
  122.  // Obtengo datos de Timer0
  123.  tt = get_timer0();
  124.  t  = tt-tti;
  125.  tti= tt;
  126.  // Si he recibido el Start Bit puedo guardar
  127.  if(start_recived==1){
  128.   // Bit "0"
  129.   if(t>40 && t<50){ sbits[ntbits]='0'; }
  130.   // Bit "1"
  131.   if(t>85 && t<90){ sbits[ntbits]='1'; }
  132.   // Si he recibido 32 bits entonces hay dato
  133.   if(++ntbits==total_bits){
  134.    hay_dato=1;
  135.   }
  136.  }
  137.  // Detecto Start Bit
  138.  if(t>525 && t<530){
  139.   start_recived=1;
  140.   limpia_bits();
  141.  }
  142. }
  143.  
  144.  
  145. // INTERRUPCION RTCC por TIMER0 -
  146.  
  147. #int_rtcc
  148. void rtcc_isr() {
  149.  
  150.  if(autoprog_enabled){
  151.   ++nrtcc;
  152.   printf(".");
  153.   flag_flash_led=1;
  154.   if(nrtcc==RTCCS_AUTOPROG){
  155.    autoprog_enabled=0;
  156.    printf("\r\nAutoprog disabled.\r\n");
  157.   }
  158.  }
  159. }
  160.  
  161. //-
  162.  
  163. void flash_led(int n){
  164.  
  165.  for(i=0;i<n-1;i++){
  166.   output_high(PIN_LED);
  167.   delay_ms(75);
  168.   output_low(PIN_LED);
  169.   delay_ms(75);
  170.  }
  171. }
  172.  
  173. void limpia_bits(void){
  174.  
  175.  for(i=0;i<total_bits;++i){
  176.   sbits[i]='\0';
  177.  }
  178.  ntbits=0;
  179. }
  180.  
  181. void convierte_bits_a_bytes(void){
  182.  
  183.  for(i=0;i<4;++i){
  184.   Bytes[i]=0x00;
  185.   for(j=0;j<8;++j){
  186.    if(sbits[(i*8)+j]=='1'){
  187.     bytes[i]=bytes[i]|Bits[j];
  188.    }
  189.   }
  190.  }
  191. }
  192.  
  193. void muestra_bits(void){
  194.  
  195.  printf("[COMANDO] %u\\%u\r\n",Bytes[0],Bytes[2]);
  196. }
  197.  
  198. void lee_config_desde_EEPROM(void){
  199.  
  200.  ADDRESSDEV    = read_eeprom( 0); if(ADDRESSDEV     ==0xFF){ADDRESSDEV=64;}
  201.  VALREF      = read_eeprom( 1); if(VALREF     ==0xFF){VALREF=127;}
  202.  COMANDODEV_FUNC_ON  = read_eeprom( 2); if(COMANDODEV_FUNC_ON ==0xFF){COMANDODEV_FUNC_ON = 24;} // Btn ON/OFF
  203.  COMANDODEV_FUNC_1   = read_eeprom( 3); if(COMANDODEV_FUNC_1  ==0xFF){COMANDODEV_FUNC_1  = 26;} // Btn 1
  204.  COMANDODEV_FUNC_2   = read_eeprom( 4); if(COMANDODEV_FUNC_2  ==0xFF){COMANDODEV_FUNC_2  = 17;} // Btn 2
  205.  COMANDODEV_FUNC_3   = read_eeprom( 5); if(COMANDODEV_FUNC_3  ==0xFF){COMANDODEV_FUNC_3  =  9;} // Btn 3
  206.  COMANDODEV_FUNC_VEX = read_eeprom( 6); if(COMANDODEV_FUNC_VEX  ==0xFF){COMANDODEV_FUNC_VEX  =  7;} // Btn Ok
  207.  COMANDODEV_FUNC_VER = read_eeprom( 7); if(COMANDODEV_FUNC_VER  ==0xFF){COMANDODEV_FUNC_VER  = 25;} // Btn Menu
  208.  COMANDODEV_FUNC_RESET = read_eeprom( 8); if(COMANDODEV_FUNC_RESET==0xFF){COMANDODEV_FUNC_RESET=  3;} // Btn Exit
  209.  COMANDODEV_FUNC_PLUS  = read_eeprom( 9); if(COMANDODEV_FUNC_PLUS ==0xFF){COMANDODEV_FUNC_PLUS=  13;} // Btn CH+
  210.  COMANDODEV_FUNC_MINUS = read_eeprom(10); if(COMANDODEV_FUNC_MINUS==0xFF){COMANDODEV_FUNC_MINUS= 30;} // Btn CH-
  211.  
  212. }
  213.  
  214. void programar_comandos(int funcion, int device_address, int device_command){
  215.  
  216.  switch(funcion){
  217.   case  0:
  218.     printf("Modo PROGRAMACIÓN activado ...\r\n");
  219.     printf("Pulse cualquier botón para obtener el ADDRESS ");
  220.     flash_led(1);
  221.     break;
  222.   case  1:
  223.     printf("Address=%2u (0x%x)\r\n",device_address,device_address);
  224.     write_eeprom(0,device_address);
  225.     delay_ms(10);
  226.     printf("Pulse para [Activar/Desactivar] ");
  227.     flash_led(2);
  228.     break;
  229.   case  2:
  230.     printf("Command=%2u (0x%x)\r\n",device_command,device_command);
  231.     write_eeprom(2,device_command);
  232.     delay_ms(10);
  233.     printf("Pulse para [Ejecutar Función 1] ");
  234.     flash_led(3);
  235.     break;
  236.   case  3:
  237.     printf("Command=%2u (0x%x)\r\n",device_command,device_command);
  238.     write_eeprom(3,device_command);
  239.     delay_ms(10);
  240.     printf("Pulse para [Ejecutar Función 2] ");
  241.     flash_led(4);
  242.     break;
  243.   case  4:
  244.     printf("Command=%2u (0x%x)\r\n",device_command,device_command);
  245.     write_eeprom(4,device_command);
  246.     delay_ms(10);
  247.     printf("Pulse para [Ejecutar Función 3] ");
  248.     flash_led(5);
  249.     break;
  250.   case  5:
  251.     printf("Command=%2u (0x%x)\r\n",device_command,device_command);
  252.     write_eeprom(5,device_command);
  253.     delay_ms(10);
  254.     printf("Pulse para [Ver estado de funciones] ");
  255.     flash_led(6);
  256.     break;
  257.   case  6:
  258.     printf("Command=%2u (0x%x)\r\n",device_command,device_command);
  259.     write_eeprom(6,device_command);
  260.     delay_ms(10);
  261.     printf("Pulse para [Ver comandos almacenados] ");
  262.     flash_led(7);
  263.     break;
  264.   case  7:
  265.     printf("Command=%2u (0x%x)\r\n",device_command,device_command);
  266.     write_eeprom(7,device_command);
  267.     delay_ms(10);
  268.     printf("Pulse para [Reset Hardware] ");
  269.     flash_led(8);
  270.     break;
  271.   case  8:
  272.     printf("Command=%2u (0x%x)\r\n",device_command,device_command);
  273.     write_eeprom(8,device_command);
  274.     delay_ms(10);
  275.     printf("Pulse para [Inc. Valor Ref.] ");
  276.     flash_led(9);
  277.     break;
  278.   case  9:
  279.     printf("Command=%2u (0x%x)\r\n",device_command,device_command);
  280.     write_eeprom(9,device_command);
  281.     delay_ms(10);
  282.     printf("Pulse para [Dec. Valor Ref.] ");
  283.     flash_led(9);
  284.     break;
  285.   case  10:
  286.     printf("Command=%2u (0x%x)\r\n",device_command,device_command);
  287.     write_eeprom(10,device_command);
  288.     delay_ms(11);
  289.     // fin programación
  290.     printf("Fin Modo PROGRAMACION.\r\n");
  291.     on_reset();
  292.     break;
  293.  }
  294. }
  295.  
  296. //-
  297.  
  298. void presenta_menu(void){
  299.  
  300.  printf("Opciones Menu RS232:\r\n\n");
  301.  printf(" [%c]  %s\r\n", COMANDO232_MENU,  COMANDO232_TXT_MENU);
  302.  printf(" [%c]  %s\r\n", COMANDO232_MODO_PROG, COMANDO232_TXT_MODO_PROG);
  303.  printf(" [%c]  %s\r\n", COMANDO232_FUNC_ON, COMANDO232_TXT_FUNC_ON);
  304.  printf(" [%c]  %s\r\n", COMANDO232_FUNC_1,  COMANDO232_TXT_FUNC_1);
  305.  printf(" [%c]  %s\r\n", COMANDO232_FUNC_2,  COMANDO232_TXT_FUNC_2);
  306.  printf(" [%c]  %s\r\n", COMANDO232_FUNC_3,  COMANDO232_TXT_FUNC_3);
  307.  printf(" [%c]  %s\r\n", COMANDO232_FUNC_VEX,  COMANDO232_TXT_FUNC_VEX);
  308.  printf(" [%c]  %s\r\n", COMANDO232_FUNC_VER,  COMANDO232_TXT_FUNC_VER);
  309.  printf(" [%c]  %s\r\n", COMANDO232_FUNC_RESET,COMANDO232_TXT_FUNC_RESET);
  310.  printf(" [%c]  %s\r\n", COMANDO232_FUNC_PLUS, COMANDO232_TXT_FUNC_PLUS);
  311.  printf(" [%c]  %s\r\n", COMANDO232_FUNC_MINUS,COMANDO232_TXT_FUNC_MINUS);
  312.  printf("\r\n");
  313. }
  314.  
  315. void on_reset(void){
  316.  
  317.  disable_interrupts(global);
  318.  setup_adc_ports(NO_ANALOGS);
  319.  setup_adc(ADC_OFF);
  320.  setup_spi(FALSE);
  321.  setup_psp(PSP_DISABLED);
  322.  setup_counters(RTCC_INTERNAL,RTCC_DIV_2);
  323.  setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
  324.  setup_timer_2(T2_DISABLED,0,1);
  325.  setup_timer_3(T3_DISABLED);
  326.  setup_comparator(NC_NC_NC_NC);
  327.  setup_vref(FALSE);
  328.  port_b_pullups(FALSE);
  329.  
  330.  setup_timer_0(RTCC_INTERNAL | RTCC_DIV_128);
  331.  
  332.  set_tris_b(0b00000001);
  333.  set_tris_c(0b10000000);
  334.  set_tris_e(0b00010000);
  335.  output_e(0x00);
  336.  
  337.  delay_ms(500);
  338.  printf("\r\n");
  339.  printf("[RRBOARD2] IR Command Receiver version %s\r\n",version);
  340.  printf("TSOP1738 Reader-Decoder over 18F4550\r\n");
  341.  printf("for ANSONIC SDG-20H with NEC-32 Protocol\r\n\n");
  342.  flash_led(3);
  343.  presenta_menu();
  344.  
  345.  ext_int_edge(H_TO_L);
  346.  first_ext=0;
  347.  start_recived=0;
  348.  hay_dato=0;
  349.  
  350.  limpia_bits();
  351.  
  352.  
  353.  rec232=0x00;
  354.  opcion=0x00;
  355.  Modo=MODO_INACTIVO;
  356.  FUNC1=0;
  357.  FUNC2=0;
  358.  FUNC3=0;
  359.  nextPROG=0;
  360.  nrtcc=0;
  361.  flag_flash_led=0;
  362.  autoprog_enabled=1;
  363.  
  364.  lee_config_desde_EEPROM();
  365.  
  366.  delay_ms(500);
  367.  printf("Autoprog enabled ");
  368.  
  369.  enable_interrupts(int_rda);
  370.  enable_interrupts(int_ext);
  371.  enable_interrupts(int_rtcc);
  372.  enable_interrupts(global);
  373.  
  374. }
  375.  
  376. void main() {
  377.  
  378.  on_reset();
  379.  do {
  380.   // Recibe y procesa IR Command para generar 232 Command -
  381.   if(hay_dato==1){
  382.    hay_dato=0;
  383.    // Extrae byte recibido y limpia -
  384.    convierte_bits_a_bytes();
  385.    limpia_bits();
  386.    // Detecta cualquier pulsacion IR durante Autoprog_enabled -
  387.    if(Autoprog_enabled){
  388.     Autoprog_enabled=0;
  389.     Opcion=COMANDO232_MODO_PROG;
  390.    }else{
  391.     // Si no estamos en modo PROGRAMACION -
  392.     if(Modo!=MODO_PROGRAMACION){
  393.      muestra_bits();
  394.      // Si el Address es correcto ... -
  395.      if(Bytes[0]==ADDRESSDEV){
  396.       // Comando COMANDO232_FUNC_ON -
  397.       if(Bytes[2]==COMANDODEV_FUNC_ON){
  398.        opcion=COMANDO232_FUNC_ON;
  399.       }
  400.       // Comando FUNC1 --
  401.       if(Bytes[2]==COMANDODEV_FUNC_1){
  402.        opcion=COMANDO232_FUNC_1;
  403.       }
  404.       // Comando FUNC2 --
  405.       if(Bytes[2]==COMANDODEV_FUNC_2){
  406.        opcion=COMANDO232_FUNC_2;
  407.       }
  408.       // Comando FUNC3 --
  409.       if(Bytes[2]==COMANDODEV_FUNC_3){
  410.        opcion=COMANDO232_FUNC_3;
  411.       }
  412.       // Comando FUNC_VEX -
  413.       if(Bytes[2]==COMANDODEV_FUNC_VEX){
  414.        opcion=COMANDO232_FUNC_VEX;
  415.       }
  416.       // Comando FUNC_VER -
  417.       if(Bytes[2]==COMANDODEV_FUNC_VER){
  418.        opcion=COMANDO232_FUNC_VER;
  419.       }
  420.       // Comando FUNC_RESET -
  421.       if(Bytes[2]==COMANDODEV_FUNC_RESET){
  422.        opcion=COMANDO232_FUNC_RESET;
  423.       }
  424.       // Comando FUNC_PLUS --
  425.       if(Bytes[2]==COMANDODEV_FUNC_PLUS){
  426.        opcion=COMANDO232_FUNC_PLUS;
  427.       }
  428.       // Comando FUNC_MINUS --
  429.       if(Bytes[2]==COMANDODEV_FUNC_MINUS){
  430.        opcion=COMANDO232_FUNC_MINUS;
  431.       }
  432.      }
  433.      // Si estamos en Modo PROGRAMACION -
  434.     }else{
  435.      programar_comandos(++nextPROG,bytes[0],bytes[2]);
  436.     }
  437.    }
  438.   }
  439.   // Recibe y procesa RS232 Opcion
  440.   if(opcion!=0x00){
  441.    Switch(opcion){
  442.     // Muestra menu de opciones -
  443.     case  COMANDO232_MENU:
  444.       presenta_menu();
  445.       break;
  446.     // Entrar en Modo PROGRAMACION --
  447.     case  COMANDO232_MODO_PROG:
  448.       nextPROG=0;
  449.       Modo=MODO_PROGRAMACION;
  450.       programar_comandos(0,0,0);
  451.       break;
  452.     // Activa/Desactiva procesar Comandos FUNC --
  453.     case  COMANDO232_FUNC_ON:
  454.       if(Modo==MODO_INACTIVO){
  455.        Modo=MODO_ACTIVO;
  456.        printf("Modo : Activada recepción de Comandos\r\n");
  457.       }else{
  458.        Modo=MODO_INACTIVO;
  459.        printf("Modo : Desactivada recepción de Comandos\r\n");
  460.       };
  461.       break;
  462.     // Reset de Hardware --
  463.     case  COMANDO232_FUNC_RESET:
  464.       if(Modo==MODO_ACTIVO){
  465.        on_reset();
  466.       }else{
  467.        printf("**Error, Recibido RESET pero Modo=INACTIVO\r\n");
  468.       }
  469.       break;
  470.     // Ejecutar Función 1 -
  471.     case  COMANDO232_FUNC_1:
  472.       if(Modo==MODO_ACTIVO){
  473.        FUNC1=!FUNC1;
  474.         if(FUNC1){
  475.         output_high(PIN_FUNC1);
  476.         printf("FUNC1 : Activada\r\n");
  477.         }else{
  478.         output_low(PIN_FUNC1);
  479.         printf("FUNC1 : Desactivada\r\n");
  480.         }
  481.       }else{
  482.        printf("**Error, Recibido F1 pero Modo=INACTIVO\r\n");
  483.       }
  484.       break;
  485.     // Ejecutar Función 2 -
  486.     case  COMANDO232_FUNC_2:
  487.       if(Modo==MODO_ACTIVO){
  488.        FUNC2=!FUNC2;
  489.         if(FUNC2){
  490.         output_high(PIN_FUNC2);
  491.         printf("FUNC2 : Activada\r\n");
  492.         }else{
  493.         output_low(PIN_FUNC2);
  494.         printf("FUNC2 : Desactivada\r\n");
  495.         }
  496.       }else{
  497.        printf("**Error, Recibido F2 pero Modo=INACTIVO\r\n");
  498.       }
  499.       break;
  500.     // Ejecutar Función 3 -
  501.     case  COMANDO232_FUNC_3:
  502.       if(Modo==MODO_ACTIVO){
  503.        FUNC3=!FUNC3;
  504.         if(FUNC3){
  505.         output_high(PIN_FUNC3);
  506.         printf("FUNC3 : Activada\r\n");
  507.         }else{
  508.         output_low(PIN_FUNC3);
  509.         printf("FUNC3 : Desactivada\r\n");
  510.         }
  511.       }else{
  512.        printf("**Error, Recibido F3 pero Modo=INACTIVO\r\n");
  513.       }
  514.       break;
  515.     // Ejecutar Plus --
  516.     case  COMANDO232_FUNC_PLUS:
  517.       if(Modo==MODO_ACTIVO){
  518.        ++VALREF;
  519.        write_eeprom(1,VALREF);
  520.        printf("V.Ref.=%u\r\n",VALREF);
  521.       }else{
  522.        printf("**Error, Recibido Inc. pero Modo=INACTIVO\r\n");
  523.       }
  524.       break;
  525.     // Ejecutar Minus -
  526.     case  COMANDO232_FUNC_MINUS:
  527.       if(Modo==MODO_ACTIVO){
  528.        --VALREF;
  529.        write_eeprom(1,VALREF);
  530.        printf("V.Ref.=%u\r\n",VALREF);
  531.       }else{
  532.        printf("**Error, Recibido Dec. pero Modo=INACTIVO\r\n");
  533.       }
  534.       break;
  535.     // Ver Estado actual de funciones -
  536.     case  COMANDO232_FUNC_VEX:
  537.       switch(Modo){
  538.        case MODO_PROGRAMACION:
  539.           printf("Estado = %s, ",MODO_TXT_PROGRAMACION);
  540.           break;
  541.        case MODO_INACTIVO:
  542.           printf("Estado = %s, ",MODO_TXT_INACTIVO);
  543.           break;
  544.        case MODO_ACTIVO:
  545.           printf("Estado = %s, ",MODO_TXT_ACTIVO);
  546.           break;
  547.       }
  548.       printf("V.Ref.=%u, ",VALREF);
  549.       if(FUNC1) printf("F1 = ON, ");   else printf("F1 = OFF, ");
  550.       if(FUNC2) printf("F2 = ON, ");   else printf("F2 = OFF, ");
  551.       if(FUNC1) printf("F3 = ON\r\n ");  else printf("F3 = OFF\r\n");
  552.       break;
  553.  
  554.     // Ver Comandos almacenados por función -
  555.     case  COMANDO232_FUNC_VER:
  556.       printf("Address= %3u (0x%x)\r\n",ADDRESSDEV,ADDRESSDEV);
  557.       printf("Command= %3u (0x%x) %s\r\n",COMANDODEV_FUNC_ON,  COMANDODEV_FUNC_ON,  COMANDO232_TXT_FUNC_ON);
  558.       printf("Command= %3u (0x%x) %s\r\n",COMANDODEV_FUNC_1,   COMANDODEV_FUNC_1,   COMANDO232_TXT_FUNC_1);
  559.       printf("Command= %3u (0x%x) %s\r\n",COMANDODEV_FUNC_2,   COMANDODEV_FUNC_2,   COMANDO232_TXT_FUNC_2);
  560.       printf("Command= %3u (0x%x) %s\r\n",COMANDODEV_FUNC_3,   COMANDODEV_FUNC_3,   COMANDO232_TXT_FUNC_3);
  561.       printf("Command= %3u (0x%x) %s\r\n",COMANDODEV_FUNC_VEX, COMANDODEV_FUNC_VEX, COMANDO232_TXT_FUNC_VEX);
  562.       printf("Command= %3u (0x%x) %s\r\n",COMANDODEV_FUNC_VER, COMANDODEV_FUNC_VER, COMANDO232_TXT_FUNC_VER);
  563.       printf("Command= %3u (0x%x) %s\r\n",COMANDODEV_FUNC_RESET, COMANDODEV_FUNC_RESET, COMANDO232_TXT_FUNC_RESET);
  564.       printf("Command= %3u (0x%x) %s\r\n",COMANDODEV_FUNC_PLUS,  COMANDODEV_FUNC_PLUS,  COMANDO232_TXT_FUNC_PLUS);
  565.       printf("Command= %3u (0x%x) %s\r\n",COMANDODEV_FUNC_MINUS, COMANDODEV_FUNC_MINUS, COMANDO232_TXT_FUNC_MINUS);
  566.       break;
  567.     //-
  568.    }
  569.    opcion=0x00;
  570.   }
  571.   // Detecto FLASH LED --
  572.   if(flag_flash_led){
  573.    flag_flash_led=0;
  574.    flash_led(2);
  575.   }
  576.  } while (TRUE);
  577. }
Contra la estupidez los propios dioses luchan en vano. Schiller
Mi Güeb : Picmania

Desconectado RedPic

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 5538
    • Picmania by Redraven
Re: Decodificando un protocolo IR y obteniendo direcciones y comandos.
« Respuesta #12 en: 29 de Julio de 2006, 12:53:06 »
No Manolo, no me está recogiendo basura. En el anterior ejemplo, con el SONY SIRC si me cogía basura de vez en cuando, pero con este ANSONIC NEC-32 es absolutamente preciso y en todas las pruebas que he hecho no he notado que haya tomado erróneamente ni un solo comando.  :mrgreen:

Lo del SONY se lo achaco presumiblemente a que la portadora original es de 40 Khz y yo estoy decodificando con un TSOP1738 para portadoras de 38 Khz. Y en verdad que noté que cada veinte o treinta bits recogía uno que no era ni carne ni pescado, ni "0" ni "1" y me dejaba el recogedor hecho unos zorros ...  :D  :D  :D

P.D. Ya he puesto las imagenes al derecho
« Última modificación: 29 de Julio de 2006, 12:55:53 por RedPic »
Contra la estupidez los propios dioses luchan en vano. Schiller
Mi Güeb : Picmania

Desconectado RedPic

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 5538
    • Picmania by Redraven
Re: Decodificando un protocolo IR y obteniendo direcciones y comandos.
« Respuesta #13 en: 29 de Julio de 2006, 13:59:18 »
Y ahora vamos a abrir la siguiente fase, entrando en otros terrenos quizás mas interesantes:

Hasta ahora hemos estado jugando con protocolos conocidos y andando sobre caminos trillados por otros amigos .... y esto es una carga que debemos soportar. O sabemos qué es lo que esperamos recibir o ....

Leemos lo que llegue y tratamos de sacar conclusiones, independiente del protocolo que se use. Y a esto es a lo que me refiero. Deseo desarrollar un sistema que reciba "lo-que-sea" y sea capaz de establecer automáticamente cúal es el bit de start y cúales son los bits "1" y "0".

Y que sea capaz asimismo de discernir qué parte es la común a todos los comandos, normalmente el Address, y qué parte es única para cada uno de ellos, normalmente el Command ....

La recepción ha de ser muy similar a la implementada en el Analizador lógico que no entiende de protocolos, sino de tiempos ... y con esa información ver si somos capaces de sacar las conclusiones oportunas ...

Ahí os dejo un par de cronogramas tomados con el Analizador desde el mando del aire acondicionado de mi oficina, cuyo protocolo a lo mejor lo conocen sus constructores pero que no se parece a nada que yo conozca ... voy a ver cómo lo puedo masticar y tragar sin que se me atasque ...  :mrgreen:




Contra la estupidez los propios dioses luchan en vano. Schiller
Mi Güeb : Picmania

Desconectado flacomaida

  • PIC10
  • *
  • Mensajes: 17
Re: Decodificando un protocolo IR y obteniendo direcciones y comandos.
« Respuesta #14 en: 18 de Diciembre de 2007, 13:54:44 »
Y ahora vamos a abrir la siguiente fase, entrando en otros terrenos quizás mas interesantes:

Hasta ahora hemos estado jugando con protocolos conocidos y andando sobre caminos trillados por otros amigos .... y esto es una carga que debemos soportar. O sabemos qué es lo que esperamos recibir o ....

Leemos lo que llegue y tratamos de sacar conclusiones, independiente del protocolo que se use. Y a esto es a lo que me refiero. Deseo desarrollar un sistema que reciba "lo-que-sea" y sea capaz de establecer automáticamente cúal es el bit de start y cúales son los bits "1" y "0".

Y que sea capaz asimismo de discernir qué parte es la común a todos los comandos, normalmente el Address, y qué parte es única para cada uno de ellos, normalmente el Command ....

La recepción ha de ser muy similar a la implementada en el Analizador lógico que no entiende de protocolos, sino de tiempos ... y con esa información ver si somos capaces de sacar las conclusiones oportunas ...

Ahí os dejo un par de cronogramas tomados con el Analizador desde el mando del aire acondicionado de mi oficina, cuyo protocolo a lo mejor lo conocen sus constructores pero que no se parece a nada que yo conozca ... voy a ver cómo lo puedo masticar y tragar sin que se me atasque ...  :mrgreen:






Hola REdPic. Un favor. Me puedes enviar el LOGIC y como funciona?? Tambien ando en lo mismo. Hasta ahora trate de capturar la trama de un mando IR atravez de la placa de sonido con un editor de audio, idea de un amigo. Pero no se ve muy claro y tampoco el tiempo es preciso. Un abrazo...