One of the other topics (RPM monitor) made me think of something. The catch is, the controller would need to read a PWM while simultaneously writing a digitally sequenced PWM.
Applic would be an LED recreation of an automotive fuel injection system, using the 3-pulse theory. The code I have below would work fine, but I forgot the critical problem, that it's going to take time to read back the pulseIn from the crankshaft Hall sensor.
The only workaround I can think of, would to have 2 arduino's communicating over I2C, where one gets the crankshaft RPM as a stored variable, and the other pulses the outputs based on that stored variable, and subtract the read time of I2C from the very last delay to make up the difference. That way the communication time is short enough to subtract the difference (unlike the crankshaft read time). Even with a 4 magnet ring, the pulseIn would still be always greater than 1875, which still couldn't be subtracted from the last delay of 594.
To test this, I would use a 3 pin PC fan, and use the TACH output to feed the PWM input, where crankshaft hall sensor would be.
Pseudo:
Going with the 3 pulses per stroke theory:
8000 crankshaft RPM
133.33 crankshaft RPS
66.67 camshaft RPS
66.67 distributor RPS
1/66.67 = 15ms per rotation
15ms per rotation / 8 plugs per rotation = 1875?s between plugs
8000 crankshaft RPM
133.33 crankshaft RPS
0.007500 seconds per crankshaft rotation
2 crankshaft rotations per fire = 15ms per fire
15ms per fire / 8 fires in between = 1875?s
133.33 crankshaft rotations per second
it takes 7500?s for the crankshaft to make one rotation
it takes 15ms for the camshaft to make one rotation
it takes 15ms for the distributor to make one rotation
15ms per fire / 8 fires in between = 1875?s
The formula:
take the PulseIn time from crankshaft, divide by 4, that's the time between fires on-center. For 3-fires-per, divide by 12.
---------------------------------------------------------------------------------------------
void loop(){
int input = pulseIn(rpmIn,HIGH);
float output = (input / 12) * 0.95;
// holds 95% between pulses (594?s @ 8000 rpm, 4750?s @ 1000 rpm), decrease if lean/increase if rich
float pulse = (input / 12) * 0.05;
// holds injector open for 5% (31?s @ 8000 rpm, 250?s @ 1000 rpm), increase if lean/decrease if rich
digitalWrite(cyl1,HIGH);
delayMicroseconds(pulse);
digitalWrite(cyl1,LOW);
delayMicroseconds(output);
digitalWrite(cyl1,HIGH);
delayMicroseconds(pulse);
digitalWrite(cyl1,LOW);
delayMicroseconds(output);
digitalWrite(cyl1,HIGH);
delayMicroseconds(pulse);
digitalWrite(cyl1,LOW);
delayMicroseconds(output);
// Spark plug 1 fires
digitalWrite(cyl8,HIGH);
delayMicroseconds(pulse);
digitalWrite(cyl8,LOW);
delayMicroseconds(output);
digitalWrite(cyl8,HIGH);
delayMicroseconds(pulse);
digitalWrite(cyl8,LOW);
delayMicroseconds(output);
digitalWrite(cyl8,HIGH);
delayMicroseconds(pulse);
digitalWrite(cyl8,LOW);
delayMicroseconds(output);
// spark plug 8 fires
digitalWrite(cyl7,HIGH);
delayMicroseconds(pulse);
digitalWrite(cyl7,LOW);
delayMicroseconds(output);
digitalWrite(cyl7,HIGH);
delayMicroseconds(pulse);
digitalWrite(cyl7,LOW);
delayMicroseconds(output);
digitalWrite(cyl7,HIGH);
delayMicroseconds(pulse);
digitalWrite(cyl7,LOW);
delayMicroseconds(output);
// spark plug 7 fires
digitalWrite(cyl3,HIGH);
delayMicroseconds(pulse);
digitalWrite(cyl3,LOW);
delayMicroseconds(output);
digitalWrite(cyl3,HIGH);
delayMicroseconds(pulse);
digitalWrite(cyl3,LOW);
delayMicroseconds(output);
digitalWrite(cyl3,HIGH);
delayMicroseconds(pulse);
digitalWrite(cyl3,LOW);
delayMicroseconds(output);
// spark plug 3 fires
digitalWrite(cyl6,HIGH);
delayMicroseconds(pulse);
digitalWrite(cyl6,LOW);
delayMicroseconds(output);
digitalWrite(cyl6,HIGH);
delayMicroseconds(pulse);
digitalWrite(cyl6,LOW);
delayMicroseconds(output);
digitalWrite(cyl6,HIGH);
delayMicroseconds(pulse);
digitalWrite(cyl6,LOW);
delayMicroseconds(output);
// spark plug 6 fires
digitalWrite(cyl5,HIGH);
delayMicroseconds(pulse);
digitalWrite(cyl5,LOW);
delayMicroseconds(output);
digitalWrite(cyl5,HIGH);
delayMicroseconds(pulse);
digitalWrite(cyl5,LOW);
delayMicroseconds(output);
digitalWrite(cyl5,HIGH);
delayMicroseconds(pulse);
digitalWrite(cyl5,LOW);
delayMicroseconds(output);
// spark plug 5 fires
digitalWrite(cyl4,HIGH);
delayMicroseconds(pulse);
digitalWrite(cyl4,LOW);
delayMicroseconds(output);
digitalWrite(cyl4,HIGH);
delayMicroseconds(pulse);
digitalWrite(cyl4,LOW);
delayMicroseconds(output);
digitalWrite(cyl4,HIGH);
delayMicroseconds(pulse);
digitalWrite(cyl4,LOW);
delayMicroseconds(output);
// spark plug 4 fires
digitalWrite(cyl2,HIGH);
delayMicroseconds(pulse);
digitalWrite(cyl2,LOW);
delayMicroseconds(output);
digitalWrite(cyl2,HIGH);
delayMicroseconds(pulse);
digitalWrite(cyl2,LOW);
delayMicroseconds(output);
digitalWrite(cyl2,HIGH);
delayMicroseconds(pulse);
digitalWrite(cyl2,LOW);
delayMicroseconds(output);
// spark plug 2 fires, restart loop
}