Autor Tema: PROBLEMA... Tacometro 4x7segmentos PIC16F628!!!  (Leído 5126 veces)

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

Desconectado adrimadeo

  • PIC10
  • *
  • Mensajes: 4
PROBLEMA... Tacometro 4x7segmentos PIC16F628!!!
« en: 28 de Noviembre de 2012, 21:24:44 »
Buenas noches, estoy programando un codigo para un tacometro digital de 4x7 segmentos para autos. El programa se basa en medir el tiempo entre pulsos de la bobina del auto y mediante una cuenta aritmetica obtener el varlor de RPMs. El problema con el que me encuentro es al momento de representar el valor en los displays ya que el valor es representado una sola vez al principio y luego de este primer barrido de los displays no se vuelven a encender nunca mas.
A continuacion les copio el codigo y les adjunto el .HEX y el archivo de Proteus...

#include <16f628a.h>
#use delay(clock=12000000)
#fuses NOWDT,HS,PUT,NOPROTECT

#use fast_io(B)

#define ON output_high
#define OFF output_low

#define DIS1 PIN_A0
#define DIS2 PIN_A1
#define DIS3 PIN_A2
#define DIS4 PIN_A3

short flagllegopulso=0;

long t1=0;
long rpm=0;
long desbordamientos=0;

long prom=0;

int tabla[10]={0b10000000,0b11110010,0b01001000,0b01100000,0b00110010,0b00100100,0b00000100,0b11110000,0b00000000,0b00100000};

int dig1=0;
int dig2=0;
int dig3=0;
int dig4=0;

#INT_TIMER1
void TMR1_Interrupt()
{
   ++desbordamientos;
}

#INT_EXT
void RB0_Interrupt()
{
   flagllegopulso=1;
}

void main()
{
   disable_interrupts(global);
   disable_interrupts(int_timer1);
   disable_interrupts(int_ext);
   setup_counters(RTCC_INTERNAL,RTCC_DIV_2);
   
   setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
     
   ext_int_edge(L_TO_H);
   
   enable_interrupts(INT_EXT);
   enable_interrupts(INT_TIMER1);
   enable_interrupts(GLOBAL);
   
   do{     
      if (flagllegopulso==1)
      {
         ++prom;
         flagllegopulso=0;
      }
        if (prom==10)
   {
         t1=get_timer1();
         set_timer1(0);
         rpm = 300000/((t1+(desbordamientos*65536))*0.00033333);
         desbordamientos=0;
         prom=0;
         
         dig1=(rpm/1000);
         dig2=(rpm/100)-(dig1*10);
         dig3=(rpm/10)-(dig1*100)-(dig2*10);
         dig4=(rpm/1)-(dig1*1000)-(dig2*100)-(dig3*10);

      output_b(tabla[dig1]);
      ON (DIS1);
      delay_ms(5);
      OFF(DIS1);
      
      output_b(tabla[dig2]);
      ON (DIS2);
      delay_ms(5);
      OFF(DIS2);   
         
      output_b(tabla[dig3]);
      ON (DIS3);
      delay_ms(5);
      OFF(DIS3);
           
      output_b(tabla[dig4]);
      ON (DIS4);
      delay_ms(5);
      OFF(DIS4);
   }
   }while(TRUE);
}

Espero me puedan ayudar ya que estoy con este problema hace un par de dias y no puedo encontrar el error.
Desde ya muchas gracias.
Adrian...

Desconectado willynovi

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 546
Re: PROBLEMA... Tacometro 4x7segmentos PIC16F628!!!
« Respuesta #1 en: 28 de Noviembre de 2012, 23:24:42 »
Hola Adrian, hace tiempo hice este mismo proyecto que encaraste vos, pero mi programa era distinto y fue de la forma que me resultó. Te digo mas o menos como era a ver si te puedo ayudar.

Lo que hacia yo era contar la cantidad de pulsos cada medio segundo y de ahí calculaba las RPM.
De paso cada ese medio segundo (500 mseg) refrezcaba el valor de las RPM.

El programa lo había hecho en ASM en un 16f84.

Lo que tienes que tener en cuenta, si dices de usar 4 digitos, es el tema de la resolución, es muy dificil que puedas usar el último digito, yo media de a 50 RPM y redondeaba.
Tambien tené en cuenta que si es para un auto no es necesario tanta precisión.

Voy a ver si en la compu viejita me quedó el programita ese y te lo paso.

Otro punto a tener en cuenta es de como prender los led de los digitos, tenes que multiplexar y a su vez hacer una frecuencia de encendido y apagado de unos 30 hz.
Intento enseñarte a pescar, si solo quieres pescados, espera que un pescador te regale los suyos.

Desconectado fantaxmax

  • PIC16
  • ***
  • Mensajes: 107
    • Libertycraft - Minecraft
Re: PROBLEMA... Tacometro 4x7segmentos PIC16F628!!!
« Respuesta #2 en: 29 de Noviembre de 2012, 18:57:49 »
es porque en alguna parte el compilador desactiva las interrupciones, me di cuenta al hacer un step-by-step (paso por paso).

para ahorrar ram, puedes usar un 7448 o 49 depende del tipo de display, ahorras asi tambien pines.

bueno eso, prueba a reescribir el codigo de otra manere, siempre ahi otra manera de hacer lo mismo.

Saludos!
"El presente es suyo, El futuro es mio" N.T.
El conocimiento es gratuito e ilimitado, solo debes saber donde buscarlo.

Desconectado Chenao

  • PIC18
  • ****
  • Mensajes: 414
Re: PROBLEMA... Tacometro 4x7segmentos PIC16F628!!!
« Respuesta #3 en: 29 de Noviembre de 2012, 21:14:23 »

Yo veo un  problema grande en la siguiente parte del código:

Código: [Seleccionar]
rpm = 300000/((t1+(desbordamientos*65536))*0.00033333);
         desbordamientos=0;
         prom=0;
         
         dig1=(rpm/1000);
         dig2=(rpm/100)-(dig1*10);
         dig3=(rpm/10)-(dig1*100)-(dig2*10);
         dig4=(rpm/1)-(dig1*1000)-(dig2*100)-(dig3*10);

Esté cálculo numérico realizado por el micro consume bastante tiempo, por lo tanto, se perderá la sincronización con el circuito de visualización, esto se evidencia en un parpadeo de los displays y en el peor de los casos como un apagón de tal circuito.

Yo te recomiendo (ya que hice un proyecto parecido, el cual, puedes encontrar utilizando el buscador del foro) utilizar otra interrupción (puede ser por timer1) para garantizar el tiempo de refresco de los displays y de esta manera te ahorraras más de un dolor de cabeza.   
Un saludo desde Pereira - Colombia

Desconectado PalitroqueZ

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5490
    • Electrónica Didacta
Re: PROBLEMA... Tacometro 4x7segmentos PIC16F628!!!
« Respuesta #4 en: 29 de Noviembre de 2012, 21:22:15 »

Yo veo un  problema grande en la siguiente parte del código:

Código: [Seleccionar]
rpm = 300000/((t1+(desbordamientos*65536))*0.00033333);
         desbordamientos=0;
         prom=0;
         
         dig1=(rpm/1000);
         dig2=(rpm/100)-(dig1*10);
         dig3=(rpm/10)-(dig1*100)-(dig2*10);
         dig4=(rpm/1)-(dig1*1000)-(dig2*100)-(dig3*10);

Esté cálculo numérico realizado por el micro consume bastante tiempo, por lo tanto, se perderá la sincronización con el circuito de visualización, esto se evidencia en un parpadeo de los displays y en el peor de los casos como un apagón de tal circuito.

....

una forma económica en rapidez (y costosa en memoria de programa) es manejar el resultado como un string y luego mediante comparaciones sacar los digitos para mostrarlos en 7-seg.

en este caso es mas importante la velocidad que el numero de lineas de código...

La propiedad privada es la mayor garantía de libertad.
Friedrich August von Hayek

Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5892
    • Picuino
Re: PROBLEMA... Tacometro 4x7segmentos PIC16F628!!!
« Respuesta #5 en: 30 de Noviembre de 2012, 20:57:37 »
Hay formas más rápidas de pasar un número binario a dígitos decimales.

Una forma podría ser utilizar la función sprintf:
   char dig[15];
   sprintf(dig, "%d", rmp)

Otra forma es con la función ltoa:
   char dig[15];
   ltoa(rpm, dig);

Otra forma es implementar la función tú mismo con una rutina en asm o C que traduzca binario a decimal:

   Aquí muchas rutinas en asm: http://www.piclist.com/techref/microchip/math/radix/index.htm

   Una rutina para convertir 16bits a decimal: http://www.piclist.com/techref/microchip/math/radix/b2a-16b5a-rl.htm


Saludos.


Desconectado willynovi

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 546
Re: PROBLEMA... Tacometro 4x7segmentos PIC16F628!!!
« Respuesta #6 en: 30 de Noviembre de 2012, 21:46:15 »
Busqué en la compu vieja pero no encontré el programilla  :(

Me acuerdo que las cuentas para pasar el número acumulado con el RA4 durante 0,5 seg a cada uno de los dígitos llevaba sus cuantas instrucciones, no era dificil, pero si llevaba varios ciclos, siempre hablando en ASM.

Usaba mucho la instrucción de desplazamiento y con eso dividía por 2 o 4 y así.
Intento enseñarte a pescar, si solo quieres pescados, espera que un pescador te regale los suyos.

Desconectado Chenao

  • PIC18
  • ****
  • Mensajes: 414
Re: PROBLEMA... Tacometro 4x7segmentos PIC16F628!!!
« Respuesta #7 en: 30 de Noviembre de 2012, 23:11:37 »

Si bien hay muchas formas para pasar de binario a bcd, el problema principal que observo en el programa del compañero adrimadeo es la siguiente linea de código

Citar
rpm = 300000/((t1+(desbordamientos*65536))*0.00033333);


Acá hay de todo (división, multiplicación de 24 bits etc), esta instrucción consumirá bastante tiempo de ejecución (y más en CCS), por lo tanto, el uso de una interrupción para multiplexar los displays es imprescindible. En el foro hay bastante información acerca de esta técnica, utiliza el buscador y de seguro la encontraras  ;-).     
Un saludo desde Pereira - Colombia

Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5892
    • Picuino
Re: PROBLEMA... Tacometro 4x7segmentos PIC16F628!!!
« Respuesta #8 en: 01 de Diciembre de 2012, 17:12:59 »
Esa línea se podría simplificar a una división de dos números long (32 bits)

Código: [Seleccionar]
   union {
      long lng;
      struct {
          unsigned int wd0;
          unsigned int wd1;
      };
   } time;


   time.wd0 = t1;
   time.wd1 = desbordamientos;

   rpm = ((long)3000*300000)/time.lng;



Saludos


 

anything