Ignition Retarding device

Hello guys! Let me just start by saying that i am just starting with arduino and I am an automotive technologies student. I have this project for school that i'm doing that involves delaying the signal from the ecu to the spark coils via software.... OK, now that's out of the way, so far my idea is to connect the 6 ecu ignition leads (6 cyl engine) directly to the arduino (5v signal), use a millis function to delay the signal and send it from the arduino to the coils. Now, the problem is that i have to read out the frequency of one of the signals as well as an imput current from the throttle position sensor (also up to 5v current). I am using an arduino uno R3 and was wondering how would you suggest i'd hook up the signals. I can use 1 analog in pin for the throttle position and maybe the 12 digital pins for the ecu in/out signals. Where do i connect the frequency check? Can I use an analog pin to measure frequency? Thanks for the help in advance!

I could also use some of the A pins for output, and make a complete mess of wires, but still, if i have to use a d pin for Hz readout would be better

1/ What makes you think you can do better than the ecu can do?

2/ Your problems are hardware as well as software - if you replace the ecu coil drivers with a delay device you have to build some new high power coil drivers.

3/ Plus the ecu will detect that things are wrong, and either try to compensate for your meddling or will give up and stop working.

Allan

1 The ECU i'm doing it on doesn't have a delay function, this is sort of an anti-lag system for when you aftermarket turbo your car.
2/ i'm not replacing anything, i'm putting it in-between the ecu and the coils that amplify the signal
3/ The idea is to have a 1ms delay between 1500-2300 RPM - that is too little for the ECU to notice, since it will not change the lambda values, as for when ignition itself occurs, the ECU is oblivious

1/ The ecu will have a complicated mapping function for ignition timing as well as injector timing and volume etc driven by a load of sensors and a self-optimising algorithm. Part of that will be variable delays. The maps and algorithms are the results of months of testing and optimising on a dyno and on the road by the engine manufacturer's designers.

2/ are your coil units driven by a 5v TTL-like pulse signal? - this is unusual. Usually high power current drivers are built into the ecu and the coils are just that.

3/ You imply that other people have done this - surely by having their ecu's remapped by an expert.... Or there are forums which deal with building your own re-mappable ecu - you would be better looking there.

4/ 1mS at 1500 rpm is about 9 degrees on the crankshaft - not that trivial. I reckon the ecu might just notice.

If you really want to do this it might be easier to delay the crankshaft sensor signal... but I still reckon it'll be a can of worms.

Allan

1/ Yes, the driver sensors are MAP sensor and Lambda sensor
2/ yes it is a 5v TTL-like pulse signal. Actually usually its a 5v signal to an amplification coil on your spark plugs. There are usually 8 ignition chips in the ECU that send the signal. Like I said, I am studying this.
3/ Before ECU remapping there were ignition retarding devices based on capacitor charge times, but those were shit, as well as delaying the crankshaft sensor signal (that's just stupid because everything is timed on that and you risk ignition during exhaust stroke...)
4/ The ECU starts knowing something is wrong around 18 deg ATDC, the spark is usually introduced 10 deg BTDC I think its fine.

Imagine that i'm working with a specialized aftermarket ECU for a BMW M3 that doesn't include delay because the M3 ISN'T Turbocharged. Imagine as well that i have all the specifications for both things including output voltages from the ECU and a complete pin out. As well as a few ECU's to spare. Now Imagine this is all in a university environment with a dyno and measurement devices. Now imagine that's true and lets move on to the questions at hand please.

I have already figured out which pin is what, and i found a way to measure hz with the pulsln function (google FTW ). Anyway i was wondering if it'd be ok to run the code through here when i complete it tomorrow, just to be sure its right, so i don't blow up a 8000$ ECU? :smiley:

This is what i got: It got verified and compiled, i hope it works. Please give me an opinion, is the delay() function ok?

int thrpos = analogRead(A0);
void setup() {
// put your setup code here, to run once:
pinMode(0, INPUT); //ECU IGN IN
pinMode(1, INPUT); //ECU IGN IN
pinMode(2, INPUT); //ECU IGN IN
pinMode(4, INPUT); //ECU IGN IN
pinMode(7, INPUT); //ECU IGN IN
pinMode(8, INPUT); //ECU IGN IN
pinMode(3, OUTPUT); //ECU IGN OUT
pinMode(5, OUTPUT); //ECU IGN OUT
pinMode(6, OUTPUT); //ECU IGN OUT
pinMode(9, OUTPUT); //ECU IGN OUT
pinMode(10, OUTPUT); //ECU IGN OUT
pinMode(11, OUTPUT); //ECU IGN OUT
pinMode(12, INPUT); //HZ
pinMode(A0, INPUT); //Throttle pos
}
int pulseln(12, LOW);
int pulse=pulseIn(12, LOW);
int frequency=500000/pulse;
void loop() {
// put your main code here, to run repeatedly:
if (frequency < 39)
{ if (thrpos > 511){
int ign1 = digitalRead(0);
if (ign1 = HIGH){
delay(0001);
digitalWrite(3, HIGH);}
else { digitalWrite(3, LOW);
int ign2 = digitalRead(1);
if (ign2 = HIGH) {
delay(0001);
digitalWrite(5, HIGH);}
else {digitalWrite(5, LOW);
int ign3 = digitalRead(2);
if (ign3 = HIGH) {
delay(0001);
digitalWrite(6, HIGH);}
else {digitalWrite(6, LOW);
int ign4 = digitalRead(4);
if (ign4 = HIGH) {
delay(0001);
digitalWrite(9, HIGH);}
else {digitalWrite(9, LOW);
int ign5 = digitalRead(7);
if (ign5 = HIGH) {
delay(0001);
digitalWrite(10, HIGH);}
else {digitalWrite(10, LOW);
int ign6 = digitalRead(8);
if (ign6 = HIGH) {
delay(0001);
digitalWrite(11, HIGH);}
else {digitalWrite(11, LOW);}
}}}}}}}
else {
int ign1 = digitalRead(0);
if (ign1 = HIGH){digitalWrite(3, HIGH);}
else { digitalWrite(3, LOW);
int ign2 = digitalRead(1);
if (ign2 = HIGH) {digitalWrite(5, HIGH);}
else {digitalWrite(5, LOW);
int ign3 = digitalRead(2);
if (ign3 = HIGH) {digitalWrite(6, HIGH);}
else {digitalWrite(6, LOW);
int ign4 = digitalRead(4);
if (ign4 = HIGH) {digitalWrite(9, HIGH);}
else {digitalWrite(9, LOW);
int ign5 = digitalRead(7);
if (ign5 = HIGH) {digitalWrite(10, HIGH);}
else {digitalWrite(10, LOW);
int ign6 = digitalRead(8);
if (ign6 = HIGH) {digitalWrite(11, HIGH);}
else {digitalWrite(11, LOW);}
}}}}}}}

Assuming that the ignition retard is triggered by the variables pulse, frequency, and thrpos (throttle position???), don't the values of these variables need to be constantly updated inside the void loop()?

delay() function is not OK. You should use a "Blink Without Delay" technique to get accurate timing.

Like vetteguy mentioned you need to get your analogRead() and pulseIn() calls inside the loop().

Also be aware that pulseIn() has a timeout of 1 second by default.

ok, here's what happened :smiley: they switched the ECU on me and now i'm working with a negative trigger ecu, which means the setup is reversed... there is always power to the coils, and the ecu acts like ground to trigger the thing. The ONLY thing that works in this code is the throttle position, which is just an analog read. I've tried reversing the code to trigger on LOW, but it still doesn't work. More interestingly, i have a test rig that uses LEDs instead of spark plugs and the curious thing is they are ALL lighting with an increasing delay with regards to my inputs? i'd understand if all were lit constantly or something, but they seem to all be firing when only one should. I tried with this code instead, but it was the same result:

void setup() {
// put your setup code here, to run once:
pinMode(0, INPUT); //ECU IGN IN
pinMode(1, INPUT); //ECU IGN IN
pinMode(2, INPUT); //ECU IGN IN
pinMode(4, INPUT); //ECU IGN IN
pinMode(7, INPUT); //ECU IGN IN
pinMode(8, INPUT); //ECU IGN IN
pinMode(3, OUTPUT); //ECU IGN OUT
pinMode(5, OUTPUT); //ECU IGN OUT
pinMode(6, OUTPUT); //ECU IGN OUT
pinMode(9, OUTPUT); //ECU IGN OUT
pinMode(10, OUTPUT); //ECU IGN OUT
pinMode(11, OUTPUT); //ECU IGN OUT
pinMode(12, INPUT); //HZ
pinMode(A0, INPUT); //Throttle pos
}

void loop() {
// put your main code here, to run repeatedly:
int thrpos = analogRead(A0);
int pulseln(12, LOW);
int pulse=pulseIn(12, LOW);
int frequency=500000/pulse;
int ign1 = digitalRead(0);
int ign2 = digitalRead(1);
int ign3 = digitalRead(2);
int ign4 = digitalRead(4);
int ign5 = digitalRead(7);
int ign6 = digitalRead(8);

if (frequency < 39)
{ if (thrpos > 511){
if (ign1 = LOW){
delay(0001);
digitalWrite(3, LOW);
digitalWrite(5, HIGH);
digitalWrite(6, HIGH);
digitalWrite(9, HIGH);
digitalWrite(10, HIGH);
digitalWrite(11, HIGH);}
else { digitalWrite(3, HIGH);
digitalWrite(5, HIGH);
digitalWrite(6, HIGH);
digitalWrite(9, HIGH);
digitalWrite(10, HIGH);
digitalWrite(11, HIGH);}
if (ign2 = LOW) {
delay(0001);
digitalWrite(5, LOW);
digitalWrite(3, HIGH);
digitalWrite(6, HIGH);
digitalWrite(9, HIGH);
digitalWrite(10, HIGH);
digitalWrite(11, HIGH);}
else {digitalWrite(5, HIGH);
digitalWrite(3, HIGH);
digitalWrite(6, HIGH);
digitalWrite(9, HIGH);
digitalWrite(10, HIGH);
digitalWrite(11, HIGH);}
if (ign3 = LOW) {
delay(0001);
digitalWrite(6, LOW);
digitalWrite(3, HIGH);
digitalWrite(5, HIGH);
digitalWrite(9, HIGH);
digitalWrite(10, HIGH);
digitalWrite(11, HIGH);}
else {digitalWrite(6, HIGH);
digitalWrite(3, HIGH);
digitalWrite(5, HIGH);
digitalWrite(9, HIGH);
digitalWrite(10, HIGH);
digitalWrite(11, HIGH);
}
if (ign4 = LOW) {
delay(0001);
digitalWrite(9, LOW);
digitalWrite(3, HIGH);
digitalWrite(6, HIGH);
digitalWrite(5, HIGH);
digitalWrite(10, HIGH);
digitalWrite(11, HIGH);}
else {digitalWrite(9, HIGH);
digitalWrite(3, HIGH);
digitalWrite(6, HIGH);
digitalWrite(5, HIGH);
digitalWrite(10, HIGH);
digitalWrite(11, HIGH);
}
if (ign5 = LOW) {
delay(0001);
digitalWrite(10, LOW);
digitalWrite(3, HIGH);
digitalWrite(6, HIGH);
digitalWrite(9, HIGH);
digitalWrite(5, HIGH);
digitalWrite(11, HIGH);}
else {digitalWrite(10, HIGH);
digitalWrite(3, HIGH);
digitalWrite(6, HIGH);
digitalWrite(9, HIGH);
digitalWrite(5, HIGH);
digitalWrite(11, HIGH);}
if (ign6 = LOW) {
delay(0001);
digitalWrite(11, LOW);
digitalWrite(3, HIGH);
digitalWrite(6, HIGH);
digitalWrite(9, HIGH);
digitalWrite(10, HIGH);
digitalWrite(5, HIGH);}
else {digitalWrite(11, HIGH);
digitalWrite(3, HIGH);
digitalWrite(6, HIGH);
digitalWrite(9, HIGH);
digitalWrite(10, HIGH);
digitalWrite(5, HIGH);}
}
else {
if (ign1 = LOW){digitalWrite(3, LOW);
digitalWrite(10, HIGH);
digitalWrite(6, HIGH);
digitalWrite(9, HIGH);
digitalWrite(5, HIGH);
digitalWrite(11, HIGH);}
else { digitalWrite(3, HIGH);
digitalWrite(10, HIGH);
digitalWrite(6, HIGH);
digitalWrite(9, HIGH);
digitalWrite(5, HIGH);
digitalWrite(11, HIGH);
}
if (ign2 = LOW) {digitalWrite(5, LOW);
digitalWrite(3, HIGH);
digitalWrite(6, HIGH);
digitalWrite(9, HIGH);
digitalWrite(10, HIGH);
digitalWrite(11, HIGH);}
else {digitalWrite(5, HIGH);
digitalWrite(3, HIGH);
digitalWrite(6, HIGH);
digitalWrite(9, HIGH);
digitalWrite(10, HIGH);
digitalWrite(11, HIGH);
}
if (ign3 = LOW) {digitalWrite(6, LOW);
digitalWrite(3, HIGH);
digitalWrite(10, HIGH);
digitalWrite(9, HIGH);
digitalWrite(5, HIGH);
digitalWrite(11, HIGH);}
else {digitalWrite(6, HIGH);
digitalWrite(3, HIGH);
digitalWrite(10, HIGH);
digitalWrite(9, HIGH);
digitalWrite(5, HIGH);
digitalWrite(11, HIGH);
}
if (ign4 = LOW) {digitalWrite(9, LOW);
digitalWrite(3, HIGH);
digitalWrite(6, HIGH);
digitalWrite(10, HIGH);
digitalWrite(5, HIGH);
digitalWrite(11, HIGH);}
else {digitalWrite(9, HIGH);
digitalWrite(3, HIGH);
digitalWrite(6, HIGH);
digitalWrite(10, HIGH);
digitalWrite(5, HIGH);
digitalWrite(11, HIGH);
}
if (ign5 = LOW) {digitalWrite(10, LOW);
digitalWrite(3, HIGH);
digitalWrite(6, HIGH);
digitalWrite(9, HIGH);
digitalWrite(5, HIGH);
digitalWrite(11, HIGH);}
else {digitalWrite(10, HIGH);
digitalWrite(3, HIGH);
digitalWrite(6, HIGH);
digitalWrite(9, HIGH);
digitalWrite(5, HIGH);
digitalWrite(11, HIGH);
int ign6 = digitalRead(8);}
if (ign6 = LOW) {digitalWrite(11, LOW);
digitalWrite(3, HIGH);
digitalWrite(6, HIGH);
digitalWrite(9, HIGH);
digitalWrite(10, HIGH);
digitalWrite(5, HIGH);}
else {digitalWrite(11, HIGH);
digitalWrite(3, HIGH);
digitalWrite(6, HIGH);
digitalWrite(9, HIGH);
digitalWrite(10, HIGH);
digitalWrite(5, HIGH);}
}}
else {
if (ign1 = LOW){digitalWrite(3, LOW);
digitalWrite(5, HIGH);
digitalWrite(6, HIGH);
digitalWrite(9, HIGH);
digitalWrite(10, HIGH);
digitalWrite(11, HIGH);}
else { digitalWrite(3, HIGH);
digitalWrite(5, HIGH);
digitalWrite(6, HIGH);
digitalWrite(9, HIGH);
digitalWrite(10, HIGH);
digitalWrite(11, HIGH);
}
if (ign2 = LOW) {digitalWrite(5, LOW);
digitalWrite(3, HIGH);
digitalWrite(6, HIGH);
digitalWrite(9, HIGH);
digitalWrite(10, HIGH);
digitalWrite(11, HIGH);}
else {digitalWrite(5, HIGH);
digitalWrite(3, HIGH);
digitalWrite(6, HIGH);
digitalWrite(9, HIGH);
digitalWrite(10, HIGH);
digitalWrite(11, HIGH);
}
if (ign3 = LOW) {digitalWrite(6, LOW);
digitalWrite(3, HIGH);
digitalWrite(5, HIGH);
digitalWrite(9, HIGH);
digitalWrite(10, HIGH);
digitalWrite(11, HIGH);}
else {digitalWrite(6, HIGH);
digitalWrite(3, HIGH);
digitalWrite(5, HIGH);
digitalWrite(9, HIGH);
digitalWrite(10, HIGH);
digitalWrite(11, HIGH);
}
if (ign4 = LOW) {digitalWrite(9, LOW);
digitalWrite(3, HIGH);
digitalWrite(6, HIGH);
digitalWrite(5, HIGH);
digitalWrite(10, HIGH);
digitalWrite(11, HIGH);}
else {digitalWrite(9, HIGH);
digitalWrite(3, HIGH);
digitalWrite(6, HIGH);
digitalWrite(5, HIGH);
digitalWrite(10, HIGH);
digitalWrite(11, HIGH);
}
if (ign5 = LOW) {digitalWrite(10, LOW);
digitalWrite(3, HIGH);
digitalWrite(6, HIGH);
digitalWrite(9, HIGH);
digitalWrite(5, HIGH);
digitalWrite(11, HIGH);}
else {digitalWrite(10, HIGH);
digitalWrite(3, HIGH);
digitalWrite(6, HIGH);
digitalWrite(9, HIGH);
digitalWrite(5, HIGH);
digitalWrite(11, HIGH);}
if (ign6 = LOW) {digitalWrite(11, LOW);}
else {digitalWrite(11, HIGH);
digitalWrite(3, HIGH);
digitalWrite(6, HIGH);
digitalWrite(9, HIGH);
digitalWrite(10, HIGH);
digitalWrite(5, HIGH);}
}}

HELP!

uhm.... maybe i'm entirely wrong... the led's all blink when one of the inputs is switched on. Also... IT WORKS WITHOUT POWER TO IT!!!

Perhaps IT WORKS WITHOUT POWER TO IT
because
if (ign1 = LOW) should be if (ign1 == LOW)

ok, note taken. Fixed the mistake, but still. Here's the deal though... it doesn't matter what i do or how i connect it, if the ECU is connected to the Arduino, (even only 1 pin) ALL LEDs flash. It's like all pins are connected to each other and it is just acting like a piece of wire. Maybe I am thinking this all wrong? Is it possible for the arduino to act as ground?

Did you fix ALL of the mistakes? (all of the if statements)
Have you connected your scope to the signal pins of the new ECU?
If so, what does it show?

  1. Please use [ code ] tags when posting code. Otherwise the forum software eats some of your code and turns it into smileys.

  2. Please use the code auto-format (control-T) in Arduino before posting code again. It is a very good way to lay out your code. If it seems like it scrambles your code, then the code was wrong, not the tool.

  3. This is a really awful mess of copy-paste. Study how other programs are written. They use names for pins, which is really going to help you keep track of this.

  4. The constant 001 is octal. It's an almost-dead feature of C but any number starting with zero is treated as octal. 010 is the same as 8.

  5. Did you fix the one mistake that oldvetteguy pointed out or all of them?

  6. A millisecond is a long time in the cycle of an engine. A millisecond delay is obviously useful but you need to be able to time that to within a few microseconds. Do you know how long the rest of your code takes? A digitalWrite() or analogRead() does take a measurable amount of time.

  7. Read up on arrays. Any time you have numbers in your variable names, you should have an array.

First of all, why do you think that you can improve on the manufacturer's engine timings?

If you were to were to alter the ignition timing, then why would you want to delay it by a certain number of milliseconds?
Surely you would want to make changes according to degrees of crankshaft rotation?

In your sketch you are delaying the spark by a fixed amount each time - delay (0001) . Is this what you intended? Wouldn't you be better off letting the retard accumulate until a certain condition is reached.

You are checking the input from every cylinder. Could you not read just one cylinder and then apply the correction to all cylinders?

There is also a delayMicroseconds() function that may be helpful.

bl4d3y:
ok, note taken. Fixed the mistake, but still. Here's the deal though... it doesn't matter what i do or how i connect it, if the ECU is connected to the Arduino, (even only 1 pin) ALL LEDs flash. It's like all pins are connected to each other and it is just acting like a piece of wire. Maybe I am thinking this all wrong? Is it possible for the arduino to act as ground?

Did you ever figure this out? I'm interested in trying to build something like this too (I'm researching on building a turbo kit for my car). I plan to use S-AFC to scale the injectors by the means of MAP signal manipulation, which will advance the timing a lot. So instead of referencing the throttle like you're doing, I might need to reference boost pressure to delay the ignition timing. If you eventually got it to work please share the working final code (assuming you can share it after passing the course). Thanks.