Autor Tema: conteo de un pulso mediante interrupciones  (Leído 6357 veces)

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

Desconectado cruz

  • PIC10
  • *
  • Mensajes: 3
conteo de un pulso mediante interrupciones
« en: 10 de Agosto de 2009, 12:20:10 »
hola equipos de todo pic, gracias por este foro
soy de venezuela, T.S.U en telecomunicaciones y estudiando actualmente para la Ing. Electronica

La duda que tengo es la frecuencia que puede soportar un PIC mediante interrupciones de RB0 o Interrupciones por cambio es de estado (RB 7:4) y RA0. ?

Esto duda viene porque quiero utilizar un encoder incremental (1000 pulsos por revolucion) mediante un motor DC de 50rpm.  segun mis calculos con estos datos tengo un frecuencia de 833.33Hz.   

No puedo hacer pruebas con el encoder incremental, porque no lo tengo y no lo quisira comprar hasta no estar seguro de que pueda funcionar a esa frecuencia. 

Estoy utilizando un simulador (proteus) para poder medir la frecuencia de interrupcion, es decir, coloco un motor encoder con 50rpm, y 360 pulsos por revolucion, el problemas son los resultados que no me convence. si el encoder genera pulsos cuya frecuencia es de 200Hz, entonces el numero de interrupiones (vista por una pantalla virctual de comunicaciones serial) corresponde al numero pulsos entregado por el encoder, entones, si yo agarro el tiempo y lo divido con el numero de interrupciones tengo el periodo del pulso y si le saco el invreso tengo la frecuencia que corresponde a la frecuencia de pulsos entregada por el encoder. en este caso 200Hz, pero si aumento la frecuencia a mas de 200Hz los calculos no cuadran. Deberia suponer que la frecuencia maxima que soporta mediante interrupciones RB0 es 200Hz, pero no lo creo por he escuchado que puede soportar mas frecuencia. Pudo pensar que existe un error en proteus pero no tengo como comprobarlo.

convoco este foro para que me oriente; lo que le explique anteriormente es todo lo que he hecho, pero en si me gustario saber la frecuencia minima y maxima que soporta el pic cuando exite un conteo de pulsos por interrupciones ya sea (RA0, RB0, o por cambios de estado RB(7:4)).

Tambien si es posible calcular la frecuencia de salida de un encoder en funcion de los rpm de un motor, tengo la siguiete ecuacion:   Hz=(rpm/60)*pulsos por revolucion. Me gustaria confirmar esa ecuacion.

Nota: El pic que utilizo es 18f4550, oscilador:20Mhz, programa: lenguaje C.   Las pruebas que mecione anteriormente son interrupciones RB0 (es un programa que cuando existe un pulso hace una interrupcion y me imprime en pantalla que hubo una interrupcion, el tiempo no lo saco del pic , lo veo cuando en proteus se corre un programa).

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: conteo de un pulso mediante interrupciones
« Respuesta #1 en: 10 de Agosto de 2009, 13:56:18 »
Bienvenido al foro cruz!

Si vas a contar pulsos te conviene utilizar el Timer0, Timer1 o Timer3 en modo contador, que dependiendo la configuración se puede detectar hasta 50 MHz.


Saludos!
No contesto mensajes privados, las consultas en el foro

Desconectado cruz

  • PIC10
  • *
  • Mensajes: 3
Re: conteo de un pulso mediante interrupciones
« Respuesta #2 en: 11 de Agosto de 2009, 15:09:27 »
hola suky,

gracias por responder.

ciertamente probe con el timer0, el problema esta en que existe un conteo hasta que se levanta una bandera, y esa bandera indica que se termino hasta el numero de pulsos que se quiere. 

Especificare mas en que se trata el proyecto.
 El encoder me va a permitir saber los grados de una antena ya sea (elevacion o azimuth)  y los pulsos que me envie el encoder son datos que tiene el pic, me explico , el ya sabe que por un pulso del encoder en la antena hay 0.001 (grados) ,ejemplo,  yo quiero colocar la antena en 45(grados), entonces cuantos pulsos necesito si tengo un encoder de 1000 pulsos por revolucion? RESP: 45000 pulsos.

que pasa el PIC hace un conteo, por cada pulso, entonces el le suma 0.001(grados) y se detine  (o manda la informacion a los motores para que se detenga) en los grados deseados por el usuario. Que pasa esto, si existe un problema en los motores y no si llegando los pulsos esta llegar a los 45000 pulsos entonces exite un problema y pic actua para enviar una informacion al usuario en que hubo un problema. como veraz es un poco complejo ya que tengo que seguir el conteo de pulso.

Es po eso que lo programe con interrupciones y el micro sabe que por cada interrupcion el pic le debe sumar 0.001(grados al conteo) hasta llegar a los grados por el usuario. 

Disculpa si el texto es muy largo, pero estoy tratando de reducir un poco lo que estoy haciendo!

en todo caso si lo hago por timer el pic tiene que esperar los pulsos hasta que se levante una bandera. a menos de que si estoy por timer y en ves de llegar a los 45000 pulsos llega a 25000 pulsos, me imagino que el pic se quedara esperando hasta que llegue el pulso, eso es algo que no me gusta, porque creo que no tengo control o me equivoco, es decir existe alguna forma de decirle al pic que si no llega los 45000 pulsos, entonces hacer una interrupcion interna que le diga al ususrio que hubo un problema. todo hacerlo por timer!, se podrá hacer ese tipo de programación por timer? .

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: conteo de un pulso mediante interrupciones
« Respuesta #3 en: 11 de Agosto de 2009, 15:44:36 »
En el Timer puedes cargar un valor inicial, de tal manera que al llegar en este caso por ejemplo los 4500 pulsos realice una interrupción y detenga el motor. Para tener mayor precisión en el conteo de pulsos si o si tendrás que usar en 1:1, pero esto te limita a contar como máximo 65536 pulsos osea aprox 60ª Esto no es problema, porque si es un giro mayor el programa por ejemplo lo divide en varias partes.
Que pasa esto, si existe un problema en los motores y no si llegando los pulsos esta llegar a los 45000 pulsos entonces exite un problema y pic actua para enviar una informacion al usuario en que hubo un problema. como veraz es un poco complejo ya que tengo que seguir el conteo de pulso.

 :shock:

Lo que puedes hacer es utilizar el concepto de Timeout, osea activar el motor y esperar un tiempo máximo a que ocurra la interrupción que indica que ha terminado el giro, si esto no ocurre entonces abortar todo el proceso he indicar al usuario que ha ocurrido un problema.

Saludos!
No contesto mensajes privados, las consultas en el foro

Desconectado cruz

  • PIC10
  • *
  • Mensajes: 3
Re: conteo de un pulso mediante interrupciones
« Respuesta #4 en: 11 de Agosto de 2009, 17:50:30 »
no se si entendi bien. voy a colocar un programa base

#include <18f4550>
Librerias


//funciones para la interrupcion

timer_0()
{ ////los numeros (1,2,3) son referencia para poder explicar la duda
     
          timer_desactivado();
 
         1.-)  Bit_clear (INTCON,2);  // Limpio el bit;
         2.-)  Set_RTCC (255);    //Permite el conteo de pulsos // los 255 es una referencia para el ejemplo, es                             //puede  cambiar de acuerdo al numero de pulsos que se necesti para llegar a los grados deseados por el usuario;
         3.-)  While (!toif);   // Continua leyendo hasta que la bandera sea = 1;

}

main()
{
        configuracion de puertos
        configurarion de contadores

      form (;;)
     {
           //programacion de otras rutinas por ejemplo recibir la cantidad de grados deseados
           // por el ususario;
          // Se hace el calculo del valor que debe ir al codigo  (  2.-)  Set_RTCC (255);)  para llegar a los grados deseados
         // se activa los motores
         // activo el timer_activo; () permite verificar si el llego el pulso en un tiempo prudencial de los contrario desactiva el sistema;
     }

}

como puedes ver es dificil llevar un seguimeinto de los pulsos;

Me escribes en la ultima parte :
"Lo que puedes hacer es utilizar el concepto de Timeout, osea activar el motor y esperar un tiempo máximo a que ocurra la interrupción que indica que ha terminado el giro, si esto no ocurre entonces abortar todo el proceso he indicar al usuario que ha ocurrido un problema."

// realmente no comprendo el concepto de timerout en una interrupcion del timer, ya que si activo el motor debo leer el encoder, no se realmente si me estoy complicando en el programa, pero esto lo estoy haciendo por seguridad de la antena en caso de una falla y para alertar al usuario de la misma.

// como lograr un timerout (muevo la antena, pero a la vez estoy leyendo el encoders) , es decir (el codigo (1.-)Set_RTCC (255); ) se encuentra calculado para recibir una cierta cantidad de pulsos, miestras esta haciendo el conteo se puede hacer una interrupción durante ese codigo, en caso de que no llegue a los pulsos deseades?

Porque este codigo ((1.-)Set_RTCC (255);), siempre va a esperar hasta que lleguen todos los pulsos, me gustario mejorar esta parte del codigo, porque quiero que verifique que son los grados deseados por el usuario y si realmente llegaron todos los pulsos, no que se quede esperando.

lo ideal seria es que despues de un tiempo prudencial si los pulsos no llegan , enviar una señal "falla en la antena" y a su vez indicarle al usuario los grados en que quedo la antena.

Suky, traté de analizar tu respuesta pero me llego a la misma duda que tenia anteriormente.


Este es el codigo por interrupcion

#include 18f4550
librerias


//funciones

timer_activo()
{
   ////rutinas
}

timer_desactivado()
{
   // permite cancelar el timer_activo();

}


#INT_EXT
EXT_ISR()
{float dato_pulso;

      Ocurre la interrupción
     dato_pulso = dato_pulso + 0.001;
      // timer_desactivado();

     if (dato_del_usuario == dato_pulso )
     {  //detener los motores

     }
          // se activa un     timer_activo(); //conteo del tiempo en tarda la interrucpion (si se sobrepaso del tiempo desactiva todo  el sistema)
         //  continua el conteo de acuerdo al numero de interrupciones
}

main ()
{dato_pulso = 0;

        //configurarción de puertos;
       // configurarion de interrupciones;

     for (;;)
    {
                /// En esta parte del programa recibo la cantidad de grados
                // hago los calculos de cuantos pulsos se necesita para lograr los pulsos deseados
                // Programación que permite saber el sentido del motor
                // Activo los motores  (automaticamente se genera una interrupcion)
                // sin embargo el programa tiene un timer que permite saber si hubo una interrupción, es decir, si llegan los
                // pulsos en un tiempo prudencial , que de ser así no existe problema, pero si es lo contrario le indica al usuario que la antena no se movio por que no hubo una interrupción y cancela todo el sistema (energia o la alimentación de los motores y por supuesto del mismo micro para evitar un corto y la unica forma de restaurar el sistema es que un tecnico vaya hasta la antena y verifique motores, encoder, y los circuitos).

              // nota: El pic ya sabe que cada pulsos que llegue, es equivalente a 0.001°.



    }

}




Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: conteo de un pulso mediante interrupciones
« Respuesta #5 en: 11 de Agosto de 2009, 22:39:22 »
Lo explico con código de como se podría hacer:

En la interrupción de conteo, al recibir la cantidad de pulsos calculados lo único que debe hacer es dar por terminado la acción de los motores:

Código: C
  1. #int_TIMER0
  2. void  TIMER0_isr(void){
  3.       // Desactivamos motor.
  4.       disable_interrupts(INT_TIMER0);
  5.       disable_interrupts(INT_TIMER3);
  6.       Ok=1; // Activo un flag que me indique el termino del proceso
  7. }

Luego dependiendo del grado de giro y según el actuador físico creo que tendrías un tiempo estimativo de lo que demoraría en posicionarse.

Entonces lo que se haría sería calcular este tiempo y crear una demora con un timer. La interrupción de este timer junto a un registro que cuente los overflow (1 sola interrupción no alcanzará para realizar la demora) determinará que ha ocurrido el máximo tiempo de espera:

Código: C
  1. #int_TIMER3
  2. void  TIMER3_isr(void){
  3.    Overflow++;
  4.    if(Overflow==Mult_timeout){
  5.         disable_interrupts(INT_TIMER0);
  6.         disable_interrupts(INT_TIMER3);
  7.         Timeout=1;     // Indico que se ha esperado el maximo tiempo...
  8.    }
  9. }

En el main se haría lo que tu indicas:

Código: C
  1. main()
  2. {
  3.         configuración de puertos
  4.         configuraron de contadores
  5.  
  6.       while(1)
  7.      {
  8.            //programación de otras rutinas por ejemplo recibir la cantidad de grados deseados
  9.            // por el usuario;
  10.           // Se hace el calculo del valor que debe ir al código  (  2.-)  Set_RTCC (255)  para llegar a los grados deseados
  11.           // Se calcula el Tiempo de Timeout, Osea Mult_Timeout.
  12.          // activo el ambos timers (Conteo de pulsos y timeout)
  13.          // se activa los motores
  14.          while((Ok==0) && (Timeout==0)){}
  15.          if(Ok==1){
  16.               // Todo ok
  17.          }else if (Timeout==1){
  18.               // Falló :-(
  19.          }
  20.      }
  21. }

Bueno, esa es mas o menos la idea.

Saludos!
No contesto mensajes privados, las consultas en el foro


 

anything