From be153bd4e71b3172c331ad4b25ea224d7dbf772d Mon Sep 17 00:00:00 2001 From: Josh Stewart Date: Fri, 29 May 2015 00:15:27 +1000 Subject: [PATCH] Allow for custom injection timing on a per channel basis --- globals.h | 18 ++++++------ reference/Speeduino base tune.msq | 15 ++++------ reference/speeduino.ini | 46 +++++++++++++++++-------------- speeduino.ino | 31 ++++++++++++++------- 4 files changed, 61 insertions(+), 49 deletions(-) diff --git a/globals.h b/globals.h index 86c3503..381c8a1 100644 --- a/globals.h +++ b/globals.h @@ -101,11 +101,10 @@ struct config1 { byte crankingPct; //Cranking enrichment byte pinMapping; // The board / ping mapping to be used byte unused96; - byte unused97; + byte tdePct; // TPS decelleration (%) byte taeColdA; byte tpsThresh; byte taeTime; - byte tdePct; //Display config bits byte displayType : 3; @@ -117,17 +116,16 @@ struct config1 { byte displayB1 : 4; byte displayB2 : 4; - byte unused105; byte reqFuel; byte divider; byte alternate; - byte injOpen; - byte injOCfuel; - byte injPwmP; - byte injPwmT; - byte unused113; - int rpmk; //2 bytes -//36 + byte injOpen; //Injector opening time (ms * 10) + unsigned int inj1Ang; + unsigned int inj2Ang; + unsigned int inj3Ang; + unsigned int inj4Ang; + +//116 //config1 in ini byte mapType : 2; byte strokes : 1; diff --git a/reference/Speeduino base tune.msq b/reference/Speeduino base tune.msq index 88865e9..c0d4cae 100644 --- a/reference/Speeduino base tune.msq +++ b/reference/Speeduino base tune.msq @@ -1,6 +1,6 @@ - + "0" @@ -91,11 +91,10 @@ 25.0 "Speeduino v0.3" 0.0 -0.0 +3.2 0.0 90.0 200.0 -80.0 "Unused" "VE" "CPU" @@ -104,16 +103,14 @@ "RPM" "RPM" "RPM" -0.0 12.4 2.0 "Alternating" 1.0 -0.0 -0.0 -0.0 -0.0 -3000.0 +355.0 +355.0 +355.0 +355.0 "250 kPa" "Four-stroke" "Port" diff --git a/reference/speeduino.ini b/reference/speeduino.ini index 3f16a96..cfab64b 100644 --- a/reference/speeduino.ini +++ b/reference/speeduino.ini @@ -93,34 +93,31 @@ page = 1 crankingPct= scalar, U08, 94, "%", 1.0, 0.0, 0.0, 255, 0 pinLayout = bits, U08, 95, [0:7], "Speeduino v0.1", "Speeduino v0.2", "Speeduino v0.3", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "Turtana PCB", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "Plazomat I/O 0.1", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID" unused96 = scalar, U08, 96, "ms", 0.1, 0.0, 0.0, 25.5, 1 - unused97 = scalar, U08, 97, "ms", 0.1, 0.0, 0.0, 25.5, 1 + tdePct = scalar, U08, 97, "ms", 0.1, 0.0, 0.0, 25.5, 1 taeColdA = scalar, U08, 98, "ms", 0.1, 0.0, 0.0, 25.5, 1 tpsThresh = scalar, U08, 99, "%/s", 1.0, 0.0, 0.0, 255, 0 taeTime = scalar, U08, 100, "ms", 10, 0.0, 0.0, 2550, 0 - tdePct = scalar, U08, 101, "%", 1.0, 0.0, 0.0, 255, 0 ; Display (Options for what the display is showing) - display = bits, U08, 102, [0:2], "Unused", "Adafruit 128x32", "Generic 128x32", "Adafruit 128x64", "Generic 128x64", "INVALID", "INVALID", "INVALID" - display1 = bits U08, 102, [3:5], "RPM", "PW", "Advance", "VE", "GammaE", "TPS", "IAT", "CLT" - display2 = bits U08, 102, [6:7], "O2", "Voltage", "CPU", "Mem" + display = bits, U08, 101, [0:2], "Unused", "Adafruit 128x32", "Generic 128x32", "Adafruit 128x64", "Generic 128x64", "INVALID", "INVALID", "INVALID" + display1 = bits U08, 101, [3:5], "RPM", "PW", "Advance", "VE", "GammaE", "TPS", "IAT", "CLT" + display2 = bits U08, 101, [6:7], "O2", "Voltage", "CPU", "Mem" - display3 = bits U08, 103, [0:2], "RPM", "PW", "Advance", "VE", "GammaE", "TPS", "IAT", "CLT" - display4 = bits U08, 103, [3:4], "O2", "Voltage", "CPU", "Mem" - display5 = bits U08, 103, [5:7], "RPM", "PW", "Advance", "VE", "GammaE", "TPS", "IAT", "CLT" + display3 = bits U08, 102, [0:2], "RPM", "PW", "Advance", "VE", "GammaE", "TPS", "IAT", "CLT" + display4 = bits U08, 102, [3:4], "O2", "Voltage", "CPU", "Mem" + display5 = bits U08, 102, [5:7], "RPM", "PW", "Advance", "VE", "GammaE", "TPS", "IAT", "CLT" - displayB1 = bits U08, 104, [0:3], "RPM", "PW", "Advance", "VE", "GammaE", "TPS", "IAT", "CLT" - displayB2 = bits U08, 104, [4:7], "RPM", "PW", "Advance", "VE", "GammaE", "TPS", "IAT", "CLT" + displayB1 = bits U08, 103, [0:3], "RPM", "PW", "Advance", "VE", "GammaE", "TPS", "IAT", "CLT" + displayB2 = bits U08, 103, [4:7], "RPM", "PW", "Advance", "VE", "GammaE", "TPS", "IAT", "CLT" - unused105 = scalar, U08, 105, "ms", 0.1, 0.0, 0.0, 25.5, 1 - reqFuel = scalar, U08, 106, "ms", 0.1, 0.0, 0.0, 25.5, 1 - divider = scalar, U08, 107, "", 1.0, 0.0 - alternate = bits, U08, 108, [0:0], "Simultaneous", "Alternating" - injOpen = scalar, U08, 109, "ms", 0.1, 0.0, 0.1, 25.5, 1 - injOCfuel = scalar, U08, 110, "ms", 0.1, 0.0, 0.0, 0.0, 0 - injPwmP = scalar, U08, 111, "%", 1.0, 0.0, 0.0, 100.0, 0 - injPwmT = scalar, U08, 112, "ms", 0.1, 0.0, 0.0, 25.5, 1 - unused113 = scalar, U08, 113, "ms/v",0.0166667, 0.0, 0.0, 1.0, 2 - rpmk = scalar, U16, 114, "", 1.0, 0.0 + reqFuel = scalar, U08, 104, "ms", 0.1, 0.0, 0.0, 25.5, 1 + divider = scalar, U08, 105, "", 1.0, 0.0 + alternate = bits, U08, 106, [0:0], "Simultaneous", "Alternating" + injOpen = scalar, U08, 107, "ms", 0.1, 0.0, 0.1, 25.5, 1 + inj1Ang = scalar, U16, 108, "deg", 1.0, 0.0, 0.0, 360, 0 + inj2Ang = scalar, U16, 110, "deg", 1.0, 0.0, 0.0, 360, 0 + inj3Ang = scalar, U16, 112, "deg", 1.0, 0.0, 0.0, 360, 0 + inj4Ang = scalar, U16, 114, "deg", 1.0, 0.0, 0.0, 360, 0 ; Config1 mapType = bits, U08, 116, [0:1], "115 kPa", "250 kPa", "INVALID", "INVALID" @@ -272,6 +269,10 @@ page = 3 defaultValue = pinLayout, 1 defaultValue = TrigPattern, 0 + defaultValue = inj1Ang, 355 + defaultValue = inj2Ang, 355 + defaultValue = inj3Ang, 355 + defaultValue = inj4Ang, 355 [Menu] @@ -398,6 +399,11 @@ page = 3 dialog = injChars, "Injector Characteristics" field = "Injector Open Time", injOpen + field = "Injector close times" + field = "Channel 1", inj1Ang + field = "Channel 2", inj2Ang, { nCylinders > 1 } + field = "Channel 3", inj3Ang, { nCylinders > 4 || nCylinders == 3 } + field = "Channel 4", inj4Ang, { nCylinders > 6 } panel = injector_voltage_curve dialog = egoControl, "" diff --git a/speeduino.ino b/speeduino.ino index cd45493..a4c248f 100644 --- a/speeduino.ino +++ b/speeduino.ino @@ -412,42 +412,42 @@ void loop() //Determine next firing angles //1 int PWdivTimerPerDegree = div(currentStatus.PW, timePerDegree).quot; //How many crank degrees the calculated PW will take at the current speed - injector1StartAngle = 355 - ( PWdivTimerPerDegree ); //This is a little primitive, but is based on the idea that all fuel needs to be delivered before the inlet valve opens. I am using 355 as the point at which the injector MUST be closed by. See http://www.extraefi.co.uk/sequential_fuel.html for more detail + injector1StartAngle = configPage1.inj1Ang - ( PWdivTimerPerDegree ); //This is a little primitive, but is based on the idea that all fuel needs to be delivered before the inlet valve opens. I am using 355 as the point at which the injector MUST be closed by. See http://www.extraefi.co.uk/sequential_fuel.html for more detail if(injector1StartAngle < 0) {injector1StartAngle += 360;} //Repeat the above for each cylinder switch (configPage1.nCylinders) { //2 cylinders case 2: - injector2StartAngle = (355 + channel2Degrees - ( PWdivTimerPerDegree )); + injector2StartAngle = (configPage1.inj2Ang + channel2Degrees - ( PWdivTimerPerDegree )); if(injector2StartAngle > 360) {injector2StartAngle -= 360;} break; //3 cylinders case 3: - injector2StartAngle = (355 + channel2Degrees - ( PWdivTimerPerDegree )); + injector2StartAngle = (configPage1.inj2Ang + channel2Degrees - ( PWdivTimerPerDegree )); if(injector2StartAngle > 360) {injector2StartAngle -= 360;} - injector3StartAngle = (355 + channel3Degrees - ( PWdivTimerPerDegree )); + injector3StartAngle = (configPage1.inj3Ang + channel3Degrees - ( PWdivTimerPerDegree )); if(injector3StartAngle > 360) {injector3StartAngle -= 360;} break; //4 cylinders case 4: - injector2StartAngle = (355 + channel2Degrees - ( PWdivTimerPerDegree )); + injector2StartAngle = (configPage1.inj2Ang + channel2Degrees - ( PWdivTimerPerDegree )); if(injector2StartAngle > 360) {injector2StartAngle -= 360;} break; //6 cylinders case 6: - injector2StartAngle = (355 + channel2Degrees - ( PWdivTimerPerDegree )); + injector2StartAngle = (configPage1.inj2Ang + channel2Degrees - ( PWdivTimerPerDegree )); if(injector2StartAngle > 360) {injector2StartAngle -= 360;} - injector3StartAngle = (355 + channel3Degrees - ( PWdivTimerPerDegree )); + injector3StartAngle = (configPage1.inj3Ang + channel3Degrees - ( PWdivTimerPerDegree )); if(injector3StartAngle > 360) {injector3StartAngle -= 360;} break; //8 cylinders case 8: - injector2StartAngle = (355 + channel2Degrees - ( PWdivTimerPerDegree )); + injector2StartAngle = (configPage1.inj2Ang + channel2Degrees - ( PWdivTimerPerDegree )); if(injector2StartAngle > 360) {injector2StartAngle -= 360;} - injector3StartAngle = (355 + channel3Degrees - ( PWdivTimerPerDegree )); + injector3StartAngle = (configPage1.inj3Ang + channel3Degrees - ( PWdivTimerPerDegree )); if(injector3StartAngle > 360) {injector3StartAngle -= 360;} - injector4StartAngle = (355 + channel4Degrees - ( PWdivTimerPerDegree )); + injector4StartAngle = (configPage1.inj4Ang + channel4Degrees - ( PWdivTimerPerDegree )); if(injector4StartAngle > 360) {injector4StartAngle -= 360;} break; //Will hit the default case on 1 cylinder or >8 cylinders. Do nothing in these cases @@ -541,6 +541,17 @@ void loop() } } + /*----------------------------------------------------------------------------------------- + | A Note on tempCrankAngle and tempStartAngle: + | The use of tempCrankAngle/tempStartAngle is described below. It is then used in the same way for channels 2, 3 and 4 on both injectors and ignition + | Essentially, these 2 variables are used to realign the current crank and and the desired start angle around 0 degrees for the given cylinder/output + | Eg: If cylinder 2 TDC is 180 degrees after cylinder 1 (Eg a standard 4 cylidner engine), then tempCrankAngle is 180* less than the current crank angle and + | tempStartAngle is the desired open time less 180*. Thus the cylinder is being treated relative to its own TDC, regardless of its offset + | + | This is done to avoid problems with very short of very long times until tempStartAngle. + | This will very likely need to be rewritten when sequential is enabled + |------------------------------------------------------------------------------------------ + */ tempCrankAngle = crankAngle - channel2Degrees; if( tempCrankAngle < 0) { tempCrankAngle += 360; } tempStartAngle = injector2StartAngle - channel2Degrees;