Captar señal inyector de moto

Hola mi nombre es José, llevo poco tiempo en el mundillo de Arduino y estoy muy ilusionado con ciertos proyectos que estoy desarrollando.

Tras buscar en google, no encuentro tal vez por desconocimiento lo que necesito o creo que necesito.

Tengo como proyecto hacer un medidor de consumo de combustible en tiempo real y para ello buscando y preguntando he conseguido realizar este código para que me muestre cuándo el inyector de mi moto se encuentra abierto, midiendo ese tiempo y mostrandomelo en una pantalla tft 2.4 montada en arduino Mega 2560. Utilizo el pin 21 para medir la señal y probada con un pulsador en la protoboard he conseguido tener los valores de tiempo y "supuestamente" a más tiempo abierto, más consumo.

Hoy me he decidido a conectar a la moto el arduino y me he encontrado con la sensación de que le roba corriente el cable que conecto al inyector que trabaja a 12v mediante un 7805 (como el inyector está conectado directamente a positivo, la ecu le da la masa para que se abra) he conectado el positivo del inyector a la patilla izquierda (input) y el negativo del inyector al alojamiento del tornillo (no sé si éste es el problema, en la protoboard me ha funcionado perfecto). la salida (patilla derecha) la llevo con un cable de 50cm aprox. al pin 21 del arduino.

De primeras el arduino se me queda en blanco antes de arrancar, le doy al botón reiniciar, cuando muestra la pantalla, le doy al arranque, la moto no consigue arrancar, le doy gas y suena como a que no funciona bien el inyector, el arduino marca un par de veces los tiempos del código y luego se pone otra vez en blanco (supongo que por algún pico de tensión de la bobina o algo parecido).

Hasta ahí he conseguido llegar, por favor disculpen los errores de publicación ya que es la primera que hago, si fueran tan amables de ayudarme con este tema la verdad que tengo mucha ilusión en poderlo conseguir y tener visualmente el consumo tanto en mi moto como en mi coche.

PD: la moto es una Yamaha FZ6 y el inyector Inyector de Yamaha Fazer 2004-2007 (Denso 5D8.5, codigo 5VX137610000). Mil gracias!

Código:

#define BLACK 0x0000
#define NAVY 0x000F
#define DARKGREEN 0x03E0
#define DARKCYAN 0x03EF
#define MAROON 0x7800
#define PURPLE 0x780F
#define OLIVE 0x7BE0
#define LIGHTGREY 0xC618
#define DARKGREY 0x7BEF
#define BLUE 0x001F
#define GREEN 0x07E0
#define CYAN 0x07FF
#define RED 0xF800
#define MAGENTA 0xF81F
#define YELLOW 0xFFE0
#define WHITE 0xFFFF
#define ORANGE 0xFD20
#define GREENYELLOW 0xAFE5
#define PINK 0xF81F


#include <Adafruit_GFX.h>    // Core graphics library
#include <MCUFRIEND_kbv.h>   // Hardware-specific library
MCUFRIEND_kbv tft;

#include "Fonts/FreeSans9pt7b.h"    // when you want other fonts

const int pin = 21;
volatile bool pulso = 0;
volatile unsigned long tiempo = 0;
unsigned long tiempo_anterior = 0;
bool subida = 0;
float Litrosporhora;
float tiempo1 = 500;
unsigned long tiempo_0 = 0;



void setup(){
    pinMode(pin, INPUT);
    Serial.begin(115200);
    uint16_t ID = tft.readID();
    tft.begin(ID);
    tft.fillRect(0, 0, 240, 420, BLACK);
    tft.setRotation(2);
    tft.setTextColor(BLUE, BLACK);
    tft.setTextSize(4);
    tft.setTextWrap(false); // escribe el texto en una línea. (true) en distintas
    //tft.setFont(&FreeMonoOblique9pt7b);
    tft.setCursor(10, 10);
    tft.println("L/h: ");
    attachInterrupt(digitalPinToInterrupt(pin), leer, CHANGE);
}

void loop(){

  if (pin == 0){
      Serial.println("el pulso es 0");

  }

   if (pulso == 1){
     if (subida ==1){
       /*Serial.print(tiempo - tiempo_anterior);
       Serial.print(" ");
       Serial.println("milisegundos entre pulsos");
       */                    }
     if (subida ==0){
       tft.setTextColor(BLUE, BLACK);
       Serial.println(tiempo - tiempo_anterior);
       Litrosporhora = tiempo - tiempo_anterior;

                           }


   tiempo_anterior = tiempo;
   subida = !subida;
   pulso = 0;
   if (millis() > tiempo1 + tiempo_0) {
     tiempo_0 = millis();
     tft.setCursor(100, 10);
     tft.println(Litrosporhora, 1);
   }
                }
}

void leer(){
   tiempo = millis();
   pulso = 1;
}

Hi,
Creo que tu problema si yo entiendo es que tu estas usando un regulador de voltaje para cambiar la senal de 12 que va a el injector y usas el regulaador para bajar esta a 5 voltios. Por lo tanto estas usando el convertidor de senales incorrecto. Para mi yo te aconseja que hagas un google y busques "opto coupler". Para que tengas una idea de como usarlo. Para mi es la mejor soluccion para tu problema. Primero te va aislar el arduino de los ruidos electricos que se producen cuando energizas un inductor = injector y te cambia los 12 voltios a 5 voltios que puede leer el arduino sin problemas.

Adjunot circuito para que tengas una idea de como hacerlo.

Muchísimas gracias por tu respuesta, ya los mire y encontré que se usaban para comandar circuitos de 12v desde Arduino no al revés. Cual me recomiendas? Yo he visto este según pone convierte 12v a 3.3v o 5v

Hi,
Ese esta perfecto pues las salidas la puedes seleccionar de 3.3 o 5 voltios.

S es correcto ese ultimo que subiste tiene esa funcion, solo tienes que revisar el esquema y listo.

Otra opcion es buscar un optoacoplador a 12V;

https://images.app.goo.gl/zamqKqKQJyUeJ6cv8

Algo así de sencillo, quizas lo puedas armar de una vez.

-Alex.

Muchas gracias a todos por responder!

Rebuscando por ahí me he encontrado un EL317 y un 4N35 y no encuentro manera de conectarlo, viendo la datasheet de ambos, pone en reverse voltage 6V y 50mA.
He conseguido reducir 12v de un transformador a 5V con 10 resistencias de 1Mohm, yo haciendo la ley de ohm me salía 7v a reducir en resistencias 7V/0.05A=140 Ohm. No sé qué burrada de resistencias he tenido que utilizar, ni por qué; algo habré hecho mal porque lo he hecho con un polímetro por la cuenta la vieja restando voltios y a cada resistencia me caía la tensión 1V aprox.

Procediento a conectarlo en la protoboard, para hacer una pequeña prueba con un pulsador y un led, me encuentro con que el ánodo (donde está el punto en la parte superior) compruebo entre ánodo y cátodo y tengo 12v.... no se cómo ya que he conectado las resistencias en serie al positivo, después el pulsador y éste al ánodo, el cátodo directo a negativo.

Resultado: No funciona, no consigo continuidad entre emisor y colector comprobado con un polimetro.

Espero no marearos mucho y haberme explicado con claridad, muchas gracias nuevamente!

Hi,
Sugerencia uno de lo problemas que uno se encuentra cuando hace los circuitos caseros es cuando se danan para remplazarlos es un problema. Yo uso los circuitos caseros cuando estoy desarollando el projecto. Una vez que ya esta realizado entonces miro a ver si los hay el mercado. Porque cuando se dana solamente los remplazas y los tira a la bsasura. Si los haces casero entonces tiene que hacerlos y esto toma tiempo. Hoy en dia los modulos son bien baratos y se pueden tirar a la basura cuando se dana. Creo que debes de tener esto en tu consideracion. Para desarollo bien pero para un projecto final y permanente no lo aconsejo. Solamente un consejo y sugerencia que debes tener en cuenta.

la idea es simular el optoacoplador que me llegará en un tiempo, para aprender también a conectarlo sin una placa. pero no consigo hacerlo funcionar, el tema de las resistencias se me escapa, parece sencillo pero no entiendo como pasando los 12v por 10MOhm me sigue dando 12v... En fín mañana será otra día

ya he logrado hacer funcionar el optoacoplador, el problema es que tengo una tensión de aprox. 1.5V residual y eso me genera señal cuando debería ser 0. con la ayuda de AlexLPD ví que poniendo en serie entre positivo y negativo una resistencia de 4.7k y otra de 6.8k en la unión entre resistencias consigo 4,8v.

Ahora el problema es que el arduino en cuanto meto el cable en el pin 21, se pone a contar, y si le meto un caudalimetro a ese mismo pin, funciona bien. no sé qué puedo estar haciendo mal en la protoboard, me gustaría probarlo fuera de la moto y luego montarlo con seguridad.

PD: el arduino mega que monté en la moto me lo he cargado, no lee los datos :frowning:

Hi,
Si usas un 4N35 la corriente max es de = 50 ma. Normalmente para extender la vida del opto se usa una corriente min de 015ma. Por la tanto si el voltaje es de 12/.015 = 800 ohmios. Ahora algunas veces es bueno estar seguro que la salida del opto o del transistor esta saturada por lo tanto tienes que aumentar la corriente del opto. Trata con una de 800 ohmios para ver si te trabaja. Ahora aqui vaz a tener que ver si el mcu de la motora le suple el ground al injector para energizarlo. Si asi entonces en el sketch tienes que lerlo cuando se va a high pues el opto va estar energizado por los 12 voltios todo el tiempo y la salida va a ser zero cuando el mcu energiza el injector la salida del transistor se va ir a los 5 voltios.

Adjunto un esquematico de una posibilidad siempre y cuando el injector tiene los 12 voltios alimentado el injector todo el tiempo. Esto va a depender de como se energiza el injector.

En efecto amigo, es cómo tu planteas, está conectado a 12 v y la ECU le da negativo. Mi que no teniendo es el voltaje que aguanta el ánodo del optoacloplador. Según el datasheet son 1.2v 50ma? O eso he logrado entender.

He probado Al someterlo a 1.2v con un divisor de tensión con 10k en el positivo y 1k al negativo, y el puente de resistencias conectado a un pulsador, me funciona pero el Arduino me detecta como si estuviera siempre algo excitada la base del transistor y por tanto el Arduino me detecta un tiempo de 9-10 ms constantes.

Probaré el esquema que me ha facilitado y le cuento que tal. Muchísimas gracias de verdad por la ayuda

PD: me puede decir cómo hacer esos esquemas para mostrarles mejor mi ayer monto en la protoboard?

Hi,
El opto coupler trabaja de un corriente max de 50 ma. Yo normalmente uso 20 ma . puedes subirla un poco mas pero la vida del opto coupler te va a desminuir dependiendo de la corriente. Trata 12/.20 ma = 600 ohmios. Si quieres usa .015 ma. 12/.015= 800. Para los circuitos yo uso CRCUITLAB.Es gratis pero estas limitado a los componentes que usas en el circuito. Puedes simular los circuitos electronicos y puedes ver si trabaja o no. Acuerdate que cuando leas los pulsos con el arduino normalmente esta en zero y se va a positivo cuando energizas el injector. En el sketch si no usas interrupt tienes que leer la entrada y cuando se va positivo es cuando el injector esta energizado.

tauro0211, el IRF530 cómo lo conecto y que función tiene? No logro entender para qué sirve. Demomento no he conseguido que funcione el circuito. Muchas gracias

Creo que me mal entendiste. El IRF530 es simunlando el transistor dentro del MCU. Para el mcu energizar el suple el ground y energiza el enjector. Para hacer funcionar el opto solamente lo conectas al cable de returno del injector. El otro cable del injector va a los 12 voltios. de la bateria.Adjunto un esquematico que te demuestra como alambrar el opto coupler. La resistencia de 800 ohmios te baja el voltaje/corriente que va al opto coupler. El injector tiene dos cables uno que conecta a la bateria y el otro es el retorno al mcu.Recuerda que tienes que tenerr mucho cuidado como haces las conecciones del injector pues un error puedes danar el mcu.

Perdone, muchas gracias. Intentaré conectarlo como lo ha puesto en el esquema. Entiendo, corríjame si me equivoco, que tengo que conectar el cable de negativo que da la ECU al positivo del coupler y el negativo de éste a batería directa. La parte de arduíno no creo que tenga problema, pero tengo que conectar la salida del transistor al gnd de arduino y a su vez a la batería? creo que eso es un error fundiría arduino o al ser masa no habría problema? Gracias de nuevo

Hi,
Para hacer la coneccion solamente necesitas dos cables conectar el returno del injector al anodo del opto coupler y el catodo del opto coupler al ground de la motora. Aqui lo que sucede es que cuando el MCU suple el ground para energizar el injector suple el ground tambien al anodo del opto por consiguiente este se apaga. Entonces cuando el MCu de-energiza el injector el opto recibe el voltaje atraves del injentor y lo energiza. Esos es todo. Alambra la salida del opto coupler como esta en el dibujo. El problema es que el simulador no tiene el componente del opto coupler y yo uso para representalo un LED y un transitor. Recuerda que cuando el injector esta de-energizado el arduino te va a leer zero voltios. Cuando lo energizas te va a leer 5 voltios.

Si te entendi lo puedes hacer como tu dices tambien. Adjunto el esquematico de como hacerlo usando tu idea.

Hola!

ya he conseguido que funcione pero no me da un valor que pueda utilizar para contar el consumo de gasolina teórico que podría tener.

Pregunta:
Qué modificación se os ocurre que pueda hacerle al código? ya que creo que necesito que me haga un cómputo de pulsos a lo largo del tiempo, ya que a relantí obtengo 50 y cuando acelero, se hace más pequeño el número. La verdad que estoy super contento que funcione pero no me vale de nada jajaja

Muchísimas gracias!

#define BLACK 0x0000
#define NAVY 0x000F
#define DARKGREEN 0x03E0
#define DARKCYAN 0x03EF
#define MAROON 0x7800
#define PURPLE 0x780F
#define OLIVE 0x7BE0
#define LIGHTGREY 0xC618
#define DARKGREY 0x7BEF
#define BLUE 0x001F
#define GREEN 0x07E0
#define CYAN 0x07FF
#define RED 0xF800
#define MAGENTA 0xF81F
#define YELLOW 0xFFE0
#define WHITE 0xFFFF
#define ORANGE 0xFD20
#define GREENYELLOW 0xAFE5
#define PINK 0xF81F


#include <Adafruit_GFX.h>    // Core graphics library
#include <MCUFRIEND_kbv.h>   // Hardware-specific library
MCUFRIEND_kbv tft;

#include "Fonts/FreeSans9pt7b.h"    // when you want other fonts

const int pin = 21;
volatile bool pulso = 0;
volatile unsigned long tiempo = 0;
unsigned long tiempo_anterior = 0;
bool subida = 0;
float Litrosporhora;
float tiempo1 = 500;
unsigned long tiempo_0 = 0;



void setup(){
    pinMode(pin, INPUT);
    Serial.begin(115200);
    uint16_t ID = tft.readID();
    tft.begin(ID);
    tft.fillRect(0, 0, 240, 420, BLACK);
    tft.setRotation(2);
    tft.setTextColor(BLUE, BLACK);
    tft.setTextSize(4);
    tft.setTextWrap(false); // escribe el texto en una línea. (true) en distintas
    //tft.setFont(&FreeMonoOblique9pt7b);
    tft.setCursor(10, 10);
    tft.println("L/h: ");
    attachInterrupt(digitalPinToInterrupt(pin), leer, CHANGE);
}

void loop(){


   if (pulso == 1){
     if (subida ==1){
       //Serial.print(tiempo - tiempo_anterior);
       //Serial.print(" ");
       //Serial.println("milisegundos entre pulsos");
                           }
     if (subida ==0){
       //tft.setTextColor(BLUE, BLACK);
       Serial.println(tiempo - tiempo_anterior);
       Litrosporhora = tiempo - tiempo_anterior;

                           }


   tiempo_anterior = tiempo;
   subida = !subida;
   pulso = 0;
   if (millis() > tiempo1 + tiempo_0) {
     tiempo_0 = millis();
     tft.setCursor(100, 10);
     tft.println(Litrosporhora, 1);
   }
                }
}

void leer(){
   tiempo = millis();
   pulso = 1;
}

Hi,

Me alegro que haya logrado hacerlo trabajar.

Adjunto un link que explica como contar pulsos usando el interrupt. Creo que lo puedes usar usando los pulsos del injector como interruptor. Modificalo para tu aplicacion. Acuerdate que el pulso se genera de 5 voltios a zero en otras palabras si usas interrupt debes de usar en el comando del interrupt la opcion "FALLING"

link: https://subscription.packtpub.com/book/web_development/9781785888564/3/ch03lvl1sec27/reading-and-counting-pulses-with-arduino

Hola tauro, gracias por tus consejos lo cambiaré como dices y lo probaré. De todas formas, el código no debería se un conteo de pulsos que cada segundo de lo muestre en pantalla y se ponga a su vez a 0?, quiero decir porque es lógico que cuando las rpm son más altas el pulso sea más corto pero hay más cantidad de pulsos por lo que hay más consumo y la forma de contabilizar esos pulsos por su tiempo de apertura no sería la función si usamos "pulsos_totales" como variable seria: pulsos_totales = pulsos_totales++
Y a cada segundo que pase con la función millis(), lo muestra en pantalla y lo pone a 0 para volver a contar.... es lo que se me ha ocurrido.

Lo que ahora mismo estoy buscando aparte del código es cómo hacer una pequeña pcb fácilmente para unir los componentes soldados y hacerle una cajita pequeña con la impresora 3d, mientras viene el optoacoplador que publiqué anteriormente. Muchas gracias

Hi,
Pero si lo haces leyendo el pin cuando aumentas las revoluciones puedes perder pulsos. Si usas el interrupt vaz a leerlo cada vez que tienes un pulso. Es mas preciso leyendo los pulsos. Creo que el uso de un milisegundo es para tener una lectura precisa y que se repita constantemente.