Multiplying pulse width times RPM, to get Fuel Flow

Hi,
I have been using airflow to control my fuel flow, and it works.
For a certain amount of air, it gets a certain amount of fuel.
The injectors have been electrically disconnected.
I'm using a needle valve, turned by a stepper motor, which is regulated by a Nano and drv8825 controller.
Now I want to use the injector pulse instead of solely the air flow sensor, because this signal, coming out of the ECU, contains acceleration fuel requirements, deceleration fuel shutoff, warm up, cold start, and temp fuel adjustments.
The arduino has been doing a good job controlling the stepper motor/needle valve combo.
But now I want get the information from the pulse to the injectors, and multiply by rpm, to tell the Arduino (and then the stepper motor) what to do.
The values gathered do not need to be specific units. Only the eventual ratios matter.
In other words if 70us of squirting and 97 rotation pulses take place in the same time period, the multiplicant is a usable value.
The thing I don't know is how to ask the Arduino to do this.
Also the injector pulse is 12 volts, and I don't think the Arduino can take a 12v signal.
If anyone can help fill in a few blanks, I can start another round of research, attempting to throw it all together.
Thank you very much.

Before asking the Arduino, please tell us about the RPM signal. And tell us if the injector signal is a single long pulse to open the injector, or is it multiple short pulses with the number of pulses changing as acceleration is needed.

Good question. You reminded me that the rpm is represented by the pulse frequency. So, as I had forgotten, no need to tap any wire beside the injector wire.
And yes, it is one long pulse. The pulses widths should not change drastically, since a cylinder gets about 1 drop of gasoline at all speeds.
But going downhill or decelerating, it can go to zero fuel. (That"s my understanding anyway)
Good questions; thanks for asking.
So to summarize the first part, the frequency of the pulse would be as effective as RPM.
I would just tap off of one injector, since that would still provide an quick response.

Depending on the engine. I assuming it is a 4 stroke so you will get a pulse only once every other RPM During the intake stroke. I am assuming this is on the bench and not in an operating vehicle. You can use a simple reisitor divider to change the 12V to 5V. Place a 50K or so resistor from the voltage divider to the input pin to protect the Arduino from transient noise.

The OP should be aware most fuel injector drives have two voltage levels. A full 12V for a short period of time (to open the injector quickly) then the voltage drops down to some voltage that can keep an already open injector open.

1 Like

Hey guys, Thanks a lot.
I did a lot of thinking and here's the thing;
Some of the problems above will be dodged because the voltage fires with no injector in the circuit.
(My follow-up research revealed that the 12v spikes when the injector closes, quite high actually. )
Also, there is apparently a CURRENT drop built into the ecu's function. Sounds like this is what John was referring to. Makes sense because any solenoid uses less current once open, right?
I then read that in a voltage divider, it's a great idea to use high resistances. Sounds good to me but how high? Maybe 3k and 4k resisors?
I'm thinking to bring only 4volts to the Arduino since thats still a nice v. for a signal, without pushing the v. limit of the arduino.
I have a fuel device that replicates the Tom Ogle experiment of 1978. Thats why Im not using injectors. https://youtu.be/er18mxZNLpo?si=YvD578aDXjOkO7UO
I should have the car back together in a few days, then I can run it a bit and check the injector signal, what it actually looks like on my tiny Chinese oscilloscope.
Btw, the car is a 2006 Scion tC.
I really don't want to hear any blatant negativity, because I've already run it and it works. I'm just making some refinements.
You guys have been helpful. T.Y.

You probably have custom injector drivers, they hit hard then backed down which is what you are seeing. There are several varities available then with different profiles. Look in some of the old Motorola data, I think one or two were made available to the general public but initially they were fully custom.

If my memory is working these driver were current controlled and if the injector was not there or did not draw enough current a fault would be generated and the injector would remain "on" until the current requirement wes met or it was timed out.

The ecu and injectors are factory. I've been driving the car with the injector signals disconnected. Believe it or not, it does not even throw a code.
I've been supplying a flow of fuel through a needle valve. The needle valve is turned by a stepper motor. The stepper motor is signalled by an Ardiuno (via a drv8825). The Arduino is signalled by a MAF sensor.
That's what I have now. The car is drivable, but lacks good acceleration, deceleration fuel shutoff, and cold start and warmup functions.
The ecu is sending these, but I'm connected to the wrong wire. I only have a tapped MAF signal. I think it's time to expand my horizons.
The pulse width times frequency has all these benefits, so I'm trying to capture that pulse data, and feed it to the needle valve (through the Arduino and stepper motor).
So its a matter of capturing and measuring the pulse width and frequency.
.7ms must be subtracted from the pulsewidth to account for injector "dead time".
So if anybody knows something about capturing pulse width and frequency im all ears.
Maybe there's also a good library that deals with this?
I can make a voltage divider, but to honest my weakspot is code.
I guess I should start looking this up and studying it. I mean this case specifically.

Hi everyone,
So I found a much better code generator and came up
with this code using the Moba library, since the it seemed to do everything good when I used solely MAF sensor.
I have to run this on the car in a couple days, because I can't produce these signals with my bench. The dead time of the injectors is 700 microseconds, so that is entered into the calculation.
The idea is to administer an amount of fuel based on all the possible factors which an ecu uses.

The following is how the calculator explained what it did,
and then the code it generated.

"In this code, first, we include the MobaTools library and define the sensor pin, stepper motor pins and the steps per revolution of the motor. We also define the range of microseconds that corresponds to 2 turns of the motor.

In the setup function, the stepper motor is attached to the drv8825 driver and a ramp length of 100ms is set for the motor to adjust to signals.

In the loop function, the pulse width is read from the sensor pin and the frequency is calculated. Then, 700 microseconds are subtracted from the pulse width. The new position of the motor is calculated as the product of the pulse width and frequency, divided by the range of microseconds, multiplied by 2 times the steps per revolution of the motor.

Finally, the motor is instructed to move to the new position.

This code is constantly looping and adjusting the motor position based on the pulse width and frequency readings from the sensor pin."

#include <MobaTools.h>  // Include MobaTools library

const int sensorPin = A4;  // Define sensor pin
const int stp = 9;  // Define stepper pin
const int dir = 8;  // Define direction pin
const int stepsPerRevolution = 200;  // Define motor steps per revolution
const int rangeMicroseconds = 800;  // Define range in microseconds

MoToStepper myStepper(stepsPerRevolution, dir, stp);  // Initialize stepper motor

void setup() {
  myStepper.attach( drv8825 );  // Attach stepper motor to driver
  myStepper.setRampLen(100);  // Set ramp length to adjust motor every 100ms
}

void loop() {
  int pulseWidth = pulseIn(sensorPin, HIGH);  // Read pulse width
  int frequency = 1000000 / pulseWidth;  // Calculate frequency

  pulseWidth -= 700;  // Subtract 700 microseconds from pulse width
  int newPosition = (pulseWidth * frequency) / rangeMicroseconds * 2 * stepsPerRevolution;  // Calculate new position

  myStepper.rotate(newPosition);  // Move motor to new position
}

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.