Autor Tema: CODIGO Manchester en CCS  (Leído 9210 veces)

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

Desconectado fedemn6

  • PIC10
  • *
  • Mensajes: 8
CODIGO Manchester en CCS
« 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

Desconectado beto1234

  • PIC12
  • **
  • Mensajes: 52
    • Osm Gps Pwa
Re: CODIGO Manchester en CCS
« Respuesta #1 en: 18 de Octubre de 2011, 22:00:21 »
 Danos el nombre del transcistor y vemos si te podemos ayudar.

Desconectado fedemn6

  • PIC10
  • *
  • Mensajes: 8
Re: CODIGO Manchester en CCS
« Respuesta #2 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


Desconectado fedemn6

  • PIC10
  • *
  • Mensajes: 8
Re: CODIGO Manchester en CCS
« Respuesta #4 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.

Desconectado fedemn6

  • PIC10
  • *
  • Mensajes: 8
Re: CODIGO Manchester en CCS
« Respuesta #5 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.

Desconectado Arsenic

  • PIC10
  • *
  • Mensajes: 47
Re:CODIGO Manchester en CCS
« Respuesta #6 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.

Desconectado elreypic2

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1295
Re:CODIGO Manchester en CCS
« Respuesta #7 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.

Desconectado RALF2

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 2059
Re:CODIGO Manchester en CCS
« Respuesta #8 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

Desconectado Arsenic

  • PIC10
  • *
  • Mensajes: 47
Re:CODIGO Manchester en CCS
« Respuesta #9 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.

Desconectado Arsenic

  • PIC10
  • *
  • Mensajes: 47
Re:CODIGO Manchester en CCS
« Respuesta #10 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:


Desconectado elreypic2

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1295
Re:CODIGO Manchester en CCS
« Respuesta #11 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.

Desconectado Arsenic

  • PIC10
  • *
  • Mensajes: 47
Re:CODIGO Manchester en CCS
« Respuesta #12 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.

Desconectado Arsenic

  • PIC10
  • *
  • Mensajes: 47
Re:CODIGO Manchester en CCS
« Respuesta #13 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. */

Desconectado elreypic2

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1295
Re:CODIGO Manchester en CCS
« Respuesta #14 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.