advice needed for arduino as diesel injection brain...

Drilling nozzles is only good for creating porcupines.

Over here you can find a small list of bosch nozzles usable on a lot of different injectors, mechanical or electronic all exchangeable:

DSLA is the "dimension" type and the 145 is the spray angle, only thing not listed is the injector angle in the head so you have to see before you buy.
If you have some other model it is still possible they can be exchanged, find some nozzle reseller and try.

Truck pumps have the disadvantage for me that they can't handle high rpm's, the 2.0l engine is good for 9000rpm (even with convential mechanical pump) so that means 4500 for the pump, large pumps like on US Cummins diesel pick up trucks can only rev to 2500 or 3000 so they are off. (and heavy since our class may only weight 600kg including driver that is an issue)
For tiny use (up to 200cc) a pump from 3.0l automotive engine will do, for your goal a truck pump will probably do it's job.

When looking at the pics from the Italians I think they can use more juice, no idea what temps and air flow they have but I don't see enough smoke... :wink:

http://www.google.nl/url?sa=t&rct=j&q=&esrc=s&frm=1&source=web&cd=1&ved=0CC4QFjAA&url=http%3A%2F%2Fwww.merlindiesel.com%2Fmedia%2Fboschpumptestplans4web.pdf&ei=nkcEUcXaPKGb0QXsxYGYBg&usg=AFQjCNE1ovvayjAUBz0UuVOi2VzjTzt4OA

He Japie, found this link and if it doesn't work pm me for the pdf. It's a list of CR pumps by bosch number.
If you look for number 0445010046 wich is for a PSA RHY/RHS 2.0 HDi, it looks like it could pump up to 540cc at 1000rpm and 1000bar.

That is great documentation!

Thanks for sharing.

I do have a coding issue I think, since I am not a coder but a mechanic I used an interrupt to drive the injectors directly with timers attached.
I did got a (digital) beating for that and understand why, if a timer connected to an interrupt is still running when a second interrupt is triggered I have trouble right?
Is there a way to let an interrupt trigger a subroutine so it gets freed immediately and the routine keeps running? (like in bash $command &)

Is there a way to let an interrupt trigger a subroutine so it gets freed immediately and the routine keeps running? (like in bash $command &)

I'm not entirely sure what you're asking here, but with regard to running more than one process like a linux box, the arduino isn't going to do it - it's single core, single threaded. You can fake it to some extent (just like a single core linux box does) but you'll have to code it yourself, there is no operating system to help you manage separate threads.

@japie

Your code will most likely work better if you get rid of the delays.

 delayMicroseconds(ThrottleDuration);

You can used the "blink without delay" style with micros() just like you can with millis().

I guess you have a newer code to look at. Here you have an overlap on pin 4.

// setup timer pins for interrupts:
int cyl1 = 1;
int cyl2 = 2;
int cyl3 = 3;
int cyl4 = 4;
volatile int state = LOW;
// setup pins for injector drivers:
int inj1 = 4;
int inj2 = 5;
int inj3 = 6;
int inj4 = 7;

@cyclegadget

Thanks for pin4, didn't see that. (but they where fictional)

@wildbill

I know it is not threaded and that is why I am concerned.
Main issue is that I want a calculated injection moment, the only stable factor is the end of the injection in degrees. (so in time dependable on rpm)
To make live easier when mounting/adjusting I like the distributor to give a pulse at TBP since that is the only position of my engine I can monitor. (with head in place)

So with cylinder 1 at TDP I have a starting point for injecting cylinder 3 (order 1342)
I have a time interval in us between 2 interrupts so I can calculate delays but main thing is that the interrupt triggers actions with delays where the end of that cycle can be after the next interrupt is triggered. (due to revving up)

I don't see a software solution, only thing I can do is mounting the distributor to the throttle cable and let the interrupt trigger injection without delay.

I wrote some code just to give you a place to start. It is not working code but, I think I wrote enough to give you an idea how to remove your delays.

// Variables will change:
int InjectorState1 = LOW;  // the state of the injector1
unsigned long previousMicros = 0;     
      )

void setup() {
      
}

void loop()
{
  
  unsigned long currentmicros = micros();
   
    
 int inject1()
{
  //////////////////////////////////////////////////I don't know what you are doing here
  // find out how many uS 90 degrees camshaft is
  TimeFrame = (micros() - TimeOld);
  TimeOld = TimeFrame;
  Delay = InjectionDelay - ThrottleDuration;
  
  ////////////////////////////////////////////////this below can work without delay
  
   static int done = 0;  // this variable will show when the inject1() function is complete. 0 = not complete, 1 = complete  
   
  // open injector, hold it and close
     if (InjectorState1 == LOW)
   {
      digitalWrite(inj1,HIGH);   //open the injector
      previousmicros = currentmicros;  // save the time the injector was opened
      InjectorState1 = HIGH;   // set the injectorState to HIGH
   } 
    
     // If the injector is open and it is time to close the injector do so.
     if(currentmicros - previousmicros > Delay && InjectorState1 == HIGH) 
     {
      digitalWrite(inj1, LOW);  // close the injector
      InjectorState1 = LOW;    // reset the injectorState to LOW
      done = 1; // injection cycle is complete
     }
     return done;  // return 0 or 1 to show if function has both opened and closed injector.
     
}

Thanks, I understand this way of handling.
Instead of putting waits in the interrupt you used a compare to see if it is time to close, but does this change behavior when 2 interrupts overlap each other?

I attached an image to explain the situation:
Each injection has 3 values: delay_from_tdp, injection_duration and remaining_time_to_next_tdp
When rpm is steady the green time is free time for the uC but when revving up it can happen that the next interrupt trigger is before that free time so it is triggered when the previous interrupt function is still running.
That don't have to be a problem since during injection there is no action, only a wait time so the start of the next cycle/interrupt can only add a couple of cpu cycles to the injection time.
Main thing I am afraid of is that if an interrupt function is not yet finished the next won't start or the first is not closed due to the overlap, that is why I was asking about the bash & solution. (free the interrupt while the injection cycle remains running)

I haven't had much practice using interrupts() so my sketch may have issues. In this sketch, the interrupt sets a flag to true. The function then runs only if the flag is set. The interrupt is done the moment the flag is set. The inject function resets the flag from "true" to "false" so that it can be set again on the next interrupt.

Each injector has it's own flag and will have it's own function.

The code is mostly written for the cylinder1. You will need to review it and see if it can be used for the rest of the cylinders.

// setup pin for throttle potentiometer:
int ThrottlePin = A0;
unsigned long ThrottleValue = 0;
unsigned long ThrottleDuration = 0;
// base idle injectiontime is 100uS
unsigned long IdleDuration = 100;
// define throttle calibration values:
// we like to inject from -45 to -10 TDP making 35 degree injection duration max.
// crank duration in uS: (1000000/(rpm/60))/360*35
// at 10K rpm that is 583uS since the throttle has 1023 steps 1023/583=1.75
float ThrottleCalib = 1.75;
// define injection delay
unsigned long InjectionDelay = 0;
// define microsecond timeframe between 2 injects = duration 90 degree camshaft/ 180 degree crankshaft
unsigned long TimeFrame = 0;
unsigned long TimeOld = 0;
unsigned long Delay = 0;

unsigned long previousMicros = 0;  
unsigned long currentmicros = 0;
int InjectorState1 = LOW;  // the state of the injector1

int cyl1 = 1;
int cyl2 = 2;
int cyl3 = 3;
int cyl4 = 4;
// setup pins for injector drivers:
int inj1 = 4;
int inj2 = 5;
int inj3 = 6;
int inj4 = 7; 

volatile int state1 = LOW; ///////////////////Flags to determine if injection functions should run
volatile int state2 = LOW;
volatile int state3 = LOW;
volatile int state4 = LOW;
volatile int Fuel1  = false;
volatile int Fuel2  = false;
volatile int Fuel3  = false;
volatile int Fuel4  = false;
void setup()
{
  // initialize the digital injector pins as an output:
  pinMode(inj1, OUTPUT);     
  pinMode(inj2, OUTPUT);     
  pinMode(inj3, OUTPUT);     
  pinMode(inj4, OUTPUT);
  // attach action when interrupt gets actived:
  pinMode(cyl1, INPUT);
  attachInterrupt(1, Fire1, RISING);
  pinMode(cyl2, INPUT);
  attachInterrupt(2, Fire2, RISING);
  pinMode(cyl3, INPUT);
  attachInterrupt(3, Fire3, RISING);
  pinMode(cyl4, INPUT);
  attachInterrupt(4, Fire4, RISING);
}

void loop()
{
  currentmicros = micros();
  /////////////////////////////check interupts//////////// 
  digitalWrite(cyl1, state1); // runs function called Fire1
  digitalWrite(cyl2, state2);  // runs function called Fire2
  digitalWrite(cyl3, state3);  // runs function called Fire3
  digitalWrite(cyl4, state4);  // runs function called Fire4

  /////////////////////////if the flag is true start the inject function///////////// 
  if (Fuel1 == true)       // START THE FUNCTION IF FLAG IS SET
  {
    inject1();
  }
}

////////////////////////////Flag setting functions///////////////    
void Fire1()
{
  Fuel1 = true;
}
void Fire2()
{
  Fuel2 = true;
}
void Fire3()
{
  Fuel3 = true;
}
void Fire4()
{
  Fuel4 = true;
}

//////////////////////////////////////injection function for cyl one
int inject1()
{
  Fuel1 = false; //reset the flag that was caused by the interrupt
  // find out how many uS 90 degrees camshaft is
  TimeFrame = (micros() - TimeOld);
  TimeOld = TimeFrame;
  Delay = InjectionDelay - ThrottleDuration;
  static int done = 0;  // this variable will show when the inject1() function is complete. 0 = not complete, 1 = complete  
  // open injector, hold it and close
  if (InjectorState1 == LOW)
  {
    digitalWrite(inj1,HIGH);   //open the injector
    previousMicros = currentmicros;  // save the time the injector was opened
    InjectorState1 = HIGH;   // set the injectorState to HIGH
    done = 0;                // injection cycle is NOT complete
  } 

  // If the injector is open and it is time to close the injector do so.
  if(currentmicros - previousMicros > Delay && InjectorState1 == HIGH) 
  {
    digitalWrite(inj1, LOW);  // close the injector
    InjectorState1 = LOW;    // reset the injectorState to LOW
    done = 1;              // injection cycle is complete
  }
  return done;  // return 0 or 1 to show if function has both opened and closed injector.
}

OK cyclegadget, that is clear:
The interrupt sets a flag, inside a loop the flag is detected and an injection subroutine for that flag is called.
One advantage of that approach is that I have to concentrate to make the loop as fast as possible since reading ADC and doing calculations in that loop could disturb injection start. (so it is more clear how many cpu cycles things use)

It does however raise another question (which also exist with any other approach), when the inject1 routine is called from within the loop what happens with the loop itself?
If if(currentmicros - previousMicros > Delay && InjectorState1 == HIGH) is running will the loop be stalled until Delay matches the micros calculation or will it keep running during every free cpu cycle?

If if(currentmicros - previousMicros > Delay && InjectorState1 == HIGH) is running will the loop be stalled until Delay matches the micros calculation or will it keep running during every free cpu cycle?

It would have been better if the variable called "Delay" would be the words "on-time-needed" . Basically, it is like you look at your wrist watch noting the time as you turn the injector turn on, next you walk off to do other things and when the time has elapsed, you stop long enough to turn the injector off then, you go back to doing other things.

Clear!

Before writing final code I will add timings to every part of my main loop to see how much time is consumed on every part, based on that information I will create something final.

Thanks for your help, I will post again if I have something working and on every step I take for the record. (calibrating injectors and timings)

I think you are on the right track and your project is very doable. I can wait to see your progress. I will help as much as I can.

Hello cyclegadget,

The parts for the injector and pump driver print are ordered so next week I can start with building the hardware.

Did some coding last week based on your idea, do have a question about it:
In the injection function you use done=0; and done=1; and at the end return done; why is that, for usage in messages when serial prints are added?

I did change things a bit, I moved time reading stuff directly into the interrupt function to make it more accurate.
Also I changed the way U used time based checks for start and stop injecting to add a "delay" before start injecting and to make it a bit more clear on when things are happening.

/*
  Cuprum-2.0 simplified 1-3-4-2 cylinder common rail injection system for Arduino Mega.
  
  Using interrupts for timing injections cycle, a timing disc (alternator) is mounted to camshaft.
  Throttle position is read from potentiometer.
  Pump pressure is bound to throttle position.
  
  Base rule for the system is that we want all fuel injected at 10 crank degree before TDP:
  - cylinder 2 gives pulse for cylinder 1
  - wait (180 degree at current rpm) - injection time (max 35 degree) - injection advance (10 degree at current rpm)
  - inject
  
  Attach the center pin of a potentiometer to pin A0, and the outside pins to +5V and ground, output will be 0-1023
  Attach timing signals to external interrupts: cyl1 pin 3, cyl2 pin 21, cyl3 pin 20 and cyl4 pin 19
  Attach injector drivers: cyl1 pin 2, cyl2 pin 4, cyl3 pin 6 and cyl4 pin 8
  Attach pump pressure to PWM pin 13
*/

// setup pin for throttle potentiometer:
int ThrottlePin = A0;
unsigned long ThrottleValue = 0;
// define throttle calibration values:
// we like to inject from -45 to -10 TDP making 35 degree injection duration max.
// crank duration in uS: (1000000/(rpm/60))/360*35
// at 10K rpm that is 583uS since the throttle has 1023 steps 1023/583=1.75
float ThrottleCalib = 1.75;
// base idle injectiontime is 50uS
unsigned long IdleDuration = 50;
// define microsecond timeframe between 2 injects = duration 180 degree crankshaft
unsigned long TimeFrame = 0;
unsigned long TimeOld = 0;
// define injection cycle times
unsigned long InjectionAdvance = 0;
unsigned long InjectionDuration = 0;
unsigned long currentmicros = 0;
// state of injectors
int InjectorState1 = LOW;
int InjectorState2 = LOW;
int InjectorState3 = LOW;
int InjectorState4 = LOW;
// injection start times
unsigned long start1micros = 0;
unsigned long start2micros = 0;
unsigned long start3micros = 0;
unsigned long start4micros = 0;
// setup timer pins for interrupts:
int cyl1 = 1;
int cyl2 = 2;
int cyl3 = 3;
int cyl4 = 4;
volatile int state = LOW;
// setup pins for injector drivers:
int inj1 = 2;
int inj2 = 4;
int inj3 = 6;
int inj4 = 8; 
// injection functions flags
volatile int state1 = LOW;
volatile int state2 = LOW;
volatile int state3 = LOW;
volatile int state4 = LOW;
volatile int Fuel1  = false;
volatile int Fuel2  = false;
volatile int Fuel3  = false;
volatile int Fuel4  = false;

void setup()
{
  // initialize the digital injector pins as an output:
  pinMode(inj1, OUTPUT);     
  pinMode(inj2, OUTPUT);     
  pinMode(inj3, OUTPUT);     
  pinMode(inj4, OUTPUT);
  // attach action when interrupt gets actived:
  pinMode(cyl1, INPUT);
  attachInterrupt(1, Fire1, RISING);
  pinMode(cyl2, INPUT);
  attachInterrupt(2, Fire2, RISING);
  pinMode(cyl3, INPUT);
  attachInterrupt(3, Fire3, RISING);
  pinMode(cyl4, INPUT);
  attachInterrupt(4, Fire4, RISING);
}

void loop()
{
  // check interupts
  digitalWrite(cyl1, state1);
  digitalWrite(cyl2, state2);
  digitalWrite(cyl3, state3);
  digitalWrite(cyl4, state4);
  // read throttle position
  throttle();
  // if the flag is true start the inject function 
  if (Fuel1 == true)
  {
    inject1();
  }
  if (Fuel2 == true)
  {
    inject2();
  }
  if (Fuel3 == true)
  {
    inject3();
  }
  if (Fuel4 == true)
  {
    inject4();
  }
}

// set flags    
void Fire1()
{
  // set flag
  Fuel1 = true;
  // set start time
  start1micros = micros();
  // calculate how many uS 180 degrees last
  TimeFrame = (micros() - TimeOld);
  TimeOld = TimeFrame;
}
void Fire2()
{
  // set flag
  Fuel2 = true;
  // set start time
  start2micros = micros();
  // calculate how many uS 180 degrees last
  TimeFrame = (micros() - TimeOld);
  TimeOld = TimeFrame;
}
void Fire3()
{
  // set flag
  Fuel3 = true;
  // set start time
  start3micros = micros();
  // calculate how many uS 180 degrees last
  TimeFrame = (micros() - TimeOld);
  TimeOld = TimeFrame;
}
void Fire4()
{
  // set flag
  Fuel4 = true;
  // set start time
  start4micros = micros();
  // calculate how many uS 180 degrees last
  TimeFrame = (micros() - TimeOld);
  TimeOld = TimeFrame;
}

// throttle reading
int throttle()
{
  // read the throttle input on analog pin 0:
  ThrottleValue = analogRead(ThrottlePin);
  // see if we are trying to have fun :-)
  if (ThrottleValue > 5)
    {
    // injection ends uS/360*350 to make sure all juice is injected 10 degree before TDP.
    InjectionAdvance = TimeFrame/360*10;
    // recalculate throttle value to wanted microseconds:
    InjectionDuration = ThrottleValue/ThrottleCalib;
    }
  // it seems we are idling :-(
  else
    {
    // make sure all juice is injected at TDP.
    InjectionAdvance = 0;
     // if we are running 900rpm (33333uS) we reduce injection time
    if (TimeFrame > 33333)
      {
      // reduce injection time
      IdleDuration=IdleDuration-5;
      InjectionDuration = IdleDuration;
      }
    // if we are running 800rpm (37500uS) we inject a bit longer
    else if (TimeFrame < 37500)
      {
      // expand injection time
      IdleDuration=IdleDuration+5;
      InjectionDuration = IdleDuration;
      }
    }
}

// injection functions
int inject1()
{
  // read time
  currentmicros = micros();
  // reset the flag that was caused by the interrupt
  Fuel1 = false;
  // this variable will show when the inject() function is complete. 0 = not complete, 1 = complete
  static int done = 0;
  // if the injector is closed see if it is time to open
  if(currentmicros - start1micros > (TimeFrame - (InjectionAdvance + InjectionDuration)) && InjectorState1 == LOW)
  {
    digitalWrite(inj1,HIGH);
    InjectorState1 = HIGH;
    done = 0;
  } 
  // If the injector is open and it is time to close the injector do so.
  if(currentmicros - start1micros > (TimeFrame - InjectionAdvance) && InjectorState1 == HIGH) 
  {
    digitalWrite(inj1, LOW);
    InjectorState1 = LOW;
    done = 1;
  }
  // return 0 or 1 to show if function has both opened and closed injector.
  return done;
}

int inject2()
{
}

int inject3()
{
}

int inject4()
{
}

Returns are the method to transfer variables from functions to the rest of the loop. It is easier for me to write a sketch to show how a return works so, hopefully you will see it in this sketch. Watch the led13 and use the serial monitor.

const int ledPin =  13;      // the number of the LED pin

// Variables will change:
int done = 0;             

long previousMillis = 0;        // will store last time LED was updated

long interval = 1200;           // interval at which to blink (milliseconds)

void setup() {
  // set the digital pin as output:
  pinMode(ledPin, OUTPUT);   
  Serial.begin(9600);  
}

void loop()
{

  unsigned long currentMillis = millis();

  if(currentMillis - previousMillis > interval)
  {
    // save the last time you blinked the LED 
    previousMillis = currentMillis;   

    whatdonedoes();

    Serial.print("done = ");
    Serial.println(done);

    digitalWrite(ledPin, done);
  }
}

////////////////////////////////function with a return called done//////////
int whatdonedoes()
{

  // if the LED is off turn it on and vice-versa:
  if (done == 1)
    done = 0;
  else
    done = 1;

  return done;
}

I think your sketch has a few problems. I need to think it over how to solve them. I recommend starting your sketch as basic as possible. Use 1 button for 1 interupt, use the led13 to simulate an injector, set the time of injection for 1 to 3 seconds range, lastly you can use 1 pot for a throttle simulator. Get the led working as expected then add more leds for injectors.

The larger the code is, the harder it is to work out problems.

In this part of your sketch, (start1micros, TimeFrame, and TimeOld all equal the same micros. You can write a sketch that prints the values and you will see that.

void Fire1()
{
  // set flag
  Fuel1 = true;
  // set start time
  start1micros = micros();
  // calculate how many uS 180 degrees last
  TimeFrame = (micros() - TimeOld);
  TimeOld = TimeFrame;
}

This function needs some time spent on it. The if(currentmicros.......... statements need checked. Using a piece of paper, put numbers in for the variables and ask yourself if the (if) function will result in true or false. Check both if statements using the same values then, values that represent a change in time.

// injection functions
int inject1()
{
  // read time
  currentmicros = micros();

  // if the injector is closed see if it is time to open
  if(currentmicros - start1micros > (TimeFrame - (InjectionAdvance + InjectionDuration)) && InjectorState1 == LOW)
  {
    digitalWrite(inj1,HIGH);
    InjectorState1 = HIGH;
  } 

  // If the injector is open and it is time to close the injector do so.
  if(currentmicros - start1micros > (TimeFrame - InjectionAdvance) && InjectorState1 == HIGH) 
  {
    digitalWrite(inj1, LOW);
    InjectorState1 = LOW;
    // reset the flag that was caused by the interrupt
    Fuel1 = false;
  }
}

I made some changes in the code. I made it more simple with just one injector in the loop and functions. It is still not correct and may not compile maybe it will help. I getting tired so, I need to stop where I am at.

// setup pin for throttle potentiometer:
int ThrottlePin = A0;
unsigned long ThrottleValue = 0;
// define throttle calibration values:
// we like to inject from -45 to -10 TDP making 35 degree injection duration max.
// crank duration in uS: (1000000/(rpm/60))/360*35
// at 10K rpm that is 583uS since the throttle has 1023 steps 1023/583=1.75
float ThrottleCalib = 1.75;
// base idle injectiontime is 50uS
unsigned long IdleDuration = 50;
// define microsecond timeframe between 2 injects = duration 180 degree crankshaft
unsigned long TimeFrame = 0;
unsigned long TimeOld = 0;
// define injection cycle times
unsigned long InjectionAdvance = 0;
unsigned long InjectionDuration = 0;
unsigned long currentmicros = 0;
// state of injectors
int InjectorState1 = LOW;
int InjectorState2 = LOW;
int InjectorState3 = LOW;
int InjectorState4 = LOW;
// injection start times
unsigned long start1micros = 0;
unsigned long start2micros = 0;
unsigned long start3micros = 0;
unsigned long start4micros = 0;
// setup timer pins for interrupts:
int cyl1 = 1;
int cyl2 = 2;
int cyl3 = 3;
int cyl4 = 4;
volatile int state = LOW;
// setup pins for injector drivers:
int inj1 = 2;
int inj2 = 4;
int inj3 = 6;
int inj4 = 8; 
// injection functions flags
volatile int state1 = LOW;
volatile int state2 = LOW;
volatile int state3 = LOW;
volatile int state4 = LOW;
volatile int Fuel1  = false;
volatile int Fuel2  = false;
volatile int Fuel3  = false;
volatile int Fuel4  = false;

void setup()
{
  // initialize the digital injector pins as an output:
  pinMode(inj1, OUTPUT);     
 
  // attach action when interrupt gets actived:
  pinMode(cyl1, INPUT);
  attachInterrupt(1, Fire1, RISING);
 
}

void loop()
{
  // check interupts
  digitalWrite(cyl1, state1);

  // read throttle position
  throttle();
  
  // if the flag is true start the inject function 
  if (Fuel1 == true)
  {
    inject1();
  }
}

/////////////////////////////////////////////////////functions below////////////

// set flags    
void Fire1()
{
  // set flag
  Fuel1 = true;
  // set start time
  start1micros = micros();

}

// injection functions
int inject1()
{
  // read time
  currentmicros = micros();

  // if the injector is closed see if it is time to open
  if(currentmicros - start1micros > (TimeFrame - (InjectionAdvance + InjectionDuration)) && InjectorState1 == LOW)
  {
    digitalWrite(inj1,HIGH);
    InjectorState1 = HIGH;
  } 

  // If the injector is open and it is time to close the injector do so.
  if(currentmicros - start1micros > (TimeFrame - InjectionAdvance) && InjectorState1 == HIGH) 
  {
    digitalWrite(inj1, LOW);
    InjectorState1 = LOW;
    // reset the flag that was caused by the interrupt
    Fuel1 = false;
  }
}

// throttle reading
int throttle()
{
  // read the throttle input on analog pin 0:
  ThrottleValue = analogRead(ThrottlePin);
  // see if we are trying to have fun :-)
  if (ThrottleValue > 5)
    {
    // injection ends uS/360*350 to make sure all juice is injected 10 degree before TDP.
    InjectionAdvance = TimeFrame/360*10;
    // recalculate throttle value to wanted microseconds:
    InjectionDuration = ThrottleValue/ThrottleCalib;
    }
  // it seems we are idling :-(
  else
    {
    // make sure all juice is injected at TDP.
    InjectionAdvance = 0;
     // if we are running 900rpm (33333uS) we reduce injection time
    if (TimeFrame > 33333)
      {
      // reduce injection time
      IdleDuration=IdleDuration-5;
      InjectionDuration = IdleDuration;
      }
    // if we are running 800rpm (37500uS) we inject a bit longer
    else if (TimeFrame < 37500)
      {
      // expand injection time
      IdleDuration=IdleDuration+5;
      InjectionDuration = IdleDuration;
      }
    }
}

Hello cyclegadget, don't make it to late... :wink:

I understand the done thing, but when going for a first dry run I will add serial prints with micros at every step and dump them into a file so I can review afterwards to see how much time is spent on every step. (suppose reading/calculating throttle takes to long I can try to strip that down)
And yes I will go for one cylinder at first step.

void Fire1()
{
  // set flag
  Fuel1 = true;
  // set start time
  start1micros = micros();
  // calculate how many uS 180 degrees last
  TimeFrame = (start1micros - TimeOld);
  TimeOld = TimeFrame;
}

The TimeFrame and TimeOld are common values shared between all 4 interrupts since TimeFrame is the time in uS for 180 degree crank. (did clean it up in above, no need for double read micros(); )
So those may look equal but when looking at more then 1 interrupt/cylinder they are not. (I think :wink:

if(currentmicros - start1micros > (TimeFrame - (InjectionAdvance + InjectionDuration)) && InjectorState1 == LOW)

currentmicros minus start1micros gives me elapsed time since the interrupt.
TimeFrame (180) minus (InjectionDuration (35) plus InjectionAdvance (10)) gives me the "wait time" from interrupt to start_injecting.

if(currentmicros - start1micros > (TimeFrame (180) - InjectionAdvance (10)) && InjectorState1 == HIGH)

TimeFrame minus InjectionAdvance gives the wait_time for stop_injecting.

I really appreciate your help, I am not a coder, give me a piece of aluminum and a lathe and I can make art but besides some bash scripting I am not that good...
Thank you for helping me out!

Schermafbeelding 2013-02-16 om 08.19.35.PNG