Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- volatile unsigned long previous_tdc; // time of the time before the last time that the crank sensor window closed (indicating TDC happened) in microseconds
- volatile unsigned long last_tdc; // last time the crank sensor window closed in microseconds
- volatile int engine_running; // is engine already running (2) or is it in the process of being started for the first time since bootup (1) or has there been no crank sensor activity at all yet since bootup (0)
- int crank_sensor_pin; // arduino interrupt pin for +5v from crank sensor
- int coil_pin; // output pin to HT coil
- int dwell; // ignition coil charge time (time required for the coil to receive 12v before it can be discharged with a good spark) in microseconds
- byte advance_map[49]; // map of spark advance indexed by rpm at 250rpm resolution to the map, advance numbers in degrees BTDC
- boolean coil_charging; // whether the coil has power to it right now or not
- int redline; // max rpm, above this spark must be restricted to 0 advance
- int minimum_rpm; // min rpm, below this we consider the engine to have stalled and we will reset to "engine not running" mode
- void setup()
- {
- last_tdc = 0;
- previous_tdc = 0;
- engine_running = 0;
- crank_sensor_pin = 0;
- dwell = 2000;
- coil_charging = false;
- coil_pin = 13;
- redline = 12000;
- minimum_rpm = 900;
- advance_map[0] = 8; // 0 rpm
- advance_map[1] = 8; // 250 rpm
- advance_map[2] = 8; // 500
- advance_map[3] = 8; // 750
- advance_map[4] = 8; // 1000
- advance_map[5] = 8;
- advance_map[6] = 8;
- advance_map[7] = 8;
- advance_map[8] = 8; // 2000
- advance_map[9] = 8;
- advance_map[10] = 8;
- advance_map[11] = 8;
- advance_map[12] = 10; // 3000
- advance_map[13] = 12;
- advance_map[14] = 14;
- advance_map[15] = 16;
- advance_map[16] = 18; // 4000
- advance_map[17] = 20;
- advance_map[18] = 22;
- advance_map[19] = 22;
- advance_map[20] = 22; // 5000
- advance_map[21] = 22;
- advance_map[22] = 22;
- advance_map[23] = 22;
- advance_map[24] = 22; // 6000
- advance_map[25] = 22;
- advance_map[26] = 22;
- advance_map[27] = 22;
- advance_map[28] = 22; // 7000
- advance_map[29] = 22;
- advance_map[30] = 22;
- advance_map[31] = 22;
- advance_map[32] = 22; // 8000
- advance_map[33] = 22;
- advance_map[34] = 22;
- advance_map[35] = 22;
- advance_map[36] = 22; // 9000
- advance_map[37] = 22;
- advance_map[38] = 22;
- advance_map[39] = 22;
- advance_map[40] = 22; // 10000
- advance_map[41] = 22;
- advance_map[42] = 22;
- advance_map[43] = 22;
- advance_map[44] = 22; // 11000
- advance_map[45] = 22;
- advance_map[46] = 22;
- advance_map[47] = 22;
- advance_map[48] = 22; // 12000
- pinMode(coil_pin, OUTPUT);
- attachInterrupt(crank_sensor_pin, sensor_ring_window_closed, RISING);
- }
- void loop()
- {
- if (engine_running == 1) // first crank revolution is just now happening
- {
- if (micros() - last_tdc >= dwell)
- {
- discharge_coil();
- engine_running = 2;
- }
- } else if (engine_running = 2) // engine spinning normally, perform normal spark advance and discharge procedures
- {
- if (coil_charging)
- {
- if (get_rpm() > redline)
- {
- if (get_microseconds_since_last_tdc() >= ((previous_tdc - last_tdc) - (get_microseconds_per_degree_at_rpm(get_rpm()) * 0))) // if we're at roughly TDC for 0 degrees advance, discharge coil at TDC since we're hitting the redline
- {
- discharge_coil();
- }
- }
- else if (get_microseconds_since_last_tdc() >= ((previous_tdc - last_tdc) - (get_microseconds_per_degree_at_rpm(get_rpm()) * advance_map[get_250_rounded_rpm_index()]))) // calc the time before expected next TDC and compare to advance_map to see if we want to fire now
- {
- discharge_coil();
- }
- } else {
- if (get_rpm() > redline)
- {
- if (get_microseconds_since_last_tdc() >= ((previous_tdc - last_tdc) - (get_microseconds_per_degree_at_rpm(get_rpm()) * 0))) // if we're at TDC at redline running speed, charge the coil and then discharge immediately
- {
- charge_coil();
- delayMicroseconds(dwell);
- discharge_coil();
- }
- }
- else if (get_microseconds_since_last_tdc() >= ((previous_tdc - last_tdc) - (get_microseconds_per_degree_at_rpm(get_rpm()) * advance_map[get_250_rounded_rpm_index()]) - dwell)) // if we've reached dwell time before spark advance before TDC, power up the coil
- {
- charge_coil();
- }
- }
- if (get_rpm() < minimum_rpm) // engine stalled
- {
- engine_running = 0;
- discharge_coil();
- }
- }
- }
- void sensor_ring_window_closed() // crank sensor has detected the end of the sensor ring window in rotation
- {
- if (engine_running == 0)
- {
- charge_coil();
- engine_running = 1;
- }
- previous_tdc = last_tdc;
- last_tdc = micros();
- }
- void charge_coil() // provide ground to ignition coil, allowing it to charge
- {
- digitalWrite(coil_pin, HIGH);
- coil_charging = true;
- }
- void discharge_coil() // cut ground to coil, making spark
- {
- digitalWrite(coil_pin, LOW);
- coil_charging = false;
- }
- unsigned int get_250_rounded_rpm_index() // returns the current rpm to the quarter of a thousand rpm in array index form
- {
- unsigned long rev_time = last_tdc - previous_tdc;
- return (round(int((60000000 + (rev_time / 2)) / rev_time) / 250));
- }
- unsigned int get_rpm() // returns the current rpm
- {
- unsigned long rev_time = last_tdc - previous_tdc;
- return (int((60000000 + (rev_time / 2)) / rev_time));
- }
- int get_microseconds_per_degree_at_rpm(int rpm)
- {
- return (((1 / (rpm / 60)) / 360) * 1000000);
- }
- unsigned long get_microseconds_since_last_tdc()
- {
- return (micros() - last_tdc);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement