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:

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.

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. ;-)

I'd probably do the whole thing in a simple loop.1) see if the last analogue conversion has finished, and if it has, read the result and map it, and start another analogue conversion2) for i = 0 to 'n'-1 cylinders Busy-wait on the sensor fire injector [n] delay un-fire injector [n]

"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.

int rpm = 9000.0;int angle = 30.0;9000 is an int. 9000.0 is a float. Which one do you think you can store in an int?

Quote

Why can't I call a delay within the interrupt routine?

Because interrupt routines are supposed to be as fast as possible, so that they don't interfere with other interrupt based things, like the clock. delay(), delayMicroseconds(), or a bunch of nop assembler calls are all wasting time, which you don't want to do in an interrupt service routine.

Ok guys, first thank you for having patience with me and helping out. (my only coding skills where with bash and at age 44 I am not that quick anymore

About adding a decimal to the int, I read somewhere that automatically triggers a float calculation or creates a workaround for rounding up values before calculation was finished so I changed them to float.Also removed the calibration calculation for sake of speed.

Using a while or a for loop is not an option, onboard the puller life is pretty hard and I don't want to risk a complete engine failure because the software is waiting for a signal that is not gonna come due to a broken wire or other damage.

In the past I had an electronic device doing the same thing, an infrared transmitter/receiver combo triggered an NE555 which controlled the duration so that is why I want to use interrupts, intimidate response nomather what.Aren't all digital ports usable as interrupts? Or do I need to add some extra function to accomplish that?

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.

Here is a rough sketch, I wrote this based on 2 examples provided with the Arduino IDE "blink without delay", and "Analog Input". The sketch is written to read one trigger sensor, a throttle pot., and be able to fire one injector. You will have to modify the sketch to read 4 injector sensors, and fire 4 injectors.

Perhaps this is enough to get you going. Keep in mind I am a Novice at programming and there is probably lots of room for improvement.

// the follow variables is a long because the time, measured in miliseconds,// will quickly become a bigger number than can be stored in an int.long interval = 1000; // interval at which to fire injectors(milliseconds)

If using a loop it opens another possibility to me, a rotary encoder for timing: http://nl.rs-online.com/web/p/rotary-encoders/2603780/?searchTerm=260-3780&relevancy-data=636F3D3126696E3D4931384E525353746F636B4E756D6265724D504E266C753D656E266D6D3D6D61746368616C6C26706D3D5E5C647B337D5B5C732D2F255C2E5D5C647B332C347D2426706F3D313426736E3D592673743D52535F53544F434B5F4E554D424552267573743D3236302D333738302677633D4E4F4E4526 (no clue how to hock it up)

int posPin = A1; // the input pin for position sensorint posValue = 0; // variable to store the value from the sensorint injectorpin1 = 13; // the pin for the injector solenoid1int injectorpin2 = 14; // the pin for the injector solenoid2int injectorpin3 = 15; // the pin for the injector solenoid3int injectorpin4 = 16; // the pin for the injector solenoid4int sensorPin = A0; // the input pin for the throtttle potentiometerint sensorValue = 0; // variable to store the value coming from the sensorlong previousMillis = 0; // will store last time injection time was updated

// the follow variables is a long because the time, measured in miliseconds,// will quickly become a bigger number than can be stored in an int.long interval = 1000; // interval at which to fire injectors(milliseconds)

int posPin = A1; // the input pin for position sensorint posValue = 0; // variable to store the value from the sensorint injectorpin1 = 13; // the pin for the injector solenoid1Consistency is good. If you were consistent, the 3rd variable would be named injectorPin1, which would be much easier to read, in my opinion.

long previousMillis = 0; // will store last time injection time was updatedTime variables are unsigned long. You don't normally need to accommodate time running backwards. At least not in our universe.

if(posPin == 0) // of camshaft position is 0 degrees then fire cylinder 1 if(posPin == 256) // of camshaft position is 90 degrees then fire cylinder 3 if(posPin == 512) // of camshaft position is 180 degrees then fire cylinder 4 if(posPin == 768) // of camshaft position is 270 degrees then fire cylinder 2I don't know what kind of analog device you are reading, but depending on exact values from an ADC with a resolution of +/- 1 is not a good idea. Your injectors are going to not fire when they are supposed to, a lot.

When to fire the injector. with respect to cam position, is typically a function of load, engine RPM, and a host of other sensor readings. I fear that you are oversimplifying a very complex process.

long previousMillis = 0; // will store last time injection time was updatedTime variables are unsigned long. You don't normally need to accommodate time running backwards. At least not in our universe.

if(posPin == 0) // of camshaft position is 0 degrees then fire cylinder 1 if(posPin == 256) // of camshaft position is 90 degrees then fire cylinder 3 if(posPin == 512) // of camshaft position is 180 degrees then fire cylinder 4 if(posPin == 768) // of camshaft position is 270 degrees then fire cylinder 2I don't know what kind of analog device you are reading, but depending on exact values from an ADC with a resolution of +/- 1 is not a good idea. Your injectors are going to not fire when they are supposed to, a lot.

When to fire the injector. with respect to cam position, is typically a function of load, engine RPM, and a host of other sensor readings. I fear that you are oversimplifying a very complex process.

I have know clue how to read a rotary encoder so I presumed that it would give me an output from 0-1023 like a potentiometer would. (the documentation of the automotive encoder also was talking about 1024 steps)You are writing that the injectors will gonna skip firing with that resolution, is that due to the duration of a single encoder step compared to the time the loop lasts?If so a loop won't work with my timing disc either since at 9K rpm the pulse from that is about 1microsecond. (that is why I tried to use interrupts in my first code)

A combustion engine isn't a very complex process at all, current automotive products make it complex due to drivability, environmental issues and so on.In tractor pulling we need an engine that runs at idle and at full throttle, we don't shift but open throttle and hold on.We have a 2.0l diesel engine making 400HP at 8000rpm with a boost pressure of 5bar, when hoocked on we rev up to 4000rpm (3bar of boost) and release the clutch.This is our conventional injected machine:https://picasaweb.google.com/lh/photo/4USFns0LHkMvU5lqaYSGmdMTjNZETYmyPJy0liipFm0?feat=directlinkAnd this is our common-rail, no uC used, ne555, HEF4044 and HEF4081.https://picasaweb.google.com/lh/photo/do7wdb7tZnFQsgpcPFTMmNMTjNZETYmyPJy0liipFm0?feat=directlink

Throttle controls the injection time, the fuel pressure (800-2500bar) and timing advance (-10 at idle and -35 at full throttle) so the only thing the uC has to do is read an input and opens an output for a throttle defined amount of time. (ok, 4 times in a cycle)

If I understand correctly;rotation encoder isn't a good idea.using a loop either.So back to my first thought with using 4 interrupts and a distributor for giving injection pulses?

I have know clue how to read a rotary encoder so I presumed that it would give me an output from 0-1023 like a potentiometer would.

No, it will not. A rotary encoder is a digital device. It is like a whole bunch of little switches. You need to read the encoder fairly often to detect the direction it is moving, and how many times the little switches have been pressed.

There is an article on the playground explaining rotary encoders.

Quote

Throttle controls the injection time, the fuel pressure (800-2500bar) and timing advance (-10 at idle and -35 at full throttle) so the only thing the uC has to do is read an input and opens an output for a throttle defined amount of time. (ok, 4 times in a cycle)

So, when does the uC switch from -10 to -35 degrees? Doing that abruptly sounds like a bad idea to me.

Quote

If I understand correctly;rotation encoder isn't a good idea.

Using a rotary encoder is a fine idea, if you understand how to read it properly.

Quote

So back to my first thought with using 4 interrupts and a distributor for giving injection pulses?

You could do that with a Mega, with more external interrupts. The UNO only has two, and you'll probably want to use those to read the encoder, since that is the critical, time-dependent, input.

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

Time variables are unsigned long. You don't normally need to accommodate time running backwards. At least not in our universe.QuoteI don't understand.In bash to would mean "if $currentTime minus $previousTime is larger then Interval (throttle position) stop injecting"It means, without the $, exactly the same thing in C.

I new that but I wanted to know what cyclegadgets reason was with that...

That portion of code was based on an example from the Arduino IDE. I mostly just changed variable names. Turns out the example has the error of not using unsigned long for previousMillis and I did not catch it. Here is the example code link: http://www.arduino.cc/en/Tutorial/BlinkWithoutDelay

So, when does the uC switch from -10 to -35 degrees? Doing that abruptly sounds like a bad idea to me.

The uC won't, the throttle cable is (was in the past) connected to distributor so more throttle means more advance.Using throttle for advance timing is discussionable but in practice it has proven to work very well, and gives a very responsive engine.In the pic. the distributor is mounted on the front of the (old) engine directly on the camshaft pulley. (square aluminum box with lots of wires Our previous device and schematics are over here: http://www.japie.deserver.nl/ftp/Cuprum/ if your interested.

I have read the playground encoder stuff and I see what you mean, I was expecting it to give a different value for each step but they only give pulses so code is always needed for calculating the position. (and adding error possibility when a pulse is missed or doubled)

I will use the exact setup as in the past with the alternator and a Mega to replace my electronics, thanks for helping me out...