Go Down

Topic: advice needed for arduino as diesel injection brain... (Read 7 times) previous topic - next topic

japie

Hello,

For use on our tractor puller we where looking for an uC and since there are a lot of them I looked at open-source, large user group and support so Arduino is the most obvious choice.
The device have to react fast, within 20 microseconds and arduino's probably will do but I must not screwup with coding.

So the main question is; is the arduino platform capable?

Our setup isn't that complicated, since it is a tractor puller no fancy stuff is needed, it only have to trigger the injection and control injection time depending on throttle position. (potentio meter)
The potentio meter also controls the pressure of the pump directly trough hardware and the timing of the injection is done by a rotating disc and infrared LED's so not much calculating things for the device.
I did try to make some code using the examples and came up with the following:

Code: [Select]

/*
  Cuprum-2.0 simplified common rail injection system.
  Use interrupts for timing injections cycle, a timing disc (alternator) is mounted to camshaft.
 
  Attach the center pin of a potentiometer to pin A0, and the outside pins to +5V and ground, output will be 0-1023.
  Potentiometer used is stereo, second line will be used to control injection pump pressure.
 
  Attach timing signals: cyl1 pin 10, cyl2 pin 11, cyl3 pin 12 and cyl4 pin 13.
 
  Attach injector hardware: cyl1 pin 4, cyl2 pin 5, cyl3 pin 6 and cyl4 pin 7.
*/

// setup pin for throttle potentiometer:
int ThrottlePin = A0;
int ThrottleValue = 0;
// define throttle calibration values:
// 9000rpm = 150rps, 1000000us/150 = 6666us per rotation.
// 6666/360*30 = 555us injection time, 30 crank degrees at 9000rpm.
// 1024/555 = 1.8
int rpm = 9000.0;
int angle = 30.0;
int ThrottleCalib = 1024.0/(1000000.0/(rpm/60.0)/360.0*angle);
// setup timer pins for interrupts:
int cyl1 = 10;
int cyl2 = 11;
int cyl3 = 12;
int cyl4 = 13;
volatile int state = LOW;
// setup pins for injector drivers:
int inj1 = 4;
int inj2 = 5;
int inj3 = 6;
int inj4 = 7;

void setup()
{
  // attach action when interrupt gets actived:
  pinMode(cyl1, OUTPUT);
  attachInterrupt(0, inject1, RISING);
  pinMode(cyl2, OUTPUT);
  attachInterrupt(0, inject2, RISING);
  pinMode(cyl3, OUTPUT);
  attachInterrupt(0, inject3, RISING);
  pinMode(cyl4, OUTPUT);
  attachInterrupt(0, inject4, RISING);
  // initialize the digital injector pins as an output:
  pinMode(inj1, OUTPUT);     
  pinMode(inj2, OUTPUT);     
  pinMode(inj3, OUTPUT);     
  pinMode(inj4, OUTPUT);
}

void loop()
{
  // read the input on analog pin 0:
  ThrottleValue = analogRead(ThrottlePin);
  // recalculate throttle value to wanted microseconds:
  ThrottleValue = ThrottleValue / ThrottleCalib;
  // check the interrupts:
  digitalWrite(cyl1, state);
  digitalWrite(cyl2, state);
  digitalWrite(cyl3, state);
  digitalWrite(cyl4, state);
}

void inject1()
{
  digitalWrite(inj1, HIGH);
  delayMicroseconds(ThrottleValue);
  digitalWrite(inj1, LOW);
}

void inject2()
{
  digitalWrite(inj2, HIGH);
  delayMicroseconds(ThrottleValue);
  digitalWrite(inj2, LOW);
}

void inject3()
{
  digitalWrite(inj3, HIGH);
  delayMicroseconds(ThrottleValue);
  digitalWrite(inj3, LOW);
}

void inject4()
{
  digitalWrite(inj4, HIGH);
  delayMicroseconds(ThrottleValue);
  digitalWrite(inj4, LOW);
}



PaulS

Quote
The device have to react fast, within 20 microseconds and arduino's probably will do but I must not screwup with coding.

So the main question is; is the arduino platform capable?

React to what? Being hit with a sledgehammer? It will react to that, nearly instantaneously.

Code: [Select]
int rpm = 9000.0;
int angle = 30.0;

Clearly, you need to learn the difference between ints and floats.

Code: [Select]
  attachInterrupt(0, inject1, RISING);
  pinMode(cyl2, OUTPUT);
  attachInterrupt(0, inject2, RISING);
  pinMode(cyl3, OUTPUT);
  attachInterrupt(0, inject3, RISING);
  pinMode(cyl4, OUTPUT);
  attachInterrupt(0, inject4, RISING);

After all this, interrupt 0 has inject4 assigned as the callback function. You might as well delete the others.

You can NOT call any form of delay in an interrupt service routine.

AWOL

#2
May 03, 2012, 03:52 pm Last Edit: May 03, 2012, 03:54 pm by AWOL Reason: 1
Quote
You can NOT call any form of delay in an interrupt service routine.

sp. "You should NOT call any form of delay in an interrupt service routine."

Yes, you can use Arduino to do what you want.
You may have to go slightly off-piste, but I don't really see that interrupts are necessary or desirable.
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

japie

Thanks for your input Paul,

Code: [Select]
int rpm = 9000.0;
int angle = 30.0;
int ThrottleCalib = 1024.0/(1000000.0/(rpm/60.0)/360.0*angle);

Reason was that I want the calculation to be accurate but the result being rounded up and have no clue how to that otherwise, will search on a float solution.

Code: [Select]
  pinMode(cyl1, OUTPUT);
  attachInterrupt(0, inject1, RISING);
  pinMode(cyl2, OUTPUT);
  attachInterrupt(1, inject2, RISING);
  pinMode(cyl3, OUTPUT);
  attachInterrupt(2, inject3, RISING);
  pinMode(cyl4, OUTPUT);
  attachInterrupt(3, inject4, RISING);

So this is what I meant? (if INPUT gets high OUTPUT is triggered for all 4 separately)

Why can't I call a delay within the interrupt routine?
Is this not possible or a coding no-no?
Theoretically the interrupt won't be actived before the timer ends, if that happens in practice it means I got 30K rpm and I am pretty sure my rods are a bigger problem then the software if that happens...

p.s. the Sledgehammer pulling team are friends so they won't hit me. ;-)

japie


"You should NOT call any form of delay in an interrupt service routine."


OK, coding no-no I presume.
Maybe a suggestion to do it otherwise?

Go Up