Autor Tema: Lector Tren de Pulsos RB0  (Leído 4380 veces)

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

Desconectado facundo_10

  • Colaborador
  • PIC16
  • *****
  • Mensajes: 179
    • DAVINCIPIC
Lector Tren de Pulsos RB0
« en: 28 de Julio de 2011, 22:28:32 »
Hola a todos, después de haberme leído y comido todos los posts de Redpic, me dedico a hacer mi propio programa, el tema es el siguiente, tengo 2 circuitos, 1 con un pic que envía pulsos (mi generador de funciones  :P), con otro pic con interfaz rs232 que recibe por interrupción en B0, el tren de pulsos generado por el primer circuito es interpretado con el 2do circuito..

Con mi circuito envio la siguiente secuencia.

START BIT = 1 en alto por 1500 us

luego envio 4 bits

1
0
1
1

es decir la letra B

y luego un stop BIT que es un 1 en 2500 us.

Cada 1 y 0 que seria lo del dato dura 100 us, en este caso yo tengo conocimiento de cuanto dura cada bit, pero no logro terminar de entender como determinar la cantidad de bits que tengo por el ancho..

Yo se que un bit 1 dura 100 us, para la interrupción uso el siguiente código:

Código: [Seleccionar]
#int_ext
void handle_ext_int(){

  if(flagToggleFlanco==0){   // He recibido Flanco de Subida

    t1=get_timer1();        // Guardo en t1 el valor de TMR1 al Flanco de Subida
    ext_int_edge(0,H_TO_L); // Configuro para capturar siguiente flanco de Bajada
    flagToggleFlanco=1;     // Indico que el siguiente flanco será de Bajada

  } else {                  // He recibido Flanco de Bajada

    t2=get_timer1();        // Guardo en t2 el valor de TMR1 al Flanco de Bajada
    ext_int_edge(0,L_TO_H); // Configuro para capturar siguiente flanco de subida
    flagToggleFlanco=0;     // Indico que el siguiente flanco será de Subida
    set_timer1(0);          // Reinicio TMR1
    if(flagHayDatos==0){    // Si los datos anteriores han sido procesados ...
      flagHayDatos=1;       // Indico que ya hay nuevos datos de flancos para calcular
    }
  }
}

Ese código me estaría dando el ancho del pulso en ALTO,



t2 - t1 me da el total del pulso en ALTO, si ese total lo divido por los 100us, que es el tiempo de 1 bit en alto, me daria la cantidad de bits es decir la cantidad de unos 111111 ??

Indefectiblemente si la proxima vez que entro en la int, hago t1 - t2, me da el tiempo que estuve en LOW, es decir BAJO, si eso lo divido por el tiempo que dura un bit en bajo/alto para este caso es lo mismo, obtengo la cantidad de bits en bajo...

Es esta la forma de hacerlo?

Después deberé escribir en un vector, unos o ceros dependiendo...

En el ejemplo de Redpic del control remoto IR, el usa el siguiente código:

Código: [Seleccionar]
#int_ext
void ext_isr() {

   // Obtengo datos de Timer0
   tt = get_timer0();
   t = tt-tti;
   tti= tt;

   // Si he recibido el Start Bit puedo guardar
   if(start_recived==1){
      // Bit "0"
      if(t>40 && t<50){ sbits[ntbits]='0'; }
      // Bit "1"
      if(t>85 && t<90){ sbits[ntbits]='1'; }
      // Si he recibido 32 bits entonces hay dato
      if(++ntbits==total_bits){
         hay_dato=1;
      }
   }

   // Detecto Start Bit
   if(t>525 && t<530){
      start_recived=1;
      limpia_bits();
   }
}

Entiendo que el código de Redpic, detecta dependiendo lo que dura cada tick, si es un 1 o un 0, pero en que parte calcula el numero de ceros o unos dependiendo el ancho del pulso, a menos que en el infrarrojo indefectiblemente después de 1 venga un 0...

Nose si me hago entender.

UN saludo
« Última modificación: 28 de Julio de 2011, 22:35:54 por facundo_10 »
PICMANIACO!

Desconectado rivale

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1707
Re: Lector Tren de Pulsos RB0
« Respuesta #1 en: 28 de Julio de 2011, 22:59:37 »
no se si te entendi bien, pero creo que lo que quieres hacer es saber cuando recibes un "1" y cuando recibes un "0", yo lo que hago es darle a los "1" un ancho de pulso mayor que a los "0".
para leer el ancho de los pulsos lo que hago es que en cuanto recibo una interrrupcion por flanco ascendente pongo a cero un timer y cambio la interrupcion para que la siguiente sea por flanco descendente, y en cuanto recibo la interrupcion por flanco descendente leo el valor del timer y ya tengo el valor del ancho del pulso.
asi ya no tienes que hacer la resta de t2-t1.

y conociendo el ancho de tus pulsos tu identificas si lo que recibiste fue un "1" o un "0"

espero te sirva.  :-)
"Nada es imposible, no si puedes imaginarlo"

Desconectado facundo_10

  • Colaborador
  • PIC16
  • *****
  • Mensajes: 179
    • DAVINCIPIC
Re: Lector Tren de Pulsos RB0
« Respuesta #2 en: 28 de Julio de 2011, 23:09:36 »
Si, entiendo lo que dices, pero en la practica, es decir en distintos equipos, los 1 y los 0 tienen el mismo ancho, es decir donde yo no armo mi protocolo, esto es solo una prueba del programa, después lo migrare, el proyecto es un interceptor de tramas VAN BUS en el coche, donde cada bit tiene un tiempo de 8 us, es decir un 0 y un 1 ambos tiene el mismo ancho 8 us, por lo cual el ancho de ceros y unos no me sirve para sabes que si es 0 o si es 1, para eso uso flanco de subida y bajada para saber que estoy en el techo del tren de pulsos es decir en la parte alta.

Ademas, el tema es que aquí en un flanco de subida, hasta el de bajada puedo tener 10 unos, no un solo 1 , nose si me explico..

para interpretar esto 11111000011110001111 con interrupción por RB0, es distinto de saber cuando viene un 1 o un 0, ya que allí tengo muchos unos y muchos ceros, me explico?

Mi idea es que al portb.0 del micro le llegue una trama como esta por ejemplo:

START BIT    11111000011110001111 STOP BIT

y procesar esa trama y sacar por el puerto serie lo mismo, o en código ASCII, en bytes etc etc etc..
PICMANIACO!

Desconectado rivale

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1707
Re: Lector Tren de Pulsos RB0
« Respuesta #3 en: 28 de Julio de 2011, 23:19:29 »
si tienen el mismo ancho de pulso que los diferencia entre si?.

y si haces lo que mencionas de dividir el tiempo total entre el ancho de los "1" sabrias cuantos "1"s tienes, pero no sabrias en que orden se recibieron


Ademas, el tema es que aquí en un flanco de subida, hasta el de bajada puedo tener 10 unos, no un solo 1 , nose si me explico..

no creo que sea asi, ya que si para cada bit tienes un cambio de flanco, no tendrias una sola interrupcion(de subida y bajada) para toda la trama de datos, tendrias una en flanco de subida y otra en flanco de bajada por cada bit que recibas.


 :huh: aunque todavia no se si te estoy entendiendo bien  :D.
"Nada es imposible, no si puedes imaginarlo"

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: Lector Tren de Pulsos RB0
« Respuesta #4 en: 28 de Julio de 2011, 23:27:36 »
  A ver si puedo aportar algo....

  Podrías entrar en la interrupción con el flanco de subida del bit de start, y luego procesar todo allí. Sé que puede resultar un poco ineficiente., pero dependerá de tus requerimientos.

  Una vez que se entrás en la interrupción, esperás 1550us (1500 us que dura el bit de start + 50 us que es la mitad de lo que te dura un bit de dato), y lees el estado del pin para saber si hay un 1 o un 0. Esperás 100 us (estarías a la mitad del siguiente pulso) y lees el estado del pin para saber si hay un 1 o un 0... y así hasta leer todos los bits. Por supuesto tenés que saber de antemano de cuantos bits es la transmisión que estás recibiendo.
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado facundo_10

  • Colaborador
  • PIC16
  • *****
  • Mensajes: 179
    • DAVINCIPIC
Re: Lector Tren de Pulsos RB0
« Respuesta #5 en: 28 de Julio de 2011, 23:34:10 »
AngelGris, entiendo lo que dices, pero no servirá para mi aplicación, ya que los comandos son variables, para el bit de start, se que vale 1000 us, para detectarlo, hago la interrupción por RB0 con flanco de subida, y luego con flanco de bajada, si los tiempos (t2-t1) me dio 1000 us, significa que estoy en el START_bit... Una vez pasado el start bit debo empezar a decodificar lo que me entra por B0, supongamos que me llega un byte, 0101 1100, sabiendo lo que dura un bit, puedo sacar la cantidad de bits, me parece que el principio seria así, de momento no veo como implementarlo, si alguien me echa un hilo lo voy a agradecer !

Gracias por sus respuestas
PICMANIACO!

Desconectado rivale

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1707
Re: Lector Tren de Pulsos RB0
« Respuesta #6 en: 29 de Julio de 2011, 00:17:37 »
si tu numero de bits es variable puedes usar un bit de stop para saber cuando acabaste de recibir datos. por lo que entiendo quieres primero saber cuantos datos recibiste, pero despues para saber cuales datos fueron necesitarias repetir la señal para volverlos a nalizar.

lo ideal seria que para cada dato hagas lo mismo que para el bit de start, medir la duracion de los pulsos ya sea en alto o bajo y diferenciarlos para irlos guardando, hasta que leas el bit de stop.

asi solo necesitas recibir una vez el tren de pulsos para hacer todo el analisis
"Nada es imposible, no si puedes imaginarlo"

Desconectado facundo_10

  • Colaborador
  • PIC16
  • *****
  • Mensajes: 179
    • DAVINCIPIC
Re: Lector Tren de Pulsos RB0
« Respuesta #7 en: 29 de Julio de 2011, 00:39:23 »
Si mi numero de bits, sera variable, en la prueba que hago, yo envio un BIT_START y al final de todos los bits, un bit stop, el código me queda algo, así para saber donde tomar el dato,

Código: [Seleccionar]
#int_ext
void handle_ext_int(){

  if(flagToggleFlanco==0){   // He recibido Flanco de Subida

    t1=get_timer1();        // Guardo en t1 el valor de TMR1 al Flanco de Subida
    ext_int_edge(0,H_TO_L); // Configuro para capturar siguiente flanco de Bajada
    flagToggleFlanco=1;     // Indico que el siguiente flanco será de Bajada

  } else {                  // He recibido Flanco de Bajada

    t2=get_timer1();        // Guardo en t2 el valor de TMR1 al Flanco de Bajada
    ext_int_edge(0,L_TO_H); // Configuro para capturar siguiente flanco de subida
    flagToggleFlanco=0;     // Indico que el siguiente flanco será de Subida
    set_timer1(0);          // Reinicio TMR1
    }


if(t2 > 900 && t1 <  1100){   // Chequeo si recibi el bit de start..
start_b = 0x01;
}

if(start_b == 0x01){ // si recibo el bit de start
while(stop_b == 0x01){   //trunco la data hasta recibir el bit de stop...
// estoy en el dato
// aca que hago?
tt = t2 - t1;  // tiempo en alto
numero_bits_alto = tt/tiempo_bit;
// dentro del while tengo que seguir tomando los datos de la interrupción....aqui es donde entro en conflicto con mi programa...



if(t2 > 1900 && t1 <  2100){   // Chequeo si recibi el bit de stop para salir de mi while...
stop_b = 0x01;
}

}




}



Rivale me seguis? Perdon si no se explicarme bien..

Gracias por tu ayuda
PICMANIACO!

Desconectado facundo_10

  • Colaborador
  • PIC16
  • *****
  • Mensajes: 179
    • DAVINCIPIC
Re: Lector Tren de Pulsos RB0
« Respuesta #8 en: 29 de Julio de 2011, 00:44:19 »
Si mal no entiendo, en el código de Redpic si o si debe haber un cambio de flanco, para que vuelva a entrar a la interrupción....

Código: [Seleccionar]
#int_ext
void ext_isr() {
 
   // Obtengo datos de Timer0
   tt = get_timer0();
   t = tt-tti;
   tti= tt;
 
   // Si he recibido el Start Bit puedo guardar
   if(start_recived==1){
      // Bit "0"
      if(t>40 && t<50){ sbits[ntbits]='0'; }
      // Bit "1"
      if(t>85 && t<90){ sbits[ntbits]='1'; }
      // Si he recibido 32 bits entonces hay dato
      if(++ntbits==total_bits){
         hay_dato=1;
      }
   }
 
   // Detecto Start Bit
   if(t>525 && t<530){
      start_recived=1;
      limpia_bits();
   }
}
 

Nose entonces como es que descodifica si se manda 1111111 porque en esa secuencia no hay cambio de flanco y el solo escribirá un 1, en ves de los 1111111
PICMANIACO!

Desconectado rivale

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1707
Re: Lector Tren de Pulsos RB0
« Respuesta #9 en: 29 de Julio de 2011, 00:57:49 »
si, ya entendi que quieres hacer, es algo como lo que mencionaba anglegris, te quedas dentro de la interrupcion mientras recobes todos los datos. el problema con esto es que necesitarias recibir la misma trama de datos vairas veces para analizarla bien.

puedes hacer algo asi:

Código: [Seleccionar]
#int_ext
void datos()
{
if(flagToggleFlanco==0)
   {   // He recibido Flanco de Subida

   set_timer1(0);//pones en 0 al timer1
    ext_int_edge(0,H_TO_L); // Configuro para capturar siguiente flanco de Bajada
    flagToggleFlanco=1;     // Indico que el siguiente flanco será de Bajada

  }
 else
  {                  // He recibido Flanco de Bajada

    t2=get_timer1();        // como pusiste tu timer en 0 en el flanco anterior yta no necesitas hacer la resta.
    ext_int_edge(0,L_TO_H); // Configuro para capturar siguiente flanco de subida
    flagToggleFlanco=0;     // Indico que el siguiente flanco será de Subida
    datos[i]=t2
     if(datos[0]>1400 && datos[0]<1600)//checas que sea el bit de star con una tolerancia
      {
          datos[i]=t2;
          i++;
             if(datos[i]==/*bit stop*/)//aca checas si es el bit de stop
               {
                      i=0;//si es el bit de stop reinicias tu contador para poder recibir otra cadena
                      //cuando llegues a esto entonces ya puedes enviar tu trama completa por rs232 o como quieras
               }
        }
    }

}




espero te ayude, es un pequeño ejemplo para darte una idea de mi manera de resolverlo, lo que te comentaba era ir guardando los datos en un vector una vez que recibes el bit de star, y cuando recibes el bit de stop entonces dejas de guardarlos y reinicias tus variables.

mientras no recibas el bit de start no guarda nada, hasta que lo recibas entonces guardas un dato e incrementas tu contador para guardar el siguiente dato en el siguiente indice de tu vector, con cada dato tendrias que hacer una discriminacion para saber si es un "1" o un "0"

"Nada es imposible, no si puedes imaginarlo"

Desconectado rivale

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1707
Re: Lector Tren de Pulsos RB0
« Respuesta #10 en: 29 de Julio de 2011, 01:01:07 »
el codigo que dices de redpic es para un solo dato, ahi checa si es un 1 o 0, pero si quieres recibir varios, tendrias que hacer una lectura por cada dato a decodificar. checa el codigo que te puse arriba, espero te de una mejor idea de como leerlos
"Nada es imposible, no si puedes imaginarlo"

Desconectado facundo_10

  • Colaborador
  • PIC16
  • *****
  • Mensajes: 179
    • DAVINCIPIC
Re: Lector Tren de Pulsos RB0
« Respuesta #11 en: 29 de Julio de 2011, 01:42:01 »
Realmente no entiendo el código de Redpic, el no cambia de flancos, siempre esta en H_TO_L por lo tanto, agarra subidas y bajadas, no agarra ancho en alto o ancho en bajo, el ancho que toma es alto y bajo...

Sobre el codigo que tu me dices esta bien, pero t2 es un ancho del pulso, a eso lo debo dividir para saber que cantidad de unos o ceros tengo, y como saber si son unos o son ceros? ?

Tendría que estar cambiando de flanco de interrupcion todo el tiempo...

Es decir entre

L_TO_H hasta H_T_L tengo lo que es el ancho de pulso de los unos...

H_TO_L hasta L_TO_H tengo lo que es el ancho de pulsos de los ceros...

Esa seria la uníca manera de saber si el ancho de pulsos que tengo son ceros o son unos....

A lo que me refiero es que redpic en su código siempre esta en H_T_L, o sea que toma ceros y unos... no entiendo como discrimina, yo no puedo usar esa técnica para discriminar porque un 1 mide lo mismo que un cero, tengo que mediante las configuraciones de las interrupciones saber si estoy en el ancho de pulso alto o ancho de pulso alto, a ese ancho dividirlo por lo que dura un pulso y hacer un bucle escribiendo unos o ceros dependiendo la cantidad que sea en el vector...

Esa es la manera que se me ocurre.. Que piensan?

Todo esto respetando lo que es start_b y stop_b...

Tu manera de poner el timer a 0, cuando recibo el flanco de subida, y tomar el tiempo cuando recibo el flanco de bajada esta muy buena, pero no me sirve para saber cuanto mide el ancho de pulso de los ceros, ya que al poner en cero en la subida, no puedo hacer una resta, porque elimino el valor que tenia ese timer.. Lo cual para mi es necesario. No se que piensas tu?

PICMANIACO!

Desconectado rivale

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1707
Re: Lector Tren de Pulsos RB0
« Respuesta #12 en: 29 de Julio de 2011, 01:53:03 »
podrias poner un dibujo de como son los anchos de pulso de tus 1s  0s, que es lo que varia entre ellos?.

supongo que redpic los discrimina por el ancho de pulso de cada uno. pero en tu caso no serviria. me gustaria ver como seria un tren de púlsos de tu codigo para darte una idea mas clara.


« Última modificación: 29 de Julio de 2011, 10:26:12 por rivale »
"Nada es imposible, no si puedes imaginarlo"

Desconectado rivale

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1707
Re: Lector Tren de Pulsos RB0
« Respuesta #13 en: 29 de Julio de 2011, 10:31:11 »
mira en esta imagen, para diferenciar los pulsos se usa el ancho de cada uno, y hay un tiempo muerto entre cada pulso de 500 us. yo para decodificar esta trama use un codigo parecido al que te puse mas arriba, tambien se podria hacer si cambiar el flanco de la interrupcion, si solo uso la interrupcion de flanco de bajada, tambien estaria contando el tiempo de 500 us con cada dato.





tus pulsos como son?, si pudieras dibujarlos para entender mejor y ayudarte a leerlos.

"Nada es imposible, no si puedes imaginarlo"

Desconectado facundo_10

  • Colaborador
  • PIC16
  • *****
  • Mensajes: 179
    • DAVINCIPIC
Re: Lector Tren de Pulsos RB0
« Respuesta #14 en: 29 de Julio de 2011, 13:16:45 »
Hola Rivale, que tal, entiendo tu imagen pero mis pulsos son distintos, cada uno tiene le mismo largo, 1 bit en 0 o en 1 dura 100 us, si no me equivoco es una comunicación a una velocidad de 100000 bps, aquí te pego una imagen para que te hagas una idea..




Creo que ya se donde puedo encontrar el código que me sirva,

http://www.todopic.com.ar/foros/index.php?topic=23020.0

Es otro de los códigos de Redpic, allí hay bastante info como para detectar flanco de subida y de bajada..
PICMANIACO!


 

anything