diff --git a/reference/speeduino.ini b/reference/speeduino.ini index e5b6d34c..613b433f 100644 --- a/reference/speeduino.ini +++ b/reference/speeduino.ini @@ -212,7 +212,7 @@ page = 2 ; Config2 fuelAlgorithm = bits, U08, 37, [0:2], "Speed Density", "Alpha-N", "IMAP/EMAP", "ITB", "INVALID", "INVALID", "INVALID", "INVALID" ;Must match the Algorithm Names PC Variable - unused2-37d = bits, U08, 37, [2:3], "INVALID", "None", "None", "None" + unused2_37d = bits, U08, 37, [3:3], "Off", "On" nInjectors = bits, U08, 37, [4:7], "INVALID","1","2","3","4","5","6","INVALID","8","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID" ; Config3 @@ -240,8 +240,10 @@ page = 2 oddfire3 = scalar, U16, 53, "deg", 1.0, 0.0, 0.0, 720, 0 ; * ( 2 byte) oddfire4 = scalar, U16, 55, "deg", 1.0, 0.0, 0.0, 720, 0 ; * ( 2 byte) - unused2-57 = scalar, U08, 57, "%", 1.0, 0.0, 0.0, 250.0, 0 - unused2-58 = scalar, U08, 58, "%", 1.0, 0.0, 0.0, 250.0, 0 + idleUpPin = bits, U08, 57, [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", "54", "A8", "A9", "A10", "A11", "A12", "A13", "A14", "A15", "INVALID" + idleUpPolarity= bits, U08, 57, [6:6], "Normal", "Inverted" + idleUpEnabled = bits, U08, 57, [7:7], "Off", "On" + idleUpAdder = scalar, U08, 58, "% / Steps" 1.0, 0.0, 0.0, 250.0, 0 unused2-59 = scalar, U08, 59, "Deg", 1.0, 0.0, 0.0, 250.0, 0 unused2-60 = scalar, U08, 60, "Deg", 1.0, 0.0, 0.0, 250.0, 0 @@ -908,6 +910,8 @@ menuDialog = main subMenu = iacPwmCrank_curve, "Idle - PWM Cranking Duty Cycle", 7, { iacAlgorithm == 2 } subMenu = iacStep_curve, "Idle - Stepper Motor", 7, { iacAlgorithm == 4 } subMenu = iacStepCrank_curve, "Idle - Stepper Motor Cranking", 7, { iacAlgorithm == 4 } + subMenu = std_separator + subMenu = idleUpSettings, "Idle Up Settings", { iacAlgorithm == 2 || iacAlgorithm == 3 || iacAlgorithm == 4 || iacAlgorithm == 5 } menu = "&Accessories" subMenu = fanSettings, "Thermo Fan" @@ -999,6 +1003,7 @@ menuDialog = main iacCLminDuty= "When using closed loop idle control, this is the minimum duty cycle that the PID loop will allow. Combined with the maximum value, this specifies the working range of your idle valve" iacCLmaxDuty= "When using closed loop idle control, this is the maximum duty cycle that the PID loop will allow. Combined with the minimum value, this specifies the working range of your idle valve" iacFastTemp = "Below this temperature, the idle output will be high (On). Above this temperature, it will turn off." + idleUpPolarity = "Normal polarity is a ground switch where an earthed signal activates the Idle Up. The internal pullup will be enabled with Normal polarity. \n Inverted may be used if a 5v signal is used to enable the Idle Up. oddfire2 = "The ATDC angle of channel 2 for oddfire engines. This is relative to the TDC angle of channel 1" oddfire3 = "The ATDC angle of channel 3 for oddfire engines. This is relative to the TDC angle of channel 1 (NOT channel 2)" @@ -1296,6 +1301,11 @@ menuDialog = main panel = stepper_idle panel = closedloop_idle + dialog = idleUpSettings, "Idle Up Settings" + field = "Idle Up Enabled", idleUpEnabled + field = "Idle Up Pin", idleUpPin, { idleUpEnabled } + field = "Idle Up Polarity", idleUpPolarity, { idleUpEnabled } + dialog = fuelpump, "Fuel pump" field = "Fuel pump pin", fuelPumpPin field = "Fuel pump prime duration", fpPrime diff --git a/speeduino/globals.h b/speeduino/globals.h index fdbeb692..c5b09017 100644 --- a/speeduino/globals.h +++ b/speeduino/globals.h @@ -330,6 +330,7 @@ struct statuses { byte flexIgnCorrection; //Amount of additional advance being applied based on flex byte afrTarget; byte idleDuty; + bool idleUpActive; bool fanOn; //Whether or not the fan is turned on volatile byte ethanolPct; //Ethanol reading (if enabled). 0 = No ethanol, 100 = pure ethanol. Eg E85 = 85. unsigned long TAEEndTime; //The target end time used whenever TAE is turned on @@ -457,8 +458,12 @@ struct config2 { uint16_t oddfire2; //The ATDC angle of channel 2 for oddfire uint16_t oddfire3; //The ATDC angle of channel 3 for oddfire uint16_t oddfire4; //The ATDC angle of channel 4 for oddfire - byte unused2_57; - byte unused2_58; + + byte idleUpPin : 6; + byte idleUpPolarity : 1; + byte idleUpEnabled : 1; + + byte idleUpAdder; byte unused2_59; byte unused2_60; @@ -762,6 +767,7 @@ byte pinTachOut; //Tacho output byte pinFuelPump; //Fuel pump on/off byte pinIdle1; //Single wire idle control byte pinIdle2; //2 wire idle control (Not currently used) +byte pinIdleUp; //Input for triggering Idle Up byte pinSpareTemp1; // Future use only byte pinSpareTemp2; // Future use only byte pinSpareOut1; //Generic output diff --git a/speeduino/idle.ino b/speeduino/idle.ino index 33bb85ed..a605d3da 100644 --- a/speeduino/idle.ino +++ b/speeduino/idle.ino @@ -205,6 +205,14 @@ void idleControl() if(idleInitComplete != configPage6.iacAlgorithm) { initialiseIdle(); } if(currentStatus.RPM > 0) { enableIdle(); } + //Check whether the idleUp is active + if(configPage2.idleUpEnabled == true) + { + if(configPage2.idleUpPolarity == 0) { currentStatus.idleUpActive = !digitalRead(pinIdleUp); } //Normal mode (ground switched) + else { currentStatus.idleUpActive = digitalRead(pinIdleUp); } //Inverted mode (5v activates idleUp) + } + else { currentStatus.idleUpActive = false; } + switch(configPage6.iacAlgorithm) { case IAC_ALGORITHM_NONE: //Case 0 is no idle control ('None') @@ -225,6 +233,7 @@ void idleControl() { //Currently cranking. Use the cranking table currentStatus.idleDuty = table2D_getValue(&iacCrankDutyTable, currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET); //All temps are offset by 40 degrees + if(currentStatus.idleUpActive == true) { currentStatus.idleDuty += configPage2.idleUpAdder; } //Add Idle Up amount if active if( currentStatus.idleDuty == 0 ) { disableIdle(); break; } idle_pwm_target_value = percentage(currentStatus.idleDuty, idle_pwm_max_count); idleOn = true; @@ -233,6 +242,7 @@ void idleControl() { //Standard running currentStatus.idleDuty = table2D_getValue(&iacPWMTable, currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET); //All temps are offset by 40 degrees + if(currentStatus.idleUpActive == true) { currentStatus.idleDuty += configPage2.idleUpAdder; } //Add Idle Up amount if active if( currentStatus.idleDuty == 0 ) { disableIdle(); break; } idle_pwm_target_value = percentage(currentStatus.idleDuty, idle_pwm_max_count); currentStatus.idleLoad = currentStatus.idleDuty >> 1; @@ -249,6 +259,7 @@ void idleControl() idle_pwm_target_value = idle_pid_target_value; if( idle_pwm_target_value == 0 ) { disableIdle(); } currentStatus.idleLoad = ((unsigned long)(idle_pwm_target_value * 100UL) / idle_pwm_max_count) >> 1; + if(currentStatus.idleUpActive == true) { currentStatus.idleDuty += configPage2.idleUpAdder; } //Add Idle Up amount if active //idle_pwm_target_value = 104; idleCounter++; @@ -263,6 +274,7 @@ void idleControl() { //Currently cranking. Use the cranking table idleStepper.targetIdleStep = table2D_getValue(&iacCrankStepsTable, (currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET)) * 3; //All temps are offset by 40 degrees. Step counts are divided by 3 in TS. Multiply back out here + if(currentStatus.idleUpActive == true) { idleStepper.targetIdleStep += configPage2.idleUpAdder; } //Add Idle Up amount if active doStep(); } else if( (currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET) < iacStepTable.axisX[IDLE_TABLE_SIZE-1]) @@ -272,6 +284,7 @@ void idleControl() { //Only do a lookup of the required value around 4 times per second. Any more than this can create too much jitter and require a hyster value that is too high idleStepper.targetIdleStep = table2D_getValue(&iacStepTable, (currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET)) * 3; //All temps are offset by 40 degrees. Step counts are divided by 3 in TS. Multiply back out here + if(currentStatus.idleUpActive == true) { idleStepper.targetIdleStep += configPage2.idleUpAdder; } //Add Idle Up amount if active iacStepTime = configPage6.iacStepTime * 1000; } doStep(); @@ -292,6 +305,7 @@ void idleControl() } idle_cl_target_rpm = table2D_getValue(&iacClosedLoopTable, currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET) * 10; //All temps are offset by 40 degrees + if(currentStatus.idleUpActive == true) { idle_pid_target_value += configPage2.idleUpAdder; } //Add Idle Up amount if active idlePID.Compute(); idleStepper.targetIdleStep = idle_pid_target_value; diff --git a/speeduino/updates.ino b/speeduino/updates.ino index 2e88bc9a..c95b34e9 100644 --- a/speeduino/updates.ino +++ b/speeduino/updates.ino @@ -99,7 +99,7 @@ void doUpdates() configPage10.flexBoostAdj[0] = (int8_t)configPage2.unused2_1; configPage10.flexFuelBins[0] = 0; - configPage10.flexFuelAdj[0] = configPage2.unused2_57; + configPage10.flexFuelAdj[0] = configPage2.idleUpPin; configPage10.flexAdvBins[0] = 0; configPage10.flexAdvAdj[0] = configPage2.unused2_59; @@ -114,7 +114,7 @@ void doUpdates() int16_t boostAdder = (((configPage2.unused2_2 - (int8_t)configPage2.unused2_1) * pct) / 100) + (int8_t)configPage2.unused2_1; configPage10.flexBoostAdj[x] = boostAdder; - uint8_t fuelAdder = (((configPage2.unused2_58 - configPage2.unused2_57) * pct) / 100) + configPage2.unused2_57; + uint8_t fuelAdder = (((configPage2.idleUpAdder - configPage2.idleUpPin) * pct) / 100) + configPage2.idleUpPin; configPage10.flexFuelAdj[x] = fuelAdder; uint8_t advanceAdder = (((configPage2.unused2_60 - configPage2.unused2_59) * pct) / 100) + configPage2.unused2_59; diff --git a/speeduino/utils.ino b/speeduino/utils.ino index 43d803f5..3d739d1c 100644 --- a/speeduino/utils.ino +++ b/speeduino/utils.ino @@ -661,6 +661,9 @@ void setPinMapping(byte boardID) if ( (configPage6.useExtBaro != 0) && (configPage6.baroPin < BOARD_NR_GPIO_PINS) ) { pinBaro = configPage6.baroPin + A0; } if ( (configPage6.useEMAP != 0) && (configPage10.EMAPPin < BOARD_NR_GPIO_PINS) ) { pinEMAP = configPage10.EMAPPin + A0; } + //Currently there's no default pin for Idle Up + pinIdleUp = pinTranslate(configPage2.idleUpPin); + /* Reset control is a special case. If reset control is enabled, it needs its initial state set BEFORE its pinMode. If that doesn't happen and reset control is in "Serial Command" mode, the Arduino will end up in a reset loop because the control pin will go low as soon as the pinMode is set to OUTPUT. */ @@ -760,12 +763,10 @@ void setPinMapping(byte boardID) pinMode(pinTrigger2, INPUT); pinMode(pinTrigger3, INPUT); pinMode(pinFlex, INPUT_PULLUP); //Standard GM / Continental flex sensor requires pullup - if (configPage6.lnchPullRes == true) { - pinMode(pinLaunch, INPUT_PULLUP); - } - else { - pinMode(pinLaunch, INPUT); //If Launch Pull Resistor is not set make input float. - } + if (configPage6.lnchPullRes == true) { pinMode(pinLaunch, INPUT_PULLUP); } + else { pinMode(pinLaunch, INPUT); } //If Launch Pull Resistor is not set make input float. + if (configPage2.idleUpPolarity == 0) { pinMode(pinIdleUp, INPUT_PULLUP); } //Normal setting + else { pinMode(pinIdleUp, INPUT); } //inverted setting //These must come after the above pinMode statements triggerPri_pin_port = portInputRegister(digitalPinToPort(pinTrigger));