// Pin Definitions
const int crankPin = 2; // Crank sensor (digital input)
const int camPin = 3; // Cam sensor (digital input)
const int coil1 = 8; // Ignition coil 1
const int coil2 = 9; // Ignition coil 2
const int fuelPump = 10; // Fuel pump control
const int injectors[] = {4,5,6,7}; // Injectors 1,3,4,2 (pins 4=inj1, 5=inj3, 6=inj4, 7=inj2)
const int fanRelay = 11; // Cooling fan control
const int ntcPin = A0; // Temperature sensor
const int airSensorPin = A1; // Air sensor (MAP/MAF)
// Engine parameters
volatile unsigned long crankTime;
volatile unsigned int rpm;
volatile int enginePosition;
volatile bool synced = false;
int injectorSequence[4] = {0,2,3,1}; // Order 1,3,4,2 (indexes injectors array)
int currentInjector = 0;
// Timing variables
unsigned long lastCrankUpdate;
unsigned int dwellTime = 3000; // Coil dwell time in microseconds
unsigned int pulseWidth = 2000; // Injector pulse width in microseconds
// Temperature control
float temperature;
const float fanOnTemp = 95.0; // Fan activation temperature (°C)
void setup() {
// Initialize I/O pins
pinMode(crankPin, INPUT);
pinMode(camPin, INPUT);
pinMode(coil1, OUTPUT);
pinMode(coil2, OUTPUT);
pinMode(fuelPump, OUTPUT);
for(int i=0; i<4; i++) pinMode(injectors[i], OUTPUT);
pinMode(fanRelay, OUTPUT);
// Attach interrupts
attachInterrupt(digitalPinToInterrupt(crankPin), crankEvent, RISING);
attachInterrupt(digitalPinToInterrupt(camPin), camEvent, RISING);
// Initial states
digitalWrite(fuelPump, HIGH); // Run fuel pump
Serial.begin(115200); // For debugging
}
void loop() {
// Update RPM calculation
if((millis() - lastCrankUpdate) > 100) rpm = 0;
// Read sensors
temperature = readTemperature();
controlFan(temperature);
// Calculate engine parameters
calculateFuel();
calculateIgnition();
// Basic fuel pump control
digitalWrite(fuelPump, rpm > 100 ? HIGH : LOW);
}
// Interrupt Service Routines
void crankEvent() {
unsigned long now = micros();
rpm = 60000000 / (now - crankTime); // RPM calculation
crankTime = now;
lastCrankUpdate = millis();
if(synced) {
handleIgnition();
handleInjection();
}
}
void camEvent() {
enginePosition = 0; // Reset engine position
synced = true; // Engine is synchronized
}
// Injection control
void handleInjection() {
static unsigned long lastInjTime;
if((micros() - lastInjTime) > pulseWidth) {
// Turn off previous injector
digitalWrite(injectors[injectorSequence[currentInjector]], LOW);
// Move to next injector in sequence
currentInjector = (currentInjector + 1) % 4;
// Activate current injector
digitalWrite(injectors[injectorSequence[currentInjector]], HIGH);
lastInjTime = micros();
}
}
// Ignition control
void handleIgnition() {
static bool fireCoil1 = false;
if(fireCoil1) {
digitalWrite(coil1, HIGH);
delayMicroseconds(dwellTime);
digitalWrite(coil1, LOW);
} else {
digitalWrite(coil2, HIGH);
delayMicroseconds(dwellTime);
digitalWrite(coil2, LOW);
}
fireCoil1 = !fireCoil1; // Alternate coils
}
// Temperature functions
float readTemperature() {
int raw = analogRead(ntcPin);
// Convert analog reading to temperature (implement proper Steinhart-Hart equation)
return (raw * 0.48876) - 50.0; // Example conversion
}
void controlFan(float temp) {
digitalWrite(fanRelay, temp > fanOnTemp ? HIGH : LOW);
}
// Fuel calculation (simplified)
void calculateFuel() {
int airValue = analogRead(airSensorPin);
// Basic fuel calculation (needs proper algorithm)
pulseWidth = map(airValue, 0, 1023, 1000, 10000);
pulseWidth = constrain(pulseWidth, 1000, 10000);
}
// Ignition calculation (simplified)
void calculateIgnition() {
// Basic dwell time adjustment by RPM
dwellTime = constrain(3000 - (rpm/100), 1000, 3000);
}
Injectors
Temp
Air Sensor
Fuel Pump
Fan
Ignition
Crank
Cam