Ok, to start with your questions:
1. I am not sure of a percent, but the Maple's timing can not be off by more than an absolute 50us.
2. Broken down, the cycle would go: signal sent--->relay delay--->device on--->wait specified time--->timer delay (or advance...)--->signal sent--->relay delay--->device off.
3. This would have to be stable for the better part of 5 minutes. Longer is better but 5 min is a conservative estimate. In actuality, I am only going to be running the main loop for about 3 min and have it in an infinite delay for 3-4 minutes (not quite so infinite) before repeating the "on/off" cycle.
4. I have no idea how to make this hardware based, or even what you mean by that. If it helps, I am posting my code at the bottom.
I understand how a clock is generated, though you lost me with timer accuracy in ppm.
FYI, the delays are actually used within an interrupt, which is why I am using delayMicroseconds() instead of delay.
Thanks for the help!
//Pins in use: 15- pot, 17- pressure, 19- temp, 2- interrupt, 3- interrupt, 10- injector, 12- spark, 14- servo
int corr = 0; //Correction factor for spark timing based on rpm (or fuel pulse grams or both...)
double MAP; //MAP
double MAT; //Manifold Air Temp
double pulseDelay; //Pulse length time (in microseconds)
double sparkDelay; //Delay after injector fires (in microseconds)
//double tach = 0; //Tachometer- should be set to idle rpm
volatile long timeNew; //Time before spark plug fires (new value)- set to initial value
volatile long timeOld; //Time before spark plug fires (old value)- set to initial value
void setup() {
pinMode(15, INPUT_ANALOG);
pinMode(17, INPUT_ANALOG);
pinMode(19, INPUT_ANALOG);
pinMode(2, INPUT_PULLDOWN);
pinMode(3, INPUT_PULLUP);
pinMode(10, OUTPUT);
pinMode(12, OUTPUT);
pinMode(14, PWM);
Timer4.setPrescaleFactor(21);
attachInterrupt(0, powerStroke, FALLING); //Trigger void injectorPulse when sensor is deactivated (digital pin 2)- can be changed if needed
attachInterrupt(1, kill, FALLING); //Kills the engine when curcuit is broken
}
void loop() {
int a = analogRead(15); //Pot analog value
pwmWrite(14, map(a, 0, 4096, 1966, 4915)); //Servo control from 0 to 90
int p = analogRead(17); //MAP analog value
MAP = map(p, 164, 4014, 20, 250); //MAP actual (kPa)
int t = analogRead(19); //MAT analog value
MAT = map(t, 0, 4096, 0, 500); //MAT actual (K)
pulseDelay = 1000*(((.79*2*14.01+.21*2*16)*7920*.148*.6)/(.0821*14.9*101.325*20))*(MAP/MAT); //Stoichiometric calculation for fuel injection timing- requires C, D, and F- simplify the number once found (allow for lean mix)
sparkDelay = 215.94214021463*(timeNew-timeOld)-pulseDelay+corr; //Delay before spark fires (should the pulse calculations be at the beginning or end?)
}
void powerStroke() {
timeOld=timeNew;
timeNew=millis();
digitalWrite(10, HIGH);
delayMicroseconds(pulseDelay);
digitalWrite(10, LOW);
delayMicroseconds(sparkDelay);
digitalWrite(12, HIGH);
digitalWrite(12, LOW);
delayMicroseconds(3);
digitalWrite(12, HIGH);
digitalWrite(12, LOW);
}
void kill() {
while (true) {
;
}
}