Hola a todos y muy agradecido desde ya por la ayuda que puedan brindarme.
Soy Ing. Mecánico desarrollando un proyecto para el cual necesito leer diferentes parámetros de un Automóvil, entre ellos las RPM y estoy teniendo problemas con estas lecturas.
Mi nivel de electrónica es medio-bajo, sin embargo entiendo de programación. Estuve revisando los foros y he visto que en ellos se recomienda mucho el MÉTODO DE NICK GAMMON para bajas frecuencias como las que se desarrollan en un Automóvil. Lo he descargado e instalado tal cual, la única modificación es que yo uso FALLING en lugar de RISSING para las interrupciones. Y las lecturas que muestra son inestables. Oscilan bastante.
Así que deduzco que en mi toma de datos algo está mal, para la toma de datos estoy usando un optoacoplador PC817 (ya que trabaja fácilmente con 20kHz).
Podrían ayudarme con saber que estoy haciendo mal? Me ayudarían muchísimo.
Estoy adjuntando el circuito que estoy usando para la toma de datos (los pulsos eléctricos).
Es bueno aclarar que los datos se toman de la Bobina primaria, donde la conexión positiva de la bobina primaria es FIJA y el lado negativo es el pulsante (representado por SW1 en el esquemático).
Otro dato a considerar es que 3 pulsos equivalen a 2 vueltas. (por ser un auto de 3 cilindros). Sin embargo por lo pronto mi interés es tener una lectura confiable y estable de la frecuencia de pulso a pulso, para luego recién hacer la conversión o equivalencia a RPM de Automovil.
El Algoritmo creado por Nick Gammon del que hago mención es:
// Frequency timer
// Author: Nick Gammon
// Date: 10th February 2012
volatile boolean first;
volatile boolean triggered;
volatile unsigned long overflowCount;
volatile unsigned long startTime;
volatile unsigned long finishTime;
// here on rising edge
void isr ()
{
unsigned int counter = TCNT1; // quickly save it
// wait until we noticed last one
if (triggered)
return;
if (first)
{
startTime = (overflowCount << 16) + counter;
first = false;
return;
}
finishTime = (overflowCount << 16) + counter;
triggered = true;
detachInterrupt(0);
} // end of isr
// timer overflows (every 65536 counts)
ISR (TIMER1_OVF_vect)
{
overflowCount++;
} // end of TIMER1_OVF_vect
void prepareForInterrupts ()
{
// get ready for next time
EIFR = _BV (INTF0); // clear flag for interrupt 0
first = true;
triggered = false; // re-arm for next time
attachInterrupt(0, isr, FALLING);
} // end of prepareForInterrupts
void setup () {
Serial.begin(19200);
Serial.println("Frequency Counter");
// reset Timer 1
TCCR1A = 0;
TCCR1B = 0;
// Timer 1 - interrupt on overflow
TIMSK1 = _BV (TOIE1); // enable Timer1 Interrupt
// zero it
TCNT1 = 0;
// start Timer 1
TCCR1B = _BV (CS10); // no prescaling
// set up for interrupts
prepareForInterrupts ();
} // end of setup
void loop ()
{
if (!triggered)
return;
unsigned long elapsedTime;
float freq;
int rpm;
elapsedTime = finishTime - startTime;
freq = 1.0 / ((float (elapsedTime) * 62.5e-9)); // each tick is 62.5 nS
rpm = freq*60;
Serial.print ("Took: ");
Serial.print (elapsedTime);
Serial.print (" counts.\t");
Serial.print ("Frequency: ");
Serial.print (freq);
Serial.print (" Hz.\t");
Serial.print ("RPM: ");
Serial.println (rpm);
// so we can read it
delay (250);
prepareForInterrupts ();
} // end of loop
Así que deduzco que en mi toma de datos algo está mal, para la toma de datos estoy usando un optoacoplador PC817 (ya que trabaja fácilmente con 20kHz).
Comparto tu opinión de que el circuito de entrada no esta actuando debidamente.
Mi consejo es que pongas un osciloscopio a ver esa salida y verifiques la calidad de los pulsos.
Te garantizo que con una entrada limpia el sistema funciona bien porque lo he usado y Gammon no propone cosas que no son.
Simplemente hay que hay separar las cosas, código y captura de datos de circuito electrónico conformador de la señal de entrada.
Hi,
Primero aqui creo yo haria un cambio y es de bajar la resistencia 1K que controla la corriente del optocoupler a una de 600 ohmios. La corriente del optocoupler diodo es de max 50 ma. Normalmente tu quires saturar la corriente de base del transistor para que no se abra/cierre al tener una corriente muy baja. Yo trataria una corriente de por lo menos 20ma. Asi estas seguro de que la base del transistor esta saturada. Segundo bajaria la resistencia del colector de 4K7 a una de 1K. La corriente tambien esta muy baja. Solamente sugerencias para tu consideracion. Por ultimo no se si esta instalado pero necesitas un condesador en paralelo con el switche. Este te va a eliminar los ruidos electricos que se generan al abrir/cerrar el contacto o lo que se conoce "bouncing".
surbyte:
Mi consejo es que pongas un osciloscopio a ver esa salida y verifiques la calidad de los pulsos.
Gracias Surbyte, lo tendré en cuenta. Analizaré la entrada de pulsos con un osciloscopio. Definitivamente es en la captura de pulsos del automóvil donde está el problema.
Creo que todos estamos de acuerdo que el problema es tu circuito, ademas de lo que te dijo @tauro, veo un error al conectar la entrada en el arduino, no entiendo porque conectas pull-up y pull-down al mismo tiempo, con esa configuración de resistencias, tienes aproximadamente 3 volts en el pin del arduino, quedando cerca de una zona indeterminada con lo que puedes obtener estados erróneos en la entrada, yo quitaría las resistencias de 10k que está conectada a gnd y la de 300 que va al pin digital, ademas de cambiar la de 4k7 por una de 10k.
Ahora una pregunta: ¿que tipo de sistema de encendido tiene ese motor? ¿es a platino y condensador o es electrónico?
Si es electrónico y tienes distribuidor con efecto hall, es mejor tomar la señal de ahí en lugar de la bobina de ignición
tauro0221:
Primero aqui creo yo haria un cambio y es de bajar la resistencia 1K que controla la corriente del optocoupler a una de 600 ohmios. La corriente del optocoupler diodo es de max 50 ma. Normalmente tu quires saturar la corriente de base del transistor para que no se abra/cierre al tener una corriente muy baja. Yo trataria una corriente de por lo menos 20ma. Asi estas seguro de que la base del transistor esta saturada.
Interesante observación @Tauro0221, gracias! haré las pruebas con esas modificaciones.
tauro0221:
Por ultimo no se si esta instalado pero necesitas un condesador en paralelo con el switche.
RIG:
no entiendo porque conectas pull-up y pull-down al mismo tiempo, con esa configuración de resistencias, tienes aproximadamente 3 volts en el pin del arduino, quedando cerca de una zona indeterminada con lo que puedes obtener estados erróneos en la entrada, yo quitaría las resistencias de 10k que está conectada a gnd y la de 300 que va al pin digital, ademas de cambiar la de 4k7 por una de 10k.
Hola RIG, gracias por responder! entiendo lo de la zona indeterminada, pero tengo una duda: Te refieres a que quite la resistencia 10k que va al gnd y el pin D2 este conectado directamente al gnd o que el pin D2 ya no tenga ningún contacto con gnd?
Yo la puse para garantizar que cuando no estén llegando los 5v del vcc el Pin D2 esté en LOW.
La de 300 ohmios la puse para que cuando conduzca el transistor del opto.. la corriente del vcc vaya directamente a gnd y no al pin d2. Está errónea mi lógica?
Otra duda. La de 4k7 por una de 10k?, nuestro compañero @Tauro acaba de sugierme que la disminuya más bien a 1k.
RIG:
¿que tipo de sistema de encendido tiene ese motor? ¿es a platino y condensador o es electrónico?
Hi,
La resistencia de 10K al pin de entrada de arduino se usa para descargar el voltaje rapidamente cuando el transistor del opto coupler se energiza y lleva la senal a ground. Esto ayuda al pulso bajar rapidamente cuando va de 5 voltios a ground. Esto no afecta en nada la senal de entrada al pin.
Otra sugerencia es de cambiar el opto coupler por uno que sea Schmitt trigger como H11L1MS. Esto te va a limpiar la senal de ruido. Adjunto foto de como trabaja el smichtt.
Una de las mejores alternativas y mas limpias es un acople inductivo.
Se trata de una bobina que enrollas alrededor del cable de la bobina haciendo que actue como antena.
Te pondré el dato del sitio donde lo encontré pero recuerdo haberlo intentado en época de secundaria y funcionaba bien. Si me preguntas cuantas vueltas... no recuerdo.
La bobina de la izquierda no es la bobina ignitora sino el arrollamiento sobre el cable de bobina. Es un acoplamientod inductivo.
Sigue el relato (fuente) y verás como el interesado va haciendo modificaciones para poder visualizar los cambios en un LED que luego reemplazaría por un optoacoplador. O sea tu enfoque.
tauro0221:
Esto ayuda al pulso bajar rapidamente cuando va de 5 voltios a ground. Esto no afecta en nada la senal de entrada al pin.
Así es. Pienso lo mismo.
He realizado los cambios que sugeriste Tauro y también quite la resistencia de 300 que entra al pin d2 (como sugirió RIG), pero manteniendo la resistencia de 10k tipo pull down . Y las lecturas se tornaron muy muy estables y con resultados coherentes.
No quiero apresurarme a confirmar que está resuelto el problema, sin antes realizar más pruebas con un tacometro (Ya que el auto de pruebas no lo tiene).
Hoy estaré haciendo esas pruebas y comento los resultados.
tauro0221:
Otra sugerencia es de cambiar el opto coupler por uno que sea Schmitt trigger como H11L1MS.
surbyte:
Una de las mejores alternativas y mas limpias es un acople inductivo.
La bobina de la izquierda no es la bobina ignitora sino el arrollamiento sobre el cable de bobina. Es un acoplamiento inductivo.
Acople inductivo! No se me había ocurrido, que ingenioso!
Ese circuito lo vi en otros foros, pero asumí que la bobina era la bobina ignitora y lo descarte porque no funciona cuando polo pulsante es el negativo. Si el pulsante fuera el positivo funcionaria bien!
En el caso de tomarlo como acople inductivo me parece muy buena opción.
Te refieres a que quite la resistencia 10k que va al gnd y el pin D2 este conectado directamente al gnd
Claro que no!! estarías provocando un corto circuito, me referia a eliminar por completo esa conexion
quite la resistencia de 300 que entra al pin d2 (como sugirió RIG), pero manteniendo la resistencia de 10k tipo pull down
Yo te sugerí quitar las 2 resistencias (no solo la de 300) y cambiar la de 4k7 por 10k, para lograr un buen PULL-UP... sigues teniendo un divisor de voltaje, por lo que no tienes ni PULL_UP ni un PULL_DW, si no algo a medias
La resistencia de 10K al pin de entrada de arduino se usa para descargar el voltaje rápidamente cuando el transistor del opto coupler se energiza y lleva la senal a ground
Vamos sacando calculos; digamos que el motor alcanza 10,000 R.P.M. (aunque lo dudo), si pasamos esto a revoluciones por segundo tenemos 166.6 R.P.S, bien, el distribuidor da media vuelta cada vuelta del cigueñal, entonces en el distribuidor tenemos 83.33 R.P.S, y por cada vuelta del distribuidor tenemos 3 pulsos, con esto tenemos como resultado un total de 250 pulsos por segundo a 10,000RPM.
Entonces:
¿descargar rápidamente descargar el voltaje rapidamente
Pones unas cuantas vueltas sobre el cable de ignición, un osciloscopio conectado a las puntas de esas vueltas. Mides la tensión inducida, estableces el nivel de la señal, le pones un AO, un smitch trigger y asunto resuelto.
Hola a todos y muchas gracias por su ayuda. He conseguido resolver el problema.
Hice las modificaciones a mi circuito sugeridas por RIG y TAURO, es decir quedó así:
Luego de hacer varias pruebas descubrí que con las correcciones mi circuito funciona perfecto para autos que trabajan con módulo (transistorizados), pero no funciona para autos con encendido a platinos y condensador.
Para autos con sistema de encendido a platino yo sugiero el método de Surbyte,
surbyte:
Pones unas cuantas vueltas sobre el cable de ignición, un osciloscopio conectado a las puntas de esas vueltas. Mides la tensión inducida, estableces el nivel de la señal, le pones un AO, un smitch trigger y asunto resuelto.