Autor Tema: Contar pulsos por segundo para cuentakilometros casero  (Leído 5455 veces)

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

Desconectado malea_ittt

  • PIC10
  • *
  • Mensajes: 11
Contar pulsos por segundo para cuentakilometros casero
« en: 10 de Septiembre de 2013, 13:59:57 »
Hola a todos. A ver si me podéis ayudar...

Poseo una placa pinguino con un PIC182550.

El sensor de velocidad de mi coche es parecido a los cuentakm de las bicicletas. Por cada vuelta de la rueda, envía un pulso a la centralita encargada de calcular la velocidad (realmente envía 8 pulsos por cada vuelta de la rueda). Haciendo un pequeño cálculo, y a una velocidad de 120km/h, tendría unos 660 pulsos por segundo.

No tengo experiencia programando y no sé muy bien cómo hacerlo (solo he conseguido encender una secuencia de leds y poca cosa más).

Me gustaría cablear el sensor del coche a una entrada digital del PIC y realizar un pequeño programa que cada segundo contase el número de pulsos que entran por esa entrada. Es esto muy difícil? Alguien me puede orientar? He estado leyendo acerca del uso de interrupciones y tal, pero no sé muy bien cómo hacerlo ni si realmente haría falta. Supongo que será más sencillo que eso.

Gracias.

Desconectado planeta9999

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3520
    • Pinballsp
Re: Contar pulsos por segundo para cuentakilometros casero
« Respuesta #1 en: 10 de Septiembre de 2013, 14:10:15 »
Hola a todos. A ver si me podéis ayudar...

Poseo una placa pinguino con un PIC182550.

El sensor de velocidad de mi coche es parecido a los cuentakm de las bicicletas. Por cada vuelta de la rueda, envía un pulso a la centralita encargada de calcular la velocidad (realmente envía 8 pulsos por cada vuelta de la rueda). Haciendo un pequeño cálculo, y a una velocidad de 120km/h, tendría unos 660 pulsos por segundo.

No tengo experiencia programando y no sé muy bien cómo hacerlo (solo he conseguido encender una secuencia de leds y poca cosa más).

Me gustaría cablear el sensor del coche a una entrada digital del PIC y realizar un pequeño programa que cada segundo contase el número de pulsos que entran por esa entrada. Es esto muy difícil? Alguien me puede orientar? He estado leyendo acerca del uso de interrupciones y tal, pero no sé muy bien cómo hacerlo ni si realmente haría falta. Supongo que será más sencillo que eso.

Gracias.


¿ De que año es el vehículo ?

Salvo que sea muy viejo (un gasolina anterior a 2001, o un Diesel anterior a 2004), puedes leer ese dato por la toma de diagnosis OBDII, sin necesidad de cablear a ningún sensor, en ese caso puedes usar un ELM327 y el PIC para mostrar los datos (velocidad, RPM, carga del motor, temperatura del refrigerante, sensores de oxígeno, test de contaminantes, códigos de averías, etc...).


Desconectado malea_ittt

  • PIC10
  • *
  • Mensajes: 11
Re: Contar pulsos por segundo para cuentakilometros casero
« Respuesta #2 en: 10 de Septiembre de 2013, 14:55:27 »
Es un diésel del 2000. El sensor lo tengo ya cableado. Solo me falta saber cómo programar el PIC. El display también lo tengo ya montado y sé cómo mostrar el dato.

Desconectado BBMNet

  • PIC12
  • **
  • Mensajes: 91
Re: Contar pulsos por segundo para cuentakilometros casero
« Respuesta #3 en: 10 de Septiembre de 2013, 15:19:45 »
Coincido con planeta9999. Te dejo un link a la interfaz ELM327.

http://www.ebay.com/bhp/elm327-interface-bluetooth-obd2

Ahora bien, y asumiendo que también lo que quieres es aprender un poco de electrónica y programación, puedo sugerir lo siguiente, si tú lo aceptas.

No pretendo darte en sí el código ya que entonces el aprendizaje sería virtualmente nulo. Te sugiero que leas un tutorial de PICS y empieces a probar con la programación. Ya de lo que vayas logrando se te podrá ir dirigiéndo

1. El programa en sí consta de dos contadores. El primero para contar los pulsos de la rueda y el segundo como timer para la ventana de 1 segundo que has definido.
2. Para el primer contador escribe un programa que contínuamente lea el estado de una entrada (la del pulso de la rueda). Al detectar un flanco (cambio de la señal de BAJO a ALTO) deberá incrementar el registro que actúe como contador.
3. Con respecto al timer, éste es similar al anterior y la fuente de impulsos puede ser tomada del reloj interno. Lee las instrucciones para utilizar el prescaler ya que de seguro lo utilizarás. El contador es incremental así que tendrás que elegir el número en el que deberá empezar.
4. Cuando el contador timer llegue al máximo se genera una interrupción. Esta interrupción la debes utilizar correr un procedimiento que copie el valor del contador de pulsos principal, restablezca a cero a éste, restablezca el registro del timer y regrese al programa principal volviéndo a iniciar la cuenta de los pulsos de la rueda.
5. El valor copiado del número de pulsos es el dato que leerás para conocer la velocidad.

Como dije, ésto es una descripción general del programa. Conforme lo vayas realizando te irás dando cuenta de cómo se hace la programación.

Nota: deberás asegurarte que la señal del sensor es compatible con tu tarjeta ya que podría no funcionar o incluso dañarla.

Un saludo y suerte. Sigue en contacto.

Desconectado malea_ittt

  • PIC10
  • *
  • Mensajes: 11
Re: Contar pulsos por segundo para cuentakilometros casero
« Respuesta #4 en: 10 de Septiembre de 2013, 17:55:59 »
Coincido con planeta9999. Te dejo un link a la interfaz ELM327.

http://www.ebay.com/bhp/elm327-interface-bluetooth-obd2

Ahora bien, y asumiendo que también lo que quieres es aprender un poco de electrónica y programación, puedo sugerir lo siguiente, si tú lo aceptas.

No pretendo darte en sí el código ya que entonces el aprendizaje sería virtualmente nulo. Te sugiero que leas un tutorial de PICS y empieces a probar con la programación. Ya de lo que vayas logrando se te podrá ir dirigiéndo

1. El programa en sí consta de dos contadores. El primero para contar los pulsos de la rueda y el segundo como timer para la ventana de 1 segundo que has definido.
2. Para el primer contador escribe un programa que contínuamente lea el estado de una entrada (la del pulso de la rueda). Al detectar un flanco (cambio de la señal de BAJO a ALTO) deberá incrementar el registro que actúe como contador.
3. Con respecto al timer, éste es similar al anterior y la fuente de impulsos puede ser tomada del reloj interno. Lee las instrucciones para utilizar el prescaler ya que de seguro lo utilizarás. El contador es incremental así que tendrás que elegir el número en el que deberá empezar.
4. Cuando el contador timer llegue al máximo se genera una interrupción. Esta interrupción la debes utilizar correr un procedimiento que copie el valor del contador de pulsos principal, restablezca a cero a éste, restablezca el registro del timer y regrese al programa principal volviéndo a iniciar la cuenta de los pulsos de la rueda.
5. El valor copiado del número de pulsos es el dato que leerás para conocer la velocidad.

Como dije, ésto es una descripción general del programa. Conforme lo vayas realizando te irás dando cuenta de cómo se hace la programación.

Nota: deberás asegurarte que la señal del sensor es compatible con tu tarjeta ya que podría no funcionar o incluso dañarla.

Un saludo y suerte. Sigue en contacto.
Claro que lo acepto. Lo que quiero es aprender y pasarlo bien a la vez.
Voy a explicarme un poco mejor. Mi coche aún siendo viejo lleva ordenador de abordo. La pantalla LCD del ordenafor de abordo esta dividida en dos partes. La parte superior muesyra información de la radio, emisora, volumen..
Al cambiar la radio original por una mejor, la parte superior del ordenador de abordo dejó de mostrar esos datos, ya que la radio original utilizaba un protocolo que ahora no recuerdo el nombre, para mostrar esa info en el ordenador de abordo.
Después de mucho buscar, logré implementar ese protocolo de comunicación en mi placa pinguino, pudiendo escribir mensajes a mi antojo en la parte superior del ordenador de abordo que quedó inutilizada al cambiar la radio.
En un principio pensaba que el sensor de velocidad de mi coche daba una salida analógica de entre 0 y 5V. Pero no es así. Da un tren de pulsos cuya frecuencia aumenta con la velocidad.
Por eso quieto hacerlo directamente con el sensor y con el PIC, porque pienso que puede quedar chulo ver la velocidad digitalmente en el mismo ordenador de abordo del coche.

Después de este rollo... tengo alguna duda. Una entrada digital es suficiente rapida como para detectar unos 1500 cambios de estado por segundo?

Gracias!

Desconectado MerLiNz

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2463
Re: Contar pulsos por segundo para cuentakilometros casero
« Respuesta #5 en: 10 de Septiembre de 2013, 21:10:38 »
Es muy simple, tienes varias opciones:
-A: Contar el numero de pulsos en un tiempo, por ejemplo cuentas cuantos flancos de subida han ocurrido en 500ms y haces el calculo
-B: Contar el tiempo entre pulso y pulso (obtener periodo) con esto haces el calculo

Para la opcion A seria tan simple como poner un timer con señal externa, ponerlo a 0 cuando se inicie el timer contador del tiempo y luego ver cuantos pulsos has recibido en ese tiempo, para ello deberias calcular las frecuencias minimas/maximas y de ello ver que tiempo te interesa contar.

Para la B pones una interrupcion externa y cuando recibes el primer pulso inicias el timer, al volver a recibir el siguiente pulso lees el timer y asi obtienes el periodo de la señal.

Buscate frecuenciometros hay muchos ejemplos por ahi y con eso sacaras como adaptar tu codigo para el calculo de km/h

Desconectado BBMNet

  • PIC12
  • **
  • Mensajes: 91
Re: Contar pulsos por segundo para cuentakilometros casero
« Respuesta #6 en: 10 de Septiembre de 2013, 22:19:00 »
En tu caso particular con los datos que presentas lo más seguro es que sí.

La tarjeta pinguino que mencionas viene con un cristal de 20 MHz según aparece en la página siguiente:

http://wiki.pinguino.cc/index.php/PIC18F2550_Pinguino

A esa velocidad de reloj añádele que el procedimiento es sumamente corto. En ensamblador y enfocándonos sólo al procedimiento de lectura, éste sería algo como lo siguiente:

PLSDAT es el valor posicional del bit por el que llega la señal de pulsos.

Se definen dos registros. Un contador para que lleve el conteo de los pulsos de la rueda llamado PLSCNT y otro IMAGEN que será el que retendrá los datos a ser mostrados.

Nota: no puedes utilizar directamente PLSCNT ya que los datos estarían cambiando en todo momento haciéndolo ilegible.

El procedimiento inicia esperando al flanco BAJO-ALTO de la señal de entrada. Cuando lo detecta brinca a incrementar el contador PLSCNT y luego esperar al flanco ALTO-BAJO para evitar contar de más. Finalmente regresa a repetir el ciclo.

; Read command.

NEWCYC   MOVF PORTB, W                          ; Lee el puerto B. (1)
                 ANDWF PLSDAT, F                       ; Deja sólo el bit PLSDAT. (1)
                BTFSC STATUS, Z                       ; Verifica si el bit es cero. (3)
                 GOTO NEWCYC                           ; Sí es cero. Entonces vuelve a seguir leyendo el puerto. (2)

                INCF PLSCNT, F                           ; No fué cero, entonces incremente el contador. (1)

WAIT        MOVF PORTB, W                          ; Lea de nuevo el puerto B. (1)
                ANDWF PLSDAT, F                       ; Deja sólo el bit PLSDAT. (1)
                BTFSS STATUS, Z                        ; Vefifica si sigue siendo uno. (3)
                GOTO WAIT                                ; Vuelva a seguir leyendo el puerto B esperando el flanco ALTO-BAJO. (2)
                GOTO NEWCYC                            ; Vuelva a seguir leyendo el puerto. (2)

Los números en paréntesis son los ciclos de reloj que toma la instrucción para ejecutarse. El número de ciclos que toma como mínimo el procedimiento es 13 que con un reloj de 20MHz/4 por la división interna del controlador nos deja que el lazo se ejecuta 384615 veces por segundo. Un poco más que los 1500 pulsos por segundo que indicas (disculpa la mala broma).

Para definir la ventana de 1 segundo necesitas programar uno de los módulos timer seguramente utilizando el prescaler y accionándolo desde el reloj interno.

Una manera para actualizar el valor de IMAGEN que es el registro que nos interesa sería programando el timer antes de iniciar el procedimiento NEWCYC e insertar los pasos necesarios para leer el timer durante el subprocedimiento WAIT (método llamado polling). En este caso si el timer no ha terminado simplemente regresa a NEWCYC. Pero si el timer terminó entoces copia los datos de PLSCNT a IMAGEN, restablece a cero PLSCNT y brinca al paso anterior a NEWCYC donde se vuelve a reprogramar al timer.

Esto debiera funcionar bien. Sin embargo si quieres mayor precisión deberás utilizar el timer para generar una interrupción y ejecutar las funciones definidas arriba.

Para que no tengas que estar probando esto directamente en el coche puedes armar un pequeño oscilador con un circuito integrado timer 555. Hay mucho de ello en internet. Sólo calcula los valores para un ciclo de trabajo lo más bajo posible a una frecuencia de 1500 Hz.

Inicia con esto y manténte en contacto.

Suerte.

Desconectado malea_ittt

  • PIC10
  • *
  • Mensajes: 11
Re: Contar pulsos por segundo para cuentakilometros casero
« Respuesta #7 en: 11 de Septiembre de 2013, 02:20:32 »
Empezaré con esto. Una última duda antes de empezar. Creo que el nivel alto del sensor da un voltaje superior al que permite la entrada del PIC. Sería suficiente con poner un regulador de voltaje tipo 7805 a la entrada? O el regulador no sera tan rapido como para cambiar de estado tantas veces por segundo?
PD. No, no creo que necesite mas precision. Así que empezare por ver si consigo avanzar en lo del timer. Estoy pensando en reducir la ventana a medio segundo para aumentar el refresco, aunque supongo que disminuiré l precisión. Bueno, esto lo dejo para cuando el programa funcione.
« Última modificación: 11 de Septiembre de 2013, 02:25:04 por malea_ittt »

Desconectado MerLiNz

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2463
Re: Contar pulsos por segundo para cuentakilometros casero
« Respuesta #8 en: 11 de Septiembre de 2013, 06:47:30 »
Los reguladores son una fuente de alimentacion pero no sirven para ese proposito, para ello simplemente usas un divisor de tension con 2 resistencias, o un zener y 1 resistencia o con un diodo y resistencia.

Desconectado BBMNet

  • PIC12
  • **
  • Mensajes: 91
Re: Contar pulsos por segundo para cuentakilometros casero
« Respuesta #9 en: 11 de Septiembre de 2013, 11:43:57 »
Coincido con MerLiNz. Los reguladores son para fuentes de alimentación no para otra cosa (alguna vez usé un 7805 para un amplificador de audio pero era un experimento loco). Con el divisor de dos resistencias es suficiente.

El zener en el pin de entrada como protección debería ser de 5.6V pero lo recomendaría con reservas ya que a veces la capacitancia de la unión afecta la lectura de pulsos sobre todo si son muy cortos. En tu caso no tengo ni idea de las características del sensor.

Si puedes trata de poner los datos del sensor.

Saludos.

Desconectado malea_ittt

  • PIC10
  • *
  • Mensajes: 11
Re: Contar pulsos por segundo para cuentakilometros casero
« Respuesta #10 en: 11 de Septiembre de 2013, 14:20:38 »
Código: [Seleccionar]
//Alias para el pin 3
#define SENSOR 3

 //Variables
int contador = 0;
int contadorAux = 0;
int estadoActual = 0;
int estadoAnterior = 0;

//Método que captura el número de pulsos
void capturarPulsos()
{
    contadorAux = contador;
    contador = 0;
}

void setup()
{
    //Configuro PIN como entrada digital
    pinMode(SENSOR, INPUT);
    //Capturo número de pulsos cada 500ms
    OnTimer0(capturarPulsos, INT_MILLISEC, 500);
}

void loop()
{
    //Capturo el estado de la entrada
    estadoActual = digitalRead(SENSOR);
    
    //Si el estado es diferente del estado anterior
    if (estadoActual != estadoAnterior)
    {
        //Si el estado es nivel alto, aumento contador
        if (estadoActual == HIGH)
        {
            contador++;
        }
    }
}

A ver si voy por el buen camino. Estoy programando en Pinguino IDE que usa su propio lenguaje, pero vamos, es ARDUINO si no me equivoco.

Tal y como está hecho no sé si funciona. Si cada medio segundo se ejecuta el método capturarPulsos, entiendo que lo que hay dentro del loop se detiene mientras esté dentro del método llamado por la interrupción no? De esta forma no necesitaría la variable auxiliar no? Si el contador mientras esté dentro del método capturarPulsos no se incrementa... o no lo he entendido bien.

Más cosas, yo para enviar el texto al ordenador de abordo utilizo una secuencia de instrucciones, y entre ellas hay varios delay. No sé muy bien cómo afectaría esto. El timer sigue contando igualmente esté en el método que esté no? O se espera a que se trate la interrupción?
Supongo que tendría que poner la secuencia de instrucciones que envían el texto a la pantalla del ordenador de abordo dentro del método que se llama cuando se produce la interrupción. Pero claro, necesito hacer delays de más de medio segundo para mostrar el texto, con lo que si el timer sigue contando, volverá a producirse la interrupción antes de que acabe de mostrar la velocidad.

Porque si realizo el envío del texto en el loop con todos los delays... voy a parar de capturar pulsos durante más de medio segundo...
« Última modificación: 11 de Septiembre de 2013, 14:32:04 por malea_ittt »

Desconectado BBMNet

  • PIC12
  • **
  • Mensajes: 91
Re: Contar pulsos por segundo para cuentakilometros casero
« Respuesta #11 en: 12 de Septiembre de 2013, 04:18:07 »
A mi parecer el programa como lo tienes está trabajando al revés. Me parece que cada medio segundo estás abriendo una ventana para leer el primer pulso que pase y luego cierras la ventana. Así te perderás todos los pulsos menos uno que lleguen cada medio segundo.

Como indique en este caso se me hace más conveniente realizar la lectura del pulso de entrada y esperar a uno de los flancos para incrementar el contador y el otro flanco para asegurar que no se lean más pulsos que los que realmente lleguen.

El timer es independiente de la operación del procedimiento de lectura e incremento indicado arriba ya que opera en el hardware interno del PIC. Así sólo cuando termina y genera el pulso de interrupción es que se interrumpe la rutina de lectura del pulso de entrada. Pero ya no es importante porque el dato que se quiere es el almacenado en PLSCNT.

Durante el tiempo que tarde en copiarse PLSCNT a IMAGEN es totalmente irrelevante que se pierdan pulsos ya que no afectarán a la lectura puesto que antes el timer debe ser reseteado para iniciar un nuevo ciclo (ventana) de lectura.

Dejame revisar un poco más tu programa y me contacto de nuevo.

Desconectado malea_ittt

  • PIC10
  • *
  • Mensajes: 11
Re: Contar pulsos por segundo para cuentakilometros casero
« Respuesta #12 en: 12 de Septiembre de 2013, 06:39:43 »
Me he basado en estos sencillos ejemplos, pero ya no sé si es que lo he entendido yo mal:

http://wiki.pinguino.cc/index.php/OnTimer0
https://code.google.com/p/pinguino32/source/browse/branches/pic32/C32/linux/examples/inter/OnTimer.pde?r=96
http://forum.pinguino.cc/showthread.php?tid=3735

En el último se ve más o menos lo que yo necesito hacer, y por lo que veo voy a tener problemas con los delays.

He modificado y supongo que debería de hacer algo así:

Código: [Seleccionar]
//Alias para el pin 3
#define SENSOR 3

//Variables
int contador = 0;
int contadorAux = 0;
int estadoActual = 0;
int estadoAnterior = 0;

//Método que captura el número de pulsos y los envía al ordenador de abordo
void tratarInterrupcion()
{
    //Capturo
    contadorAux = contador;
    //Reinicio contador
    contador = 0;
    //Muestro por pantalla
    mostrarPorPantalla (contadorAux);
}

//Método que envía la velocidad al ordenador de abordo del coche
void mostrarPorPantalla(int speed)
{
    //Aquí es donde pondría todas las instrucciones que necesito para mostrar la velocidad
}

void setup()
{
    //Configuro PIN como entrada digital
    pinMode(SENSOR, INPUT);
    //Capturo número de pulsos cada 500ms
    OnTimer0(tratarInterrupcion, INT_MILLISEC, 500);
}

void loop()
{
    //Capturo el estado de la entrada
    estadoActual = digitalRead(SENSOR);
    
    //Si el estado es diferente del estado anterior
    if (estadoActual != estadoAnterior)
    {
        //Si el estado es nivel alto, aumento contador
        if (estadoActual == HIGH)
        {
            contador++;
        }
    }
}
« Última modificación: 12 de Septiembre de 2013, 18:00:07 por malea_ittt »

Desconectado BBMNet

  • PIC12
  • **
  • Mensajes: 91
Re: Contar pulsos por segundo para cuentakilometros casero
« Respuesta #13 en: 12 de Septiembre de 2013, 11:29:57 »
A riesgo de aparentar querer forzarte a utilizar mi idea, porqué no pruebas la secuencia que te dí.

Comenta el resultado.
« Última modificación: 12 de Septiembre de 2013, 11:39:08 por BBMNet »

Desconectado malea_ittt

  • PIC10
  • *
  • Mensajes: 11
Re: Contar pulsos por segundo para cuentakilometros casero
« Respuesta #14 en: 12 de Septiembre de 2013, 17:54:42 »
Me he basado en tu secuencia.
Aumento el contador siempre que hay un flanco ascendente en la entrada digital. Programo el timer para que produzca una interrupción cada 500ms, y cuando se produce, capturo valor del contador, reseteo éste y envío el texto al ordenador de abordo. Entiendo que mientras no acabe de tratar la interrupción, el timer no empieza a contar otra vez. Es así no?
Si no he entendido bien tu secuencia por favor, dímelo. Estoy aquí para aprender.
Otra duda. He leído el datasheet del PIC18F2550 y no encuentro la tensión maxima de entrada para una entrada digital. Me podrías decir cómo averiguar este dato?
Gracias a todos por el interés, de verdad. Para alguien que no tiene mucha idea vuestra ayuda es incalculable.


 

anything