i have been playing with the idea of using Arduino to sequence COPs on a 3SGE for a while, currently have attached a "Magic black box" which, when engine was running, exhibited weird issues.
i have tested the code below on Arduino nano attached to a signal generator, code stops sequencing correctly around 9500 rpm when using Serial.print over terminal to output firing order.
Code:
//==================================================================================
#define OUT_COP01 8
#define OUT_COP02 9
#define OUT_COP03 10
#define OUT_COP04 11
#define PIN_IGT 3
#define PIN_IG1 2
volatile boolean syncAchieved = 0; //Set this to true if sync has been achieved
volatile byte cylinderCounter = 10;
volatile boolean CylFireOK = 1;
void setup() {
//Serial.begin(9600);
pinMode(OUT_COP01, OUTPUT);
pinMode(OUT_COP02, OUTPUT);
pinMode(OUT_COP03, OUTPUT);
pinMode(OUT_COP04, OUTPUT);
pinMode(PIN_IGT, INPUT);
pinMode(PIN_IG1, INPUT);
attachInterrupt(digitalPinToInterrupt(PIN_IG1), IN_IG1, RISING); // function for creating external interrupts at pin2 on Rising (LOW to HIGH)
attachInterrupt(digitalPinToInterrupt(PIN_IGT), IN_IGT, RISING); // function for creating external interrupts at pin3 on Rising (LOW to HIGH)
}
void loop() {
while (syncAchieved == 1) { //Start sequencing ignition outputs when sync has occured. Otherwise just wait until engine starts rotating.
if (CylFireOK == 0) { // wait here for next ignition event.
switch (cylinderCounter) {
case 0:
Serial.println("COP03");
digitalWrite(OUT_COP03, HIGH);
delay(2); //Dwell Time
digitalWrite(OUT_COP03, LOW);
CylFireOK = 1;
break;
case 1:
Serial.println("COP04");
digitalWrite(OUT_COP04, HIGH);
delay(2); //Dwell Time
digitalWrite(OUT_COP04, LOW);
CylFireOK = 1;
break;
case 2:
Serial.println("COP02");
digitalWrite(OUT_COP02, HIGH);
delay(2); //Dwell Time
digitalWrite(OUT_COP02, LOW);
CylFireOK = 1;
break;
case 3:
Serial.println("COP01");
digitalWrite(OUT_COP01, HIGH);
delay(2); //Dwell Time
digitalWrite(OUT_COP01, LOW);
CylFireOK = 1;
break;
}
}
}
}
void IN_IG1() //Wait for G1 to begin sequence
{
detachInterrupt(digitalPinToInterrupt(PIN_IG1));
Serial.println("CAM_TDC");
syncAchieved = 1;
cylinderCounter = 0;
}
void IN_IGT()
{
cylinderCounter++;
CylFireOK = 0;
delay(1); // IGT Input debounce
if (cylinderCounter > 3) {
cylinderCounter = 0;
}
}
//==================================================================================
testing this on the engine will be another story, my project is currently in pieces, the code is also missing failsafes.
i doubt this code will hot start, ie. Arduino has to be powered off and back on between attempts at starting.
need something to drive COPs (TC4468EPD or similar), and Arduino should be shielded form EMI / EMF.
If using the G1 G2 signals from the Dizz, a signal conditioner will also be required. G1 and G2 signals don't reach Arduino logic voltage
Bookmarks