From ad2f798089c856929a46ba71a84a8548a36c907a Mon Sep 17 00:00:00 2001 From: stevenhowes <38082088+stevenhowes@users.noreply.github.com> Date: Tue, 28 Aug 2018 11:34:23 +0100 Subject: [PATCH] Add files via upload --- ECU.ino | 36 +++++++++++++++++++ cas.ino | 93 ++++++++++++++++++++++++++++++++++++++++++++++++ data.h | 42 ++++++++++++++++++++++ debug.ino | 18 ++++++++++ ignition.ino | 9 +++++ map.ino | 20 +++++++++++ pins.h | 23 ++++++++++++ rpm.ino | 8 +++++ schedule.h | 20 +++++++++++ schedule.ino | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++++ tables.h | 41 ++++++++++++++++++++++ tach.ino | 13 +++++++ 12 files changed, 422 insertions(+) create mode 100644 ECU.ino create mode 100644 cas.ino create mode 100644 data.h create mode 100644 debug.ino create mode 100644 ignition.ino create mode 100644 map.ino create mode 100644 pins.h create mode 100644 rpm.ino create mode 100644 schedule.h create mode 100644 schedule.ino create mode 100644 tables.h create mode 100644 tach.ino diff --git a/ECU.ino b/ECU.ino new file mode 100644 index 0000000..c1b5aaa --- /dev/null +++ b/ECU.ino @@ -0,0 +1,36 @@ +#include "pins.h" +#include "data.h" +#include "schedule.h" +#include "tables.h" + +void setup() { + debug_setup(); + + pinMode(pin_map, INPUT); + + pinMode(pin_tach, OUTPUT); + pinMode(pin_coil1, OUTPUT); + pinMode(pin_coil2, OUTPUT); + pinMode(pin_coil3, OUTPUT); + pinMode(pin_coil4, OUTPUT); + + digitalWrite(pin_tach, LOW); + digitalWrite(pin_coil1, LOW); + digitalWrite(pin_coil2, LOW); + digitalWrite(pin_coil3, LOW); + digitalWrite(pin_coil4, LOW); + + map_init(); +} + +void loop() { + cas_process(); + schedule_process(); + +// map_process(); +// cas_process(); +// tach_process(); +// ignition_process(); + + +} diff --git a/cas.ino b/cas.ino new file mode 100644 index 0000000..e9b7cf0 --- /dev/null +++ b/cas.ino @@ -0,0 +1,93 @@ +void cas_process() +{ + // SGT is a pulse for TDC of *any* cylinder. By combining this with SGT it's possible to + // identify which cylinder it is + byte sgt = digitalRead(pin_cas_sgt); + unsigned long timestamp = micros(); + + // Find rising edge + if(sgt == 1) + { + if(cas_sgt_lastvalue == 0) + { + // Handle tach + task_tach_high = micros(); + + cas_sgt_lastrise = timestamp; + } + } + + // Find falling edge + if(sgt == 0) + { + if(cas_sgt_lastvalue == 1) + { + // Difference between last and current is 180 degrees + usec_per_degree = (timestamp - cas_sgt_lastfall) / 180; + + cas_sgt_lastfall = timestamp; + + // If we have crank pulse present then cyl1 is TDC + if(digitalRead(pin_cas_sgc) == HIGH) + { + cylinder_tdc = 1; + } + else + { + cylinder_tdc = cylinder_next[cylinder_tdc]; + } + + // Schedule next cylinder, this one is already past TDC + cylinder_next_fire = cylinder_next[cylinder_tdc]; + if(cylinder_next_fire == 1) + { + 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; + } + } + } + cas_sgt_lastvalue = sgt; + + + // SGC is the once per revolution pulse. Used to identify when Cyl 1 is TDC (as opposed to 4) + // and is also handy for determining RPM if you trigger on the leading edge + byte sgc = digitalRead(pin_cas_sgc); + timestamp = micros(); + + // Find rising edge + if(sgc == 1) + { + if(cas_sgc_lastvalue == 0) + { + // For rising edge (the consitent one) we need to update RPM + rpm_current_value = 60000000 / (timestamp - cas_sgc_lastrise); + + cas_sgc_lastrise = timestamp; + } + } + + // Find falling edge + if(sgc == 0) + { + if(cas_sgc_lastvalue == 1) + { + cas_sgc_lastfall= timestamp; + } + } + cas_sgc_lastvalue = sgc; +} + + + diff --git a/data.h b/data.h new file mode 100644 index 0000000..4a77a49 --- /dev/null +++ b/data.h @@ -0,0 +1,42 @@ +// 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 + +// 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 + +// 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_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 + +// 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 + +// Ignition +const int coil_dwell = 5000; // 5ms for stock coil + +// Tachometer +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 + diff --git a/debug.ino b/debug.ino new file mode 100644 index 0000000..72333de --- /dev/null +++ b/debug.ino @@ -0,0 +1,18 @@ +void debug_setup() +{ + Serial.begin(115200); +} + +void task_debug_run() +{ + Serial.print("MAP = "); + Serial.print(map_current_index); + Serial.print(" ("); + Serial.print(map_current_value); + Serial.print(")\t RPM = "); + Serial.print(rpm_current_index); + Serial.print(" ("); + Serial.print(rpm_current_value); + Serial.println(")\t"); +} + diff --git a/ignition.ino b/ignition.ino new file mode 100644 index 0000000..787fe43 --- /dev/null +++ b/ignition.ino @@ -0,0 +1,9 @@ +void task_coilx_fire_run(int pin) +{ + digitalWrite(pin, LOW); +} + +void task_coilx_charge_run(int pin) +{ + digitalWrite(pin, HIGH); +} diff --git a/map.ino b/map.ino new file mode 100644 index 0000000..3d7add2 --- /dev/null +++ b/map.ino @@ -0,0 +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)"); + else if(map_current_value > 108) + Serial.println(" (ERROR: High)"); + else + Serial.println(" (OK)"); +} + +void task_map_run() +{ + map_current_value = map(analogRead(A3), 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 new file mode 100644 index 0000000..2273f6e --- /dev/null +++ b/pins.h @@ -0,0 +1,23 @@ + +//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_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_injector1 = 8; +//const int pin_injector2 = 9; +//const int pin_injector3 = 10; +//const int pin_injector4 = 11; + +const int pin_coil1 = 47; +const int pin_coil2 = 45; +const int pin_coil3 = 43; +const int pin_coil4 = 41; + diff --git a/rpm.ino b/rpm.ino new file mode 100644 index 0000000..0e7e100 --- /dev/null +++ b/rpm.ino @@ -0,0 +1,8 @@ +void task_rpm_run() +{ + // Calculate our 4-bit table index + rpm_current_index = map(rpm_current_value, rpm_range_min, rpm_range_max, 0, 15); + + // Dont exceed table + rpm_current_index = constrain(rpm_current_index,0,15); +} diff --git a/schedule.h b/schedule.h new file mode 100644 index 0000000..aa2732e --- /dev/null +++ b/schedule.h @@ -0,0 +1,20 @@ +unsigned long task_map = 1; // Get initial figure +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_tach_high = 0; // Ilde +unsigned long task_tach_low = 0; // Idle + +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 new file mode 100644 index 0000000..81138b7 --- /dev/null +++ b/schedule.ino @@ -0,0 +1,99 @@ + + +void schedule_process() +{ + byte tasks = 0; + + // Coil 1 + if((task_coil1_fire > 0) && (micros() > task_coil1_fire)) + { + task_coilx_fire_run(pin_coil1); + task_coil1_fire = 0; + tasks++; + }else if((task_coil1_charge > 0) && (micros() > task_coil1_charge)) + { + task_coilx_charge_run(pin_coil1); + task_coil1_charge = 0; + tasks++; + } + + // Coil 2 + if((task_coil2_fire > 0) && (micros() > task_coil2_fire)) + { + task_coilx_fire_run(pin_coil2); + task_coil2_fire = 0; + tasks++; + }else if((task_coil2_charge > 0) && (micros() > task_coil2_charge)) + { + task_coilx_charge_run(pin_coil2); + task_coil2_charge = 0; + tasks++; + } + + // Coil 3 + if((task_coil3_fire > 0) && (micros() > task_coil3_fire)) + { + task_coilx_fire_run(pin_coil3); + task_coil3_fire = 0; + tasks++; + }else if((task_coil3_charge > 0) && (micros() > task_coil3_charge)) + { + task_coilx_charge_run(pin_coil3); + task_coil3_charge = 0; + tasks++; + } + + // Coil 4 + if((task_coil4_fire > 0) && (micros() > task_coil4_fire)) + { + task_coilx_fire_run(pin_coil4); + task_coil4_fire = 0; + tasks++; + }else if((task_coil4_charge > 0) && (micros() > task_coil4_charge)) + { + task_coilx_charge_run(pin_coil4); + task_coil4_charge = 0; + tasks++; + } + + // Only carry on to the lower priority stuff if we did nothing else + if(tasks > 0) + return; + + // These should never clash, but if they do then only do MAP, RPM can't have shifted much + if(micros() > task_map) + { + task_map = micros() + task_map_interval; + task_map_run(); + tasks++; + }else if(micros() > task_rpm) + { + task_rpm = micros() + task_rpm_interval; + task_rpm_run(); + tasks++; + } + + // We never high and low at the same time + if((task_tach_high > 0) && (micros() > task_tach_high)) + { + task_tach_high_run(); + task_tach_high = 0; + tasks++; + }else if((task_tach_low > 0) && (micros() > task_tach_low)) + { + task_tach_low_run(); + task_tach_low = 0; + tasks++; + } + + // Dont do debug output unless we have nothing better to do + if(tasks > 0) + return; + + if((task_debug > 0) && (micros() > task_debug)) + { + task_debug_run(); + task_debug = micros() + task_debug_interval; + } +} + diff --git a/tables.h b/tables.h new file mode 100644 index 0000000..4fb0309 --- /dev/null +++ b/tables.h @@ -0,0 +1,41 @@ +// To get value, do map_current_index * 16 + rpm_current_index (or some shit like that) and that gives duty percent or something +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, + 37, 37, 45, 36, 22, 25, 21, 37, 52, 52, 52, 52, 52, 52, 52, 52, + 36, 38, 41, 50, 33, 33, 29, 44, 53, 54, 54, 55, 55, 56, 56, 56, + 41, 49, 50, 48, 38, 42, 38, 45, 53, 54, 55, 56, 57, 58, 58, 58, + 45, 50, 51, 56, 47, 50, 45, 54, 59, 59, 59, 59, 59, 59, 59, 59, + 47, 50, 52, 65, 53, 52, 52, 59, 69, 68, 66, 65, 64, 63, 62, 62, + 44, 49, 53, 68, 59, 54, 53, 61, 69, 69, 69, 68, 68, 68, 68, 68, + 46, 49, 60, 69, 65, 60, 59, 67, 61, 61, 60, 60, 60, 59, 59, 59, + 47, 50, 64, 71, 66, 65, 64, 67, 61, 61, 62, 62, 62, 63, 63, 63, + 52, 52, 64, 70, 72, 70, 68, 69, 63, 66, 68, 71, 73, 76, 77, 77, + 53, 59, 65, 72, 76, 77, 77, 81, 86, 85, 85, 84, 84, 83, 83, 83, + 53, 61, 65, 76, 88, 90, 89, 86, 93, 93, 93, 93, 93, 93, 93, 93, + 53, 61, 68, 81, 95, 96, 95, 104, 98, 99, 99, 100, 101, 102, 102, 102, + 53, 61, 69, 83, 99, 102, 107, 128, 141, 137, 133, 128, 124, 120, 118, 118, + 53, 58, 76, 97, 106, 108, 115, 119, 122, 121, 121, 120, 120, 119, 119, 119 + }; + +// X = RPM 0 - 7200 +// Y = kPA 250 - 20 +// 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, + }; diff --git a/tach.ino b/tach.ino new file mode 100644 index 0000000..abe13ca --- /dev/null +++ b/tach.ino @@ -0,0 +1,13 @@ +void task_tach_low_run() +{ + digitalWrite(pin_tach, LOW); +} + +void task_tach_high_run() +{ + digitalWrite(pin_tach, HIGH); + + // Auto-schedule the end + task_tach_low = micros() + tach_pulse_length; +} +