Add deceleration enleanment feature (#939)

* Add decel enleanment feature

* Fix tps and map DOT scaling in TS.

* updates.ino

* Small bug fix.

* One more small bug fix.

* Update cancomms.ino

Cast tps/mapDOT as uint8 to cancomms to retain backwards compatibility

* Fix programmable outputs list.

* Fix programmable outputs in updates.ino

* Add abs around currentStatus.mapDOT
This commit is contained in:
Pasi Kemppainen 2022-12-14 02:17:47 +02:00 committed by GitHub
parent eb97b8458c
commit f59d013714
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 366 additions and 329 deletions

View File

@ -102,10 +102,10 @@
#define comp_IO_Pins = $comp_IO_Pins_0, $comp_IO_Pins_1, $comp_IO_Pins_2, $comp_IO_Pins_3
;All definitions of split fullStatus should keep 32 options
#define fullStatus_def_1= "seconds", "status bits", "Engine status", "syncLossCounter", "MAP (Kpa)", "INVALID", "IAT / MAT", "coolant", "batCorrection", "battery voltage x10", "O2", "egoCorrection", "iatCorrection", "wueCorrection", "RPM", "INVALID", "AEamount/2", "GammaE", "INVALID", "VE1", "VE2", "AFR Target", "TPS DOT", "Advance", "TPS", "loopsPerSecond", "INVALID", "free RAM", "INVALID", "boostTarget/2", "Boost duty", "spark bits"
#define fullStatus_def_2= "RPM DOT", "INVALID", "ethanolPct", "flexCorrection", "flexIgnCorrection", "idle Load", "testOutputs", "O2_2", "baro", "Aux in 0", "INVALID", "Aux in 1", "INVALID", "Aux in 2", "INVALID", "Aux in 3", "INVALID", "Aux in 4", "INVALID", "Aux in 5", "INVALID", "Aux in 6", "INVALID", "Aux in 7", "INVALID", "Aux in 8", "INVALID", "Aux in 9", "INVALID", "Aux in 10", "INVALID", "Aux in 11"
#define fullStatus_def_3= "INVALID", "Aux in 12", "INVALID", "Aux in 13", "INVALID", "Aux in 14", "INVALID", "Aux in 15", "INVALID", "TPS ADC", "Error code", "Pulsewidth 1", "INVALID", "Pulsewidth 2", "INVALID", "Pulsewidth 3", "INVALID", "Pulsewidth 4", "INVALID", "status bits 3", "engineProtectStatus", "Fuel load", "INVALID", "Ignition load", "INVALID", "dwell", "INVALID", "idle C.L. target", "MAP DOT", "VVT1 Angle", "INVALID", "VVT1 Target"
#define fullStatus_def_4= "VVT1 duty", "flexBoostCorrection", "INVALID", "baro correction", "Current VE", "ASE Value", "vss", "INVALID", "Gear", "Fuel Pressure", "Oil Pressure", "WMI duty", "WMI empty", "VVT2 angle", "INVALID", "VVT2 target", "VVT2 duty", "outputs status", "Fuel temp", "Fuel temp correction", "Advance 1", "Advance 2", "SD status", "INVALID", "EMAP", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID"
#define fullStatus_def_1= "seconds", "status bits", "Engine status", "syncLossCounter", "MAP (Kpa)", "INVALID", "IAT / MAT", "coolant", "batCorrection", "battery voltage x10", "O2", "egoCorrection", "iatCorrection", "wueCorrection", "RPM", "INVALID", "AEamount/2", "GammaE", "INVALID", "VE1", "VE2", "AFR Target", "TPS DOT", "INVALID", "Advance", "TPS", "loopsPerSecond", "INVALID", "free RAM", "INVALID", "boostTarget/2", "Boost duty"
#define fullStatus_def_2= "spark bits", "RPM DOT", "INVALID", "ethanolPct", "flexCorrection", "flexIgnCorrection", "idle Load", "testOutputs", "O2_2", "baro", "Aux in 0", "INVALID", "Aux in 1", "INVALID", "Aux in 2", "INVALID", "Aux in 3", "INVALID", "Aux in 4", "INVALID", "Aux in 5", "INVALID", "Aux in 6", "INVALID", "Aux in 7", "INVALID", "Aux in 8", "INVALID", "Aux in 9", "INVALID", "Aux in 10", "INVALID"
#define fullStatus_def_3= "Aux in 11", "INVALID", "Aux in 12", "INVALID", "Aux in 13", "INVALID", "Aux in 14", "INVALID", "Aux in 15", "INVALID", "TPS ADC", "Error code", "Pulsewidth 1", "INVALID", "Pulsewidth 2", "INVALID", "Pulsewidth 3", "INVALID", "Pulsewidth 4", "INVALID", "status bits 3", "engineProtectStatus", "Fuel load", "INVALID", "Ignition load", "INVALID", "dwell", "INVALID", "idle C.L. target", "MAP DOT", "INVALID", "VVT1 Angle"
#define fullStatus_def_4= "INVALID", "VVT1 Target", "VVT1 duty", "flexBoostCorrection", "INVALID", "baro correction", "Current VE", "ASE Value", "vss", "INVALID", "Gear", "Fuel Pressure", "Oil Pressure", "WMI duty", "WMI empty", "VVT2 angle", "INVALID", "VVT2 target", "VVT2 duty", "outputs status", "Fuel temp", "Fuel temp correction", "Advance 1", "Advance 2", "SD status", "EMAP", "INVALID", "Fan duty", "airConStatus", "INVALID", "INVALID"
#define fullStatus_def_5= "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID"
#define fullStatus_def_6= "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID"
#define fullStatus_def_7= "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID"
@ -455,7 +455,7 @@ page = 1
enable2Cluster = bits, U08, 126, [3:3], "Off", "On"
unusedClusterBits = bits, U08, 126, [4:7], "Off","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID"
unused2-95 = scalar, U08, 127, "RPM", 100, 0.0, 0.0, 16320, 0
decelAmount = scalar, U08, 127, "%", 1.0, 0.0, 0.0, 150.0, 0
;Page 2 is the fuel map and axis bins only
page = 2
@ -1612,6 +1612,7 @@ page = 15
defaultValue = aeColdPct, 100
defaultValue = aeColdTaperMin, 0
defaultValue = aeColdTaperMax, 60
defaultValue = decelAmount, 100
defaultValue = aeMode, 0 ;Set aeMode to TPS
defaultValue = batVoltCorrect, 0
defaultValue = aeApplyMode, 0
@ -2186,6 +2187,7 @@ menuDialog = main
aeColdPct = "Acceleration enrichment adjustment for cold engine. Cold adjustment % is tapered between start and end temperatures.\n100% = no adjustment."
aeColdTaperMin = "AE cold adjustment taper start temperature. When coolant is below this value, full cold adjustment is applied."
aeColdTaperMax = "AE cold adjustment taper end temperature. When coolant is above this value, no cold adjustment is applied."
decelAmount = "Reduces fuel compared to VE table during deceleration. 100% means no reduction in fuel amount and 0% means all fuel is cut during decel (Do not confuse this with DFCO). Recommended to use values between 100 and 70%. Default: 100%. Works with both TPS and MAP based AE."
dfcoRPM = "The RPM above which DFCO will be active. Typically set a few hundred RPM above maximum idle speed"
dfcoHyster = "Hysteresis for DFCO RPM. 200-300 RPM is typical for this, however a higher value may be needed if the RPM is fluctuating around the cutout speed"
dfcoTPSThresh = "The TPS value below which DFCO will be active. Typical value is 5%-10%, but higher may be needed if TPS signal is noisy"
@ -2599,6 +2601,9 @@ menuDialog = main
field = "Taper Start RPM", aeTaperMin
field = "Taper End RPM", aeTaperMax
dialog = decelEnleanment, "Deceleration Enleanment"
field = "Fuel Amount", decelAmount
dialog = accelEnrichments_coldAdj, "Acceleration Enrichment cold adjustment"
field = "Cold adjustment", aeColdPct
field = "Cold adjustment taper start temperature", aeColdTaperMin
@ -2635,6 +2640,7 @@ menuDialog = main
panel = accelEnrichments_north, North
panel = accelEnrichments_north_south, Center
panel = accelEnrichments_center, Center
panel = decelEnleanment
panel = accelEnrichments_south, South
dialog = veTableDialog_north, ""
@ -5006,8 +5012,8 @@ cmdVSSratio6 = "E\x99\x06"
afrGauge = afr, "Air:Fuel Ratio", "", 7, 25, 12, 13, 15, 16, 2, 2
afrGauge2 = afr2, "Air:Fuel Ratio 2", "", 7, 25, 12, 13, 15, 16, 2, 2
lambdaGauge = lambda, "Lambda", "", 0.5, 1.5, 0.5, 0.7, 2, 1.1, 2, 2
TPSdotGauge = TPSdot, "TPS DOT", "%/s", 0, 1000, -1, -1, 2560, 2560, 0, 0
MAPdotGauge = MAPdot, "MAP DOT", "kPa/s", 0, 1000, -1, -1, 2560, 2560, 0, 0
TPSdotGauge = TPSdot, "TPS DOT", "%/s", -1000, 1000, -2560, -2560, 2560, 2560, 0, 0
MAPdotGauge = MAPdot, "MAP DOT", "kPa/s", -1000, 1000, -2560, -2560, 2560, 2560, 0, 0
#if CELSIUS
cltGauge = coolant, "Coolant Temp", "TEMP", -40, 120, -15, 0, 95, 105, 0, 0
@ -5142,7 +5148,7 @@ cmdVSSratio6 = "E\x99\x06"
; you change it.
ochGetCommand = "r\$tsCanId\x30%2o%2c"
ochBlockSize = 123
ochBlockSize = 125
secl = scalar, U08, 0, "sec", 1.000, 0.000
status1 = scalar, U08, 1, "bits", 1.000, 0.000
@ -5179,126 +5185,125 @@ cmdVSSratio6 = "E\x99\x06"
VE1 = scalar, U08, 19, "%", 1.000, 0.000
VE2 = scalar, U08, 20, "%", 1.000, 0.000
afrTarget = scalar, U08, 21, "O2", 0.100, 0.000
TPSdot = scalar, U08, 22, "%/s", 10.00, 0.000
advance = scalar, S08, 23, "deg", 1.000, 0.000
tps = scalar, U08, 24, "%", 0.500, 0.000
loopsPerSecond = scalar, U16, 25, "loops", 1.000, 0.000
freeRAM = scalar, U16, 27, "bytes", 1.000, 0.000
boostTarget = scalar, U08, 29, "kPa", 2.000, 0.000
boostDuty = scalar, U08, 30, "%", 1.000, 0.000
status2 = scalar, U08, 31, "bits", 1.000, 0.000
launchHard = bits, U08, 31, [0:0]
launchSoft = bits, U08, 31, [1:1]
hardLimitOn = bits, U08, 31, [2:2]
softlimitOn = bits, U08, 31, [3:3]
boostCutSpark = bits, U08, 31, [4:4]
error = bits, U08, 31, [5:5]
idleControlOn = bits, U08, 31, [6:6]
sync = bits, U08, 31, [7:7]
rpmDOT = scalar, S16, 32, "rpm/s", 1.000, 0.000
flex = scalar, U08, 34, "%", 1.000, 0.000
flexFuelCor = scalar, U08, 35, "%", 1.000, 0.000
flexIgnCor = scalar, S08, 36, "deg", 1.000, 0.000
idleLoad = scalar, U08, 37, { bitStringValue( idleUnits , iacAlgorithm ) }, { (iacAlgorithm == 2 || iacAlgorithm == 3 || iacAlgorithm == 6 || iacMaxSteps <= 255) ? 1.000 : 2.000 }, 0.000 ; This is a combined variable covering both PWM and stepper IACs. The units and precision used depend on which idle algorithm is chosen
testoutputs = scalar, U08, 38, "bits", 1.000, 0.000
testenabled = bits, U08, 38, [0:0]
testactive = bits, U08, 38, [1:1]
afr2 = scalar, U08, 39, "O2", 0.100, 0.000
baro = scalar, U08, 40, "kpa", 1.000, 0.000
auxin_gauge0 = scalar, U16, 41, "", 1.000, 0.000
auxin_gauge1 = scalar, U16, 43, "", 1.000, 0.000
auxin_gauge2 = scalar, U16, 45, "", 1.000, 0.000
auxin_gauge3 = scalar, U16, 47, "", 1.000, 0.000
auxin_gauge4 = scalar, U16, 49, "", 1.000, 0.000
auxin_gauge5 = scalar, U16, 51, "", 1.000, 0.000
auxin_gauge6 = scalar, U16, 53, "", 1.000, 0.000
auxin_gauge7 = scalar, U16, 55, "", 1.000, 0.000
auxin_gauge8 = scalar, U16, 57, "", 1.000, 0.000
auxin_gauge9 = scalar, U16, 59, "", 1.000, 0.000
auxin_gauge10 = scalar, U16, 61, "", 1.000, 0.000
auxin_gauge11 = scalar, U16, 63, "", 1.000, 0.000
auxin_gauge12 = scalar, U16, 65, "", 1.000, 0.000
auxin_gauge13 = scalar, U16, 67, "", 1.000, 0.000
auxin_gauge14 = scalar, U16, 69, "", 1.000, 0.000
auxin_gauge15 = scalar, U16, 71, "", 1.000, 0.000
tpsADC = scalar, U08, 73, "ADC", 1.000, 0.000
errors = scalar, U08, 74, "bits", 1.000, 0.000
errorNum = bits, U08, 74, [0:1]
currentError = bits, U08, 74, [2:7]
pulseWidth = scalar, U16, 75, "ms", 0.001, 0.000
pulseWidth2 = scalar, U16, 77, "ms", 0.001, 0.000
pulseWidth3 = scalar, U16, 79, "ms", 0.001, 0.000
pulseWidth4 = scalar, U16, 81, "ms", 0.001, 0.000
status3 = scalar, U08, 83, "bits", 1.000, 0.000
resetLockOn = bits, U08, 83, [0:0]
nitrousOn = bits, U08, 83, [1:1]
fuel2Active = bits, U08, 83, [2:2]
vssRefresh = bits, U08, 83, [3:3]
halfSync = bits, U08, 83, [4:4]
nSquirts = bits, U08, 83, [5:7]
engineProtectStatus = scalar, U08, 84, "bits", 1.000, 0.000
engineProtectRPM = bits, U08, 84, [0:0]
engineProtectMAP = bits, U08, 84, [1:1]
engineProtectOil = bits, U08, 84, [2:2]
engineProtectAFR = bits, U08, 84, [3:3]
engineProtectCoolant = bits, U08, 84, [4:4]
engineProtectOth = bits, U08, 84, [5:6] ; Unused for now
IOError = bits, U08, 84, [7:7]
unused1 = scalar, U08, 84, "ADC",1.000, 0.000
fuelLoad = scalar, S16, 85, { bitStringValue( algorithmUnits , algorithm ) }, fuelLoadFeedBack, 0.000
ignLoad = scalar, S16, 87, { bitStringValue( algorithmUnits , ignAlgorithm ) }, ignLoadFeedBack, 0.000
dwell = scalar, U16, 89, "ms", 0.001, 0.000
CLIdleTarget = scalar, U08, 91, "RPM", 10.00, 0.000
MAPdot = scalar, U08, 92, "kPa/s", 10.00, 0.000
vvt1Angle = scalar, S16, 93, "deg", 0.50, 0.000
vvt1Target = scalar, U08, 95, "deg", 0.50, 0.000
vvt1Duty = scalar, U08, 96, "%", 0.50, 0.000
flexBoostCor = scalar, S16, 97, "kPa", 1.000, 0.000
baroCorrection = scalar, U08, 99, "%", 1.000, 0.000
veCurr = scalar, U08, 100, "%", 1.000, 0.000
ASECurr = scalar, U08, 101, "%", 1.000, 0.000
vss = scalar, U16, 102, "km/h", 1.000, 0.000
gear = scalar, U08, 104, "", 1.000, 0.000
fuelPressure = scalar, U08, 105, "PSI", 1.000, 0.000
oilPressure = scalar, U08, 106, "PSI", 1.000, 0.000
wmiPW = scalar, U08, 107, "%", 1.000, 0.000
status4 = scalar, U08, 108, "bits", 1.000, 0.000
wmiEmptyBit = bits, U08, 108, [0:0]
vvt1Error = bits, U08, 108, [1:1]
vvt2Error = bits, U08, 108, [2:2]
fanStatus = bits, U08, 108, [3:3]
burnPending = bits, U08, 108, [4:4]
UnusedBits4 = bits, U08, 108, [5:7]
vvt2Angle = scalar, S16, 109, "deg", 0.50, 0.000
vvt2Target = scalar, U08, 111, "deg", 0.50, 0.000
vvt2Duty = scalar, U08, 112, "%", 0.50, 0.000
outputsStatus0 = bits, U08, 113, [0:0]
outputsStatus1 = bits, U08, 113, [1:1]
outputsStatus2 = bits, U08, 113, [2:2]
outputsStatus3 = bits, U08, 113, [3:3]
outputsStatus4 = bits, U08, 113, [4:4]
outputsStatus5 = bits, U08, 113, [5:5]
outputsStatus6 = bits, U08, 113, [6:6]
outputsStatus7 = bits, U08, 113, [7:7]
fuelTempRaw = scalar, U08, 114, "°C", 1.000, 0.000
fuelTempCor = scalar, U08, 115, "%", 1.000, 0.000
advance1 = scalar, S08, 116, "deg", 1.000, 0.000
advance2 = scalar, S08, 117, "deg", 1.000, 0.000
sd_status = scalar, U08, 118, "", 1.0, 0.0
emap = scalar, U16, 119, "kpa", 1.000, 0.000
fanDuty = scalar, U08, 121, "%", 0.5, 0.000
airConStatus = scalar, U08, 122, "bits", 1.000, 0.000
airConRequest = bits, U08, 122, [0:0]
airConCompressor = bits, U08, 122, [1:1]
airConRPMMLockout = bits, U08, 122, [2:2]
airConTPSLockout = bits, U08, 122, [3:3]
airConTurningOn = bits, U08, 122, [4:4]
airConCLTLockout = bits, U08, 122, [5:5]
airConFanStatus = bits, U08, 122, [6:6]
airConUnusedBits = bits, U08, 122, [7:7]
;sd_filenum = scalar, U16, 123, "", 1, 0
;sd_error = scalar, U08, 125, "", 1, 0
;sd_phase = scalar, U08, 126, "", 1, 0
TPSdot = scalar, S16, 22, "%/s", 1.000, 0.000
advance = scalar, S08, 24, "deg", 1.000, 0.000
tps = scalar, U08, 25, "%", 0.500, 0.000
loopsPerSecond = scalar, U16, 26, "loops", 1.000, 0.000
freeRAM = scalar, U16, 28, "bytes", 1.000, 0.000
boostTarget = scalar, U08, 30, "kPa", 2.000, 0.000
boostDuty = scalar, U08, 31, "%", 1.000, 0.000
status2 = scalar, U08, 32, "bits", 1.000, 0.000
launchHard = bits, U08, 32, [0:0]
launchSoft = bits, U08, 32, [1:1]
hardLimitOn = bits, U08, 32, [2:2]
softlimitOn = bits, U08, 32, [3:3]
boostCutSpark = bits, U08, 32, [4:4]
error = bits, U08, 32, [5:5]
idleControlOn = bits, U08, 32, [6:6]
sync = bits, U08, 32, [7:7]
rpmDOT = scalar, S16, 33, "rpm/s", 1.000, 0.000
flex = scalar, U08, 35, "%", 1.000, 0.000
flexFuelCor = scalar, U08, 36, "%", 1.000, 0.000
flexIgnCor = scalar, S08, 37, "deg", 1.000, 0.000
idleLoad = scalar, U08, 38, { bitStringValue( idleUnits , iacAlgorithm ) }, { (iacAlgorithm == 2 || iacAlgorithm == 3 || iacAlgorithm == 6 || iacMaxSteps <= 255) ? 1.000 : 2.000 }, 0.000 ; This is a combined variable covering both PWM and stepper IACs. The units and precision used depend on which idle algorithm is chosen
testoutputs = scalar, U08, 39, "bits", 1.000, 0.000
testenabled = bits, U08, 39, [0:0]
testactive = bits, U08, 39, [1:1]
afr2 = scalar, U08, 40, "O2", 0.100, 0.000
baro = scalar, U08, 41, "kpa", 1.000, 0.000
auxin_gauge0 = scalar, U16, 42, "", 1.000, 0.000
auxin_gauge1 = scalar, U16, 44, "", 1.000, 0.000
auxin_gauge2 = scalar, U16, 46, "", 1.000, 0.000
auxin_gauge3 = scalar, U16, 48, "", 1.000, 0.000
auxin_gauge4 = scalar, U16, 50, "", 1.000, 0.000
auxin_gauge5 = scalar, U16, 52, "", 1.000, 0.000
auxin_gauge6 = scalar, U16, 54, "", 1.000, 0.000
auxin_gauge7 = scalar, U16, 56, "", 1.000, 0.000
auxin_gauge8 = scalar, U16, 58, "", 1.000, 0.000
auxin_gauge9 = scalar, U16, 60, "", 1.000, 0.000
auxin_gauge10 = scalar, U16, 62, "", 1.000, 0.000
auxin_gauge11 = scalar, U16, 64, "", 1.000, 0.000
auxin_gauge12 = scalar, U16, 66, "", 1.000, 0.000
auxin_gauge13 = scalar, U16, 68, "", 1.000, 0.000
auxin_gauge14 = scalar, U16, 70, "", 1.000, 0.000
auxin_gauge15 = scalar, U16, 72, "", 1.000, 0.000
tpsADC = scalar, U08, 74, "ADC", 1.000, 0.000
errors = scalar, U08, 75, "bits", 1.000, 0.000
errorNum = bits, U08, 75, [0:1]
currentError = bits, U08, 75, [2:7]
pulseWidth = scalar, U16, 76, "ms", 0.001, 0.000
pulseWidth2 = scalar, U16, 78, "ms", 0.001, 0.000
pulseWidth3 = scalar, U16, 80, "ms", 0.001, 0.000
pulseWidth4 = scalar, U16, 82, "ms", 0.001, 0.000
status3 = scalar, U08, 84, "bits", 1.000, 0.000
resetLockOn = bits, U08, 84, [0:0]
nitrousOn = bits, U08, 84, [1:1]
fuel2Active = bits, U08, 84, [2:2]
vssRefresh = bits, U08, 84, [3:3]
halfSync = bits, U08, 84, [4:4]
nSquirts = bits, U08, 84, [5:7]
engineProtectStatus = scalar, U08, 85, "bits", 1.000, 0.000
engineProtectRPM = bits, U08, 85, [0:0]
engineProtectMAP = bits, U08, 85, [1:1]
engineProtectOil = bits, U08, 85, [2:2]
engineProtectAFR = bits, U08, 85, [3:3]
engineProtectCoolant = bits, U08, 85, [4:4]
engineProtectOth = bits, U08, 85, [5:6] ; Unused for now
IOError = bits, U08, 85, [7:7]
fuelLoad = scalar, S16, 86, { bitStringValue( algorithmUnits , algorithm ) }, fuelLoadFeedBack, 0.000
ignLoad = scalar, S16, 88, { bitStringValue( algorithmUnits , ignAlgorithm ) }, ignLoadFeedBack, 0.000
dwell = scalar, U16, 90, "ms", 0.001, 0.000
CLIdleTarget = scalar, U08, 92, "RPM", 10.00, 0.000
MAPdot = scalar, S16, 93, "kPa/s", 1.000, 0.000
vvt1Angle = scalar, S16, 95, "deg", 0.50, 0.000
vvt1Target = scalar, U08, 97, "deg", 0.50, 0.000
vvt1Duty = scalar, U08, 98, "%", 0.50, 0.000
flexBoostCor = scalar, S16, 99, "kPa", 1.000, 0.000
baroCorrection = scalar, U08, 101, "%", 1.000, 0.000
veCurr = scalar, U08, 102, "%", 1.000, 0.000
ASECurr = scalar, U08, 103, "%", 1.000, 0.000
vss = scalar, U16, 104, "km/h", 1.000, 0.000
gear = scalar, U08, 106, "", 1.000, 0.000
fuelPressure = scalar, U08, 107, "PSI", 1.000, 0.000
oilPressure = scalar, U08, 108, "PSI", 1.000, 0.000
wmiPW = scalar, U08, 109, "%", 1.000, 0.000
status4 = scalar, U08, 110, "bits", 1.000, 0.000
wmiEmptyBit = bits, U08, 110, [0:0]
vvt1Error = bits, U08, 110, [1:1]
vvt2Error = bits, U08, 110, [2:2]
fanStatus = bits, U08, 110, [3:3]
burnPending = bits, U08, 110, [4:4]
UnusedBits4 = bits, U08, 110, [5:7]
vvt2Angle = scalar, S16, 111, "deg", 0.50, 0.000
vvt2Target = scalar, U08, 113, "deg", 0.50, 0.000
vvt2Duty = scalar, U08, 114, "%", 0.50, 0.000
outputsStatus0 = bits, U08, 115, [0:0]
outputsStatus1 = bits, U08, 115, [1:1]
outputsStatus2 = bits, U08, 115, [2:2]
outputsStatus3 = bits, U08, 115, [3:3]
outputsStatus4 = bits, U08, 115, [4:4]
outputsStatus5 = bits, U08, 115, [5:5]
outputsStatus6 = bits, U08, 115, [6:6]
outputsStatus7 = bits, U08, 115, [7:7]
fuelTempRaw = scalar, U08, 116, "°C", 1.000, 0.000
fuelTempCor = scalar, U08, 117, "%", 1.000, 0.000
advance1 = scalar, S08, 118, "deg", 1.000, 0.000
advance2 = scalar, S08, 119, "deg", 1.000, 0.000
sd_status = scalar, U08, 120, "", 1.0, 0.0
emap = scalar, U16, 121, "kpa", 1.000, 0.000
fanDuty = scalar, U08, 123, "%", 0.5, 0.000
airConStatus = scalar, U08, 124, "bits", 1.000, 0.000
airConRequest = bits, U08, 124, [0:0]
airConCompressor = bits, U08, 124, [1:1]
airConRPMMLockout = bits, U08, 124, [2:2]
airConTPSLockout = bits, U08, 124, [3:3]
airConTurningOn = bits, U08, 124, [4:4]
airConCLTLockout = bits, U08, 124, [5:5]
airConFanStatus = bits, U08, 124, [6:6]
airConUnusedBits = bits, U08, 124, [7:7]
;sd_filenum = scalar, U16, 125, "", 1, 0
;sd_error = scalar, U08, 127, "", 1, 0
;sd_phase = scalar, U08, 128, "", 1, 0
#if CELSIUS

View File

@ -229,7 +229,7 @@ void sendcanValues(uint16_t offset, uint16_t packetLength, byte cmd, byte portTy
fullStatus[19] = currentStatus.afrTarget;
fullStatus[20] = lowByte(currentStatus.PW1); //Pulsewidth 1 multiplied by 10 in ms. Have to convert from uS to mS.
fullStatus[21] = highByte(currentStatus.PW1); //Pulsewidth 1 multiplied by 10 in ms. Have to convert from uS to mS.
fullStatus[22] = currentStatus.tpsDOT; //TPS DOT
fullStatus[22] = (uint8_t)(currentStatus.tpsDOT / 10); //TPS DOT
fullStatus[23] = currentStatus.advance;
fullStatus[24] = currentStatus.TPS; // TPS (0% to 100%)
//Need to split the int loopsPerSecond value into 2 bytes
@ -313,7 +313,7 @@ void sendcanValues(uint16_t offset, uint16_t packetLength, byte cmd, byte portTy
fullStatus[89] = highByte(currentStatus.injAngle);
fullStatus[90] = currentStatus.idleLoad;
fullStatus[91] = currentStatus.CLIdleTarget; //closed loop idle target
fullStatus[92] = currentStatus.mapDOT; //rate of change of the map
fullStatus[92] = (uint8_t)(currentStatus.mapDOT / 10); //rate of change of the map
fullStatus[93] = (int8_t)currentStatus.vvt1Angle;
fullStatus[94] = currentStatus.vvt1TargetAngle;
fullStatus[95] = currentStatus.vvt1Duty;

View File

@ -744,11 +744,11 @@ void sendValuesLegacy(void)
bytestosend -= Serial.write(99); // cold_adv_deg
bytestosend -= Serial.write(99); // cold_adv_deg
temp = currentStatus.tpsDOT * 10;
temp = currentStatus.tpsDOT;
bytestosend -= Serial.write(temp>>8); // TPSdot
bytestosend -= Serial.write(temp); // TPSdot
temp = currentStatus.mapDOT * 10;
temp = currentStatus.mapDOT;
bytestosend -= Serial.write(temp >> 8); // MAPdot
bytestosend -= Serial.write(temp); // MAPdot

View File

@ -294,30 +294,27 @@ uint16_t correctionAccel(void)
{
//Get the MAP rate change
MAP_change = (currentStatus.MAP - MAPlast);
MAP_rateOfChange = ldiv(1000000, (MAP_time - MAPlast_time)).quot * MAP_change; //This is the % per second that the TPS has moved
//MAP_rateOfChange = 15 * MAP_change; //This is the kpa per second that the MAP has moved
if(MAP_rateOfChange >= 0) { currentStatus.mapDOT = MAP_rateOfChange / 10; } //The MAE bins are divided by 10 in order to allow them to be stored in a byte. Faster as this than divu10
else { currentStatus.mapDOT = 0; } //Prevent overflow as mapDOT is signed
currentStatus.mapDOT = ldiv(1000000, (MAP_time - MAPlast_time)).quot * MAP_change; //This is the % per second that the MAP has moved
//currentStatus.mapDOT = 15 * MAP_change; //This is the kpa per second that the MAP has moved
}
else if(configPage2.aeMode == AE_MODE_TPS)
{
//Get the TPS rate change
TPS_change = (currentStatus.TPS - currentStatus.TPSlast);
//TPS_rateOfChange = ldiv(1000000, (TPS_time - TPSlast_time)).quot * TPS_change; //This is the % per second that the TPS has moved
TPS_rateOfChange = (TPS_READ_FREQUENCY * TPS_change) / 2; //This is the % per second that the TPS has moved, adjusted for the 0.5% resolution of the TPS
if(TPS_rateOfChange >= 0) { currentStatus.tpsDOT = TPS_rateOfChange / 10; } //The TAE bins are divided by 10 in order to allow them to be stored in a byte
else { currentStatus.tpsDOT = 0; } //Prevent overflow as tpsDOT is signed
//currentStatus.tpsDOT = ldiv(1000000, (TPS_time - TPSlast_time)).quot * TPS_change; //This is the % per second that the TPS has moved
currentStatus.tpsDOT = (TPS_READ_FREQUENCY * TPS_change) / 2; //This is the % per second that the TPS has moved, adjusted for the 0.5% resolution of the TPS
}
//First, check whether the accel. enrichment is already running
if( BIT_CHECK(currentStatus.engine, BIT_ENGINE_ACC) )
if( BIT_CHECK(currentStatus.engine, BIT_ENGINE_ACC) || BIT_CHECK(currentStatus.engine, BIT_ENGINE_DCC))
{
//If it is currently running, check whether it should still be running or whether it's reached it's end time
if( micros_safe() >= currentStatus.AEEndTime )
{
//Time to turn enrichment off
BIT_CLEAR(currentStatus.engine, BIT_ENGINE_ACC);
BIT_CLEAR(currentStatus.engine, BIT_ENGINE_DCC);
currentStatus.AEamount = 0;
accelValue = 100;
@ -333,17 +330,24 @@ uint16_t correctionAccel(void)
//Need to check whether the accel amount has increased from when AE was turned on
//If the accel amount HAS increased, we clear the current enrich phase and a new one will be started below
if( (configPage2.aeMode == AE_MODE_MAP) && (currentStatus.mapDOT > activateMAPDOT) ) { BIT_CLEAR(currentStatus.engine, BIT_ENGINE_ACC); }
else if( (configPage2.aeMode == AE_MODE_TPS) && (currentStatus.tpsDOT > activateTPSDOT) ) { BIT_CLEAR(currentStatus.engine, BIT_ENGINE_ACC); }
if( (configPage2.aeMode == AE_MODE_MAP) && (abs(currentStatus.mapDOT) > activateMAPDOT) )
{
BIT_CLEAR(currentStatus.engine, BIT_ENGINE_ACC);
BIT_CLEAR(currentStatus.engine, BIT_ENGINE_DCC);
}
else if( (configPage2.aeMode == AE_MODE_TPS) && (abs(currentStatus.tpsDOT) > activateTPSDOT) )
{
BIT_CLEAR(currentStatus.engine, BIT_ENGINE_ACC);
BIT_CLEAR(currentStatus.engine, BIT_ENGINE_DCC);
}
}
}
//else
if( !BIT_CHECK(currentStatus.engine, BIT_ENGINE_ACC) ) //Need to check this again as it may have been changed in the above section
if( !BIT_CHECK(currentStatus.engine, BIT_ENGINE_ACC) && !BIT_CHECK(currentStatus.engine, BIT_ENGINE_DCC)) //Need to check this again as it may have been changed in the above section (Both ACC and DCC are off if this has changed)
{
if(configPage2.aeMode == AE_MODE_MAP)
{
if (MAP_change <= configPage2.maeMinChange)
if (abs(MAP_change) <= configPage2.maeMinChange)
{
accelValue = 100;
currentStatus.mapDOT = 0;
@ -351,58 +355,65 @@ uint16_t correctionAccel(void)
else
{
//If MAE isn't currently turned on, need to check whether it needs to be turned on
if (MAP_rateOfChange > configPage2.maeThresh)
if (abs(currentStatus.mapDOT) > configPage2.maeThresh)
{
BIT_SET(currentStatus.engine, BIT_ENGINE_ACC); //Mark acceleration enrichment as active.
activateMAPDOT = currentStatus.mapDOT;
activateMAPDOT = abs(currentStatus.mapDOT);
currentStatus.AEEndTime = micros_safe() + ((unsigned long)configPage2.aeTime * 10000); //Set the time in the future where the enrichment will be turned off. taeTime is stored as mS / 10, so multiply it by 100 to get it in uS
accelValue = table2D_getValue(&maeTable, currentStatus.mapDOT);
//Apply the RPM taper to the above
//The RPM settings are stored divided by 100:
uint16_t trueTaperMin = configPage2.aeTaperMin * 100;
uint16_t trueTaperMax = configPage2.aeTaperMax * 100;
if (currentStatus.RPM > trueTaperMin)
//Check if the MAP rate of change is negative or positive. Negative means decelarion.
if (currentStatus.mapDOT < 0)
{
if(currentStatus.RPM > trueTaperMax) { accelValue = 0; } //RPM is beyond taper max limit, so accel enrich is turned off
else
{
int16_t taperRange = trueTaperMax - trueTaperMin;
int16_t taperPercent = ((currentStatus.RPM - trueTaperMin) * 100UL) / taperRange; //The percentage of the way through the RPM taper range
accelValue = percentage((100-taperPercent), accelValue); //Calculate the above percentage of the calculated accel amount.
}
}
//Apply AE cold coolant modifier, if CLT is less than taper end temperature
if ( currentStatus.coolant < (int)(configPage2.aeColdTaperMax - CALIBRATION_TEMPERATURE_OFFSET) )
BIT_SET(currentStatus.engine, BIT_ENGINE_DCC); //Mark deceleration enleanment as active.
accelValue = configPage2.decelAmount; //In decel, use the decel fuel amount as accelValue
} //Deceleration
//Positive MAP rate of change is acceleration.
else
{
//If CLT is less than taper min temp, apply full modifier on top of accelValue
if ( currentStatus.coolant <= (int)(configPage2.aeColdTaperMin - CALIBRATION_TEMPERATURE_OFFSET) )
BIT_SET(currentStatus.engine, BIT_ENGINE_ACC); //Mark acceleration enrichment as active.
accelValue = table2D_getValue(&maeTable, currentStatus.mapDOT / 10); //The x-axis of mae table is divided by 10 to fit values in byte.
//Apply the RPM taper to the above
//The RPM settings are stored divided by 100:
uint16_t trueTaperMin = configPage2.aeTaperMin * 100;
uint16_t trueTaperMax = configPage2.aeTaperMax * 100;
if (currentStatus.RPM > trueTaperMin)
{
uint16_t accelValue_uint = percentage(configPage2.aeColdPct, accelValue);
accelValue = (int16_t) accelValue_uint;
if(currentStatus.RPM > trueTaperMax) { accelValue = 0; } //RPM is beyond taper max limit, so accel enrich is turned off
else
{
int16_t taperRange = trueTaperMax - trueTaperMin;
int16_t taperPercent = ((currentStatus.RPM - trueTaperMin) * 100UL) / taperRange; //The percentage of the way through the RPM taper range
accelValue = percentage((100-taperPercent), accelValue); //Calculate the above percentage of the calculated accel amount.
}
}
//If CLT is between taper min and max, taper the modifier value and apply it on top of accelValue
else
//Apply AE cold coolant modifier, if CLT is less than taper end temperature
if ( currentStatus.coolant < (int)(configPage2.aeColdTaperMax - CALIBRATION_TEMPERATURE_OFFSET) )
{
int16_t taperRange = (int16_t) configPage2.aeColdTaperMax - configPage2.aeColdTaperMin;
int16_t taperPercent = (int)((currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET - configPage2.aeColdTaperMin) * 100) / taperRange;
int16_t coldPct = (int16_t) 100 + percentage( (100-taperPercent), (configPage2.aeColdPct-100) );
uint16_t accelValue_uint = (uint16_t) accelValue * coldPct / 100; //Potential overflow (if AE is large) without using uint16_t (percentage() may overflow)
accelValue = (int16_t) accelValue_uint;
//If CLT is less than taper min temp, apply full modifier on top of accelValue
if ( currentStatus.coolant <= (int)(configPage2.aeColdTaperMin - CALIBRATION_TEMPERATURE_OFFSET) )
{
uint16_t accelValue_uint = percentage(configPage2.aeColdPct, accelValue);
accelValue = (int16_t) accelValue_uint;
}
//If CLT is between taper min and max, taper the modifier value and apply it on top of accelValue
else
{
int16_t taperRange = (int16_t) configPage2.aeColdTaperMax - configPage2.aeColdTaperMin;
int16_t taperPercent = (int)((currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET - configPage2.aeColdTaperMin) * 100) / taperRange;
int16_t coldPct = (int16_t) 100 + percentage( (100-taperPercent), (configPage2.aeColdPct-100) );
uint16_t accelValue_uint = (uint16_t) accelValue * coldPct / 100; //Potential overflow (if AE is large) without using uint16_t (percentage() may overflow)
accelValue = (int16_t) accelValue_uint;
}
}
accelValue = 100 + accelValue; //In case of AE, add the 100 normalisation to the calculated amount
}
accelValue = 100 + accelValue; //Add the 100 normalisation to the calculated amount
} //MAE Threshold
}
}
} //MAP change threshold
} //AE Mode
else if(configPage2.aeMode == AE_MODE_TPS)
{
//Check for deceleration (Deceleration adjustment not yet supported)
//Also check for only very small movement. This not only means we can skip the lookup, but helps reduce false triggering around 0-2% throttle openings
if (TPS_change <= configPage2.taeMinChange)
//Check for only very small movement. This not only means we can skip the lookup, but helps reduce false triggering around 0-2% throttle openings
if (abs(TPS_change) <= configPage2.taeMinChange)
{
accelValue = 100;
currentStatus.tpsDOT = 0;
@ -410,51 +421,59 @@ uint16_t correctionAccel(void)
else
{
//If TAE isn't currently turned on, need to check whether it needs to be turned on
if (TPS_rateOfChange > configPage2.taeThresh)
if (abs(currentStatus.tpsDOT) > configPage2.taeThresh)
{
BIT_SET(currentStatus.engine, BIT_ENGINE_ACC); //Mark acceleration enrichment as active.
activateTPSDOT = currentStatus.tpsDOT;
activateTPSDOT = abs(currentStatus.tpsDOT);
currentStatus.AEEndTime = micros_safe() + ((unsigned long)configPage2.aeTime * 10000); //Set the time in the future where the enrichment will be turned off. taeTime is stored as mS / 10, so multiply it by 100 to get it in uS
accelValue = table2D_getValue(&taeTable, currentStatus.tpsDOT);
//Apply the RPM taper to the above
//The RPM settings are stored divided by 100:
uint16_t trueTaperMin = configPage2.aeTaperMin * 100;
uint16_t trueTaperMax = configPage2.aeTaperMax * 100;
if (currentStatus.RPM > trueTaperMin)
//Check if the TPS rate of change is negative or positive. Negative means decelarion.
if (currentStatus.tpsDOT < 0)
{
if(currentStatus.RPM > trueTaperMax) { accelValue = 0; } //RPM is beyond taper max limit, so accel enrich is turned off
else
{
int16_t taperRange = trueTaperMax - trueTaperMin;
int16_t taperPercent = ((currentStatus.RPM - trueTaperMin) * 100UL) / taperRange; //The percentage of the way through the RPM taper range
accelValue = percentage( (100 - taperPercent), accelValue); //Calculate the above percentage of the calculated accel amount.
}
}
//Apply AE cold coolant modifier, if CLT is less than taper end temperature
if ( currentStatus.coolant < (int)(configPage2.aeColdTaperMax - CALIBRATION_TEMPERATURE_OFFSET) )
BIT_SET(currentStatus.engine, BIT_ENGINE_DCC); //Mark deceleration enleanment as active.
accelValue = configPage2.decelAmount; //In decel, use the decel fuel amount as accelValue
} //Deceleration
//Positive TPS rate of change is Acceleration.
else
{
//If CLT is less than taper min temp, apply full modifier on top of accelValue
if ( currentStatus.coolant <= (int)(configPage2.aeColdTaperMin - CALIBRATION_TEMPERATURE_OFFSET) )
BIT_SET(currentStatus.engine, BIT_ENGINE_ACC); //Mark acceleration enrichment as active.
accelValue = table2D_getValue(&taeTable, currentStatus.tpsDOT / 10); //The x-axis of tae table is divided by 10 to fit values in byte.
//Apply the RPM taper to the above
//The RPM settings are stored divided by 100:
uint16_t trueTaperMin = configPage2.aeTaperMin * 100;
uint16_t trueTaperMax = configPage2.aeTaperMax * 100;
if (currentStatus.RPM > trueTaperMin)
{
uint16_t accelValue_uint = percentage(configPage2.aeColdPct, accelValue);
accelValue = (int16_t) accelValue_uint;
if(currentStatus.RPM > trueTaperMax) { accelValue = 0; } //RPM is beyond taper max limit, so accel enrich is turned off
else
{
int16_t taperRange = trueTaperMax - trueTaperMin;
int16_t taperPercent = ((currentStatus.RPM - trueTaperMin) * 100UL) / taperRange; //The percentage of the way through the RPM taper range
accelValue = percentage( (100 - taperPercent), accelValue); //Calculate the above percentage of the calculated accel amount.
}
}
//If CLT is between taper min and max, taper the modifier value and apply it on top of accelValue
else
//Apply AE cold coolant modifier, if CLT is less than taper end temperature
if ( currentStatus.coolant < (int)(configPage2.aeColdTaperMax - CALIBRATION_TEMPERATURE_OFFSET) )
{
int16_t taperRange = (int16_t) configPage2.aeColdTaperMax - configPage2.aeColdTaperMin;
int16_t taperPercent = (int)((currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET - configPage2.aeColdTaperMin) * 100) / taperRange;
int16_t coldPct = (int16_t)100 + percentage( (100 - taperPercent), (configPage2.aeColdPct-100) );
uint16_t accelValue_uint = (uint16_t) accelValue * coldPct / 100; //Potential overflow (if AE is large) without using uint16_t
accelValue = (int16_t) accelValue_uint;
//If CLT is less than taper min temp, apply full modifier on top of accelValue
if ( currentStatus.coolant <= (int)(configPage2.aeColdTaperMin - CALIBRATION_TEMPERATURE_OFFSET) )
{
uint16_t accelValue_uint = percentage(configPage2.aeColdPct, accelValue);
accelValue = (int16_t) accelValue_uint;
}
//If CLT is between taper min and max, taper the modifier value and apply it on top of accelValue
else
{
int16_t taperRange = (int16_t) configPage2.aeColdTaperMax - configPage2.aeColdTaperMin;
int16_t taperPercent = (int)((currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET - configPage2.aeColdTaperMin) * 100) / taperRange;
int16_t coldPct = (int16_t)100 + percentage( (100 - taperPercent), (configPage2.aeColdPct-100) );
uint16_t accelValue_uint = (uint16_t) accelValue * coldPct / 100; //Potential overflow (if AE is large) without using uint16_t
accelValue = (int16_t) accelValue_uint;
}
}
}
accelValue = 100 + accelValue; //Add the 100 normalisation to the calculated amount
accelValue = 100 + accelValue; //In case of AE, add the 100 normalisation to the calculated amount
} //Acceleration
} //TAE Threshold
} //TPS change > 2
} //TPS change threshold
} //AE Mode
} //AE active

View File

@ -655,9 +655,9 @@ struct statuses {
byte baro; ///< Barometric pressure is simply the initial MAP reading, taken before the engine is running. Alternatively, can be taken from an external sensor
byte TPS; /**< The current TPS reading (0% - 100%). Is the tpsADC value after the calibration is applied */
byte tpsADC; /**< byte (valued: 0-255) representation of the TPS. Downsampled from the original 10-bit (0-1023) reading, but before any calibration is applied */
byte tpsDOT; /**< TPS delta over time. Measures the % per second that the TPS is changing. Value is divided by 10 to be stored in a byte */
int16_t tpsDOT; /**< TPS delta over time. Measures the % per second that the TPS is changing. Note that is signed value, because TPSdot can be also negative */
byte TPSlast; /**< The previous TPS reading */
byte mapDOT; /**< MAP delta over time. Measures the kpa per second that the MAP is changing. Value is divided by 10 to be stored in a byte */
int16_t mapDOT; /**< MAP delta over time. Measures the kpa per second that the MAP is changing. Note that is signed value, because MAPdot can be also negative */
volatile int rpmDOT; /**< RPM delta over time (RPM increase / s ?) */
byte VE; /**< The current VE value being used in the fuel calculation. Can be the same as VE1 or VE2, or a calculated value of both. */
byte VE1; /**< The VE value from fuel table 1 */
@ -924,7 +924,7 @@ struct config2 {
byte enableCluster2 : 1;
byte unusedClusterBits : 4;
byte unused2_95;
byte decelAmount;
#if defined(CORE_AVR)
};

View File

@ -12,8 +12,8 @@
#include <assert.h>
#ifndef UNIT_TEST // Scope guard for unit testing
#define LOG_ENTRY_SIZE 123 /**< The size of the live data packet. This MUST match ochBlockSize setting in the ini file */
#define SD_LOG_ENTRY_SIZE 123 /**< The size of the live data packet used by the SD card.*/
#define LOG_ENTRY_SIZE 125 /**< The size of the live data packet. This MUST match ochBlockSize setting in the ini file */
#define SD_LOG_ENTRY_SIZE 125 /**< The size of the live data packet used by the SD card.*/
#else
#define LOG_ENTRY_SIZE 1 /**< The size of the live data packet. This MUST match ochBlockSize setting in the ini file */
#define SD_LOG_ENTRY_SIZE 1 /**< The size of the live data packet used by the SD card.*/
@ -31,7 +31,7 @@ bool is2ByteEntry(uint8_t key);
// This array indicates which index values from the log are 2 byte values
// This array MUST remain in ascending order
// !!!! WARNING: If any value above 255 is required in this array, changes MUST be made to is2ByteEntry() function !!!!
const byte PROGMEM fsIntIndex[] = {4, 14, 17, 25, 27, 32, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63, 65, 67, 69, 71, 75, 77, 79, 81, 85, 87, 89, 93, 97, 102, 109, 119 };
const byte PROGMEM fsIntIndex[] = {4, 14, 17, 22, 26, 28, 33, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 76, 78, 80, 82, 86, 88, 90, 93, 95, 99, 104, 111, 121 };
//List of logger field names. This must be in the same order and length as logger_updateLogdataCSV()
const char header_0[] PROGMEM = "secl";

View File

@ -40,131 +40,133 @@ byte getTSLogEntry(uint16_t byteNum)
case 19: statusValue = currentStatus.VE1; break; //VE 1 (%)
case 20: statusValue = currentStatus.VE2; break; //VE 2 (%)
case 21: statusValue = currentStatus.afrTarget; break;
case 22: statusValue = currentStatus.tpsDOT; break; //TPS DOT
case 23: statusValue = currentStatus.advance; break;
case 24: statusValue = currentStatus.TPS; break; // TPS (0% to 100%)
case 22: statusValue = lowByte(currentStatus.tpsDOT); break; //TPS DOT
case 23: statusValue = highByte(currentStatus.tpsDOT); break; //TPS DOT
case 24: statusValue = currentStatus.advance; break;
case 25: statusValue = currentStatus.TPS; break; // TPS (0% to 100%)
case 25:
case 26:
if(currentStatus.loopsPerSecond > 60000) { currentStatus.loopsPerSecond = 60000;}
statusValue = lowByte(currentStatus.loopsPerSecond);
break;
case 26:
case 27:
if(currentStatus.loopsPerSecond > 60000) { currentStatus.loopsPerSecond = 60000;}
statusValue = highByte(currentStatus.loopsPerSecond);
break;
case 27:
case 28:
currentStatus.freeRAM = freeRam();
statusValue = lowByte(currentStatus.freeRAM); //(byte)((currentStatus.loopsPerSecond >> 8) & 0xFF);
break;
case 28:
case 29:
currentStatus.freeRAM = freeRam();
statusValue = highByte(currentStatus.freeRAM);
break;
case 29: statusValue = (byte)(currentStatus.boostTarget >> 1); break; //Divide boost target by 2 to fit in a byte
case 30: statusValue = (byte)(currentStatus.boostDuty / 100); break;
case 31: statusValue = currentStatus.spark; break; //Spark related bitfield
case 30: statusValue = (byte)(currentStatus.boostTarget >> 1); break; //Divide boost target by 2 to fit in a byte
case 31: statusValue = (byte)(currentStatus.boostDuty / 100); break;
case 32: statusValue = currentStatus.spark; break; //Spark related bitfield
//rpmDOT must be sent as a signed integer
case 32: statusValue = lowByte(currentStatus.rpmDOT); break;
case 33: statusValue = highByte(currentStatus.rpmDOT); break;
case 33: statusValue = lowByte(currentStatus.rpmDOT); break;
case 34: statusValue = highByte(currentStatus.rpmDOT); break;
case 34: statusValue = currentStatus.ethanolPct; break; //Flex sensor value (or 0 if not used)
case 35: statusValue = currentStatus.flexCorrection; break; //Flex fuel correction (% above or below 100)
case 36: statusValue = currentStatus.flexIgnCorrection; break; //Ignition correction (Increased degrees of advance) for flex fuel
case 35: statusValue = currentStatus.ethanolPct; break; //Flex sensor value (or 0 if not used)
case 36: statusValue = currentStatus.flexCorrection; break; //Flex fuel correction (% above or below 100)
case 37: statusValue = currentStatus.flexIgnCorrection; break; //Ignition correction (Increased degrees of advance) for flex fuel
case 37: statusValue = currentStatus.idleLoad; break;
case 38: statusValue = currentStatus.testOutputs; break;
case 38: statusValue = currentStatus.idleLoad; break;
case 39: statusValue = currentStatus.testOutputs; break;
case 39: statusValue = currentStatus.O2_2; break; //O2
case 40: statusValue = currentStatus.baro; break; //Barometer value
case 40: statusValue = currentStatus.O2_2; break; //O2
case 41: statusValue = currentStatus.baro; break; //Barometer value
case 41: statusValue = lowByte(currentStatus.canin[0]); break;
case 42: statusValue = highByte(currentStatus.canin[0]); break;
case 43: statusValue = lowByte(currentStatus.canin[1]); break;
case 44: statusValue = highByte(currentStatus.canin[1]); break;
case 45: statusValue = lowByte(currentStatus.canin[2]); break;
case 46: statusValue = highByte(currentStatus.canin[2]); break;
case 47: statusValue = lowByte(currentStatus.canin[3]); break;
case 48: statusValue = highByte(currentStatus.canin[3]); break;
case 49: statusValue = lowByte(currentStatus.canin[4]); break;
case 50: statusValue = highByte(currentStatus.canin[4]); break;
case 51: statusValue = lowByte(currentStatus.canin[5]); break;
case 52: statusValue = highByte(currentStatus.canin[5]); break;
case 53: statusValue = lowByte(currentStatus.canin[6]); break;
case 54: statusValue = highByte(currentStatus.canin[6]); break;
case 55: statusValue = lowByte(currentStatus.canin[7]); break;
case 56: statusValue = highByte(currentStatus.canin[7]); break;
case 57: statusValue = lowByte(currentStatus.canin[8]); break;
case 58: statusValue = highByte(currentStatus.canin[8]); break;
case 59: statusValue = lowByte(currentStatus.canin[9]); break;
case 60: statusValue = highByte(currentStatus.canin[9]); break;
case 61: statusValue = lowByte(currentStatus.canin[10]); break;
case 62: statusValue = highByte(currentStatus.canin[10]); break;
case 63: statusValue = lowByte(currentStatus.canin[11]); break;
case 64: statusValue = highByte(currentStatus.canin[11]); break;
case 65: statusValue = lowByte(currentStatus.canin[12]); break;
case 66: statusValue = highByte(currentStatus.canin[12]); break;
case 67: statusValue = lowByte(currentStatus.canin[13]); break;
case 68: statusValue = highByte(currentStatus.canin[13]); break;
case 69: statusValue = lowByte(currentStatus.canin[14]); break;
case 70: statusValue = highByte(currentStatus.canin[14]); break;
case 71: statusValue = lowByte(currentStatus.canin[15]); break;
case 72: statusValue = highByte(currentStatus.canin[15]); break;
case 42: statusValue = lowByte(currentStatus.canin[0]); break;
case 43: statusValue = highByte(currentStatus.canin[0]); break;
case 44: statusValue = lowByte(currentStatus.canin[1]); break;
case 45: statusValue = highByte(currentStatus.canin[1]); break;
case 46: statusValue = lowByte(currentStatus.canin[2]); break;
case 47: statusValue = highByte(currentStatus.canin[2]); break;
case 48: statusValue = lowByte(currentStatus.canin[3]); break;
case 49: statusValue = highByte(currentStatus.canin[3]); break;
case 50: statusValue = lowByte(currentStatus.canin[4]); break;
case 51: statusValue = highByte(currentStatus.canin[4]); break;
case 52: statusValue = lowByte(currentStatus.canin[5]); break;
case 53: statusValue = highByte(currentStatus.canin[5]); break;
case 54: statusValue = lowByte(currentStatus.canin[6]); break;
case 55: statusValue = highByte(currentStatus.canin[6]); break;
case 56: statusValue = lowByte(currentStatus.canin[7]); break;
case 57: statusValue = highByte(currentStatus.canin[7]); break;
case 58: statusValue = lowByte(currentStatus.canin[8]); break;
case 59: statusValue = highByte(currentStatus.canin[8]); break;
case 60: statusValue = lowByte(currentStatus.canin[9]); break;
case 61: statusValue = highByte(currentStatus.canin[9]); break;
case 62: statusValue = lowByte(currentStatus.canin[10]); break;
case 63: statusValue = highByte(currentStatus.canin[10]); break;
case 64: statusValue = lowByte(currentStatus.canin[11]); break;
case 65: statusValue = highByte(currentStatus.canin[11]); break;
case 66: statusValue = lowByte(currentStatus.canin[12]); break;
case 67: statusValue = highByte(currentStatus.canin[12]); break;
case 68: statusValue = lowByte(currentStatus.canin[13]); break;
case 69: statusValue = highByte(currentStatus.canin[13]); break;
case 70: statusValue = lowByte(currentStatus.canin[14]); break;
case 71: statusValue = highByte(currentStatus.canin[14]); break;
case 72: statusValue = lowByte(currentStatus.canin[15]); break;
case 73: statusValue = highByte(currentStatus.canin[15]); break;
case 73: statusValue = currentStatus.tpsADC; break;
case 74: statusValue = getNextError(); break;
case 74: statusValue = currentStatus.tpsADC; break;
case 75: statusValue = getNextError(); break;
case 75: statusValue = lowByte(currentStatus.PW1); break; //Pulsewidth 1 multiplied by 10 in ms. Have to convert from uS to mS.
case 76: statusValue = highByte(currentStatus.PW1); break; //Pulsewidth 1 multiplied by 10 in ms. Have to convert from uS to mS.
case 77: statusValue = lowByte(currentStatus.PW2); break; //Pulsewidth 2 multiplied by 10 in ms. Have to convert from uS to mS.
case 78: statusValue = highByte(currentStatus.PW2); break; //Pulsewidth 2 multiplied by 10 in ms. Have to convert from uS to mS.
case 79: statusValue = lowByte(currentStatus.PW3); break; //Pulsewidth 3 multiplied by 10 in ms. Have to convert from uS to mS.
case 80: statusValue = highByte(currentStatus.PW3); break; //Pulsewidth 3 multiplied by 10 in ms. Have to convert from uS to mS.
case 81: statusValue = lowByte(currentStatus.PW4); break; //Pulsewidth 4 multiplied by 10 in ms. Have to convert from uS to mS.
case 82: statusValue = highByte(currentStatus.PW4); break; //Pulsewidth 4 multiplied by 10 in ms. Have to convert from uS to mS.
case 76: statusValue = lowByte(currentStatus.PW1); break; //Pulsewidth 1 multiplied by 10 in ms. Have to convert from uS to mS.
case 77: statusValue = highByte(currentStatus.PW1); break; //Pulsewidth 1 multiplied by 10 in ms. Have to convert from uS to mS.
case 78: statusValue = lowByte(currentStatus.PW2); break; //Pulsewidth 2 multiplied by 10 in ms. Have to convert from uS to mS.
case 79: statusValue = highByte(currentStatus.PW2); break; //Pulsewidth 2 multiplied by 10 in ms. Have to convert from uS to mS.
case 80: statusValue = lowByte(currentStatus.PW3); break; //Pulsewidth 3 multiplied by 10 in ms. Have to convert from uS to mS.
case 81: statusValue = highByte(currentStatus.PW3); break; //Pulsewidth 3 multiplied by 10 in ms. Have to convert from uS to mS.
case 82: statusValue = lowByte(currentStatus.PW4); break; //Pulsewidth 4 multiplied by 10 in ms. Have to convert from uS to mS.
case 83: statusValue = highByte(currentStatus.PW4); break; //Pulsewidth 4 multiplied by 10 in ms. Have to convert from uS to mS.
case 83: statusValue = currentStatus.status3; break;
case 84: statusValue = currentStatus.engineProtectStatus; break;
case 85: statusValue = lowByte(currentStatus.fuelLoad); break;
case 86: statusValue = highByte(currentStatus.fuelLoad); break;
case 87: statusValue = lowByte(currentStatus.ignLoad); break;
case 88: statusValue = highByte(currentStatus.ignLoad); break;
case 89: statusValue = lowByte(currentStatus.dwell); break;
case 90: statusValue = highByte(currentStatus.dwell); break;
case 91: statusValue = currentStatus.CLIdleTarget; break;
case 92: statusValue = currentStatus.mapDOT; break;
case 93: statusValue = lowByte(currentStatus.vvt1Angle); break; //2 bytes for vvt1Angle
case 94: statusValue = highByte(currentStatus.vvt1Angle); break;
case 95: statusValue = currentStatus.vvt1TargetAngle; break;
case 96: statusValue = (byte)(currentStatus.vvt1Duty); break;
case 97: statusValue = lowByte(currentStatus.flexBoostCorrection); break;
case 98: statusValue = highByte(currentStatus.flexBoostCorrection); break;
case 99: statusValue = currentStatus.baroCorrection; break;
case 100: statusValue = currentStatus.VE; break; //Current VE (%). Can be equal to VE1 or VE2 or a calculated value from both of them
case 101: statusValue = currentStatus.ASEValue; break; //Current ASE (%)
case 102: statusValue = lowByte(currentStatus.vss); break;
case 103: statusValue = highByte(currentStatus.vss); break;
case 104: statusValue = currentStatus.gear; break;
case 105: statusValue = currentStatus.fuelPressure; break;
case 106: statusValue = currentStatus.oilPressure; break;
case 107: statusValue = currentStatus.wmiPW; break;
case 108: statusValue = currentStatus.status4; break;
case 109: statusValue = lowByte(currentStatus.vvt2Angle); break; //2 bytes for vvt2Angle
case 110: statusValue = highByte(currentStatus.vvt2Angle); break;
case 111: statusValue = currentStatus.vvt2TargetAngle; break;
case 112: statusValue = (byte)(currentStatus.vvt2Duty); break;
case 113: statusValue = currentStatus.outputsStatus; break;
case 114: statusValue = (byte)(currentStatus.fuelTemp + CALIBRATION_TEMPERATURE_OFFSET); break; //Fuel temperature from flex sensor
case 115: statusValue = currentStatus.fuelTempCorrection; break; //Fuel temperature Correction (%)
case 116: statusValue = currentStatus.advance1; break; //advance 1 (%)
case 117: statusValue = currentStatus.advance2; break; //advance 2 (%)
case 118: statusValue = currentStatus.TS_SD_Status; break; //SD card status
case 119: statusValue = lowByte(currentStatus.EMAP); break; //2 bytes for EMAP
case 120: statusValue = highByte(currentStatus.EMAP); break;
case 121: statusValue = currentStatus.fanDuty; break;
case 122: statusValue = currentStatus.airConStatus; break;
case 84: statusValue = currentStatus.status3; break;
case 85: statusValue = currentStatus.engineProtectStatus; break;
case 86: statusValue = lowByte(currentStatus.fuelLoad); break;
case 87: statusValue = highByte(currentStatus.fuelLoad); break;
case 88: statusValue = lowByte(currentStatus.ignLoad); break;
case 89: statusValue = highByte(currentStatus.ignLoad); break;
case 90: statusValue = lowByte(currentStatus.dwell); break;
case 91: statusValue = highByte(currentStatus.dwell); break;
case 92: statusValue = currentStatus.CLIdleTarget; break;
case 93: statusValue = lowByte(currentStatus.mapDOT); break;
case 94: statusValue = highByte(currentStatus.mapDOT); break;
case 95: statusValue = lowByte(currentStatus.vvt1Angle); break; //2 bytes for vvt1Angle
case 96: statusValue = highByte(currentStatus.vvt1Angle); break;
case 97: statusValue = currentStatus.vvt1TargetAngle; break;
case 98: statusValue = (byte)(currentStatus.vvt1Duty); break;
case 99: statusValue = lowByte(currentStatus.flexBoostCorrection); break;
case 100: statusValue = highByte(currentStatus.flexBoostCorrection); break;
case 101: statusValue = currentStatus.baroCorrection; break;
case 102: statusValue = currentStatus.VE; break; //Current VE (%). Can be equal to VE1 or VE2 or a calculated value from both of them
case 103: statusValue = currentStatus.ASEValue; break; //Current ASE (%)
case 104: statusValue = lowByte(currentStatus.vss); break;
case 105: statusValue = highByte(currentStatus.vss); break;
case 106: statusValue = currentStatus.gear; break;
case 107: statusValue = currentStatus.fuelPressure; break;
case 108: statusValue = currentStatus.oilPressure; break;
case 109: statusValue = currentStatus.wmiPW; break;
case 110: statusValue = currentStatus.status4; break;
case 111: statusValue = lowByte(currentStatus.vvt2Angle); break; //2 bytes for vvt2Angle
case 112: statusValue = highByte(currentStatus.vvt2Angle); break;
case 113: statusValue = currentStatus.vvt2TargetAngle; break;
case 114: statusValue = (byte)(currentStatus.vvt2Duty); break;
case 115: statusValue = currentStatus.outputsStatus; break;
case 116: statusValue = (byte)(currentStatus.fuelTemp + CALIBRATION_TEMPERATURE_OFFSET); break; //Fuel temperature from flex sensor
case 117: statusValue = currentStatus.fuelTempCorrection; break; //Fuel temperature Correction (%)
case 118: statusValue = currentStatus.advance1; break; //advance 1 (%)
case 119: statusValue = currentStatus.advance2; break; //advance 2 (%)
case 120: statusValue = currentStatus.TS_SD_Status; break; //SD card status
case 121: statusValue = lowByte(currentStatus.EMAP); break; //2 bytes for EMAP
case 122: statusValue = highByte(currentStatus.EMAP); break;
case 123: statusValue = currentStatus.fanDuty; break;
case 124: statusValue = currentStatus.airConStatus; break;
}
return statusValue;

View File

@ -227,6 +227,7 @@ void loop(void)
BIT_CLEAR(currentStatus.engine, BIT_ENGINE_RUN); //Same as above except for RUNNING status
BIT_CLEAR(currentStatus.engine, BIT_ENGINE_ASE); //Same as above except for ASE status
BIT_CLEAR(currentStatus.engine, BIT_ENGINE_ACC); //Same as above but the accel enrich (If using MAP accel enrich a stall will cause this to trigger)
BIT_CLEAR(currentStatus.engine, BIT_ENGINE_DCC); //Same as above but the decel enleanment
//This is a safety check. If for some reason the interrupts have got screwed up (Leading to 0rpm), this resets them.
//It can possibly be run much less frequently.
//This should only be run if the high speed logger are off because it will change the trigger interrupts back to defaults rather than the logger versions

View File

@ -678,6 +678,16 @@ void doUpdates(void)
//202210
configPage2.taeMinChange = 4; //Default is 2% minimum change to match prior behaviour. (4 = 2% account for 0.5 resolution)
configPage2.maeMinChange = 2; //Default is 2% minimum change to match prior behaviour.
configPage2.decelAmount = 100; //Default decel fuel amount is 100%, so no change in fueling in decel as before.
//full status structure has been changed. Update programmable outputs settings to match.
for (uint8_t y = 0; y < sizeof(configPage13.outputPin); y++)
{
if ((configPage13.firstDataIn[y] > 22) && (configPage13.firstDataIn[y] < 240)) {configPage13.firstDataIn[y]++;}
if ((configPage13.firstDataIn[y] > 92) && (configPage13.firstDataIn[y] < 240)) {configPage13.firstDataIn[y]++;}
if ((configPage13.secondDataIn[y] > 22) && (configPage13.secondDataIn[y] < 240)) {configPage13.secondDataIn[y]++;}
if ((configPage13.secondDataIn[y] > 92) && (configPage13.secondDataIn[y] < 240)) {configPage13.secondDataIn[y]++;}
}
//AC Control (configPage15)
//Set A/C default values - these line up with the ini file defaults