Add files via upload

This commit is contained in:
stevenhowes
2018-08-28 11:34:23 +01:00
committed by GitHub
parent d2163ce1f0
commit ad2f798089
12 changed files with 422 additions and 0 deletions
+36
View File
@@ -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();
}
+93
View File
@@ -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;
}
+42
View File
@@ -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
+18
View File
@@ -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");
}
+9
View File
@@ -0,0 +1,9 @@
void task_coilx_fire_run(int pin)
{
digitalWrite(pin, LOW);
}
void task_coilx_charge_run(int pin)
{
digitalWrite(pin, HIGH);
}
+20
View File
@@ -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);
}
+23
View File
@@ -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;
+8
View File
@@ -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);
}
+20
View File
@@ -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
+99
View File
@@ -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;
}
}
+41
View File
@@ -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,
};
+13
View File
@@ -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;
}