diff --git a/ECU.ino b/ECU.ino index c1b5aaa..18989fc 100644 --- a/ECU.ino +++ b/ECU.ino @@ -20,7 +20,9 @@ void setup() { digitalWrite(pin_coil3, LOW); digitalWrite(pin_coil4, LOW); + // Get an initial reading and output debug if it's not atmospheric map_init(); + battery_init(); } void loop() { @@ -34,3 +36,4 @@ void loop() { } + diff --git a/battery.ino b/battery.ino new file mode 100644 index 0000000..be6190c --- /dev/null +++ b/battery.ino @@ -0,0 +1,23 @@ +void battery_init() +{ + task_battery_run(); + + if(battery_voltage_value < 12) + { + Serial.println("ERR: Battery low"); + } + else if(battery_voltage_value > 14) + { + Serial.println("ERR: Battery high"); + } + else + Serial.println("INF: Battery ok"); +} + +void task_battery_run() +{ + battery_voltage_value = map(analogRead(pin_batt), battery_cal_7v, battery_cal_16v, 7, 16); + battery_voltage_index = constrain(battery_voltage_value,7,16) - 7; +} + + diff --git a/cas.ino b/cas.ino index e9b7cf0..9e39e65 100644 --- a/cas.ino +++ b/cas.ino @@ -5,6 +5,14 @@ void cas_process() byte sgt = digitalRead(pin_cas_sgt); unsigned long timestamp = micros(); + if(rpm_current_value > rpm_range_max) + { + rpm_limited_log = 1; + rpm_limited = 1; + }else{ + rpm_limited = 0; + } + // Find rising edge if(sgt == 1) { @@ -30,6 +38,18 @@ void cas_process() // If we have crank pulse present then cyl1 is TDC if(digitalRead(pin_cas_sgc) == HIGH) { + // If we've arrived at cylinder 1 unexpectedly then we need to know! + if(cylinder_next[cylinder_tdc] != 1) + { + cas_sync_fail=1; + cas_sync_fail_log=1; + } + else + { + cas_sync_fail = 0; + } + + // Use this number because we KNOW it's right cylinder_tdc = 1; } else @@ -39,22 +59,27 @@ void cas_process() // Schedule next cylinder, this one is already past TDC cylinder_next_fire = cylinder_next[cylinder_tdc]; - if(cylinder_next_fire == 1) + + // If we're out of sync, we kill ignition for a bit for now + if((cas_sync_fail == 0) && (rpm_limited == 0)) { - task_coil1_fire = micros() + (usec_per_degree * 180); - task_coil1_charge = task_coil1_fire - coil_dwell; - }else if(cylinder_next_fire == 2) - { - task_coil2_fire = micros() + (usec_per_degree * 180); - task_coil2_charge = task_coil2_fire - coil_dwell; - }else if(cylinder_next_fire == 3) - { - task_coil3_fire = micros() + (usec_per_degree * 180); - task_coil3_charge = task_coil3_fire - coil_dwell; - }else if(cylinder_next_fire == 4) - { - task_coil4_fire = micros() + (usec_per_degree * 180); - task_coil4_charge = task_coil4_fire - coil_dwell; + if(cylinder_next_fire == 1) + { + task_coil1_fire = micros() + (usec_per_degree * (180 + ignition_offset - table_ignition[rpm_current_index + (map_current_index << 4)])); + task_coil1_charge = task_coil1_fire - (coil_dwell + table_dwell[battery_voltage_index]); + }else if(cylinder_next_fire == 2) + { + task_coil2_fire = micros() + (usec_per_degree * (180 + ignition_offset - table_ignition[rpm_current_index + (map_current_index << 4)])); + task_coil2_charge = task_coil2_fire - (coil_dwell + table_dwell[battery_voltage_index]); + }/*else if(cylinder_next_fire == 3) + { + task_coil3_fire = micros() + (usec_per_degree * 180); + task_coil3_charge = task_coil3_fire - (coil_dwell + table_dwell[battery_voltage_index]); + }else if(cylinder_next_fire == 4) + { + task_coil4_fire = micros() + (usec_per_degree * 180); + task_coil4_charge = task_coil4_fire - (coil_dwell + table_dwell[battery_voltage_index]); + }*/ } } } @@ -91,3 +116,4 @@ void cas_process() + diff --git a/data.h b/data.h index 4a77a49..be4af98 100644 --- a/data.h +++ b/data.h @@ -1,42 +1,57 @@ // MAP Sensor -const int map_sensor_min_kpa = 20; // Physical minimum of the hardware -const int map_sensor_max_kpa = 250; // Physical maximum of the hardware -const int map_range_min = 20; // Index 0 (min we care about) -const int map_range_max = 100; // Index 15 (max we care about, anything >100 can be atmospheric as far as we care) -byte map_current_index = 0; // Index -byte map_current_value = 0; // KPA value +const int map_sensor_min_kpa = 20; // Physical minimum of the hardware +const int map_sensor_max_kpa = 250; // Physical maximum of the hardware +const int map_range_min = 20; // Index 0 (min we care about) +const int map_range_max = 100; // Index 15 (max we care about, anything >100 can be atmospheric as far as we care) +byte map_current_index = 0; // Index +byte map_current_value = 0; // KPA value // Rotation -const int rpm_range_min = 0; // Index 0 -const int rpm_range_max = 7200; // Index 15 -byte rpm_current_index = 0; // Table index of current RPM -int rpm_current_value = 0; // Current engine RPM -int usec_per_degree = 0; // uSec per degree of rotation at current RPM +byte rpm_limited = 0; +byte rpm_limited_log = 0; +const int rpm_range_min = 0; // Index 0 +const int rpm_range_max = 7200; // Index 15 +byte rpm_current_index = 0; // Table index of current RPM +int rpm_current_value = 0; // Current engine RPM +int usec_per_degree = 0; // uSec per degree of rotation at current RPM +//unsigned long usec_per_degree = 0; // Cam Angle Sensor -unsigned long cas_sgt_lastrise = 0; // micros() of the last rise -unsigned long cas_sgt_lastfall = 0; // "" of the last fall -byte cas_sgt_lastvalue = 0; // The state of SGT on previous cycle +unsigned long cas_sgt_lastrise = 0; // micros() of the last rise +unsigned long cas_sgt_lastfall = 0; // "" of the last fall +byte cas_sgt_lastvalue = 0; // The state of SGT on previous cycle -unsigned long cas_sgc_lastrise = 0; // micros() of the last rise -unsigned long cas_sgc_lastfall = 0; // "" of the last fall -byte cas_sgc_lastvalue = 0; // The state of SGC on the previous cycle +unsigned long cas_sgc_lastrise = 0; // micros() of the last rise +unsigned long cas_sgc_lastfall = 0; // "" of the last fall +byte cas_sgc_lastvalue = 0; // The state of SGC on the previous cycle + +byte cas_sync_fail = 0; +byte cas_sync_fail_log = 0; // Cylinder sequencing -byte cylinder_tdc = 0; // Most recent cylinder to hit TDC -byte cylinder_next_fire = 0; // Next cylinder due a spark -//byte cylinder_next_inject = 0; // Next cylinder due fuel -byte cylinder_next[] = {0,3,1,4,2}; // For 1-3-4-2 Current cylinder as index returns next cylinder +byte cylinder_tdc = 0; // Most recent cylinder to hit TDC +byte cylinder_next_fire = 0; // Next cylinder due a spark +//byte cylinder_next_inject = 0; // Next cylinder due fuel +// Sequential and wasted spark +//byte cylinder_next[] = {0,3,1,4,2}; // For 1-3-4-2 Current cylinder as index returns next cylinder +byte cylinder_next[] = {0,2,1,2,1}; // For 1-3-4-2 Current cylinder as index returns next cylinder // Ignition -const int coil_dwell = 5000; // 5ms for stock coil +const int coil_dwell = 4000; // 5ms for stock coil +const int ignition_offset = 0; // Tachometer -const int tach_pulse_length = 5000; // 5ms equiv to dwell time on old coil at sensible RPM (tach pulse length) +const int tach_pulse_length = 5000; // 5ms equiv to dwell time on old coil at sensible RPM (tach pulse length) // O2 sensor -//const int o2_min = 200; // 200mV is lean -//const int o2_targe = 450; // 450mV is 14.7:1 apparently... -//const int o2_max = 800; // 800mv is rich -//int o2_current_value = 0; // Curent milivolts +//const int o2_min = 200; // 200mV is lean +//const int o2_target = 450; // 450mV is 14.7:1 apparently... +//const int o2_max = 800; // 800mv is rich +//int o2_current_value = 0; // Curent milivolts + +// Battery +byte battery_voltage_value = 13; +byte battery_voltage_index = 7; +const int battery_cal_7v = 252; +const int battery_cal_16v = 579; diff --git a/debug.ino b/debug.ino index 72333de..9123c7b 100644 --- a/debug.ino +++ b/debug.ino @@ -1,18 +1,55 @@ void debug_setup() { Serial.begin(115200); + + Serial.println(""); + Serial.println(""); + + Serial.print("DAT: "); + Serial.print("map_current_index"); + Serial.print(","); + Serial.print("rpm_current_index"); + Serial.print(","); + Serial.print("battery_voltage_index"); + Serial.print(","); + Serial.print("map_current_value"); + Serial.print(","); + Serial.print("rpm_current_value"); + Serial.print(","); + Serial.print("battery_voltage_value"); + Serial.println(""); + + // Now we have init we can do real loop + task_debug = 1; } void task_debug_run() { - Serial.print("MAP = "); + Serial.print("DAT: "); Serial.print(map_current_index); - Serial.print(" ("); - Serial.print(map_current_value); - Serial.print(")\t RPM = "); + Serial.print(","); Serial.print(rpm_current_index); - Serial.print(" ("); + Serial.print(","); + Serial.print(battery_voltage_index); + Serial.print(","); + Serial.print(map_current_value); + Serial.print(","); Serial.print(rpm_current_value); - Serial.println(")\t"); + Serial.print(","); + Serial.print(battery_voltage_value); + Serial.println(""); + + if(cas_sync_fail_log > 0) + { + Serial.println("ERR: CAS sync fail"); + cas_sync_fail_log = 0; + } + + if(rpm_limited_log > 0) + { + Serial.println("ERR: RPM limit"); + rpm_limited_log = 0; + } } + diff --git a/ignition.ino b/ignition.ino index 787fe43..52de07e 100644 --- a/ignition.ino +++ b/ignition.ino @@ -7,3 +7,4 @@ void task_coilx_charge_run(int pin) { digitalWrite(pin, HIGH); } + diff --git a/map.ino b/map.ino index 3d7add2..db3a6ab 100644 --- a/map.ino +++ b/map.ino @@ -1,20 +1,20 @@ void map_init() { task_map_run(); - Serial.print("MAP: "); - Serial.print(map_current_value); + if(map_current_value < 87) - Serial.println(" (ERROR: Low)"); + Serial.println("ERR: MAP low"); else if(map_current_value > 108) - Serial.println(" (ERROR: High)"); + Serial.println("ERR: MAP high "); else - Serial.println(" (OK)"); + Serial.println("INF: MAP ok"); } void task_map_run() { - map_current_value = map(analogRead(A3), 0, 1023, map_sensor_min_kpa, map_sensor_max_kpa); + map_current_value = map(analogRead(pin_map), 0, 1023, map_sensor_min_kpa, map_sensor_max_kpa); map_current_index = map(map_current_value, map_range_min, map_range_max, 0, 15); map_current_index = constrain(map_current_index,0,15); } + diff --git a/pins.h b/pins.h index 2273f6e..d91a151 100644 --- a/pins.h +++ b/pins.h @@ -1,15 +1,16 @@ -//const int pin_idle_control = 5; // OUT: Idle valve ground -const int pin_cas_sgc = 18; // IN: crank pulse - yellow/blue -const int pin_cas_sgt = 19; // IN: ignition pulse -white -//const int pin_fuel_pump = 45; // OUT: Fuel relay ground -//const int pin_fan = 47; // OUT: Fan relay ground -const int pin_tach = 49; // OUT: pulse for tach (should be 49 -//const int pin_intake_temp = A0; // IN: Intake temperature -//const int pin_coolant_temp = A1; // IN: Cooland temperature +//const int pin_idle_control = 5; // OUT: Idle valve ground +const int pin_cas_sgc = 19; // IN: crank pulse - yellow/blue +const int pin_cas_sgt = 18; // IN: ignition pulse -white +//const int pin_fuel_pump = 45; // OUT: Fuel relay ground +//const int pin_fan = 47; // OUT: Fan relay ground +const int pin_tach = 49; // OUT: pulse for tach +//const int pin_intake_temp = A0; // IN: Intake temperature +//const int pin_coolant_temp = A1; // IN: Coolant temperature //const int pin_throttle_position = A2; // IN: Throttle position -const int pin_map = A3; // IN: Manifold absolute pressure -//const int pin_o2 = A8; // IN: O2 sensor +const int pin_map = A3; // IN: Manifold absolute pressure +const int pin_batt = A4; // IN: Battery voltage +//const int pin_o2 = A8; // IN: O2 sensor //const int pin_injector1 = 8; //const int pin_injector2 = 9; @@ -18,6 +19,7 @@ const int pin_map = A3; // IN: Manifold absolute pressure const int pin_coil1 = 47; const int pin_coil2 = 45; -const int pin_coil3 = 43; -const int pin_coil4 = 41; +const int pin_coil3 = 43; // TMP: SGT out +const int pin_coil4 = 41; // TMP: SGC out + diff --git a/rpm.ino b/rpm.ino index 0e7e100..a2b5cb0 100644 --- a/rpm.ino +++ b/rpm.ino @@ -6,3 +6,4 @@ void task_rpm_run() // Dont exceed table rpm_current_index = constrain(rpm_current_index,0,15); } + diff --git a/schedule.h b/schedule.h index aa2732e..07f6f1e 100644 --- a/schedule.h +++ b/schedule.h @@ -4,8 +4,11 @@ const unsigned long task_map_interval = 93000; // 93ms unsigned long task_rpm = 1; // Get initial figure const unsigned long task_rpm_interval = 199000; // 199ms -unsigned long task_debug = 1; // Get initial figure -const unsigned long task_debug_interval = 387000; // 2s +unsigned long task_battery = 1; // Get initial figure +const unsigned long task_battery_interval = 265000; // 265ms + +unsigned long task_debug = 0; // Triggers after init +const unsigned long task_debug_interval = 387000; // 2s (eh?) unsigned long task_tach_high = 0; // Ilde unsigned long task_tach_low = 0; // Idle @@ -14,7 +17,10 @@ unsigned long task_coil1_charge = 0; // Idle unsigned long task_coil1_fire = 0; // Idle unsigned long task_coil2_charge = 0; // Idle unsigned long task_coil2_fire = 0; // Idle +/* unsigned long task_coil3_charge = 0; // Idle unsigned long task_coil3_fire = 0; // Idle unsigned long task_coil4_charge = 0; // Idle unsigned long task_coil4_fire = 0; // Idle +*/ + diff --git a/schedule.ino b/schedule.ino index 81138b7..4cf0183 100644 --- a/schedule.ino +++ b/schedule.ino @@ -29,7 +29,7 @@ void schedule_process() task_coil2_charge = 0; tasks++; } - +/* // Coil 3 if((task_coil3_fire > 0) && (micros() > task_coil3_fire)) { @@ -55,7 +55,7 @@ void schedule_process() task_coil4_charge = 0; tasks++; } - +*/ // Only carry on to the lower priority stuff if we did nothing else if(tasks > 0) return; @@ -71,6 +71,11 @@ void schedule_process() task_rpm = micros() + task_rpm_interval; task_rpm_run(); tasks++; + }else if(micros() > task_battery) + { + task_battery = micros() + task_battery_interval; + task_battery_run(); + tasks++; } // We never high and low at the same time @@ -97,3 +102,4 @@ void schedule_process() } } + diff --git a/tables.h b/tables.h index 4fb0309..c04db26 100644 --- a/tables.h +++ b/tables.h @@ -1,4 +1,7 @@ -// To get value, do map_current_index * 16 + rpm_current_index (or some shit like that) and that gives duty percent or something +// X = RPM 0 - 7200 +// Y = kPA 250 - 20 +// Index = [rpm_current_index + (map_current_index << 4)] +// Value = volumetric efficiency byte table_ve[] = { 36, 36, 40, 40, 19, 16, 14, 26, 42, 42, 42, 41, 41, 41, 41, 41, 36, 37, 40, 31, 16, 17, 14, 24, 51, 50, 49, 48, 47, 46, 46, 46, @@ -20,22 +23,33 @@ byte table_ve[] = { // X = RPM 0 - 7200 // Y = kPA 250 - 20 +// Index = [rpm_current_index + (map_current_index << 4)] // Value = degrees byte table_ignition[] = { - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 21, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 21, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 21, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 21, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 21, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 21, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 21, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - }; + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10 + }; + +// X = Voltage 7-16 +// Index = [battery_voltage_index] +// Value = additional dwell in usec +const int table_dwell[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + + + diff --git a/tach.ino b/tach.ino index abe13ca..17503b9 100644 --- a/tach.ino +++ b/tach.ino @@ -7,7 +7,8 @@ void task_tach_high_run() { digitalWrite(pin_tach, HIGH); - // Auto-schedule the end + // Schedule the end task_tach_low = micros() + tach_pulse_length; } +