Autor Tema: Tomando pulsos del Timer1:velocimetro  (Leído 10732 veces)

0 Usuarios y 2 Visitantes están viendo este tema.

Desconectado Trev_11

  • PIC10
  • *
  • Mensajes: 44
Re: Tomando pulsos del Timer1:velocimetro
« Respuesta #15 en: 15 de Octubre de 2007, 14:31:12 »
Esta muy bueno y es todavia mas preciso,pero no se si conseguire ese cristal  :D ,no te parece mucho un segundo para el ciclo?,digo porque me gustaria modificar el duty al final de cada ciclo y en un segundo puede pasar mucho,hoy que es feriado  me voy a poner con eso ya les contare.Salu2 a todos

Desconectado jfh900

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3595
Re: Tomando pulsos del Timer1:velocimetro
« Respuesta #16 en: 15 de Octubre de 2007, 14:37:25 »
Hola pocher, si me permites una pequeña sugerencia, podrias modificar el código que pusiste:

Código: [Seleccionar]
main()
{
   int8 radios=4;                                 //Encoder de 4 radios
   float n;
   int16 pulsos;
   int8 cuenta_interrupciones;
   int16 velocidad_s,velocidad_m;  

Por:

Código: [Seleccionar]

#define radios 4

main()
{
   float n;
   int16 pulsos;
   int8 cuenta_interrupciones;
   int16 velocidad_s,velocidad_m;   

Con eso el código es ligeramente más corto y más rápido.

Un saludo
* Cuando hables, procura que tus palabras sean mejores que el silencio.
* 'Todos somos ignorantes, lo que ocurre es que no todos ignoramos las mismas cosas.' Albert Einstein.
* No hay nada peor que un experto para evitar el progreso en un campo
* "La vida es como una novela. No importa que sea larga, sino que esté bien narrada" Seneca
* La vida no se vive por las veces que respiras, sino por los momentos que dejan sin aliento.
* Dios dijo: ∇·E=ρ/ε0 ; ∇·B=0 ; ∇xE=-dB/dt ; ∇xB= μ0ε0dE/dt..y la luz se hizo..!!..

Desde España Jesús

Desconectado pocher

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 2568
Re: Tomando pulsos del Timer1:velocimetro
« Respuesta #17 en: 15 de Octubre de 2007, 15:46:26 »
oido cocina, marchando una de #define

Desconectado Trev_11

  • PIC10
  • *
  • Mensajes: 44
Re: Tomando pulsos del Timer1:velocimetro
« Respuesta #18 en: 18 de Octubre de 2007, 17:42:29 »
Hola :) modifique el código un poco,le agregue un keypad para poder visualizar un numero de 4 digitos sobre la LCD,me surge otro problema,tengo pequeños cambios esporadicos en la lectura de la velocidad despues de cada vez que ingreso este numero,le agregue un par de lineas y mejoró pero no del todo,como podria solucionarse?,gracias les dejo el codigo:

Código: [Seleccionar]
#include <16f877.h>
#fuses XT, NOPROTECT, NOWDT, NOPUT, NOBROWNOUT, NOLVP, NOCPD, NOWRT
#use delay(clock=4000000)
#include <lcd.c>
#include <math.h>
#byte portb=6
#define radios 4

int TECLA_PULSADA;
int8 digitos;                                 //Encoder de 4 radios
float n;
int16 pulsos;
int8 interrupcion;
int16 velocidad_s,velocidad_m;

char escan_teclado()
{
     
     int tecla=44;
     int i=0;
     int vect[5]={0x0E,0x0D,0x0B,0x07,0};
     int matriz_teclado[4][3]={1,2,3,4,5,6,7,8,9,0,0,0};
     while(i<4)
          {
          portb=vect[i];
          if(!input(PIN_B4))
                {
                 tecla=0;
                 tecla=matriz_teclado[i][tecla];
                }
          if(!input(PIN_B5))
                {
                 tecla=1;
                 tecla=matriz_teclado[i][tecla];
                }
          if(!input(PIN_B6))
                {
                 tecla=2;
                 tecla=matriz_teclado[i][tecla];
                }
          i++;     
          }         
     return(tecla);
     
}

#int_RB
RB_isr()
{
disable_interrupts(int_rtcc);
port_b_pullups(true);
digitos=0;
    lcd_gotoxy(7,1);
    lcd_putc("          ");
    while(digitos<4)   
    {
    while(escan_teclado()!=0x2c)
      {
    TECLA_PULSADA=escan_teclado();
      if(digitos==0){
      lcd_gotoxy(1,1);
      printf(lcd_putc,"V.Ref=%d",TECLA_PULSADA);
      }
      if(digitos==1){
      printf(lcd_putc,"%d",TECLA_PULSADA);
      }
      if(digitos==2){     
      printf(lcd_putc,"%d",TECLA_PULSADA);
      }
      if(digitos==3){     
      printf(lcd_putc,"%d",TECLA_PULSADA);
      delay_ms(250);
      printf(lcd_putc," R.p.m");
      }
    delay_ms(1000);   
    digitos++;
      }
    }
portb=0x00;
set_timer1(0);
enable_interrupts(int_rtcc);
set_timer0(217);
}

#int_RTCC
RTCC_isr()
{
   pulsos=get_timer1();                       //Se entra en la interrupción cada 10ms   
   interrupcion++;
   if(interrupcion==100)                      //10ms*100 =1s
   {
      n=pulsos/radios;     
      velocidad_s=floor(n+(n-floor(n)));      //Redondea n, por si recibe algún pulso
                                              //de más ó de menos
      velocidad_m=velocidad_s*60;
      lcd_gotoxy(1,2);       
      printf(lcd_putc,"Vel.=%lu R.p.m.",velocidad_m);                     //r.p.m.
      interrupcion=0;
      set_timer1(0);
      //set_rtcc(178);                        //Inicializa el TMR0
      set_rtcc(217);                          //Inicializa el TMR0     
   }
   else
   {
      //set_rtcc(178);                       //Inicializa el TMR0
      set_rtcc(217);                         //Inicializa el TMR0     
      set_timer1(pulsos);                    //Recupera los pulsos
   }


main()

   
   set_tris_b(0xf0);
   portb=0x0f;
   set_tris_c(0x01);                         //Entrada de pulsos por RC0.
   set_tris_d(0x00);
   enable_interrupts(global);
   enable_interrupts(int_rtcc);
   enable_interrupts(int_rb);
   //setup_timer_0 ( rtcc_internal|rtcc_div_128);
   //set_rtcc(178);                //10ms -> 10000us -> 10000/128=78,125 -> 256-78=178
   setup_timer_0 ( rtcc_internal|rtcc_div_256);
   set_rtcc(217);                  //10ms -> 10000us -> 10000/256=39,0625 -> 256-39=217   
   setup_timer_1(t1_external|t1_div_by_1);
   set_timer1(0);
   interrupcion=0;   
   lcd_init();
   printf(lcd_putc,"V.Ref=3500 R.p.m");
   lcd_gotoxy(9,1);
   while(1);
}

Desconectado criscol64

  • PIC10
  • *
  • Mensajes: 1
Re: Tomando pulsos del Timer1:velocimetro
« Respuesta #19 en: 18 de Noviembre de 2008, 19:37:47 »
Hola, yo pienso que si desea la mayor precision y velocidad en la muestra de los datos le recomiendo no hacer escaneos de pulsos por segundo, mas bien mida el tiempo entre un pulso y el siguiente, asi obtiene exactamente las revoluciones y puede mostrar los datos de manera instantanea sin tener que esperar a que pase un segundo...
Yo lo he hecho y me ha funcionado de maravilla

Desconectado cago41

  • PIC10
  • *
  • Mensajes: 1
Re: Tomando pulsos del Timer1:velocimetro
« Respuesta #20 en: 14 de Diciembre de 2008, 21:47:50 »
hola, estoy haciendo algo parecido y no he podido entender lo que hacen ustedes con la variable "radios". si alguno me pudiera explicar su función les agradecería mucho, porque no entiendo cómo dividiendo los pulsos por esa variable da correcta la lectura. gracias!

Desconectado elmumoperalta

  • PIC10
  • *
  • Mensajes: 1
Re: Tomando pulsos del Timer1:velocimetro
« Respuesta #21 en: 02 de Diciembre de 2011, 00:53:42 »
estimados:

se me estan por care todas las nueces del nogal y sigo con este problema. No puedo encontrar la falla en este programa para mikroc.
La logica es similar a muchos programas los cuales investigue pero no doy en la tecla, sumado a mi novatez en el tema.

adjunto codigo, espero que me puedan ayudar. NO TOMAR EN CUENTA LOS COMENTARIOS DEL PROGRAMA

///////////////////////////


void envio1 ();
void envio2 ();
void envio3 ();
void recibo ();
void pulsos ();
unsigned int peso1,peso2,set,temp_p1,temp_p2,cntL,cntH, sel, i;
unsigned int TMR1H_old, TMR1L_old, cnt, TMR1H_NEW, TMR1L_NEW;

void interrupt()
{   // Rutina de interrupción
cnt++;
INTCON =0xa0;
tmr0=217;
             // Interrupción causa el incremento de cnt por 1
}
 
 

void main()

{
  ADCON1 = 0x81;  // Configure analog inputs and Vref en la entrada RA3
  PORTA = 0;               // Reiniciar el puerto PORTA
  TRISA  = 0xFF;  // PORTA is input
  TRISB  = 0x00;  // Pins RB7, RB6 are outputs
                   //Configuro el prescaler del Timer1
  T1CON.TMR1CS = 1;              //modo de trabajo de tmr1 como contador de pulsos externos
  T1CON.T1OSCEN = 0;             //Desabilita el Oscilador externo
  T1CON.T1SYNC = 1;              // desabilita la sincronizacion con el reloj
  T1CON.T1CKPS1 = 0;
  T1CON.T1CKPS0 = 0;         // Start timer1
  OPTION_REG = 0x87;         // Pre-escalador en 256
  INTCON =0xa0;
  cnt=0;
  TMR1H=0;
  TMR1L=0;
  Usart_Init(19200);
  TMR1H_old = 0;
  TMR1L_old = 0;

                             //precarga

  do {
    T1CON.F0 = 1;            //habilito cnt de pulsos
    envio1();
    //delay_ms(10);
    envio2();
    //delay_ms(10);
    if (cnt==100)
     {
       TMR1H_NEW = TMR1H;
       TMR1L_NEW = TMR1L;
       TMR1H_old = TMR1H;
       TMR1L_old = TMR1L;
       TMR1H=0;
       TMR1L=0;
       cnt=0;}
    else
        {
       TMR1H_NEW = TMR1H_old;
       TMR1L_NEW = TMR1L_old;
        }
   // ENVIO DE CUENTAS TMR1
    Usart_Write(TMR1H_NEW);
    Usart_Write(TMR1L_NEW);
    Usart_Write(cnt);
    Usart_Write(TMR0);
    Usart_Write (0x0A);
    recibo();
    PORTB = set;

    } while(1);
}

void envio1()

{
    peso1 = Adc_Read(0); // Get results of AD conversion
    delay_us(5);
    temp_p1 = ADRESH;
    temp_p2 = ADRESL;
    Usart_Write(temp_p1);
    Usart_Write(temp_p2);

}

void envio2()

{
    peso2 = Adc_Read(1); // Get results of AD conversion
    delay_us(5);
    temp_p1 = ADRESH;
    temp_p2 = ADRESL;
    Usart_Write(temp_p1);
    Usart_Write(temp_p2);

}


void recibo ()
{
if (Usart_Data_Ready())
 {
 set = Usart_Read();
  }
}

Desconectado reiniertl

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 1187
Re: Tomando pulsos del Timer1:velocimetro
« Respuesta #22 en: 26 de Diciembre de 2011, 14:06:28 »
Luego de releer este hilo me he dado cuenta de un error de concepto cometido por mi al hacerte la primera recomendación.

Lo que en realidad debí recomendarte implica que los sufrimientos a los que te has sometido pudieron ser evitados al utilizar adecuadamente las opciones que muy probablemente ya vienen incluidas en el hardware de tu microcontrolador.

Si utilizas el TIMER1 en modo Input capture te podrías ahorrar una pila de problemas. En este modo lo que haces es medir el tiempo que le toma al temporizador detectar una cierta cantidad de pulsos por la entrada externa. De este modo si por ejemplo tu motor tiene un detector de índice, es decir un detector que da un pulso por revolución, puedes perfectamente saber con el timer cuanto le tomó al motor dar una vuelta completa. Si el motor gira muy rápido, entoces lo dejas dar varias vueltas y promedias el tiempo entre el número de vueltas y así obtienes la velocidad angular media del motor.

Es un método muy eficaz, incluso si tienes un encoder que da varios pulsos por vuelta, basta con configurar el módulo en modo Input Capture y decirle cuantos frentes de subida o caía o ambos deseas contar, luego calculas y listo.

Si escoges apropiadamente la cantidad de pulsos a contar, supongamos que cuentas pulsos en potencias de dos, entoces puedes ahorrarte algunas divisiones con un simple desplazamiento del resultado. Hay muchas formas de hacer esto de manera eficaz y eficiente. Con mucho menos código y a velocidades de vértigo. Sin tener que utilizar dos TIMERs y poner cristales externos de valores de resonancia complicados o difíciles de hayar.

Un saludo
Reinier


 

anything