Autor Tema: Inicios de mi tacometro  (Leído 3461 veces)

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

Desconectado Cryn

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4169
Inicios de mi tacometro
« en: 07 de Junio de 2007, 13:07:33 »
saludos pues estaba intentando realizar un tacometro para mi bicicleta, jeje (ya que no tengo auto :(), jeje :lol:

y la idea que tengo es usar dos timers, el TMR0 para contar un segundo, y el TMR1 para contar los pulsos de un circuito que envie un cero o un uno cada vez qeu pase por un lugar en la rueda, el TMR1 será en realidad el contador de revoluciones en el segundo que cuenta el TMR0, una vez que pase el segundo del TMR0 captura lo que tiene el TIMER1 aprovechando que es de 16bits aguantará muchas vueltas en un segundo, en realidad 64k de vueltas como maximo, aunque agregando codigo se lograria más no hay problema, para probar solo cuento como máximo 64k. Una vez capturado puede facilmente llevarse a un LCD o a displays de Leds (que es mi caso, ya que en definitiva mi LCD no sirve :(), la idea creo que está bien, o hay algo más qeu deba considerar??

y pues como pense que estaba bien, le puse manos a la obra, y pues parece que da, pero presenta algunos errores, solo estoy en torno a simulación, simulo como siempre en proteus 7.1 sp2, le pongo un generador de clock en el T1CKI, a la frecuencia que quiera, por ejemplo 60Hz, es decir 60 rps (revoluciones por segundo), ya que eso es lo que mediría con el TMR1, para llevarlo a rpm solo una división entre 60 y listo, en ese caso sería uno, y se ve bien el 1, pero si cambio la frecuencia a 120Hz, deberia leer 2, y en efecto veo un dos, pero solo un momento despues se va a 5, y no entiendo porque lo hace, y si pongo por ejemplo 60KHz de freceuncia, lo que deberia medir en realidad es 1000rpm, y me da como 1026 rpm; y en esos valores erroneos va oscilando, por ejemplo en que mide 1026 primero mide 1027 despues 1025 y recien se va quedando en 1026 o despues sigue oscilando, medio que tiene error, y nose muy bien porque puede darse, aca les dejo mi código y la simulacion, espero haya logrado ser claro y puedan ayudarme, un saludo y muchas gracias, adios!

ahh se me olivdaba uso un 16f88 y lenguaje CCS 4.032
Código: [Seleccionar]
#include <16f88.h>
#fuses intrc,NOWDT,NOLVP,PUT,NOMCLR,NOBROWNOUT
#use delay(internal=4000000)
#use fast_io(a)
#use fast_io(b)

unsigned int CONST LED [10]={0x3f,0x06,0x9B,0x8f,0xa6,0xAd,0xbd,0x27,0xbf,0xaf}; //datos para los displays
int i=0,pin,count=0,total[5],caso=0;
int16 rpm=0,div,rps,mps;

#INT_TIMER0
void tmr0_handler()
{
   count++;
   if(count==125)       // cuento 125 interrupciones 1u*125*32*250=1s
   {
      rps=GET_TIMER1(); // capturo el valor de tmr1 cuando llegue al segundo el tmr0
      rpm=rps/60;       // convierto rps a rpm
      count=0;          // reestablesco contador de interrupciones para tmr0
      set_timer1(0);    // restablezco tmr1
   }
   set_timer0(5);       // si no ha llegado al segundo otravez inicia tmr0 en 5
}

/*#INT_TIMER1
void tmr1_handler()
{
   rpm=0;
   set_timer1(0);
}*/

void array(int16 resultado)   // función para convertir un entero a array
{
   div=10000;                 // inicialización divisor
   for(i=0;i<5;i++)           // bucle de conversión
   {
   total[i]=resultado/div;    // se obtiene el primer digito para el array
   if(total[i]!=0)            // si es igual a cero no se lo considera
   resultado=resultado-total[i]*div;   // se actualiza el valor de resultado, sin contar el dígito extraido
   div=div/10;                // se reduce el orden de magnitud del divisor
   }
}

void mux()      // función de multiplexación
{
   pin=40;         // inicilaiza el valor del pin en el que comenzará la multiplexación, PIN_A0=40
   for(i=0;i<5;i++)      // bucle de trabajo
   {
      output_b(LED[total[i]]);   // se despliega dato correspondiente a la variable array a mostrar
      output_low(pin);           // displays de cátado común, se activa cátodo correspondiente
      delay_us(100);             // retardo para observación contínua
      output_high(pin);          // apagamos display, para pasar al siguiente
      pin++;                     // cambiamos de pin
   }
}

void main()
{
   setup_oscillator(OSC_4MHZ|OSC_INTRC);  // fijo oscilador interno
   SET_TIMER0(5);                         // valor de inicio del TMR0
   SETUP_TIMER_0(RTCC_INTERNAL|RTCC_DIV_32); // reloj interno y prescaler=32 pra tmr0
   setup_timer_1(T1_EXTERNAL|T1_DIV_BY_1);   // reloj externo y preescaler=1 para tmr1
   SET_TIMER1(0);                         // valor de inicio para tmr1
   SETUP_ADC(adc_off);                    // apago el adc
   SETUP_ADC_PORTS(NO_ANALOGS);           // todas digitales en portA
   enable_interrupts(INT_TIMER0);         // habilito interrupción por desborde de tmr0
   //enable_interrupts(INT_TIMER1);
   enable_interrupts(GLOBAL);             // habilito interrupciones
   set_tris_a(0xe0);                      // salidas RA0 a RA4
   set_tris_b(0x40);                      // todas salidas portB, excepto RB6(T1CKI)
   output_a(0x1f);                        // todos los displays apagados
   for(i=0;i<5;i++)                       // inicialización de total
      total[i]=0;
   while(true)                            // bucle de trabajo
   {
      array(rpm);                         // convierto el valor de rpm a array apra visualizar en displays
      mux();                              // multiplexo para ver en todos los displays
   }
}

la simulacion la adjunto aquí: tacometro.zip
.

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18286
    • MicroPIC
Re: Inicios de mi tacometro
« Respuesta #1 en: 07 de Junio de 2007, 16:15:44 »
Cryn, ese sistema de contar los pulsos recibidos en un segundo tiene un margen de error muy alto a frecuencias bajas.
Imagina que vas despacio con la bici, hasta el punto que la rueda da 1 o 2 vueltas por segundo. Si en un momento lee un sólo pulso te dirá que vas a 60rpm, si en la vuelta siguiente lee 2 pulsos te dirá que vas a 120rpm.
Yo en tu caso utilizaría otro método: medir el periodo (T) transcurrido entre un pulso y otro y hallar la frecuencia dividiendo: f=1/T

Desconectado Cryn

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4169
Re: Inicios de mi tacometro
« Respuesta #2 en: 07 de Junio de 2007, 16:48:21 »
umm.. pero como puede suceder que lea mas de una vuelta, si el qeu lee las vueltas es el T1CKI, si se va lento pues no leera nada mas qeu una o dos en el peor caso (a menos que lea ruido), y si no lee ninguna, pues mostraria cero porque en mi codigo divido lo leido entre 60 (0/60=0), y mostrara 0 rpm; si fuera 1 o dos vuetas tb mostra cero, ya que 2/60=0.0... y no uso floats todavia, pero puede ser una variante, lograste ver mi simulación??? viste algo del codigo que pues?? por favor echale una miradita para ver si se debe corregir algo.

sobre el periodo, no lo tengo bien claro, seria el periodo entre dos vueltas, es decir el tiempo entre una vuelta y la siguiente?, pero eso no es constante, ya que cuando empiezas la marcha es lento, acelerando y llegas casi a un frec constante, casi, y nunca creo qeu será constante, al menos en una bicicleta... o dije alguna bobada, disculpa si lo hice esque ya me hice bolas, jeje

un saludo y gracias por la respuesta, adios.
.

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18286
    • MicroPIC
Re: Inicios de mi tacometro
« Respuesta #3 en: 08 de Junio de 2007, 02:52:28 »
No me funciona bien el Proteus. Pero te hago una sugerencia; ¿porqué no empiezas mostrando primero las RPS?
Si la lectura de las mismas es correcta, ya estarás seguro que la parte de recuento es correcta y tendrás que buscar el problema en el cálculo. Si no, pues ya sabes que no cuentas bien.

Desconectado Cryn

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4169
Re: Inicios de mi tacometro
« Respuesta #4 en: 08 de Junio de 2007, 14:50:09 »
pues si presenta error en las rps, pero no comprendo a que se debe, porque uso un generador de clock (osea es ideal) en T1CKI, o como debo hacerlo?

creo que hasta llegar a capturar el valor del TMR1, pasado el segundo:

#INT_TIMER0
void tmr0_handler()
{
   count++;
   if(count==125)       // cuento 125 interrupciones 1u*125*32*250=1s
   {

      rps=GET_TIMER1(); // capturo el valor de tmr1 cuando llegue al segundo el tmr0
....

se meten otros pulsos más y se cuenta mas rps's, pero eso en frecuencias altas, lo puedo aceptar, pero en bajas deberia ser muy pequeño el error, en 1Hz va bien, pero en 2 ya se raya, me lee como 5 o 6 rps, y no lo entiendo, primero lee bien 2 y despues se loquea y lee 5 o 6, y sigue asi para frecuencias mas arriba, pero bajas todavia. Seguro que estoy haciendo la lectura mal como me mencionas Nocturno, pero como te mencione creo que si se mide solo la freceuncia entre dos pulsos, tb se esta haciendo una estimación porque las rpm (en el caso de mi bicicleta) creo yo que nunca será constante. Alguna sugerencia

gracias, adios.

umm espero me haya dejado entender
« Última modificación: 08 de Junio de 2007, 15:11:26 por Cryn »
.

Desconectado Cryn

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4169
Re: Inicios de mi tacometro
« Respuesta #5 en: 09 de Junio de 2007, 12:15:28 »
mentira, en 2 rps no me lee 5 o 6 me lee más, primero lee 2 y parece que va bien pero despues se dispara hasta 193!! con 3rps me lee 194!!! muy pero muy mal, si le pongo a 100Hz mide bien 99 tb, despues le puse 200 y 250, y como siempre primero lee bien y despues se dispara y esta vez se disparo hacia abajo; qeu hago mal, como debo hacerlo?? :(

gracias
« Última modificación: 09 de Junio de 2007, 12:21:57 por Cryn »
.

Desconectado Cryn

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4169
Re: Inicios de mi tacometro
« Respuesta #6 en: 09 de Junio de 2007, 14:08:10 »
creo que le encontre el problema, pues lo que genera para:
....................    setup_timer_1(T1_DIV_BY_1|T1_EXTERNAL);   // reloj externo y preescaler=1 para tmr1
014D:  MOVLW  87                           10000111
014E:  BCF    03.5
014F:  MOVWF  10                            T1CON

ya qeu deberia ser 00001111, segun veia por otro post: http://www.todopic.com.ar/foros/index.php?topic=17020.msg115135#msg115135

pero ahi se toma en cuenta el clock out, y creo que esa es la raiz del problema, esqeu usaba ese pin de out como salida para los display, y pues supongo que el PIC se raya y no llega a contar bien, verdad?? osea que, no puedo usar solo un pin para el ingreso del contador?? y debo usar los dos el T1OSO y el T1OSI??

weno haber si me dicen algo, gracias
.