VVT2 addition and closed loop VVT improvement (#551)

* VVT2 and closed loop VVT improvement

* Fix building for latest changes

* Fix CRC error

Co-authored-by: Josh Stewart <josh@noisymime.org>
This commit is contained in:
Pasi Kemppainen 2021-04-22 01:56:39 +03:00 committed by GitHub
parent 1f47f8dcd6
commit 982e52db1b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 451 additions and 216 deletions

View File

@ -539,7 +539,12 @@ page = 4
engineProtectMaxRPM = scalar, U08, 120, "rpm", 100, 0.0, 100, 25500, 0
unused4-120 = array, U08, 121, [7], "%", 1.0, 0.0, 0.0, 255, 0
vvt2CL0DutyAng = scalar, S16, 121, "deg", 1.0, 0.0, -360.0, 360.0, 0 ; * ( 2 bytes)
vvt2PWMdir = bits, U08, 123, [0:0], "Advance", "Retard"
unusedBits4-123 = bits, U08, 123, [1:7],
ANGLEFILTER_VVT = scalar, U08, 124, "%", 1.0, 0.0, 0, 100, 0
unused4-124 = array, U08, 125, [3], "%", 1.0, 0.0, 0.0, 255, 0
;--------------------------------------------------
;Start AFR page
@ -590,7 +595,7 @@ page = 6
useExtBaro = bits, U08, 13, [6:6], "No", "Yes"
boostMode = bits, U08, 13, [7:7], "Simple", "Full"
boostPin = bits, U08, 14, [0:5], "Board Default", "INVALID", "INVALID", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "50", "51", "52", "53", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID"
VVTasOnOff = bits, U08, 14, [6:6], "No", "Yes"
unused_bit = bits, U08, 14, [6:6], "No", "Yes"
useEMAP = bits, U08, 14, [7:7], "No", "Yes"
brvBins = array, U08, 15, [6], "V", 0.1, 0, 6, 24, 1 ; Bins for the battery reference voltage
injBatRates = array, U08, 21, [6], "%", 1, 0, 0, 255, 0 ;Values for injector pulsewidth vs voltage
@ -691,7 +696,7 @@ page = 7
boostTable = array, U08, 0,[8x8], { bitStringValue( boostTableLabels, boostType ) }, 2.0, 0.0, 0, boostTableLimit, 0
rpmBinsBoost = array, U08, 64,[ 8], "RPM", 100.0, 0.0, 100, 25500, 0
tpsBinsBoost = array, U08, 72,[ 8], "TPS", 1.0, 0.0, 0.0, 255.0, 0
vvtTable = array, U08, 80,[8x8], "%", 1.0, 0.0, 0, 100, 0
vvtTable = array, U08, 80,[8x8], "%", 0.5, 0.0, 0, 100, 1
rpmBinsVVT = array, U08, 144,[ 8], "RPM", 100.0, 0.0, 100, 25500, 0
loadBinsVVT = array, U08, 152,[ 8], { bitStringValue(algorithmUnits , vvtLoadSource) }, 1.0, 0.0, 0.0, 255.0, 0
;Fuel staging Table
@ -1070,12 +1075,13 @@ page = 10
fuel2InputPullup = bits , U08, 125, [7:7], "No", "Yes"
;All related to the closed loop VVT control
vvtCLholdDuty = scalar, U08, 126, "%", 1.0, 0.0, 0.0, 100.0, 0
vvtCLKP = scalar, U08, 127, "%", 0.03125, 0.0, 0.0, 7.96, 2 ; * ( 1 byte)
vvtCLKI = scalar, U08, 128, "%", 0.03125, 0.0, 0.0, 7.96, 2 ; * ( 1 byte)
vvtCLKD = scalar, U08, 129, "%", 0.00781, 0.0, 0.0, 1.99, 3 ; * ( 1 byte)
vvtCLMinAng = scalar, S16, 130, "deg", 1.0, 0.0, -360.0, 360.0, 0 ; * ( 2 bytes)
vvtCLMaxAng = scalar, S16, 132, "deg", 1.0, 0.0, -360.0, 360.0, 0 ; * ( 2 bytes)
vvtCLholdDuty = scalar, U08, 126, "%", 0.5, 0.0, 0.0, 100.0, 1
vvtCLKP = scalar, U08, 127, "%", 0.03125, 0.0, 0.0, 7.96, 2 ; * ( 1 byte)
vvtCLKI = scalar, U08, 128, "%", 0.03125, 0.0, 0.0, 7.96, 2 ; * ( 1 byte)
vvtCLKD = scalar, U08, 129, "%", 0.00781, 0.0, 0.0, 1.99, 3 ; * ( 1 byte)
vvtCL0DutyAng = scalar, S16, 130, "deg", 1.0, 0.0, -360.0, 360.0, 0 ; * ( 2 bytes)
vvtCLMinAng = scalar, U08, 132, "deg", 0.5, 0.0, 0.0, 100.0, 0 ; * ( 1 byte)
vvtCLMaxAng = scalar, U08, 133, "deg", 0.5, 0.0, 0.0, 100.0, 0 ; * ( 1 byte)
crankingEnrichTaper = scalar, U08, 134, "s", 0.1, 0.0, 0.0, 25.5, 1
@ -1125,9 +1131,12 @@ page = 10
wmiAdvBins = array, U08, 159, [6], "kPa", 2.0, 0.0, 0.0, 511.0, 0
wmiAdvAdj = array, U08, 165, [6], "Deg", 1.0, -40, -40, 215.0, 0
vvtCLminDuty = scalar, U08, 171, "%", 1.0, 0.0, 0.0, 100.0, 0 ; Minimum and maximum duty cycles when using closed loop
vvtCLmaxDuty = scalar, U08, 172, "%", 1.0, 0.0, 0.0, 100.0, 0
vvtCLminDuty = scalar, U08, 171, "%", 0.5, 0.0, 0.0, 100.0, 1 ; Minimum and maximum duty cycles when using closed loop
vvtCLmaxDuty = scalar, U08, 172, "%", 0.5, 0.0, 0.0, 100.0, 1
vvt2Pin = bits , U08, 173, [0:5], "Board Default", "INVALID", "INVALID", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "50", "51", "52", "53", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID"
vvt2Enabled = bits, U08, 173, [6:6], "Off", "On"
TrigEdgeThrd = bits, U08, 173, [7:7], "RISING", "FALLING"
;Fuel temperature correction
#if CELSIUS
@ -1159,16 +1168,18 @@ page = 11
;--------------------------------------------------
;Water methanol inejction maps (Page 12)
;Water methanol inejction and vvt2 maps (Page 12)
;--------------------------------------------------
page = 12
wmiTable = array, U08, 0,[8x8], "%", 1.0, 0.0, 0.0, 255.0, 0
wmiTable = array, U08, 0,[8x8], "%", 1.0, 0.0, 0.0, 255.0, 0
rpmBinsWMI = array, U08, 64,[ 8], "RPM", 100.0, 0.0, 100, 25500, 0
mapBinsWMI = array, U08, 72,[ 8], "kPa", 2.0, 0.0, 0.0, 511.0, 0
;VVT2 map should be here in the middle
dwellTable = array, U08, 160,[4x4], "ms", 0.1, 0.0, 0.1, 8.0, 1
mapBinsWMI = array, U08, 72,[ 8], "kPa", 2.0, 0.0, 0.0, 511.0, 0
vvt2Table = array, U08, 80,[8x8], "%", 0.5, 0.0, 0, 100, 1
rpmBinsVVT2 = array, U08, 144,[ 8], "RPM", 100.0, 0.0, 100, 25500, 0
loadBinsVVT2 = array, U08, 152,[ 8], { bitStringValue(algorithmUnits , vvtLoadSource) }, 1.0, 0.0, 0.0, 255.0, 0
dwellTable = array, U08, 160,[4x4], "ms", 0.1, 0.0, 0.1, 8.0, 1
rpmBinsDwell = array, U08, 176,[ 4], "RPM", 100.0, 0.0, 100, 25500, 0
mapBinsDwell = array, U08, 180,[ 4], "kPa", 2.0, 0.0, 0.0, 511.0, 0
mapBinsDwell = array, U08, 180,[ 4], "kPa", 2.0, 0.0, 0.0, 511.0, 0
;Page 13 is the programmable outputs
page = 13
@ -1247,8 +1258,6 @@ page = 14
rpmBins3 = array, U08, 256,[ 16], "RPM", 100.0, 0.0, 100, 25500, 0
mapBins2 = array, U08, 272, [ 16], { bitStringValue(algorithmUnits , spark2Algorithm) }, 2.0, 0.0, 0.0, { ign2LoadMax }, 0 ; This name has to be used in order for the table to show up in MLVs table. I can't find the regexs that make this work :(
;-------------------------------------------------------------------------------
[EventTriggers]
@ -1395,7 +1404,6 @@ page = 14
defaultValue = speeduino_tsCanId, 0
defaultValue = true_address, 256
defaultValue = realtime_base_address, 336
defaultValue = VVTasOnOff, 0
defaultValue = stagingEnabled, 0
defaultValue = lnchCtrlTPS, 0
defaultValue = resetControl, 0
@ -1421,10 +1429,14 @@ page = 14
defaultValue = primingDelay, 0.5
defaultValue = vvtCLminDuty, 0
defaultValue = vvtCLmaxDuty, 80 ;80% is a completely arbitrary amount for the max duty cycle, but seems inline with most VVT documentation
defaultValue = vvtCL0DutyAng, 0
defaultValue = vvt2CL0DutyAng, 0
defaultValue = ANGLEFILTER_VVT, 0
;Default pins
defaultValue = fanPin, 0
defaultValue = vvt1Pin, 0
defaultValue = vvt2Pin, 0
defaultValue = launchPin, 0
defaultValue = boostPin, 0
defaultValue = fuelPumpPin, 0
@ -1639,6 +1651,7 @@ menuDialog = main
subMenu = std_separator
subMenu = vvtSettings, "VVT Control"
subMenu = vvtTbl, "VVT duty cycle", 8, { vvtEnabled }
subMenu = vvt2Tbl, "VVT2 duty cycle", 8, { vvtEnabled && vvt2Enabled }
subMenu = std_separator
subMenu = wmiSettings, "WMI Control", { !vvtEnabled }
subMenu = wmiTbl, "WMI duty cycle", 8, { !vvtEnabled && wmiEnabled && wmiMode > 1 }
@ -2027,7 +2040,15 @@ menuDialog = main
ADCFILTER_BARO = "This setting is only available when using an external Baro sensor. Recommended value: 64"
boostIntv = "The closed loop control interval will run every this many ms. Generally values between 50% and 100% of the valve frequency work best"
VVTasOnOff = "Whether or not the VVT table should be treated as on and off control only. If you are using the VVT map to control a switch, this should be Yes. If you are using the VVT control to drive a PWM signal, this should be No"
vvtMode = "Selects method of VVT control.\nOn/Off = No PWM control and output is only on or off.\nOpen Loop = PWM control where duty is taken directly from VVT table.\nClosed Loop = PWM control where VVT table is Cam angle target map and output duty is PID controlled."
vvt2Enabled = "Secondary VVT output. Uses same frequency and control algorithm as primary VVT output."
vvtPWMdir = "This is used to invert VVT closed loop PID direction if needed."
vvt2PWMdir = "This is used to invert VVT2 closed loop PID direction if needed."
vvtCL0DutyAng = "This value is used to bring the VVT cam angle to 0-100 range in closed loop mode by subtracting this value from the raw cam angle reading."
vvt2CL0DutyAng = "This value is used to bring the VVT2 cam angle to 0-100 range in closed loop mode by subtracting this value from the raw cam angle reading."
vvtCLMinAng = "Safety limit for minimum expected cam angle value. If cam angle gets smaller or equal to this, it triggers VVT error state, closed loop adjustment is disabled and VVT output duty drops to 0%"
vvtCLMaxAng = "Safety limit for maximum expected cam angle value. If cam angle gets bigger than this, it triggers VVT error state, closed loop adjustment is disabled and VVT output duty drops to 0%"
ANGLEFILTER_VVT = "Can be used to smooth out cam angle readings if needed. Only supported on specific decoders that have cam angle reading capability"
stagedInjSizePri= "Size of the primary injectors. The sum of the Pri and Sec injectors values MUST match the value used in the req_fuel calculation"
stagedInjSizeSec= "Size of the secondary injectors. The sum of the Pri and Sec injectors values MUST match the value used in the req_fuel calculation"
@ -2758,11 +2779,21 @@ menuDialog = main
field = "I", boostKI, { boostEnabled && boostMode && boostType == 1 }
field = "D", boostKD, { boostEnabled && boostMode && boostType == 1 }
dialog = vvt2, "Second VVT output"
field = "VVT2 Control Enabled", vvt2Enabled
field = "VVT2 output pin", vvt2Pin, { vvt2Enabled }
field = "Increased duty direction",vvt2PWMdir, { vvt2Enabled && vvtMode == 2 }
field = "VVT2 Cam angle @ 0% duty",vvt2CL0DutyAng { vvt2Enabled && vvtMode == 2 }
field = "VVT2 Trigger edge", TrigEdgeThrd, { vvt2Enabled && vvtMode == 2 }
dialog = vvtClosedLoop, "Closed loop"
field = "Increased duty direction", vvtPWMdir
field = "Hold duty used", vvtCLUseHold
field = "Hold duty", vvtCLholdDuty, { vvtCLUseHold }
field = "Adjust fuel timing", vvtCLAlterFuelTiming
field = "Cam angle @ 0% duty", vvtCLMinAng
field = "Cam angle @ 0% duty", vvtCL0DutyAng
field = "Minimum Cam angle", vvtCLMinAng
field = "Maximum Cam angle", vvtCLMaxAng
field = ""
field = "Proportional Gain", vvtCLKP
field = "Integral Gain", vvtCLKI
@ -2774,13 +2805,13 @@ menuDialog = main
dialog = vvtSettings, "VVT Control"
field = "VVT Control Enabled", vvtEnabled
field = "VVT Mode", vvtMode, { vvtEnabled }
field = "#Please note that close loop is currently experimental for Miata patterns ONLY"
field = "#Please note that closed loop is currently experimental for Miata and missing tooth patterns ONLY"
field = "Load source", vvtLoadSource, { vvtEnabled }
field = "Use VVT map as On / Off only", VVTasOnOff, { vvtEnabled && vvtMode != 2 }
field = "VVT output pin", vvt1Pin, { vvtEnabled }
field = "VVT solenoid freq.", vvtFreq, { vvtEnabled }
field = "Increased duty direction", vvtPWMdir, { vvtEnabled }
slider = "VVT angle filter ", ANGLEFILTER_VVT,horizontal, { vvtEnabled }
panel = vvtClosedLoop, { vvtEnabled && vvtMode == 2 }
panel = vvt2, { vvtEnabled }
dialog = wmiSettings, "WMI Control"
field = "#Experimental!"
@ -4303,6 +4334,15 @@ cmdVSSratio6 = "E\x99\x06"
gridHeight = 3.0
upDownLabel = "HIGHER", "LOWER"
table = vvt2Tbl, vvt2Map, "VVT2 control Table", 8
xBins = rpmBinsVVT2, rpm
;yBins = tpsBinsVVT, throttle
yBins = loadBinsVVT2, vvtLoad
zBins = vvt2Table
xyLabels = "RPM", "VVT Load: "
gridHeight = 3.0
upDownLabel = "HIGHER", "LOWER"
table = wmiTbl, wmiMapMap, "WMI control Table", 8
xBins = rpmBinsWMI, rpm
yBins = mapBinsWMI, map
@ -4457,12 +4497,12 @@ cmdVSSratio6 = "E\x99\x06"
lambdaTargetGauge = lambdaTarget, "Target Lambda", "", 0.5, 1.5, 0.82, 0.89, 1.02, 1.09, 3, 3
IdleTargetGauge = CLIdleTarget, "Idle Target RPM", "RPM", 0, 2000, 300, 600, 1500, 1700, 0, 0
idleLoadGauge = idleLoad, "IAC Value", "%/Steps", 0, {maphigh}, 0, 20, {mapwarn}, {mapdang}, 0, 0
vvt1DutyCycleGauge= vvt1Duty, "VVT Duty Cycle", "%", 0, 100, -1, -1, 101, 110, 1, 1
vvt1TargetGauge = vvt1Target, "VVT Target Angle", "deg", 0, 100, 15, 25, 65, 75, 0, 0
vvt1AngleGauge = vvt1Angle, "VVT Angle", "deg", -20, 100, 0, -5, 70, 90, 0, 0
vvt2DutyCycleGauge= vvt2Duty, "VVT Duty Cycle", "%", 0, 100, -1, -1, 101, 110, 1, 1
vvt2TargetGauge = vvt2Target, "VVT Target Angle", "deg", 0, 100, 15, 25, 65, 75, 0, 0
vvt2AngleGauge = vvt2Angle, "VVT Angle", "deg", -20, 100, 0, -5, 70, 90, 0, 0
vvt1DutyCycleGauge= vvt1Duty, "VVT Duty Cycle", "%", 0, 100, -1, -1, 101, 110, 1, 1
vvt1TargetGauge = vvt1Target, "VVT Target Angle", "deg", 0, 100, 15, 25, 65, 75, 1, 1
vvt1AngleGauge = vvt1Angle, "VVT Angle", "deg", -20, 100, 0, -5, 70, 90, 1, 1
vvt2DutyCycleGauge= vvt2Duty, "VVT2 Duty Cycle", "%", 0, 100, -1, -1, 101, 110, 1, 1
vvt2TargetGauge = vvt2Target, "VVT2 Target Angle", "deg", 0, 100, 15, 25, 65, 75, 1, 1
vvt2AngleGauge = vvt2Angle, "VVT2 Angle", "deg", -20, 100, 0, -5, 70, 90, 1, 1
WMIdutyCycleGauge = wmiPW, "WMI Duty Cycle", "%", 0, 100, -1, -1, 101, 110, 1, 1
@ -4574,6 +4614,8 @@ cmdVSSratio6 = "E\x99\x06"
indicator = { engineProtectOil }, "Oil Pres. Protect OFF","Oil Pres. Protect ON",white, black, red, black
indicator = { engineProtectAFR }, "AFR Protect OFF", "AFR Protect ON", white, black, red, black
indicator = { wmiEmptyBit }, "WMI Tank NOT Empty", "WMI Tank Empty", white, black, red, black
indicator = { vvt1Error }, "VVT1 Ok", "VVT1 Error", white, black, red, black
indicator = { vvt2Error }, "VVT2 Ok", "VVT2 Error", white, black, red, black
indicator = { outputsStatus0 }, "Programmable out 1 Off", "Programmable out 1 ON", white, black, green, black
indicator = { outputsStatus1 }, "Programmable out 2 Off", "Programmable out 2 ON", white, black, green, black
indicator = { outputsStatus2 }, "Programmable out 3 Off", "Programmable out 3 ON", white, black, green, black
@ -4592,7 +4634,7 @@ cmdVSSratio6 = "E\x99\x06"
; you change it.
ochGetCommand = "r\$tsCanId\x30%2o%2c"
ochBlockSize = 117
ochBlockSize = 119
secl = scalar, U08, 0, "sec", 1.000, 0.000
status1 = scalar, U08, 1, "bits", 1.000, 0.000
@ -4699,36 +4741,39 @@ cmdVSSratio6 = "E\x99\x06"
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, S08, 93, "deg", 1.00, 0.000
vvt1Target = scalar, U08, 94, "deg", 1.00, 0.000
vvt1Duty = scalar, U08, 95, "%", 1.00, 0.000
flexBoostCor = scalar, S16, 96, "kPa", 1.000, 0.000
baroCorrection = scalar, U08, 98, "%", 1.000, 0.000
veCurr = scalar, U08, 99, "%", 1.000, 0.000
ASECurr = scalar, U08, 100, "%", 1.000, 0.000
vss = scalar, U16, 101, "km/h", 1.000, 0.000
gear = scalar, U08, 103, "", 1.000, 0.000
fuelPressure = scalar, U08, 104, "PSI", 1.000, 0.000
oilPressure = scalar, U08, 105, "PSI", 1.000, 0.000
wmiPW = scalar, U08, 106, "%", 1.000, 0.000
wmiEmpty = scalar, U08, 107, "bits", 1.000, 0.000
wmiEmptyBit = bits, U08, 107, [0:0]
vvt2Angle = scalar, S08, 108, "deg", 1.00, 0.000
vvt2Target = scalar, U08, 109, "deg", 1.00, 0.000
vvt2Duty = scalar, U08, 110, "%", 1.00, 0.000
outputsStatus0 = bits, U08, 111, [0:0]
outputsStatus1 = bits, U08, 111, [1:1]
outputsStatus2 = bits, U08, 111, [2:2]
outputsStatus3 = bits, U08, 111, [3:3]
outputsStatus4 = bits, U08, 111, [4:4]
outputsStatus5 = bits, U08, 111, [5:5]
outputsStatus6 = bits, U08, 111, [6:6]
outputsStatus7 = bits, U08, 111, [7:7]
fuelTempRaw = scalar, U08, 112, "°C", 1.000, 0.000
fuelTempCor = scalar, U08, 113, "%", 1.000, 0.000
advance1 = scalar, S08, 114, "deg", 1.000, 0.000
advance2 = scalar, S08, 115, "deg", 1.000, 0.000
sd_status = scalar, U08, 116, "", 1.0, 0.0
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]
UnusedBits4 = bits, U08, 108, [3: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
;sd_filenum = scalar, U16, 117, "", 1, 0
;sd_error = scalar, U08, 119, "", 1, 0
;sd_phase = scalar, U08, 120, "", 1, 0
@ -4865,17 +4910,17 @@ cmdVSSratio6 = "E\x99\x06"
entry = baro, "Baro Pressure", int, "%d"
entry = nitrousOn, "Nitrous", int, "%d", { n2o_enable > 0 }
entry = syncLossCounter, "Sync Loss #", int, "%d"
entry = vvt1Angle, "VVT Angle", int, "%d", { vvtMode == 2 } ;;Only show when using close loop vvt
entry = vvt1Target, "VVT Target Angle", int, "%d", { vvtMode == 2 } ;;Only show when using close loop vvt
entry = vvt1Duty, "VVT Duty", int, "%d", { vvtEnabled > 0 }
entry = vvt1Angle, "VVT1 Angle", int, "%.1f", { vvtEnabled > 0 }
entry = vvt1Target, "VVT1 Target Angle",int, "%.1f", { vvtEnabled > 0 && vvtMode == 2 } ;;Only show when using close loop vvt
entry = vvt1Duty, "VVT1 Duty", int, "%.1f", { vvtEnabled > 0 }
entry = vss, "Wheel Speed (kph)",int, "%d", { vssMode > 1 }
entry = vssMPH, "Wheel Speed (mph)",int, "%d", { vssMode > 1 }
entry = gear, "Gear", int, "%d", { vssMode > 1 }
entry = fuelPressure, "Fuel Pressure", int, "%d", { fuelPressureEnable > 0 }
entry = oilPressure, "Oil Pressure", int, "%d", { oilPressureEnable > 0 }
entry = vvt2Angle, "VVT Angle", int, "%d", { vvtMode == 2 } ;;Only show when using close loop vvt
entry = vvt2Target, "VVT Target Angle",int, "%d", { vvtMode == 2 } ;;Only show when using close loop vvt
entry = vvt2Duty, "VVT Duty", int, "%d", { vvtEnabled > 0 }
entry = vvt2Angle, "VVT2 Angle", int, "%.1f", { vvt2Enabled > 0 }
entry = vvt2Target, "VVT2 Target Angle",int, "%.1f", { vvt2Enabled > 0 && vvtMode == 2 } ;;Only show when using close loop vvt
entry = vvt2Duty, "VVT2 Duty", int, "%.1f", { vvt2Enabled > 0 && vvtMode == 2 }
entry = auxin_gauge0, { stringValue(AUXin00Alias) }, int, "%d", {(caninput_sel0b != 0)}
entry = auxin_gauge1, { stringValue(AUXin01Alias) }, int, "%d", { (caninput_sel1b != 0)}

View File

@ -23,12 +23,10 @@ void wmiControl();
#define VVT1_PIN_HIGH() *vvt1_pin_port |= (vvt1_pin_mask)
#define VVT2_PIN_LOW() *vvt2_pin_port &= ~(vvt2_pin_mask)
#define VVT2_PIN_HIGH() *vvt2_pin_port |= (vvt2_pin_mask)
#define VVT1_PIN_ON() if (configPage6.vvtPWMdir == 0) { VVT1_PIN_HIGH(); } else { VVT1_PIN_LOW(); }
#define VVT1_PIN_OFF() if (configPage6.vvtPWMdir == 0) { VVT1_PIN_LOW() ; } else { VVT1_PIN_HIGH(); }
//#define VVT2_PIN_ON() if (configPage6.vvtPWMdir == 0) { VVT2_PIN_HIGH(); } else { VVT2_PIN_LOW(); }
//#define VVT2_PIN_OFF() if (configPage6.vvtPWMdir == 0) { VVT2_PIN_LOW() ; } else { VVT2_PIN_HIGH(); }
#define VVT2_PIN_ON() {} //Disabled as VVT2 not yet complete
#define VVT2_PIN_OFF() {} //Disabled as VVT2 not yet complete
#define VVT1_PIN_ON() VVT1_PIN_HIGH();
#define VVT1_PIN_OFF() VVT1_PIN_LOW();
#define VVT2_PIN_ON() VVT2_PIN_HIGH();
#define VVT2_PIN_OFF() VVT2_PIN_LOW();
#define FAN_PIN_LOW() *fan_pin_port &= ~(fan_pin_mask)
#define FAN_PIN_HIGH() *fan_pin_port |= (fan_pin_mask)
#define N2O_STAGE1_PIN_LOW() *n2o_stage1_pin_port &= ~(n2o_stage1_pin_mask)
@ -40,7 +38,7 @@ void wmiControl();
#define FAN_ON() ((configPage6.fanInv) ? FAN_PIN_LOW() : FAN_PIN_HIGH())
#define FAN_OFF() ((configPage6.fanInv) ? FAN_PIN_HIGH() : FAN_PIN_LOW())
#define WMI_TANK_IS_EMPTY() ((configPage10.wmiEmptyEnabled) ? ((configPage10.wmiEmptyPolarity) ? !digitalRead(pinWMIEmpty) : digitalRead(pinWMIEmpty)) : 0)
#define WMI_TANK_IS_EMPTY() ((configPage10.wmiEmptyEnabled) ? ((configPage10.wmiEmptyPolarity) ? digitalRead(pinWMIEmpty) : !digitalRead(pinWMIEmpty)) : 0)
volatile PORT_TYPE *boost_pin_port;
volatile PINMASK_TYPE boost_pin_mask;
@ -79,6 +77,9 @@ volatile unsigned int vvt2_pwm_cur_value;
long vvt1_pwm_value;
long vvt2_pwm_value;
long vvt_pid_target_angle;
long vvt2_pid_target_angle;
long vvt_pid_current_angle;
long vvt2_pid_current_angle;
void boostInterrupt();
void vvtInterrupt();

View File

@ -12,7 +12,9 @@ A full copy of the license may be found in the projects root directory
//Old PID method. Retained incase the new one has issues
//integerPID boostPID(&MAPx100, &boost_pwm_target_value, &boostTargetx100, configPage6.boostKP, configPage6.boostKI, configPage6.boostKD, DIRECT);
integerPID_ideal boostPID(&currentStatus.MAP, &currentStatus.boostDuty , &currentStatus.boostTarget, &configPage10.boostSens, &configPage10.boostIntv, configPage6.boostKP, configPage6.boostKI, configPage6.boostKD, DIRECT); //This is the PID object if that algorithm is used. Needs to be global as it maintains state outside of each function call
integerPID vvtPID(&currentStatus.vvt1Angle, &vvt1_pwm_value, &vvt_pid_target_angle, configPage10.vvtCLKP, configPage10.vvtCLKI, configPage10.vvtCLKD, DIRECT); //This is the PID object if that algorithm is used. Needs to be global as it maintains state outside of each function call
integerPID vvtPID(&vvt_pid_current_angle, &currentStatus.vvt1Duty, &vvt_pid_target_angle, configPage10.vvtCLKP, configPage10.vvtCLKI, configPage10.vvtCLKD, configPage6.vvtPWMdir); //This is the PID object if that algorithm is used. Needs to be global as it maintains state outside of each function call
integerPID vvt2PID(&vvt2_pid_current_angle, &currentStatus.vvt2Duty, &vvt2_pid_target_angle, configPage10.vvtCLKP, configPage10.vvtCLKI, configPage10.vvtCLKD, configPage4.vvt2PWMdir); //This is the PID object if that algorithm is used. Needs to be global as it maintains state outside of each function call
/*
Fan control
@ -105,10 +107,17 @@ void initialiseAuxPWM()
if(configPage6.vvtMode == VVT_MODE_CLOSED_LOOP)
{
vvtPID.SetOutputLimits(percentage(configPage10.vvtCLminDuty, vvt_pwm_max_count), percentage(configPage10.vvtCLmaxDuty, vvt_pwm_max_count));
vvtPID.SetOutputLimits( (configPage10.vvtCLminDuty), (configPage10.vvtCLmaxDuty) );
vvtPID.SetTunings(configPage10.vvtCLKP, configPage10.vvtCLKI, configPage10.vvtCLKD);
vvtPID.SetSampleTime(33); //30Hz is 33,33ms
vvtPID.SetMode(AUTOMATIC); //Turn PID on
if (configPage10.vvt2Enabled == 1) // same for VVT2 if it's enabled
{
vvt2PID.SetOutputLimits( (configPage10.vvtCLminDuty), (configPage10.vvtCLmaxDuty) );
vvt2PID.SetTunings(configPage10.vvtCLKP, configPage10.vvtCLKI, configPage10.vvtCLKD);
vvt2PID.SetSampleTime(33); //30Hz is 33,33ms
vvt2PID.SetMode(AUTOMATIC); //Turn PID on
}
}
currentStatus.vvt1Duty = 0;
@ -116,6 +125,8 @@ void initialiseAuxPWM()
currentStatus.vvt2Duty = 0;
vvt2_pwm_value = 0;
ENABLE_VVT_TIMER(); //Turn on the B compare unit (ie turn on the interrupt)
BIT_CLEAR(currentStatus.status4, BIT_STATUS4_VVT1_ERROR);
BIT_CLEAR(currentStatus.status4, BIT_STATUS4_VVT2_ERROR);
}
if( (configPage6.vvtEnabled == 0) && (configPage10.wmiEnabled >= 1) )
{
@ -125,7 +136,7 @@ void initialiseAuxPWM()
#elif defined(CORE_TEENSY)
vvt_pwm_max_count = 1000000L / (32 * configPage6.vvtFreq * 2); //Converts the frequency in Hz to the number of ticks (at 16uS) it takes to complete 1 cycle. Note that the frequency is divided by 2 coming from TS to allow for up to 512hz
#endif
currentStatus.wmiEmpty = 0;
BIT_CLEAR(currentStatus.status4, BIT_STATUS4_WMI_EMPTY);
currentStatus.wmiPW = 0;
vvt1_pwm_value = 0;
ENABLE_VVT_TIMER(); //Turn on the B compare unit (ie turn on the interrupt)
@ -220,7 +231,7 @@ void boostControl()
void vvtControl()
{
if( (configPage6.vvtEnabled == 1) && (currentStatus.RPM > 0) )
if( (configPage6.vvtEnabled == 1) && (BIT_CHECK(currentStatus.engine, BIT_ENGINE_RUN)) )
{
//currentStatus.vvt1Duty = 0;
//Calculate the current cam angle
@ -233,10 +244,21 @@ void vvtControl()
else { currentStatus.vvt1Duty = get3DTableValue(&vvtTable, currentStatus.MAP, currentStatus.RPM); }
//VVT table can be used for controlling on/off switching. If this is turned on, then disregard any interpolation or non-binary values
if( (configPage6.VVTasOnOff == true) && (currentStatus.vvt1Duty < 100) ) { currentStatus.vvt1Duty = 0; }
if( (configPage6.vvtMode == VVT_MODE_ONOFF) && (currentStatus.vvt1Duty < 200) ) { currentStatus.vvt1Duty = 0; }
vvt1_pwm_value = percentage(currentStatus.vvt1Duty, vvt_pwm_max_count);
if(currentStatus.vvt1Duty > 0) { ENABLE_VVT_TIMER(); }
vvt1_pwm_value = halfpercentage(currentStatus.vvt1Duty, vvt_pwm_max_count);
if (configPage10.vvt2Enabled == 1) // same for VVT2 if it's enabled
{
//Lookup VVT duty based on either MAP or TPS
if(configPage6.vvtLoadSource == VVT_LOAD_TPS) { currentStatus.vvt2Duty = get3DTableValue(&vvt2Table, currentStatus.TPS, currentStatus.RPM); }
else { currentStatus.vvt2Duty = get3DTableValue(&vvt2Table, currentStatus.MAP, currentStatus.RPM); }
//VVT table can be used for controlling on/off switching. If this is turned on, then disregard any interpolation or non-binary values
if( (configPage6.vvtMode == VVT_MODE_ONOFF) && (currentStatus.vvt2Duty < 200) ) { currentStatus.vvt2Duty = 0; }
vvt2_pwm_value = halfpercentage(currentStatus.vvt2Duty, vvt_pwm_max_count);
}
} //Open loop
else if( (configPage6.vvtMode == VVT_MODE_CLOSED_LOOP) )
@ -245,38 +267,79 @@ void vvtControl()
if(configPage6.vvtLoadSource == VVT_LOAD_TPS) { currentStatus.vvt1TargetAngle = get3DTableValue(&vvtTable, currentStatus.TPS, currentStatus.RPM); }
else { currentStatus.vvt1TargetAngle = get3DTableValue(&vvtTable, currentStatus.MAP, currentStatus.RPM); }
if( (vvtCounter & 31) == 1) { vvtPID.SetTunings(configPage10.vvtCLKP, configPage10.vvtCLKI, configPage10.vvtCLKD); } //This only needs to be run very infrequently, once every 32 calls to vvtControl(). This is approx. once per second
if( (vvtCounter & 31) == 1) { vvtPID.SetTunings(configPage10.vvtCLKP, configPage10.vvtCLKI, configPage10.vvtCLKD); //This only needs to be run very infrequently, once every 32 calls to vvtControl(). This is approx. once per second
vvtPID.SetControllerDirection(configPage6.vvtPWMdir); }
// safety check that the cam angles are ok. The engine will be totally undriveable if the cam sensor is faulty and giving wrong cam angles, so if that happens, default to 0 duty.
// This also prevents using zero or negative current angle values for PID adjustment, because those don't work in integer PID.
if ( currentStatus.vvt1Angle <= configPage10.vvtCLMinAng || currentStatus.vvt1Angle > configPage10.vvtCLMaxAng )
{
currentStatus.vvt1Duty = 0;
vvt1_pwm_value = halfpercentage(currentStatus.vvt1Duty, vvt_pwm_max_count);
BIT_SET(currentStatus.status4, BIT_STATUS4_VVT1_ERROR);
}
//Check that we're not already at the angle we want to be
if((configPage6.vvtCLUseHold > 0) && (currentStatus.vvt1TargetAngle == currentStatus.vvt1Angle) )
else if((configPage6.vvtCLUseHold > 0) && (currentStatus.vvt1TargetAngle == currentStatus.vvt1Angle) )
{
currentStatus.vvt1Duty = configPage10.vvtCLholdDuty;
vvt1_pwm_value = percentage(currentStatus.vvt1Duty, vvt_pwm_max_count);
vvt1_pwm_value = halfpercentage(currentStatus.vvt1Duty, vvt_pwm_max_count);
vvtPID.Initialize();
BIT_CLEAR(currentStatus.status4, BIT_STATUS4_VVT1_ERROR);
}
else
{
//This is dumb, but need to convert the current angle into a long pointer
vvt_pid_target_angle = currentStatus.vvt1TargetAngle;
//This is dumb, but need to convert the current angle into a long pointer.
vvt_pid_target_angle = (unsigned long)currentStatus.vvt1TargetAngle;
vvt_pid_current_angle = (long)currentStatus.vvt1Angle;
//If not already at target angle, calculate new value from PID
bool PID_compute = vvtPID.Compute(false);
bool PID_compute = vvtPID.Compute(true);
//vvtPID.Compute2(currentStatus.vvt1TargetAngle, currentStatus.vvt1Angle, false);
//vvt_pwm_target_value = percentage(40, vvt_pwm_max_count);
//if (currentStatus.vvt1Angle > currentStatus.vvt1TargetAngle) { vvt_pwm_target_value = 0; }
if(PID_compute == true) { currentStatus.vvt1Duty = (vvt1_pwm_value * 100) / vvt_pwm_max_count; }
if(PID_compute == true) { vvt1_pwm_value = halfpercentage(currentStatus.vvt1Duty, vvt_pwm_max_count); }
BIT_CLEAR(currentStatus.status4, BIT_STATUS4_VVT1_ERROR);
}
if (configPage10.vvt2Enabled == 1) // same for VVT2 if it's enabled
{
if(configPage6.vvtLoadSource == VVT_LOAD_TPS) { currentStatus.vvt2TargetAngle = get3DTableValue(&vvt2Table, currentStatus.TPS, currentStatus.RPM); }
else { currentStatus.vvt2TargetAngle = get3DTableValue(&vvt2Table, currentStatus.MAP, currentStatus.RPM); }
if( vvtCounter == 30) { vvt2PID.SetTunings(configPage10.vvtCLKP, configPage10.vvtCLKI, configPage10.vvtCLKD); //This only needs to be run very infrequently, once every 32 calls to vvtControl(). This is approx. once per second
vvt2PID.SetControllerDirection(configPage4.vvt2PWMdir); }
// safety check that the cam angles are ok. The engine will be totally undriveable if the cam sensor is faulty and giving wrong cam angles, so if that happens, default to 0 duty.
// This also prevents using zero or negative current angle values for PID adjustment, because those don't work in integer PID.
if ( currentStatus.vvt2Angle <= configPage10.vvtCLMinAng || currentStatus.vvt2Angle > configPage10.vvtCLMaxAng )
{
currentStatus.vvt2Duty = 0;
vvt2_pwm_value = halfpercentage(currentStatus.vvt2Duty, vvt_pwm_max_count);
BIT_SET(currentStatus.status4, BIT_STATUS4_VVT2_ERROR);
}
//Check that we're not already at the angle we want to be
else if((configPage6.vvtCLUseHold > 0) && (currentStatus.vvt2TargetAngle == currentStatus.vvt2Angle) )
{
currentStatus.vvt2Duty = configPage10.vvtCLholdDuty;
vvt2_pwm_value = halfpercentage(currentStatus.vvt2Duty, vvt_pwm_max_count);
vvt2PID.Initialize();
BIT_CLEAR(currentStatus.status4, BIT_STATUS4_VVT2_ERROR);
}
else
{
//This is dumb, but need to convert the current angle into a long pointer.
vvt2_pid_target_angle = (unsigned long)currentStatus.vvt2TargetAngle;
vvt2_pid_current_angle = (long)currentStatus.vvt2Angle;
//If not already at target angle, calculate new value from PID
bool PID_compute = vvt2PID.Compute(true);
if(PID_compute == true) { vvt2_pwm_value = halfpercentage(currentStatus.vvt2Duty, vvt_pwm_max_count); }
BIT_CLEAR(currentStatus.status4, BIT_STATUS4_VVT2_ERROR);
}
}
if( (currentStatus.vvt1Duty > 0) || (currentStatus.vvt2Duty > 0) ) { ENABLE_VVT_TIMER(); }
//currentStatus.vvt1Duty = 0;
vvtCounter++;
}
//SET VVT2 to be the same as VVT1 - THIS WILL NEED TO BE REMOVED IN THE FUTURE WHEN VVT2 IS SUPPORTED!!!
currentStatus.vvt2Duty = currentStatus.vvt1Duty;
vvt2_pwm_value = vvt1_pwm_value ;
//Set the PWM state based on the above lookups
if( (currentStatus.vvt1Duty == 0) && (currentStatus.vvt2Duty == 0) )
{
@ -289,7 +352,7 @@ void vvtControl()
vvt2_max_pwm = false;
DISABLE_VVT_TIMER();
}
else if( (currentStatus.vvt1Duty >= 100) && (currentStatus.vvt2Duty >= 100) )
else if( (currentStatus.vvt1Duty >= 200) && (currentStatus.vvt2Duty >= 200) )
{
//Make sure solenoid is on (100% duty)
VVT1_PIN_ON();
@ -304,8 +367,8 @@ void vvtControl()
{
//Duty cycle is between 0 and 100. Make sure the timer is enabled
ENABLE_VVT_TIMER();
if(currentStatus.vvt1Duty < 100) { vvt1_max_pwm = false; }
if(currentStatus.vvt2Duty < 100) { vvt2_max_pwm = false; }
if(currentStatus.vvt1Duty < 200) { vvt1_max_pwm = false; }
if(currentStatus.vvt2Duty < 200) { vvt2_max_pwm = false; }
}
}
@ -388,9 +451,9 @@ void wmiControl()
// wmi can only work when vvt is disabled
if( (configPage6.vvtEnabled == 0) && (configPage10.wmiEnabled >= 1) )
{
currentStatus.wmiEmpty = WMI_TANK_IS_EMPTY();
if(currentStatus.wmiEmpty == 0)
if( WMI_TANK_IS_EMPTY() )
{
BIT_CLEAR(currentStatus.status4, BIT_STATUS4_WMI_EMPTY);
if( (currentStatus.TPS >= configPage10.wmiTPS) && (currentStatus.RPMdiv100 >= configPage10.wmiRPM) && ( (currentStatus.MAP / 2) >= configPage10.wmiMAP) && ( (currentStatus.IAT + CALIBRATION_TEMPERATURE_OFFSET) >= configPage10.wmiIAT) )
{
switch(configPage10.wmiMode)
@ -418,6 +481,7 @@ void wmiControl()
}
}
}
else { BIT_SET(currentStatus.status4, BIT_STATUS4_WMI_EMPTY); }
currentStatus.wmiPW = wmiPW;
vvt1_pwm_value = wmiPW;
@ -561,7 +625,7 @@ void boostDisable()
else { vvt1_max_pwm = true; }
if(vvt2_pwm_value < (long)vvt_pwm_max_count) //Don't toggle if at 100%
{
VVT1_PIN_OFF();
VVT2_PIN_OFF();
vvt2_pwm_state = false;
vvt2_max_pwm = false;
VVT_TIMER_COMPARE = VVT_TIMER_COUNTER + (vvt_pwm_max_count - vvt2_pwm_cur_value);

View File

@ -877,30 +877,32 @@ byte getStatusEntry(uint16_t byteNum)
case 90: statusValue = highByte(currentStatus.dwell); break;
case 91: statusValue = currentStatus.CLIdleTarget; break;
case 92: statusValue = currentStatus.mapDOT; break;
case 93: statusValue = (int8_t)currentStatus.vvt1Angle; break;
case 94: statusValue = currentStatus.vvt1TargetAngle; break;
case 95: statusValue = currentStatus.vvt1Duty; break;
case 96: statusValue = lowByte(currentStatus.flexBoostCorrection); break;
case 97: statusValue = highByte(currentStatus.flexBoostCorrection); break;
case 98: statusValue = currentStatus.baroCorrection; break;
case 99: statusValue = currentStatus.VE; break; //Current VE (%). Can be equal to VE1 or VE2 or a calculated value from both of them
case 100: statusValue = currentStatus.ASEValue; break; //Current ASE (%)
case 101: statusValue = lowByte(currentStatus.vss); break;
case 102: statusValue = highByte(currentStatus.vss); break;
case 103: statusValue = currentStatus.gear; break;
case 104: statusValue = currentStatus.fuelPressure; break;
case 105: statusValue = currentStatus.oilPressure; break;
case 106: statusValue = currentStatus.wmiPW; break;
case 107: statusValue = currentStatus.wmiEmpty; break;
case 108: statusValue = (int8_t)currentStatus.vvt2Angle; break;
case 109: statusValue = currentStatus.vvt2TargetAngle; break;
case 110: statusValue = currentStatus.vvt2Duty; break;
case 111: statusValue = currentStatus.outputsStatus; break;
case 112: statusValue = (byte)(currentStatus.fuelTemp + CALIBRATION_TEMPERATURE_OFFSET); break; //Fuel temperature from flex sensor
case 113: statusValue = currentStatus.fuelTempCorrection; break; //Fuel temperature Correction (%)
case 114: statusValue = currentStatus.advance1; break; //advance 1 (%)
case 115: statusValue = currentStatus.advance2; break; //advance 2 (%)
case 116: statusValue = currentStatus.TS_SD_Status; break; //SD card status
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
}
return statusValue;

View File

@ -706,7 +706,7 @@ int8_t correctionFlexTiming(int8_t advance)
int8_t correctionWMITiming(int8_t advance)
{
if( configPage10.wmiEnabled >= 1 && configPage10.wmiAdvEnabled == 1 && currentStatus.wmiEmpty == 0 ) //Check for wmi being enabled
if( configPage10.wmiEnabled >= 1 && configPage10.wmiAdvEnabled == 1 && BIT_CHECK(currentStatus.status4, BIT_STATUS4_WMI_EMPTY) == 0 ) //Check for wmi being enabled
{
if(currentStatus.TPS >= configPage10.wmiTPS && currentStatus.RPM >= configPage10.wmiRPM && currentStatus.MAP/2 >= configPage10.wmiMAP && currentStatus.IAT + CALIBRATION_TEMPERATURE_OFFSET >= configPage10.wmiIAT)
{

View File

@ -33,6 +33,9 @@
#define DECODER_WEBER 19
#define DECODER_ST170 20
//This isn't to to filter out wrong pulses on triggers, but just to smooth out the cam angle reading for better closed loop VVT control.
#define ANGLE_FILTER(input, alpha, prior) (((long)input * (256 - alpha) + ((long)prior * alpha))) >> 8
void loggerPrimaryISR();
void loggerSecondaryISR();
@ -40,6 +43,7 @@ void loggerSecondaryISR();
void triggerSetup_missingTooth();
void triggerPri_missingTooth();
void triggerSec_missingTooth();
void triggerThird_missingTooth();
uint16_t getRPM_missingTooth();
int getCrankAngle_missingTooth();
extern void triggerSetEndTeeth_missingTooth();
@ -183,6 +187,8 @@ void triggerSetEndTeeth_FordST170();
extern void (*triggerHandler)(); //Pointer for the trigger function (Gets pointed to the relevant decoder)
extern void (*triggerSecondaryHandler)(); //Pointer for the secondary trigger function (Gets pointed to the relevant decoder)
extern void (*triggerTertiaryHandler)(); //Pointer for the tertiary trigger function (Gets pointed to the relevant decoder)
extern uint16_t (*getRPM)(); //Pointer to the getRPM function (Gets pointed to the relevant decoder)
extern int (*getCrankAngle)(); //Pointer to the getCrank Angle function (Gets pointed to the relevant decoder)
extern void (*triggerSetEndTeeth)(); //Pointer to the triggerSetEndTeeth function of each decoder
@ -191,6 +197,8 @@ extern volatile unsigned long curTime;
extern volatile unsigned long curGap;
extern volatile unsigned long curTime2;
extern volatile unsigned long curGap2;
extern volatile unsigned long curTime3;
extern volatile unsigned long curGap3;
extern volatile unsigned long lastGap;
extern volatile unsigned long targetGap;
extern volatile unsigned long compositeLastToothTime;
@ -201,6 +209,7 @@ extern volatile byte toothSystemCount; //Used for decoders such as Audi 135 wher
extern volatile unsigned long toothSystemLastToothTime; //As below, but used for decoders where not every tooth count is used for calculation
extern volatile unsigned long toothLastToothTime; //The time (micros()) that the last tooth was registered
extern volatile unsigned long toothLastSecToothTime; //The time (micros()) that the last tooth was registered on the secondary input
extern volatile unsigned long toothLastThirdToothTime; //The time (micros()) that the last tooth was registered on the second cam input
extern volatile unsigned long toothLastMinusOneToothTime; //The time (micros()) that the tooth before the last tooth was registered
extern volatile unsigned long toothLastMinusOneSecToothTime; //The time (micros()) that the tooth before the last tooth was registered on secondary input
extern volatile unsigned long targetGap2;

View File

@ -30,6 +30,7 @@ toothLastToothTime - The time (In uS) that the last primary tooth was 'seen'
void (*triggerHandler)(); //Pointer for the trigger function (Gets pointed to the relevant decoder)
void (*triggerSecondaryHandler)(); //Pointer for the secondary trigger function (Gets pointed to the relevant decoder)
void (*triggerTertiaryHandler)(); //Pointer for the tertiary trigger function (Gets pointed to the relevant decoder)
uint16_t (*getRPM)(); //Pointer to the getRPM function (Gets pointed to the relevant decoder)
int (*getCrankAngle)(); //Pointer to the getCrank Angle function (Gets pointed to the relevant decoder)
void (*triggerSetEndTeeth)(); //Pointer to the triggerSetEndTeeth function of each decoder
@ -38,6 +39,8 @@ volatile unsigned long curTime;
volatile unsigned long curGap;
volatile unsigned long curTime2;
volatile unsigned long curGap2;
volatile unsigned long curTime3;
volatile unsigned long curGap3;
volatile unsigned long lastGap;
volatile unsigned long targetGap;
volatile unsigned long compositeLastToothTime;
@ -48,6 +51,7 @@ volatile byte toothSystemCount = 0; //Used for decoders such as Audi 135 where n
volatile unsigned long toothSystemLastToothTime = 0; //As below, but used for decoders where not every tooth count is used for calculation
volatile unsigned long toothLastToothTime = 0; //The time (micros()) that the last tooth was registered
volatile unsigned long toothLastSecToothTime = 0; //The time (micros()) that the last tooth was registered on the secondary input
volatile unsigned long toothLastThirdToothTime = 0; //The time (micros()) that the last tooth was registered on the second cam input
volatile unsigned long toothLastMinusOneToothTime = 0; //The time (micros()) that the tooth before the last tooth was registered
volatile unsigned long toothLastMinusOneSecToothTime = 0; //The time (micros()) that the tooth before the last tooth was registered on secondary input
volatile unsigned long targetGap2;
@ -513,19 +517,31 @@ void triggerSec_missingTooth()
secondaryToothCount++;
}
toothLastSecToothTime = curTime2;
//Record the VVT Angle
if( (configPage6.vvtEnabled > 0) && (revolutionOne == 1) )
{
int16_t curAngle;
curAngle = getCrankAngle();
while(curAngle > 360) { curAngle -= 360; }
curAngle -= configPage4.triggerAngle; //Value at TDC
if( configPage6.vvtMode == VVT_MODE_CLOSED_LOOP ) { curAngle -= configPage10.vvtCLMinAng; }
currentStatus.vvt1Angle = curAngle;
}
} //Trigger filter
//Record the VVT Angle
if( (configPage6.vvtEnabled > 0) && (revolutionOne == 1) )
{
int16_t curAngle;
curAngle = getCrankAngle();
while(curAngle > 360) { curAngle -= 360; }
curAngle -= configPage4.triggerAngle; //Value at TDC
if( configPage6.vvtMode == VVT_MODE_CLOSED_LOOP ) { curAngle -= configPage10.vvtCL0DutyAng; }
currentStatus.vvt1Angle = ANGLE_FILTER( (curAngle << 1), configPage4.ANGLEFILTER_VVT, currentStatus.vvt1Angle);
}
}
void triggerThird_missingTooth()
{
//Record the VVT2 Angle (the only purpose of the third trigger)
int16_t curAngle;
curAngle = getCrankAngle();
while(curAngle > 360) { curAngle -= 360; }
curAngle -= configPage4.triggerAngle; //Value at TDC
if( configPage6.vvtMode == VVT_MODE_CLOSED_LOOP ) { curAngle -= configPage4.vvt2CL0DutyAng; }
//currentStatus.vvt2Angle = int8_t (curAngle); //vvt1Angle is only int8, but +/-127 degrees is enough for VVT control
currentStatus.vvt2Angle = ANGLE_FILTER( (curAngle << 1), configPage4.ANGLEFILTER_VVT, currentStatus.vvt2Angle);
}
uint16_t getRPM_missingTooth()
@ -2228,9 +2244,11 @@ int getCrankAngle_Miata9905()
int getCamAngle_Miata9905()
{
int16_t curAngle;
//lastVVTtime is the time between tooth #1 (10* BTDC) and the single cam tooth.
//All cam angles in in BTDC, so the actual advance angle is 370 - fastTimeToAngle(lastVVTtime) - <the angle of the cam at 0 advance>
currentStatus.vvt1Angle = 370 - fastTimeToAngle(lastVVTtime) - configPage10.vvtCLMinAng;
curAngle = 370 - fastTimeToAngle(lastVVTtime) - configPage10.vvtCLMinAng;
currentStatus.vvt1Angle = ANGLE_FILTER( (curAngle << 1), configPage4.ANGLEFILTER_VVT, currentStatus.vvt1Angle);
return currentStatus.vvt1Angle;
}
@ -3954,7 +3972,8 @@ void triggerSec_FordST170()
while(curAngle > 360) { curAngle -= 360; }
if( configPage6.vvtMode == VVT_MODE_CLOSED_LOOP )
{
currentStatus.vvt1Angle = 360 - curAngle - configPage10.vvtCLMinAng;
curAngle = ANGLE_FILTER( (curAngle << 1), configPage4.ANGLEFILTER_VVT, curAngle);
currentStatus.vvt1Angle = 360 - curAngle - configPage10.vvtCL0DutyAng;
}
}
} //Trigger filter

View File

@ -195,6 +195,15 @@
#define BIT_STATUS3_NSQUIRTS2 6
#define BIT_STATUS3_NSQUIRTS3 7
#define BIT_STATUS4_WMI_EMPTY 0 //Indicates whether the WMI tank is empty
#define BIT_STATUS4_VVT1_ERROR 1 //VVT1 cam angle within limits or not
#define BIT_STATUS4_VVT2_ERROR 2 //VVT2 cam angle within limits or not
#define BIT_STATUS4_UNUSED4 3
#define BIT_STATUS4_UNUSED5 4
#define BIT_STATUS4_UNUSED6 5
#define BIT_STATUS4_UNUSED7 6
#define BIT_STATUS4_UNUSED8 7
#define VALID_MAP_MAX 1022 //The largest ADC value that is valid for the MAP sensor
#define VALID_MAP_MIN 2 //The smallest ADC value that is valid for the MAP sensor
@ -386,6 +395,7 @@ extern struct table3D afrTable; //16x16 afr target map
extern struct table3D stagingTable; //8x8 fuel staging table
extern struct table3D boostTable; //8x8 boost map
extern struct table3D vvtTable; //8x8 vvt map
extern struct table3D vvt2Table; //8x8 vvt2 map
extern struct table3D wmiTable; //8x8 wmi map
extern struct table3D trim1Table; //6x6 Fuel trim 1 map
extern struct table3D trim2Table; //6x6 Fuel trim 2 map
@ -499,7 +509,7 @@ extern int ignition7StartAngle;
extern int ignition8StartAngle;
//These are variables used across multiple files
extern const byte PROGMEM fsIntIndex[31];
extern const byte PROGMEM fsIntIndex[34];
extern bool initialisationComplete; //Tracks whether the setup() function has run completely
extern byte fpPrimeTime; //The time (in seconds, based on currentStatus.secl) that the fuel pump started priming
extern volatile uint16_t mainLoopCount;
@ -522,9 +532,11 @@ extern volatile uint16_t ignitionCount; /**< The count of ignition events that h
#if defined(CORE_SAMD21)
extern PinStatus primaryTriggerEdge;
extern PinStatus secondaryTriggerEdge;
extern PinStatus tertiaryTriggerEdge;
#else
extern byte primaryTriggerEdge;
extern byte secondaryTriggerEdge;
extern byte tertiaryTriggerEdge;
#endif
extern int CRANK_ANGLE_MAX;
extern int CRANK_ANGLE_MAX_IGN;
@ -649,10 +661,9 @@ struct statuses {
bool knockActive;
bool toothLogEnabled;
bool compositeLogEnabled;
//int8_t vvt1Angle;
long vvt1Angle;
int16_t vvt1Angle; //Has to be a long for PID calcs (CL VVT control)
byte vvt1TargetAngle;
byte vvt1Duty;
long vvt1Duty; //Has to be a long for PID calcs (CL VVT control)
uint16_t injAngle;
byte ASEValue;
uint16_t vss; /**< Current speed reading. Natively stored in kph and converted to mph in TS if required */
@ -662,10 +673,10 @@ struct statuses {
byte oilPressure; /**< Oil pressure in PSI */
byte engineProtectStatus;
byte wmiPW;
bool wmiEmpty;
long vvt2Angle;
volatile byte status4;
int16_t vvt2Angle; //Has to be a long for PID calcs (CL VVT control)
byte vvt2TargetAngle;
byte vvt2Duty;
long vvt2Duty; //Has to be a long for PID calcs (CL VVT control)
byte outputsStatus;
byte TS_SD_Status; //TunerStudios SD card status
};
@ -921,7 +932,12 @@ struct config4 {
byte engineProtectMaxRPM;
byte unused4_120[7];
int16_t vvt2CL0DutyAng;
byte vvt2PWMdir : 1;
byte unusedBits4 : 7;
byte ANGLEFILTER_VVT;
byte unused4_124[3];
#if defined(CORE_AVR)
};
@ -960,7 +976,7 @@ struct config6 {
byte useExtBaro : 1;
byte boostMode : 1; //Simple of full boost control
byte boostPin : 6;
byte VVTasOnOff : 1; //Whether or not to use the VVT table as an on/off map
byte unused_bit : 1; //Previously was VVTasOnOff
byte useEMAP : 1;
byte voltageCorrectionBins[6]; //X axis bins for voltage correction tables
byte injVoltageCorrectionValues[6]; //Correction table for injector PW vs battery voltage
@ -1212,8 +1228,9 @@ struct config10 {
byte vvtCLKP; //Byte 127
byte vvtCLKI; //Byte 128
byte vvtCLKD; //Byte 129
int16_t vvtCLMinAng; //Bytes 130-131
int16_t vvtCLMaxAng; //Bytes 132-133
int16_t vvtCL0DutyAng; //Bytes 130-131
uint8_t vvtCLMinAng; //Byte 132
uint8_t vvtCLMaxAng; //Byte 133
byte crankingEnrichTaper; //Byte 134
@ -1261,8 +1278,8 @@ struct config10 {
byte vvtCLminDuty;
byte vvtCLmaxDuty;
byte vvt2Pin : 6;
byte unused11_174_1 : 1;
byte unused11_174_2 : 1;
byte vvt2Enabled : 1;
byte TrigEdgeThrd : 1;
byte fuelTempBins[6];
byte fuelTempValues[6]; //180

View File

@ -12,6 +12,7 @@ struct table3D afrTable; //16x16 afr target map
struct table3D stagingTable; //8x8 fuel staging table
struct table3D boostTable; //8x8 boost map
struct table3D vvtTable; //8x8 vvt map
struct table3D vvt2Table; //8x8 vvt2 map
struct table3D wmiTable; //8x8 wmi map
struct table3D trim1Table; //6x6 Fuel trim 1 map
struct table3D trim2Table; //6x6 Fuel trim 2 map
@ -116,7 +117,7 @@ int ignition7EndAngle = 0;
int ignition8EndAngle = 0;
//These are variables used across multiple files
const byte PROGMEM fsIntIndex[31] = {4, 14, 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, 96, 101}; //int indexes in fullStatus array
const byte PROGMEM fsIntIndex[34] = {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, 190 }; //int indexes in fullStatus array
bool initialisationComplete = false; //Tracks whether the setup() function has run completely
byte fpPrimeTime = 0; //The time (in seconds, based on currentStatus.secl) that the fuel pump started priming
volatile uint16_t mainLoopCount;
@ -138,9 +139,11 @@ volatile uint16_t ignitionCount; /**< The count of ignition events that have tak
#if defined(CORE_SAMD21)
PinStatus primaryTriggerEdge;
PinStatus secondaryTriggerEdge;
PinStatus tertiaryTriggerEdge;
#else
byte primaryTriggerEdge;
byte secondaryTriggerEdge;
byte tertiaryTriggerEdge;
#endif
int CRANK_ANGLE_MAX = 720;
int CRANK_ANGLE_MAX_IGN = 360;
@ -259,4 +262,4 @@ uint16_t iatCalibration_values[32];
struct table2D iatCalibrationTable;
uint16_t o2Calibration_bins[32];
uint8_t o2Calibration_values[32];
struct table2D o2CalibrationTable;
struct table2D o2CalibrationTable;

View File

@ -38,6 +38,7 @@ void initialiseAll()
table3D_setSize(&stagingTable, 8);
table3D_setSize(&boostTable, 8);
table3D_setSize(&vvtTable, 8);
table3D_setSize(&vvt2Table, 8);
table3D_setSize(&wmiTable, 8);
table3D_setSize(&trim1Table, 6);
table3D_setSize(&trim2Table, 6);
@ -1204,6 +1205,7 @@ void setPinMapping(byte boardID)
pinCoil5 = 34; //Pin for coil 5 PLACEHOLDER value for now
pinTrigger = 20; //The CAS pin
pinTrigger2 = 21; //The Cam Sensor pin
pinTrigger3 = 3; //The Cam sensor 2 pin
pinTPS = A2; //TPS input pin
pinMAP = A3; //MAP sensor pin
pinIAT = A0; //IAT sensor pin
@ -1237,6 +1239,7 @@ void setPinMapping(byte boardID)
pinCoil5 = 34; //Pin for coil 5 PLACEHOLDER value for now
pinTrigger = 19; //The CAS pin
pinTrigger2 = 18; //The Cam Sensor pin
pinTrigger3 = 3; //The Cam sensor 2 pin
pinTPS = A2;//TPS input pin
pinMAP = A3; //MAP sensor pin
pinIAT = A0; //IAT sensor pin
@ -1288,6 +1291,7 @@ void setPinMapping(byte boardID)
pinCoil5 = 34; //Pin for coil 5 PLACEHOLDER value for now
pinTrigger = 19; //The CAS pin
pinTrigger2 = 18; //The Cam Sensor pin
pinTrigger3 = 3; //The Cam sensor 2 pin
pinTPS = A2;//TPS input pin
pinMAP = A3; //MAP sensor pin
pinIAT = A0; //IAT sensor pin
@ -1485,6 +1489,7 @@ void setPinMapping(byte boardID)
pinCoil5 = 34; //Pin for coil 5 PLACEHOLDER value for now
pinTrigger = 19; //The CAS pin
pinTrigger2 = 18; //The Cam Sensor pin
pinTrigger3 = 2; //The Cam sensor 2 pin
pinTPS = A2;//TPS input pin
pinMAP = A5; //MAP sensor pin
pinIAT = A0; //IAT sensor pin
@ -1714,7 +1719,7 @@ void setPinMapping(byte boardID)
pinCoil5 = 34; //Pin for coil 5 PLACEHOLDER value for now
pinTrigger = 19; //The CAS pin
pinTrigger2 = 18; //The Cam Sensor pin
pinTrigger3 = 17; // cam sensor 2 pin
pinTrigger3 = 17; // cam sensor 2 pin, pin17 isn't external trigger enabled in arduino mega??
pinTPS = A2;//TPS input pin
pinMAP = A3; //MAP sensor pin
pinIAT = A0; //IAT sensor pin
@ -1757,6 +1762,7 @@ void setPinMapping(byte boardID)
pinCoil6 = 34; //Pin for coil 6
pinTrigger = 19; //The CAS pin
pinTrigger2 = 18; //The Cam Sensor pin
pinTrigger3 = 20; //The Cam sensor 2 pin
pinTPS = A2;//TPS input pin
pinMAP = A3; //MAP sensor pin
pinIAT = A0; //IAT sensor pin
@ -1798,6 +1804,7 @@ void setPinMapping(byte boardID)
pinCoil5 = 46; //Placeholder only - NOT USED
pinTrigger = 19; //The CAS pin
pinTrigger2 = 18; //The Cam Sensor pin
pinTrigger3 = 21; //The Cam sensor 2 pin
pinTPS = A3; //TPS input pin
pinMAP = A0; //MAP sensor pin
pinIAT = A5; //IAT sensor pin
@ -1842,6 +1849,7 @@ void setPinMapping(byte boardID)
pinCoil5 = 44; //Pin for coil 5 PLACEHOLDER value for now
pinTrigger = 19; //The CAS pin
pinTrigger2 = 18; //The Cam Sensor pin
pinTrigger3 = 3; //The Cam sensor 2 pin
pinFlex = 20; // Flex sensor
pinTPS = A3; //TPS input pin
pinMAP = A0; //MAP sensor pin
@ -1888,6 +1896,7 @@ void setPinMapping(byte boardID)
pinCoil5 = 26; //Placeholder for coil 5
pinTrigger = 19; //The CAS pin
pinTrigger2 = 18; //The Cam Sensor pin
pinTrigger3 = 21;// The Cam sensor 2 pin
pinFlex = 20; // Flex sensor
pinTPS = A3; //TPS input pin
pinMAP = A2; //MAP sensor pin
@ -2691,6 +2700,7 @@ void initialiseTriggers()
{
byte triggerInterrupt = 0; // By default, use the first interrupt
byte triggerInterrupt2 = 1;
byte triggerInterrupt3 = 2;
#if defined(CORE_AVR)
switch (pinTrigger) {
@ -2736,15 +2746,39 @@ void initialiseTriggers()
triggerInterrupt2 = pinTrigger2;
#endif
#if defined(CORE_AVR)
switch (pinTrigger3) {
//Arduino Mega 2560 mapping
case 2:
triggerInterrupt3 = 0; break;
case 3:
triggerInterrupt3 = 1; break;
case 18:
triggerInterrupt3 = 5; break;
case 19:
triggerInterrupt3 = 4; break;
case 20:
triggerInterrupt3 = 3; break;
case 21:
triggerInterrupt3 = 2; break;
default:
triggerInterrupt3 = 0; break; //This should NEVER happen
}
#else
triggerInterrupt3 = pinTrigger3;
#endif
pinMode(pinTrigger, INPUT);
pinMode(pinTrigger2, INPUT);
pinMode(pinTrigger3, INPUT);
//digitalWrite(pinTrigger, HIGH);
detachInterrupt(triggerInterrupt);
detachInterrupt(triggerInterrupt2);
detachInterrupt(triggerInterrupt3);
//The default values for edges
primaryTriggerEdge = 0; //This should ALWAYS be changed below
secondaryTriggerEdge = 0; //This is optional and may not be changed below, depending on the decoder in use
tertiaryTriggerEdge = 0; //This is even more optional and may not be changed below, depending on the decoder in use
//Set the trigger function based on the decoder in the config
switch (configPage4.TrigPattern)
@ -2754,6 +2788,7 @@ void initialiseTriggers()
triggerSetup_missingTooth();
triggerHandler = triggerPri_missingTooth;
triggerSecondaryHandler = triggerSec_missingTooth;
triggerTertiaryHandler = triggerThird_missingTooth;
decoderHasSecondary = true;
getRPM = getRPM_missingTooth;
getCrankAngle = getCrankAngle_missingTooth;
@ -2763,9 +2798,12 @@ void initialiseTriggers()
else { primaryTriggerEdge = FALLING; }
if(configPage4.TrigEdgeSec == 0) { secondaryTriggerEdge = RISING; }
else { secondaryTriggerEdge = FALLING; }
if(configPage10.TrigEdgeThrd == 0) { tertiaryTriggerEdge = RISING; }
else { tertiaryTriggerEdge = FALLING; }
attachInterrupt(triggerInterrupt, triggerHandler, primaryTriggerEdge);
attachInterrupt(triggerInterrupt2, triggerSecondaryHandler, secondaryTriggerEdge);
if(configPage10.vvt2Enabled > 0) { attachInterrupt(triggerInterrupt3, triggerTertiaryHandler, tertiaryTriggerEdge); } // we only need this for vvt2, so not really needed if it's not used
/*
if(configPage4.TrigEdge == 0) { attachInterrupt(triggerInterrupt, triggerHandler, RISING); }

View File

@ -10,8 +10,8 @@
#define LOGGER_H
#ifndef UNIT_TEST // Scope guard for unit testing
#define LOG_ENTRY_SIZE 117 /**< The size of the live data packet. This MUST match ochBlockSize setting in the ini file */
#define SD_LOG_ENTRY_SIZE 117 /**< The size of the live data packet used by the SD car.*/
#define LOG_ENTRY_SIZE 119 /**< The size of the live data packet. This MUST match ochBlockSize setting in the ini file */
#define SD_LOG_ENTRY_SIZE 119 /**< The size of the live data packet used by the SD car.*/
#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 car.*/

View File

@ -114,9 +114,9 @@ void createLog(uint8_t *logBuffer)
logBuffer[90] = highByte(currentStatus.dwell);
logBuffer[91] = currentStatus.CLIdleTarget;
logBuffer[92] = currentStatus.mapDOT;
logBuffer[93] = (int8_t)currentStatus.vvt1Angle;
logBuffer[93] = currentStatus.vvt1Angle;
logBuffer[94] = currentStatus.vvt1TargetAngle;
logBuffer[95] = currentStatus.vvt1Duty;
logBuffer[95] = (byte) currentStatus.vvt1Duty;
logBuffer[96] = lowByte(currentStatus.flexBoostCorrection);
logBuffer[97] = highByte(currentStatus.flexBoostCorrection);
logBuffer[98] = currentStatus.baroCorrection;
@ -128,10 +128,10 @@ void createLog(uint8_t *logBuffer)
logBuffer[104] = currentStatus.fuelPressure;
logBuffer[105] = currentStatus.oilPressure;
logBuffer[106] = currentStatus.wmiPW;
logBuffer[107] = currentStatus.wmiEmpty;
logBuffer[108] = (int8_t)currentStatus.vvt2Angle;
logBuffer[107] = currentStatus.status4;
logBuffer[108] = currentStatus.vvt2Angle;
logBuffer[109] = currentStatus.vvt2TargetAngle;
logBuffer[110] = currentStatus.vvt2Duty;
logBuffer[110] = (byte) currentStatus.vvt2Duty;
logBuffer[111] = currentStatus.advance1;
logBuffer[112] = currentStatus.advance2;

View File

@ -68,6 +68,12 @@ unsigned long percentage(byte x, unsigned long y)
//return divu100(y * x);
}
//Same as above, but 0.5% accurasy
unsigned long halfpercentage(byte x, unsigned long y)
{
return (y * x) / 200;
}
/*
* Calculates integer power values. Same as pow() but with ints
*/

View File

@ -196,9 +196,9 @@ entity_t map_page_offset_to_entity_inline(uint8_t pageNumber, uint16_t offset)
case wmiMapPage:
CHECK_TABLE(offset, 0U, &wmiTable, 8, pageNumber)
CHECK_NOENTITY(offset, TABLE8_SIZE, 80, pageNumber)
CHECK_TABLE(offset, TABLE8_SIZE + 80, &dwellTable, 4, pageNumber)
END_OF_PAGE(wmiMapPage, TABLE8_SIZE + 80 + TABLE4_SIZE);
CHECK_TABLE(offset, TABLE8_SIZE, &vvt2Table, 8, pageNumber)
CHECK_TABLE(offset, TABLE8_SIZE*2, &dwellTable, 4, pageNumber)
END_OF_PAGE(wmiMapPage, TABLE8_SIZE*2 + TABLE4_SIZE);
break;
case ignMap2Page:

View File

@ -353,7 +353,7 @@ void loop()
if ( (configPage10.wmiEnabled > 0) && (configPage10.wmiIndicatorEnabled > 0) )
{
// water tank empty
if (currentStatus.wmiEmpty > 0)
if (BIT_CHECK(currentStatus.status4, BIT_STATUS4_WMI_EMPTY) > 0)
{
// flash with 1sec inverval
digitalWrite(pinWMIIndicator, !digitalRead(pinWMIIndicator));

View File

@ -210,7 +210,7 @@ int PID::GetDirection(){ return controllerDirection;}
* @return byte The current target advance value in degrees
*/
integerPID::integerPID(long* Input, long* Output, long* Setpoint,
byte Kp, byte Ki, byte Kd, byte ControllerDirection)
int16_t Kp, int16_t Ki, int16_t Kd, byte ControllerDirection)
{
myOutput = Output;
@ -220,12 +220,12 @@ integerPID::integerPID(long* Input, long* Output, long* Setpoint,
integerPID::SetOutputLimits(0, 255); //default output limit corresponds to the arduino pwm limits
SampleTime = 250; //default Controller Sample Time is 0.25 seconds. This is the 4Hz control time for Idle and VVT
SampleTime = 250; //default Controller Sample Time is 0.25 seconds. This is the 4Hz control time for Idle and VVT
integerPID::SetControllerDirection(ControllerDirection);
integerPID::SetTunings(Kp, Ki, Kd);
integerPID::SetControllerDirection(ControllerDirection);
integerPID::SetTunings(Kp, Ki, Kd);
lastTime = millis()-SampleTime;
lastTime = millis()-SampleTime;
}
@ -248,15 +248,13 @@ bool integerPID::Compute(bool pOnE, long FeedForwardTerm)
{
long error = *mySetpoint - input;
long dInput = (input - lastInput);
long outMinResized = outMin<<PID_SHIFTS;
long outMaxResized = outMax<<PID_SHIFTS;
FeedForwardTerm <<= PID_SHIFTS;
if (ki != 0)
{
outputSum += (ki * error); //integral += error × dt
if(outputSum > outMaxResized-FeedForwardTerm) { outputSum = outMaxResized-FeedForwardTerm; }
else if(outputSum < outMinResized-FeedForwardTerm) { outputSum = outMinResized-FeedForwardTerm; }
if(outputSum > outMax-FeedForwardTerm) { outputSum = outMax-FeedForwardTerm; }
else if(outputSum < outMin-FeedForwardTerm) { outputSum = outMin-FeedForwardTerm; }
}
/*Compute PID Output*/
@ -266,25 +264,22 @@ bool integerPID::Compute(bool pOnE, long FeedForwardTerm)
{
output = (kp * error);
if (ki != 0) { output += outputSum; }
if (kd != 0) { output -= (kd * dInput)>>2; }
output += FeedForwardTerm;
output >>= PID_SHIFTS;
}
else
{
outputSum -= (kp * dInput);
if(outputSum > outMaxResized) { outputSum = outMaxResized; }
else if(outputSum < outMinResized) { outputSum = outMinResized; }
if(outputSum > outMax) { outputSum = outMax; }
else if(outputSum < outMin) { outputSum = outMin; }
output = outputSum;
if (kd != 0) { output -= (kd * dInput)>>2; }
output += FeedForwardTerm;
output >>= PID_SHIFTS;
}
if (kd != 0) { output -= (kd * dInput)>>2; }
output += FeedForwardTerm;
if(output > outMax) output = outMax;
else if(output < outMin) output = outMin;
*myOutput = output;
*myOutput = output >> PID_SHIFTS;
/*Remember some variables for next time*/
lastInput = input;
@ -400,7 +395,7 @@ bool integerPID::Compute2(int target, int input, bool pOnE)
* it's called automatically from the constructor, but tunings can also
* be adjusted on the fly during normal operation
******************************************************************************/
void integerPID::SetTunings(byte Kp, byte Ki, byte Kd, byte realTime)
void integerPID::SetTunings(int16_t Kp, int16_t Ki, int16_t Kd, byte realTime)
{
if ( dispKp == Kp && dispKi == Ki && dispKd == Kd ) return; //Only do anything if one of the values has changed
dispKp = Kp; dispKi = Ki; dispKd = Kd;
@ -414,10 +409,10 @@ void integerPID::SetTunings(byte Kp, byte Ki, byte Kd, byte realTime)
if(realTime == 0)
{
long InverseSampleTimeInSec = 1000 / SampleTime;
//New resolution, 5 shifts to improve ki here | kp 3.125% | ki 3.125% | kd 0.781%
kp = (uint16_t)Kp<<5;
ki = (long)(Ki<<5) / InverseSampleTimeInSec;
kd = (long)(Kd<<5) * InverseSampleTimeInSec;
//New resolution, 32x to improve ki here | kp 3.125% | ki 3.125% | kd 0.781%
kp = Kp * 32;
ki = (long)(Ki * 32) / InverseSampleTimeInSec;
kd = (long)(Kd * 32) * InverseSampleTimeInSec;
}
else
{
@ -459,16 +454,16 @@ void integerPID::SetSampleTime(uint16_t NewSampleTime)
void integerPID::SetOutputLimits(long Min, long Max)
{
if(Min >= Max) return;
outMin = Min;
outMax = Max;
outMin = Min << PID_SHIFTS;
outMax = Max << PID_SHIFTS;
if(inAuto)
{
if(*myOutput > outMax) *myOutput = outMax;
else if(*myOutput < outMin) *myOutput = outMin;
if(*myOutput > Max) *myOutput = Max;
else if(*myOutput < Min) *myOutput = Min;
if((outputSum>>PID_SHIFTS) > outMax) { outputSum = outMax<<PID_SHIFTS; }
else if((outputSum>>PID_SHIFTS) < outMin) { outputSum = outMin<<PID_SHIFTS; }
if(outputSum > outMax) { outputSum = outMax; }
else if(outputSum < outMin) { outputSum = outMin; }
}
}
@ -496,8 +491,8 @@ void integerPID::Initialize()
outputSum = *myOutput<<PID_SHIFTS;
lastInput = *myInput;
lastMinusOneInput = *myInput;
if((outputSum>>PID_SHIFTS) > outMax) { outputSum = outMax<<PID_SHIFTS; }
else if((outputSum>>PID_SHIFTS) < outMin) { outputSum = outMin<<PID_SHIFTS; }
if(outputSum > outMax) { outputSum = outMax; }
else if(outputSum < outMin) { outputSum = outMin; }
}
/* SetControllerDirection(...)*************************************************

View File

@ -92,7 +92,7 @@ class integerPID
//commonly used functions **************************************************************************
integerPID(long*, long*, long*, // * constructor. links the PID to the Input, Output, and
byte, byte, byte, byte); // Setpoint. Initial tuning parameters are also set here
int16_t, int16_t, int16_t, byte); // Setpoint. Initial tuning parameters are also set here
void SetMode(int Mode); // * sets PID to either Manual (0) or Auto (non-0)
@ -111,8 +111,8 @@ class integerPID
//available but not commonly used functions ********************************************************
void SetTunings(byte, byte, // * While most users will set the tunings once in the
byte, byte=0); // constructor, this function gives the user the option
void SetTunings(int16_t, int16_t, // * While most users will set the tunings once in the
int16_t, byte=0); // constructor, this function gives the user the option
// of changing tunings during runtime for Adaptive control
void SetControllerDirection(byte); // * Sets the Direction, or "Action" of the controller. DIRECT
// means the output will increase when error is positive. REVERSE
@ -132,12 +132,12 @@ class integerPID
private:
byte dispKp;
byte dispKi;
byte dispKd;
uint16_t kp; // * (P)roportional Tuning Parameter
uint16_t ki; // * (I)ntegral Tuning Parameter
uint16_t kd; // * (D)erivative Tuning Parameter
int16_t dispKp;
int16_t dispKi;
int16_t dispKd;
int16_t kp; // * (P)roportional Tuning Parameter
int16_t ki; // * (I)ntegral Tuning Parameter
int16_t kd; // * (D)erivative Tuning Parameter
int controllerDirection;

View File

@ -160,10 +160,10 @@ Current layout of EEPROM data (Version 3) is as follows (All sizes are in bytes)
#define EEPROM_CONFIG12_XBINS 2451
#define EEPROM_CONFIG12_YBINS 2459
#define EEPROM_CONFIG12_XSIZE2 2467
//#define EEPROM_CONFIG12_YSIZE2 2468
//#define EEPROM_CONFIG12_MAP2 2469
//#define EEPROM_CONFIG12_XBINS2 2533
//#define EEPROM_CONFIG12_YBINS2 2541
#define EEPROM_CONFIG12_YSIZE2 2468
#define EEPROM_CONFIG12_MAP2 2469
#define EEPROM_CONFIG12_XBINS2 2533
#define EEPROM_CONFIG12_YBINS2 2541
#define EEPROM_CONFIG12_XSIZE3 2549
#define EEPROM_CONFIG12_YSIZE3 2550
#define EEPROM_CONFIG12_MAP3 2551

View File

@ -246,10 +246,13 @@ void writeConfig(byte tableNum)
/*---------------------------------------------------
| WMI and Dwell tables (See storage.h for data layout) - Page 12
| 8x8 WMI table itself + the 8 values along each of the axis
| 8x8 VVT2 table + the 8 values along each of the axis
| 4x4 Dwell table itself + the 4 values along each of the axis
-----------------------------------------------------*/
index = EEPROM_CONFIG12_XSIZE;
writeCounter = writeTable(&wmiTable, index, writeCounter);
index = EEPROM_CONFIG12_XSIZE2;
writeCounter = writeTable(&vvt2Table, index, writeCounter);
index = EEPROM_CONFIG12_XSIZE3;
writeCounter = writeTable(&dwellTable, index, writeCounter);
eepromWritesPending = writeCounter > EEPROM_MAX_WRITE_BLOCK;
@ -391,8 +394,9 @@ void loadConfig()
loadTable(&fuelTable2, EEPROM_CONFIG11_MAP);
//*********************************************************************************************************************************************************************************
// WMI and Dwell table load
// WMI, VVT2 and Dwell table load
loadTable(&wmiTable, EEPROM_CONFIG12_MAP);
loadTable(&vvt2Table, EEPROM_CONFIG12_MAP2);
loadTable(&dwellTable, EEPROM_CONFIG12_MAP3);
//*********************************************************************************************************************************************************************************

View File

@ -27,6 +27,7 @@ This file is used for everything related to maps/tables including their definiti
#define TABLE_STAGING_SIZE 8;
#define TABLE_BOOST_SIZE 8;
#define TABLE_VVT1_SIZE 8;
#define TABLE_VVT2_SIZE 8;
#define TABLE_WMI_SIZE 8;
#define TABLE_TRIM1_SIZE 6;
#define TABLE_TRIM2_SIZE 6;
@ -42,7 +43,7 @@ This file is used for everything related to maps/tables including their definiti
*********** WARNING! ***********
YOU MUST UPDATE THE TABLE COUNTS IN THE LINE BELOW WHENEVER A NEW TABLE IS ADDED!
*/
#define TABLE_HEAP_SIZE ((5 * TABLE3D_SIZE_16) + (4 * TABLE3D_SIZE_8) + (8 * TABLE3D_SIZE_6) + (1 * TABLE3D_SIZE_4) + 1)
#define TABLE_HEAP_SIZE ((5 * TABLE3D_SIZE_16) + (5 * TABLE3D_SIZE_8) + (8 * TABLE3D_SIZE_6) + (1 * TABLE3D_SIZE_4) + 1)
/*

View File

@ -10,7 +10,7 @@
void doUpdates()
{
#define CURRENT_DATA_VERSION 17
#define CURRENT_DATA_VERSION 18
//Only the latest updat for small flash devices must be retained
#ifndef SMALL_FLASH_MODE
@ -459,7 +459,38 @@ void doUpdates()
writeAllConfig();
EEPROM.write(EEPROM_DATA_VERSION, 17);
}
if(EEPROM.read(EEPROM_DATA_VERSION) == 17)
{
//VVT stuff has now 0.5 accurasy, so shift values in vvt table by one.
for(int x=0; x<8; x++)
{
for(int y=0; y<8; y++)
{
vvtTable.values[x][y] = vvtTable.values[x][y] << 1;
}
}
configPage10.vvtCLholdDuty = configPage10.vvtCLholdDuty << 1;
configPage10.vvtCLminDuty = configPage10.vvtCLminDuty << 1;
configPage10.vvtCLmaxDuty = configPage10.vvtCLmaxDuty << 1;
//VVT2 added, so default values and disable it
configPage10.vvt2Enabled = 0;
configPage4.vvt2PWMdir = 0;
configPage10.TrigEdgeThrd = 0;
//Old use as On/Off selection is removed, so change VVT mode to On/Off based on that
if(configPage6.unused_bit == 1) { configPage6.vvtMode = VVT_MODE_ONOFF; }
//Closed loop VVT improvements. Set safety limits to max/min working values and filter to minimum.
configPage10.vvtCLMinAng = 0;
configPage10.vvtCLMaxAng = 200;
configPage4.ANGLEFILTER_VVT = 0;
writeAllConfig();
EEPROM.write(EEPROM_DATA_VERSION, 18);
}
//Final check is always for 255 and 0 (Brand new arduino)
if( (EEPROM.read(EEPROM_DATA_VERSION) == 0) || (EEPROM.read(EEPROM_DATA_VERSION) == 255) )
{