TODOPIC

Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: fedemn6 en 18 de Octubre de 2011, 11:42:40

Título: CODIGO Manchester en CCS
Publicado por: fedemn6 en 18 de Octubre de 2011, 11:42:40
Hola amigos, che tengo un pegueño problema es que estoy por transmitir con un modulo de 493Mhz. y por lo que he leido tiene que trabajar con unos decoder o con codigo manchester. como ya tengo hecho el pcb no puedo agregarle mas componentes  pero tengo un micro que esta conectado directamente al modulo. la idea principal era transmitir por RS 232, pero estos modulos tiene un problema que cuando se transmiten 00 o mas cero el receptor aumenta su gannacia y se decajeta la transmicion. Bueno lo que ando buscando es si alguien renego con el codigo manchester ante y a hecho una libreria en CCS. Sino algo que me pueda ayudar
Título: Re: CODIGO Manchester en CCS
Publicado por: beto1234 en 18 de Octubre de 2011, 22:00:21
 Danos el nombre del transcistor y vemos si te podemos ayudar.
Título: Re: CODIGO Manchester en CCS
Publicado por: fedemn6 en 21 de Octubre de 2011, 10:54:09
Los modulos que estoy por usar son TX= TWS-BS-3(433.9) RX= RWS-371-6(433.9), tengo entendido que si no estas transmitiendo un alternacia de bits se decajeta la transimicion. por eso quiero usar codigo manchester
Título: Re: CODIGO Manchester en CCS
Publicado por: Nocturno en 22 de Octubre de 2011, 01:48:11
¿Has probado a buscar en Google? (http://www.docstoc.com/docs/27908303/Manchester-encoding-using-RS232-for-Microchip-PIC-RF-applications)
Título: Re: CODIGO Manchester en CCS
Publicado por: fedemn6 en 23 de Octubre de 2011, 12:58:01
si en eso estoy no he encontrado nada que funcione. queria ver si por aca alguien a renegado con lo mismo.  estoy tratando con un programa pero no le encuentro la vuelta.
Título: Re: CODIGO Manchester en CCS
Publicado por: fedemn6 en 24 de Octubre de 2011, 19:05:25
Hola a todos llevo 2 dia renegando con este codigo jajjaja. pero he avanzado mucho, lo unico que no se si es que esta funcionando mal PROTEUS o si esta mal el codigo, metira cualquier cosa la uart. lo que hice fue conetar dos micro  por puerto serie en donde el transmisor envia los datos del ADC y el receptro muetro los datos de ADC, sin convertilo a float. hay valores  en donde anda, pero con otro no. Aca le subo todo lo que he hecho, tanto codigo de Transmisor como el receptor y el ciruito

///////////////////////////////////////////////////////////////////////////RECEPTOR///////////////////////////////////////
#include <16f877a.h>
#FUSES NOWDT                    //No Watch Dog Timer
#FUSES HS                       //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#use standard_io(b)
#use delay(clock=20000000)
#use rs232(baud=2400,parity=N,xmit=PIN_A3,rcv=PIN_A2,bits=8)//,invert)
#include <flex_lcd.c>

int i=0;
////////////////////////////////DECODE MANCHESTER///////////////////////////////
 
int Recibir_dato(int dato)
{
    int i=0,dec=0,x=0,enc=0,band=0;
    enc = dato;
    x=0;
   
    for(i=3; i>0; i--)
       {band=0;       
        band=enc&0b11000000;     //corroboro que bit estan en 1 y 0, y voy haciendolo de 2 bit a dos bit
        if(band==0b10000000) //1
          {bit_set(dec,x); //coloco un 1 en la pocicion i
          }
        if(band==0b01000000) //0
         {bit_clear(dec,x); //coloco un 0 en la pocicion i
         }
        if((band==0b00)||(band==0b11)) //como el codigo manchester no acepta que se repitan los 00 ni los 11 devuelve un valor error.
            {return 0xff;              //lo uso para ver si trabaja bien el coder y decoder
            }
        enc<<=2;                       //desplazo asia la izquierda, el dato de dos en dos, es lo mismo que multiplicarlo en 4
        x++;
       }
     return dec;                      //devuelvo 4bit de la palabra
     dato=0;
}


Void main (void)
{ lcd_init();

int valor=0,low=0,high=0,datomanch=0,status=0,dato=0,valorfinal=0;
float p;

while(true)
{valor=0;
 low=0;
 high=0;
 datomanch=0;
 dato=0;
 valor = getc();                     //tomo los valores de la uart
 datomanch=recibir_dato(valor);      //envio los valores a la funcion
 if(status==0)                       //uso esta bandera para trabajar de 4 bit en 4bit. cuando es 0 trabajo con los bit 0 al 3,
 {status=1;                          //cuando es 1 trabajo con los bit 4 al 7
  low=datomanch;                     //low son los primeros 4 bit
  valorfinal=0;                      //utilizo esta bandera para que no me imprima el valor del ADC hasta que no tenga completo el el valor enviado del ADC
 }
 else
   {status=0;
    high=datomanch;                  //son los bit los utilmos 4 bit
    high<<=4;                       
    dato=(high | low);               //sumo todo los bit, recuperando el valor enviado
    valorfinal=1;
    }

 if(datomanch==0xff)                 // imprimo si hay error
  {printf(lcd_putc,"\fERROR");
  }
 else
   {if(valorfinal==1)             
    {p=(dato*5/(256-1));               //realizo la conversion del ADC
    printf(lcd_putc,"\fADC=%d",dato);  //imprimo los datos recibido del ADC
    //printf(lcd_putc,"\nVolt=%1.2fV",p);
    }
   }
   delay_ms(50);
}
}

/////////////////////////////////////////////////////////////////////////Transmisor/////////////////////////////////////////////////
#include <16f877A.h>
#device adc=8
#FUSES NOWDT                    //No Watch Dog Timer
#FUSES HS                       //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#use standard_io(b)
#use delay(clock=20000000)
#use rs232(baud=2400,parity=N,xmit=PIN_A3,rcv=PIN_A2,bits=8)//,invert)
#include <flex_lcd.c>


/////////////////////////////////CODE MANCHESTER////////////////////////////////
void Enviar_dato(int dato)
{
    int i,j,b,me,x;
    b=dato;
    for (i=0; i<2; i++)             //divido en 2 al BYTE y cada nibble los guardo y trabajo en "me".
    {   me = 0;                     //hay que recordar que el bit menos significativo esta a la derecha
        x=0;
        for (j=0 ; j<4; j++)
        {   if (bit_test(b,j))      // si en la posicion j del Byte b hay un 1 entonces pongo en el bit x===>0 y en el bitx++==>1
               {bit_clear(me,x);
                x++;
                bit_set(me,x);               
                x++;
               }
            else                   // si en la posicion j del Byte b hay un 0 entonces pongo en el bit x===>1 y en el bitx++==>0
               {bit_set(me,x);
                x++;
                bit_clear(me,x);
                x++;
               }
        }
        putc(me);
    }
}
void main()
{setup_adc_ports(AN0);
setup_adc(ADC_CLOCK_INTERNAL);
 
lcd_init();
int q;

while(true)
{
     set_adc_channel(0);
     delay_us(20);
     q=read_adc();
     Enviar_dato(q);
     
   
}
}



Otra consulta puede ser que cuando se transmite en RS232 el receptor reciba los datos invertidos ejemplo.

Transmitido==> 0b10100101
Recibido ===>0b01011010
Relacion
TX              RX
bit 0            bit6
bit 1            bit7
bit 2            bit4
bit 3            bit5
bit 4            bit2
bit 5            bit3
bit 6            bit0
bit7             bit1

yo creo que no pero eso es lo que me tira cuando lo debageo en el proteus.
si me pueden tirar una onda.

Gracias por la pagina, con ese prog empece y lo fui modificando por que no me andaba.
Título: Re:CODIGO Manchester en CCS
Publicado por: Arsenic en 25 de Septiembre de 2016, 23:58:00
Hola, amigos! Estoy en un proyecto similar, con dos PIC16F628A. Lo único que me falta lograr es que lea bit a bit, ya que raramente el array del rx me toma 2 bits y no uno por cada índice. Les mando la carpeta completa con el proyecto.
Título: Re:CODIGO Manchester en CCS
Publicado por: elreypic2 en 26 de Septiembre de 2016, 13:23:38
Que tal Arsenic,

No se a que te refieres con que necesitas es leer bit a bit. El puerto serie nunca lee dos bits, por naturaleza es imposible. Yo he implementado la codificación manchester usando lenguaje ensamblador y en Basic y he sido capaz de enviar hasta 32bytes en un solo frame, sin perdida de datos a una distancia de 50 metros sin obstáculos. Pero he visto el código que usas en C y es correcto en lo que respecta a  la forma de codificado y decodificado.

En la parte de transmisión lo único que veo un poco extraño es por que tienes que dejar un delay de 50ms entre cada byte transmitido.
        putc(me);
        delay_ms(50);

Eso no es necesario de hecho eso pudiera afectar tu recepcion ya que un tiempo tan largo sin recibir nada, el receptor cambiará su ganancia y comenzara a ver ruido, perdiendo así tu dato.
otra cosa que necesitas es enviar mas veces el dato $F0, ya que eso te ayudara a que el receptor fije su ganacia y al llegar el dato pueda procesarlo de la mejor manera.

Actualmente tienes esto:

         SS_data();
         SEND_DATA(0x53);
         SS_data();

Mi sugerencia es que hagas lo siguiente:
 
       SS_data();
       delay_ms(2);  //Este delay lo que hace es dejar en nivel alto el pin de transmision por otros 2 milisegundos.
       SS_data();
       delay_ms(2);
       SS_data();
       delay_ms(2);
       SS_data();
       delay_ms(2);
       SEND_DATA(0x53);
       SS_data();


Saludos y espero que esto te sirva.

Elreypic.
Título: Re:CODIGO Manchester en CCS
Publicado por: RALF2 en 26 de Septiembre de 2016, 13:34:34
Yo agregaría, si estas utilizando comunicación por Rf, que desactives el transmisor cuando no envies ningun dato y solo lo actives cuando vayas a realizar algun envio, esto ademas de ahorrar baterías si es tu caso tambien evita problemas en el receptor  :mrgreen:
El transmisor lo puedes habilitar y desactivar por medio de un transistor!

Saludos
Título: Re:CODIGO Manchester en CCS
Publicado por: Arsenic en 26 de Septiembre de 2016, 14:50:24
Que tal Arsenic,

No se a que te refieres con que necesitas es leer bit a bit. El puerto serie nunca lee dos bits, por naturaleza es imposible. Yo he implementado la codificación manchester usando lenguaje ensamblador y en Basic y he sido capaz de enviar hasta 32bytes en un solo frame, sin perdida de datos a una distancia de 50 metros sin obstáculos. Pero he visto el código que usas en C y es correcto en lo que respecta a  la forma de codificado y decodificado.

En la parte de transmisión lo único que veo un poco extraño es por que tienes que dejar un delay de 50ms entre cada byte transmitido.
        putc(me);
        delay_ms(50);



Eso no es necesario de hecho eso pudiera afectar tu recepcion ya que un tiempo tan largo sin recibir nada, el receptor cambiará su ganancia y comenzara a ver ruido, perdiendo así tu dato.
otra cosa que necesitas es enviar mas veces el dato $F0, ya que eso te ayudara a que el receptor fije su ganacia y al llegar el dato pueda procesarlo de la mejor manera.

Actualmente tienes esto:

         SS_data();
         SEND_DATA(0x53);
         SS_data();

Mi sugerencia es que hagas lo siguiente:
 
       SS_data();
       delay_ms(2);  //Este delay lo que hace es dejar en nivel alto el pin de transmision por otros 2 milisegundos.
       SS_data();
       delay_ms(2);
       SS_data();
       delay_ms(2);
       SS_data();
       delay_ms(2);
       SEND_DATA(0x53);
       SS_data();


Saludos y espero que esto te sirva.

Elreypic.

Muchas gracias por la sugerencia! Ando medio crudo en el tema todavía. Exactamente, la idea es tomar un código que manda un llaverito. Como el llavero es "code learn" tengo que además hacer el transmisor para cargarle los códigos.
Título: Re:CODIGO Manchester en CCS
Publicado por: Arsenic en 26 de Septiembre de 2016, 14:52:01
Yo agregaría, si estas utilizando comunicación por Rf, que desactives el transmisor cuando no envies ningun dato y solo lo actives cuando vayas a realizar algun envio, esto ademas de ahorrar baterías si es tu caso tambien evita problemas en el receptor  :mrgreen:
El transmisor lo puedes habilitar y desactivar por medio de un transistor!

Saludos

Hola, Ralf. Mira, estoy utilizando estos llaveros:

Título: Re:CODIGO Manchester en CCS
Publicado por: elreypic2 en 26 de Septiembre de 2016, 15:32:24
Que tal Arsenic,

Entonces lo que tu necesitas es otra cosa. El codigo manchester se utiliza para enviar tramas de datos. En tu caso es un poquito diferente. Regularmente existen dos tipos de contro remoto con "learning Mode".
1) El que usa un circuito integrado EV1527 que lo que hace es enviar una trama de 24 bits, de los cuales 20 bits son el identificador del control remoto y los otros cuatro bits son el estado de los botones. Si este es tu caso es muy simple emular el funcionamiento del EV1527, solo necesitas saber la frecuencia de operación (que depende de un resistor externo) verificalo y busca el datasheet del circuito y con eso podras emular el funcionamiento

2) Ahora bien si el circuito esta usando un encriptado del tipo KEELOG, ya es una historia muy diferente, ya que para realizar el protocolo necesitas comprar la licencia para generar correctamente los codigos.

Te sugiero que abras el control remoto y veas que es lo que utiliza. Y usando un sociloscopio o mejor aun un analizador logico para ver la señal transmitida y entonces analizarla para realizar "el clon" por así decirlo.

Saludos.

Elreypic.
Título: Re:CODIGO Manchester en CCS
Publicado por: Arsenic en 26 de Septiembre de 2016, 15:54:34
Gracias, elreypic2! El control ya lo desarmé hace tiempo. Utiliza un PIC12F629, el cual tiene la capacidad de copiar los códigos. Lo vende una empresa argentina, llamada SICCBA. Te dejo el manual con lo único que trae. Aparentemente tiene la capacidad de aprender cualquier código en cualquier formato.
Título: Re:CODIGO Manchester en CCS
Publicado por: Arsenic en 26 de Septiembre de 2016, 16:17:24
Hice las modificaciones al código que me sugeriste. El problema que estoy teniendo es que carga toda la trama a cada índice del array nib. Por lo tanto, no me lee bien y al no poder indizar correctamente, la decodificación se me imposibilita. Les dejo el código del RX modificado:

Código: CSS
  1. #include <16f628a.h>
  2. #fuses XT,NOPROTECT,NOCPD,NOBROWNOUT,NOPUT,NOWDT,NOLVP
  3. #use delay(clock=4000000, internal)
  4.  
  5. #use rs232(baud=600, xmit=pin_B2, rcv=pin_B1,ERRORS)
  6.  
  7. char c,a,i,dec,dec1,dec2,enc,pattern,son;
  8. char nib[6]; //
  9. char x;
  10.  
  11.  
  12. #define data   PIN_A0
  13. #define clock  PIN_A1
  14. #define Strobe PIN_A2
  15.  
  16. #include <lcd4094.c>
  17.  
  18. void gotit()
  19. {
  20.    output_high(pin_b5);
  21.    delay_ms(100);
  22.    output_low(pin_b5);
  23.    delay_ms(100);
  24.    output_high(pin_b5);
  25.    delay_ms(100);
  26.    output_low(pin_b5);
  27.    delay_ms(100);
  28.    output_high(pin_b5);
  29.    delay_ms(100);
  30.    output_low(pin_b5);
  31. }
  32.  
  33.  
  34.  
  35. BYTE DECODE_DATA()  //decode function for machester encoded data. This code is working fine. I checked it.
  36. {
  37.  
  38. for (i=0; i<7; i++)
  39. {
  40.    nib[i] = c;
  41.    
  42. }
  43.  
  44.  
  45. enc = nib[0];
  46.  
  47. //printf(lcd_putc,"%X",c);
  48. printf(lcd_putc,"%X",nib[0]);
  49.  
  50.     if (enc == 0xF0)    //  start/end condition encountered
  51.         return 0xF0;
  52.  
  53. enc = nib[0];
  54.  
  55.     dec = 0;    
  56.     for (i=0; i<4; i++) {
  57.    
  58.         dec >>=1;
  59.         pattern = enc & 0b11;        
  60.         if (pattern == 0b01)        // 1
  61.            bit_set(dec,3);
  62.         else if (pattern == 0b10)
  63.            bit_clear(dec,3);       // 0
  64.         else
  65.             return 0xff;            // illegal code
  66.            
  67.         enc >>=2;
  68.         dec1=dec;
  69.     }
  70. enc = nib[1];
  71.        
  72.          
  73.     dec = 0;    
  74.     for (i=0; i<4; i++) {
  75.    
  76.         dec >>=1;
  77.         pattern = enc & 0b11;        
  78.         if (pattern == 0b01)        // 1
  79.            bit_set(dec,3);
  80.         else if (pattern == 0b10)
  81.             bit_clear(dec,3);       // 0
  82.         else
  83.             return 0xff;            // illegal code
  84.            
  85.         enc >>=2;
  86.         dec2=dec;
  87.     }
  88.    
  89. enc = nib[0];
  90.  
  91.  
  92.     if (enc == 0xF0)    //  start/end condition encountered
  93.         return 0xF0;
  94.        
  95.        
  96. dec2<<=4;
  97. son=dec1|dec2;
  98. x=0;
  99. dec=0;
  100. dec1=0;
  101. dec2=0;
  102. gotit();
  103. return (son);
  104. }
  105.  
  106.  
  107.  
  108.  
  109.  
  110.  
  111. #int_rda
  112. void komut_al() //interrupt for receiving manchester coded data
  113. {
  114.  
  115. x=1;
  116.  
  117. disable_interrupts(int_rda);
  118. c=getc();
  119.  
  120.  
  121.  
  122.  
  123.  
  124. }
  125.  
  126. void main()
  127. {
  128. x=0;
  129. nib[0]=0;
  130. nib[1]=0;
  131.  
  132. enable_interrupts(int_rda);
  133. enable_interrupts(GLOBAL);
  134.  
  135. lcd_init();
  136.  
  137.  
  138.  
  139. while(true)
  140. {
  141.  
  142.    if  (x==1)
  143.    
  144.    {
  145.       x=0;
  146.      
  147.       a=DECODE_DATA();
  148.       //printf(lcd_putc,"%X",a);
  149.       //delay_ms(500);
  150.       //lcd_putc('\f');
  151.      
  152.             if  (a==0x41)
  153.                {
  154.                output_high(pin_b4);
  155.                }
  156.             if  (a==0x53)
  157.                {
  158.                output_low(pin_b4);
  159.                }
  160.                
  161.       enable_interrupts(int_rda);
  162.    
  163.    }
  164.    //delay_ms(1000);
  165.    //lcd_putc('\f');
  166.    }
  167.  
  168. }
  169.  
  170.  
  171. /*
  172.  
  173.  
  174.  
  175. */
Título: Re:CODIGO Manchester en CCS
Publicado por: elreypic2 en 26 de Septiembre de 2016, 17:00:19
Arsenic,

No entiendo lo que estas tratando de hacer. Las modificaciones que realizaste provocan cada vez peores problemas y no tienen sentido para mi.

Primero en la funcion de decodificacion tienes esto:

for (i=0; i<7; i++)
{
   nib = c;
   
}

Eso lo que hace es que tu array va a contener el mismo dato, es decir nib[0] al nib[6] son iguales.

Otra cosa, en la interrupcion ahora solo estas recibiendo un solo dato, al cual lo asignas a la variable c. No tiene logica lo que intentas hacer.

Mira, recibes un dato por la interrupcion del puerto serial y la asignas a la variable c;

c = getc();
supongamos que recibiste un 0xA5 (entonces c=0xA5) y haces que la variable x sea uno con:
x=1;

al regresar al propagra principal, es decir a la funcion main preguntas si x=1, como esa condicion se cumple entonces llama a la rutina de decodificacion, es decir la funcion DECODE_DATA. Al entrar a la función, inmediatamente llenas todo tu array con 0XA5 mediante el for que ya te indique anteriormente, lo que quiere decir que todo tu array desde nib[0] hasta nib[6] tiene el valo 0xA5. Entonces pasas a decodicar el dato, pero nib[0] y nib[1] tienen el mismo valor, por lo tanto no obtendras el valor correto decodificado. Puedes ver que la logica que usas no es correcta?

Cuando un dato (un byte) es codificado en manchester este produce 2 bytes y esos dos bytes tiene que ser transmitidos y el receptor espera esos dos bytes y luego los decodifica, tu recibas un dato, y quieres decodificar, eso no es posile, porque falta un dato.

Saludos,

Elreypic.
Título: Re:CODIGO Manchester en CCS
Publicado por: Arsenic en 26 de Septiembre de 2016, 17:30:30
Funcionando. Chequeame la función de decodificación, esa condición "IF" que le puse al principio. Tendría que probar mandarle otra cosa con el TX para ver si funciona bien en caso de no mandarle 4 veces el 0xF0. Observa:

Código: CSS
  1. #include <16f628a.h>
  2. #fuses XT,NOPROTECT,NOCPD,NOBROWNOUT,NOPUT,NOWDT,NOLVP
  3. #use delay(clock=4000000, internal)
  4.  
  5. #use rs232(baud=600, xmit=pin_B2, rcv=pin_B1,ERRORS)
  6.  
  7. char c,a,i,dec,dec1,dec2,enc,pattern,son;
  8. char nib[7]; //
  9. char x;
  10.  
  11.  
  12. #define data   PIN_A0
  13. #define clock  PIN_A1
  14. #define Strobe PIN_A2
  15.  
  16. #include <lcd4094.c>
  17.  
  18. void gotit()
  19. {
  20.    output_high(pin_b5);
  21.    delay_ms(100);
  22.    output_low(pin_b5);
  23.    delay_ms(100);
  24.    output_high(pin_b5);
  25.    delay_ms(100);
  26.    output_low(pin_b5);
  27.    delay_ms(100);
  28.    output_high(pin_b5);
  29.    delay_ms(100);
  30.    output_low(pin_b5);
  31. }
  32.  
  33.  
  34.  
  35. BYTE DECODE_DATA()  //decode function for machester encoded data. This code is working fine. I checked it.
  36. {
  37.  
  38. for (i=0; i<7; i++)
  39. {
  40.    nib[i] = getc();
  41.    
  42. }
  43.  
  44.  
  45. if (nib[0] == nib[1] == nib[2] == nib[3] == nib[6] == 0xF0)
  46. {
  47. return ;
  48. }
  49.  
  50.  
  51. enc = nib[4];
  52.  
  53.  
  54.  
  55.  
  56.     dec = 0;
  57.     for (i=0; i<4; i++) {
  58.    
  59.         dec >>=1;
  60.         pattern = enc & 0b11;        
  61.         if (pattern == 0b01)        // 1
  62.            bit_set(dec,3);
  63.         else if (pattern == 0b10)
  64.            bit_clear(dec,3);       // 0
  65.         else
  66.             return 0xff;            // illegal code
  67.            
  68.         enc >>=2;
  69.         dec1=dec;
  70.     }
  71. enc = nib[5];
  72.        
  73.          
  74.     dec = 0;    
  75.     for (i=0; i<4; i++)
  76.     {
  77.    
  78.         dec >>=1;
  79.         pattern = enc & 0b11;        
  80.         if (pattern == 0b01)        // 1
  81.            bit_set(dec,3);
  82.         else if (pattern == 0b10)
  83.             bit_clear(dec,3);       // 0
  84.         else
  85.             return 0xff;            // illegal code
  86.            
  87.         enc >>=2;
  88.         dec2=dec;
  89.        
  90.    }
  91.  
  92.  
  93. dec2<<=4;
  94. son=dec1|dec2;
  95. x=0;
  96. dec=0;
  97. dec1=0;
  98. dec2=0;
  99. gotit();
  100. return (son);
  101. }
  102.  
  103.  
  104.  
  105.  
  106.  
  107.  
  108.  
  109. #int_rda
  110. void komut_al() //interrupt for receiving manchester coded data
  111. {
  112.  
  113. x=1;
  114.  
  115. disable_interrupts(int_rda);
  116.  
  117.  
  118.  
  119.  
  120.  
  121.  
  122. }
  123.  
  124. void main()
  125. {
  126. x=0;
  127. nib[0]=0;
  128. nib[1]=0;
  129.  
  130. enable_interrupts(int_rda);
  131. enable_interrupts(GLOBAL);
  132.  
  133. lcd_init();
  134.  
  135.  
  136.  
  137. while(true)
  138. {
  139.  
  140.    if  (x==1)
  141.    
  142.    {
  143.       x=0;
  144.      
  145.       a=DECODE_DATA();
  146.       printf(lcd_putc,"%X",a);
  147.       //delay_ms(500);
  148.       //lcd_putc('\f');
  149.      
  150.             if  (a==0x41)
  151.                {
  152.                output_high(pin_b4);
  153.                }
  154.             if  (a==0x53)
  155.                {
  156.                output_low(pin_b4);
  157.                }
  158.                
  159.       enable_interrupts(int_rda);
  160.    
  161.    }
  162.    //delay_ms(1000);
  163.    //lcd_putc('\f');
  164.    }
  165.  
  166. }
  167.  
  168.  
  169. /*
  170.  
  171.  
  172.  
  173. */
Título: Re:CODIGO Manchester en CCS
Publicado por: elreypic2 en 26 de Septiembre de 2016, 17:46:15
Por lo que veo lo estas simulando en proteus, verdad?

Bueno, pues en la realidad temo decirte que el primer 0xF0 que transmitas se perderá, es decir el receptor no podra recibirlo correctamente debido a que esta ajustando su ganancia para recibir los datos, esa es la razon por la cual necesitas envia varias veces el dato. La idea es que si el receptor recibe ese dato lo descarte ya que no puede exitir un dato de ese tipo cunado codificas en manchester, lo unicos pares validos son "10" y "01" los pares "11" y "00" son invalidos y sirven para detectar un error en la transmision-recepcion de los datos.

Yo no compararias todos los datos entre sí como lo haces en tu if. Lo correcto es que si el dato recibido es un 0xF0 descartes el dato, y si no es ese dato entonces considerarlo como dato valido a m,enos que este contenga un par invalido. De hecho la funcion detecta esos pares invalidos y por lo tanto te regresa un dato FF, indicando que el dato recibido es invalido.

Saludos,

Elreypic.
Título: Re:CODIGO Manchester en CCS
Publicado por: Arsenic en 26 de Septiembre de 2016, 18:34:00
Ok, guardaré las que no sean 0xF0 en otro array de 2 datos.
Título: Re:CODIGO Manchester en CCS
Publicado por: Arsenic en 26 de Septiembre de 2016, 19:29:22
.
Título: Re:CODIGO Manchester en CCS
Publicado por: Arsenic en 26 de Septiembre de 2016, 19:42:53
¿Así te convence más? Hice un "scanf" generada por un while, guardando los datos diferentes a 0xF0 en el array dat de longitud 2.

Código: CSS
  1. #include <16f628a.h>
  2. #fuses XT,NOPROTECT,NOCPD,NOBROWNOUT,NOPUT,NOWDT,NOLVP
  3. #use delay(clock=4000000, internal)
  4.  
  5. #use rs232(baud=600, xmit=pin_B2, rcv=pin_B1,ERRORS)
  6.  
  7. char c,a,i,j,n,dec,dec1,dec2,enc,pattern,son;
  8. char nib[7]; //
  9. char dat[2];
  10.  
  11. char x;
  12.  
  13.  
  14. #define data   PIN_A0
  15. #define clock  PIN_A1
  16. #define Strobe PIN_A2
  17.  
  18. #include <lcd4094.c>
  19.  
  20. void gotit()
  21. {
  22.    output_high(pin_b5);
  23.    delay_ms(100);
  24.    output_low(pin_b5);
  25.    delay_ms(100);
  26.    output_high(pin_b5);
  27.    delay_ms(100);
  28.    output_low(pin_b5);
  29.    delay_ms(100);
  30.    output_high(pin_b5);
  31.    delay_ms(100);
  32.    output_low(pin_b5);
  33. }
  34.  
  35.  
  36.  
  37. BYTE DECODE_DATA()  //decode function for machester encoded data. This code is working fine. I checked it.
  38. {
  39.  
  40. for (i=0; i<7; i++)
  41. {
  42.    nib[i] = getc();
  43.    
  44. }
  45.  j=0;
  46.  n=0;
  47. while (j<2)
  48. {
  49.  
  50.    if (nib[n]!=0xF0)
  51.       {
  52.          dat[j]=nib[n];
  53.          j++;
  54.       }
  55.    n++;
  56.    
  57. }
  58.  
  59.  
  60.  
  61. enc = dat[0];
  62. //printf(lcd_putc,"%X",enc);
  63.  
  64.     dec = 0;
  65.     for (i=0; i<4; i++) {
  66.    
  67.         dec >>=1;
  68.         pattern = enc & 0b11;        
  69.         if (pattern == 0b01)        // 1
  70.            bit_set(dec,3);
  71.         else if (pattern == 0b10)
  72.            bit_clear(dec,3);       // 0
  73.         else
  74.             return 0xff;            // illegal code
  75.            
  76.         enc >>=2;
  77.         dec1=dec;
  78.     }
  79. enc = dat[1];
  80.        
  81.          
  82.     dec = 0;    
  83.     for (i=0; i<4; i++)
  84.     {
  85.    
  86.         dec >>=1;
  87.         pattern = enc & 0b11;        
  88.         if (pattern == 0b01)        // 1
  89.            bit_set(dec,3);
  90.         else if (pattern == 0b10)
  91.             bit_clear(dec,3);       // 0
  92.         else
  93.             return 0xff;            // illegal code
  94.            
  95.         enc >>=2;
  96.         dec2=dec;
  97.        
  98.    }
  99.  
  100.  
  101. dec2<<=4;
  102. son=dec1|dec2;
  103. x=0;
  104. dec=0;
  105. dec1=0;
  106. dec2=0;
  107. gotit();
  108. return (son);
  109. }
  110.  
  111.  
  112.  
  113.  
  114.  
  115.  
  116.  
  117.  
  118. #int_rda
  119. void komut_al() //interrupt for receiving manchester coded data
  120. {
  121.  
  122. x=1;
  123.  
  124. disable_interrupts(int_rda);
  125.  
  126.  
  127.  
  128.  
  129.  
  130.  
  131. }
  132.  
  133. void main()
  134. {
  135. x=0;
  136. dat[0]=0;
  137. dat[1]=0;
  138.  
  139. enable_interrupts(int_rda);
  140. enable_interrupts(GLOBAL);
  141.  
  142. lcd_init();
  143.  
  144.  
  145.  
  146. while(true)
  147. {
  148.  
  149.    if  (x==1)
  150.    
  151.    {
  152.       x=0;
  153.      
  154.       a=DECODE_DATA();
  155.       printf(lcd_putc,"%X",a);
  156.       //delay_ms(500);
  157.       //lcd_putc('\f');
  158.      
  159.             if  (a==0x41)
  160.                {
  161.                output_high(pin_b4);
  162.                }
  163.             if  (a==0x53)
  164.                {
  165.                output_low(pin_b4);
  166.                }
  167.                
  168.       enable_interrupts(int_rda);
  169.    
  170.    }
  171.    //delay_ms(1000);
  172.    //lcd_putc('\f');
  173.    }
  174.  
  175. }
Título: Re:CODIGO Manchester en CCS
Publicado por: elreypic2 en 27 de Septiembre de 2016, 01:21:18
Que tal Arsenic,

Me parece que no estas entendiendo mi punto. No se trata de si me gusta o no, se trata de que el funcionamiento sea el esperado.
Yo no he usado de esta manera la transmision RF, si bien he usado la codificación manchester, pero yo uso el puerto serial en forma invertida, de esta manera garantizo que mientras no se transmite ningun dato el transmisor esta apagado.
Usando el puerto serial en modo normal, el transmisor seria algo así:

Código: C
  1. void SEND_DATA(BYTE txbyte)
  2. {
  3.     int i,j,b,me;  
  4.     b = txbyte;  
  5.     for (i=0; i<2; i++)
  6.     {
  7.         me = 0;         // manchester encoded txbyte
  8.         for (j=0 ; j<4; j++)
  9.         {
  10.             me >>=2;
  11.             if (bit_test(b,0))
  12.                 me |= 0b01000000; // 1->0
  13.             else
  14.                 me |= 0b10000000; // 0->1
  15.             b >>=1;
  16.         }
  17.         putc(me);        
  18.     }
  19. }
  20.  
  21.  
  22. void main()
  23. {
  24.    int8  txdata;
  25.    //output_low (PIN_A1);
  26.    //delay_ms(1);
  27.    setup_comparator(NC_NC);
  28.    setup_vref(FALSE);
  29.    while (1)
  30.    {
  31.       for (txdata=0x30; txdata<=0x39; txdata++)
  32.          {
  33.             putc(0xF0);
  34.             putc(0xF0);
  35.             putc(0xF0);
  36.             putc(0xF0);
  37.             SEND_DATA(txdata);
  38.             putc(0xF0);
  39.             //output_low(PIN_A1);
  40.             delay_ms(1000);
  41.          }
  42.    }
  43. }

Y el receptor seria algo como esto:

Código: C
  1. int8  nib[2], x, a;
  2.  
  3. BYTE DECODE_DATA()  //decode function for machester encoded data. This code is working fine. I checked it.
  4. {
  5.    int8 enc, dec, pattern, dec1, dec2, son, i;
  6.    enc = nib[0];
  7.        
  8.     //if (enc == 0xf0)    //  start/end condition encountered
  9.         //return 0xf0;
  10.        
  11.     dec = 0;    
  12.     for (i=0; i<4; i++) {
  13.    
  14.         dec >>=1;
  15.         pattern = enc & 0b11;        
  16.         if (pattern == 0b01)        // 1
  17.            bit_set(dec,3);
  18.         else if (pattern == 0b10)
  19.            bit_clear(dec,3);       // 0
  20.         else
  21.             return 0xff;            // illegal code
  22.            
  23.         enc >>=2;
  24.         dec1=dec;
  25.     }
  26.    enc = nib[1];
  27.        
  28.     //if (enc == 0xf0)    //  start/end condition encountered
  29.         //return 0xf0;
  30.        
  31.          
  32.     dec = 0;    
  33.     for (i=0; i<4; i++) {
  34.    
  35.         dec >>=1;
  36.         pattern = enc & 0b11;        
  37.         if (pattern == 0b01)        // 1
  38.            bit_set(dec,3);
  39.         else if (pattern == 0b10)
  40.             bit_clear(dec,3);       // 0
  41.         else
  42.             return 0xff;            // illegal code
  43.            
  44.         enc >>=2;
  45.         dec2=dec;
  46.     }
  47.    dec2<<=4;
  48.    son=dec1|dec2;
  49.    x=0;
  50.    dec=0;
  51.    dec1=0;
  52.    dec2=0;
  53.    return (son);
  54. }
  55.  
  56.  
  57. void main()
  58. {
  59.    setup_comparator(NC_NC);
  60.    setup_vref(FALSE);
  61.    while (1)
  62.    {
  63.       do
  64.       {
  65.          nib[0] = getc();
  66.       } while ((nib[0]==0xF0)||(nib[0]==0xFF));
  67.       nib[1] = getc();
  68.       a = DECODE_DATA();
  69.       putc(a);
  70.       putc(13);
  71.       putc(10);
  72.    }
  73.    
  74. }

He simulado los codigos en proteus usando los PIC12F629 y trabaja bien. Pero esto no quiere decir que vaya a funcionar en la realidad.

Espero esto te sirva.

Saludos.

elreypic.
Título: Re:CODIGO Manchester en CCS
Publicado por: Arsenic en 27 de Septiembre de 2016, 22:27:55
El "Así te convence?" es como un "Así sería?" en este País. entiendo tu punto pero el tema es que el llavero que me tocó, no aprende el código y por ende tengo que pensar que está mal.
Título: Re:CODIGO Manchester en CCS
Publicado por: elreypic2 en 28 de Septiembre de 2016, 11:55:08
Que tal Arsenic,

Gracias por la explicación en cuanto a la interpretación del "Así te convence?".
Por lo que ahora describes lo que quieres es realizar un emisor y que ese se grabe en el llavero de siccba?
Si es así yo creo que estas en el camino equivocado. Lo primero que yo haría es saber que tipo de "code learn" usa el llavero de siccba, si este es fijo (fixed code) como el del ev1527 o usa un rolling code (Keeloq).
Si usa un fixed code como el del ev1527, ese no usa codificación manchester, este usa codificacion por PWM. Te recomiendo leer el datasheet del ev1527. Para realizar un llavero "clon" emisor de ev1527 es muy sencillo y te puedo ayudar.

Ahora bien si usa un rollin code ahi se complica la situación. En ese campo no tengo experiencia pero hay muchísima información en la página de microchip.

Saludos,

elreypic.
Título: Re:CODIGO Manchester en CCS
Publicado por: doppel en 29 de Septiembre de 2016, 09:22:49
Hola Arsenic, conozco un poco esos controles que mencionas.... dime de que color es el led del que tu tienes??
Título: Re:CODIGO Manchester en CCS
Publicado por: Arsenic en 06 de Octubre de 2016, 09:03:44
Ya logré decodificarlos! No se preocupen. Puse la data en otro thread. Un saludo!
Título: Re:CODIGO Manchester en CCS
Publicado por: elreypic2 en 06 de Octubre de 2016, 11:56:03
Que tal Arsenic,

Seria bueno que compartieras la información y la forma en que los decodificaste, por si alguien mas en el futuro tiene esta necesidad.

Saludos,

elreypic.
Título: Re:CODIGO Manchester en CCS
Publicado por: Arsenic en 09 de Octubre de 2016, 03:43:48
Me temo que este thread es para tratar la codificación Manchester. Yo me puse a publicar sobre la TPO, la cual es muy diferente y por cierto un tanto más compleja. Le debo una disculpa al autor del hilo y a los administradores.
Título: Re:CODIGO Manchester en CCS
Publicado por: tsk en 18 de Octubre de 2016, 10:52:44
Que tal, tal vez les interese el hecho de que algunos de los nuevos microcontroladores de Microchip vienen Celdas Lógicas Configurables

http://ww1.microchip.com/downloads/en/DeviceDoc/40001825A.pdf

Y uno de los ejemplos incluidos en el siguiente archivo realiza la codificación Manchester usando esas celdas.
http://ww1.microchip.com/downloads/en/DeviceDoc/41631B.pdf

El 16f628a que manejan aquí tiene un costo de 2.14 en mouser, y el 16f18875 es de 2.22 o el 16f18855 a 1.97
Título: Re:CODIGO Manchester en CCS
Publicado por: Arsenic en 02 de Mayo de 2017, 22:43:54
Arsenic,

No entiendo lo que estas tratando de hacer. Las modificaciones que realizaste provocan cada vez peores problemas y no tienen sentido para mi.

Primero en la funcion de decodificacion tienes esto:

for (i=0; i<7; i++)
{
   nib = c;
   
}

Eso lo que hace es que tu array va a contener el mismo dato, es decir nib[0] al nib[6] son iguales.

Otra cosa, en la interrupcion ahora solo estas recibiendo un solo dato, al cual lo asignas a la variable c. No tiene logica lo que intentas hacer.

Mira, recibes un dato por la interrupcion del puerto serial y la asignas a la variable c;

c = getc();
supongamos que recibiste un 0xA5 (entonces c=0xA5) y haces que la variable x sea uno con:
x=1;

al regresar al propagra principal, es decir a la funcion main preguntas si x=1, como esa condicion se cumple entonces llama a la rutina de decodificacion, es decir la funcion DECODE_DATA. Al entrar a la función, inmediatamente llenas todo tu array con 0XA5 mediante el for que ya te indique anteriormente, lo que quiere decir que todo tu array desde nib[0] hasta nib[6] tiene el valo 0xA5. Entonces pasas a decodicar el dato, pero nib[0] y nib[1] tienen el mismo valor, por lo tanto no obtendras el valor correto decodificado. Puedes ver que la logica que usas no es correcta?

Cuando un dato (un byte) es codificado en manchester este produce 2 bytes y esos dos bytes tiene que ser transmitidos y el receptor espera esos dos bytes y luego los decodifica, tu recibas un dato, y quieres decodificar, eso no es posile, porque falta un dato.

Saludos,

Elreypic.

Gracias a las pistas que me has dado he podido resolver los errores que tenía mi código. ¡Infinitas gracias por la ayuda!
Título: Re:CODIGO Manchester en CCS
Publicado por: Arsenic en 23 de Octubre de 2017, 06:27:49
Que tal Arsenic,

Seria bueno que compartieras la información y la forma en que los decodificaste, por si alguien mas en el futuro tiene esta necesidad.

Saludos,

elreypic.

Aquí está. Es el último mensaje en este thread.
http://www.todopic.com.ar/foros/index.php?action=post;quote=390966;topic=26071.15;last_msg=390966 (http://www.todopic.com.ar/foros/index.php?action=post;quote=390966;topic=26071.15;last_msg=390966)