diff --git a/auxiliaries.h b/auxiliaries.h index 04fb8a6..38b9126 100644 --- a/auxiliaries.h +++ b/auxiliaries.h @@ -8,10 +8,12 @@ volatile byte vvt_pin_mask; volatile bool boost_pwm_state; unsigned int boost_pwm_max_count; //Used for variable PWM frequency volatile unsigned int boost_pwm_cur_value; -unsigned int boost_pwm_target_value; +long boost_pwm_target_value; +long boost_cl_target_boost; volatile bool vvt_pwm_state; unsigned int vvt_pwm_max_count; //Used for variable PWM frequency volatile unsigned int vvt_pwm_cur_value; -unsigned int vvt_pwm_target_value; +long vvt_pwm_target_value; + diff --git a/auxiliaries.ino b/auxiliaries.ino index fdbdee4..dec6a3e 100644 --- a/auxiliaries.ino +++ b/auxiliaries.ino @@ -3,6 +3,7 @@ Speeduino - Simple engine management for the Arduino Mega 2560 platform Copyright (C) Josh Stewart A full copy of the license may be found in the projects root directory */ +integerPID boostPID(¤tStatus.longRPM, &boost_pwm_target_value, &boost_cl_target_boost, configPage3.boostKP, configPage3.boostKI, configPage3.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 /* Fan control @@ -44,6 +45,8 @@ void boostControl() if(configPage3.boostEnabled) { byte boostDuty = get3DTableValue(&boostTable, currentStatus.TPS, currentStatus.RPM); + if( boostDuty == 0 ) { TIMSK1 &= ~(1 << OCIE1A); digitalWrite(pinBoost, LOW); return; } + TIMSK1 |= (1 << OCIE1A); //Turn on the compare unit (ie turn on the interrupt) boost_pwm_target_value = percentage(boostDuty, boost_pwm_max_count); } #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) diff --git a/globals.h b/globals.h index b0e1066..d5394ae 100644 --- a/globals.h +++ b/globals.h @@ -86,6 +86,7 @@ volatile byte ign4_pin_mask; struct statuses { volatile boolean hasSync; unsigned int RPM; + long longRPM; int mapADC; int MAP; byte TPS; //The current TPS reading (0% - 100%) @@ -328,9 +329,9 @@ struct config3 { byte idleKD; byte boostLimit; //Is divided by 2, allowing kPa values up to 511 - byte unused57; - byte unused58; - byte unused59; + byte boostKP; + byte boostKI; + byte boostKD; byte unused60; byte unused61; byte unused62; diff --git a/idle.ino b/idle.ino index 25088c4..414b0bb 100644 --- a/idle.ino +++ b/idle.ino @@ -12,8 +12,7 @@ These functions cover the PWM and stepper idle control Idle Control Currently limited to on/off control and open loop PWM and stepper drive */ -long longRPM; -integerPID idlePID(&longRPM, &idle_pwm_target_value, &idle_cl_target_rpm, configPage3.idleKP, configPage3.idleKI, configPage3.idleKD, 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 idlePID(¤tStatus.longRPM, &idle_pwm_target_value, &idle_cl_target_rpm, configPage3.idleKP, configPage3.idleKI, configPage3.idleKD, DIRECT); //This is the PID object if that algorithm is used. Needs to be global as it maintains state outside of each function call void initialiseIdle() { @@ -151,7 +150,6 @@ void idleControl() case 3: //Case 3 is PWM closed loop //No cranking specific value for closed loop (yet?) idle_cl_target_rpm = table2D_getValue(&iacClosedLoopTable, currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET) * 10; //All temps are offset by 40 degrees - longRPM = currentStatus.RPM; //The PID object needs a long as the RPM input. A separate variable is used for this idlePID.SetTunings(configPage3.idleKP, configPage3.idleKI, configPage3.idleKD); idlePID.Compute(); diff --git a/reference/speeduino.ini b/reference/speeduino.ini index bafe4e7..4a44dec 100644 --- a/reference/speeduino.ini +++ b/reference/speeduino.ini @@ -340,9 +340,9 @@ page = 6 idleKI = scalar, U08, 54, "%", 1.0, 0.0, 0.0, 200.0, 0 ; * ( 1 byte) idleKD = scalar, U08, 55, "%", 1.0, 0.0, 0.0, 200.0, 0 ; * ( 1 byte) boostLimit = scalar, U08, 56, "kPa", 2.0, 0.0, 0, 511, 0 - unused6-57 = scalar, U08, 57, "RPM", 100.0, 0.0, 100, 25500, 0 - unused6-58 = scalar, U08, 58, "RPM", 100.0, 0.0, 100, 25500, 0 - unused6-59 = scalar, U08, 59, "RPM", 100.0, 0.0, 100, 25500, 0 + boostKP = scalar, U08, 57, "%", 1.0, 0.0, 0.0, 200.0, 0 ; * ( 1 byte) + boostKI = scalar, U08, 58, "%", 1.0, 0.0, 0.0, 200.0, 0 ; * ( 1 byte) + boostKD = scalar, U08, 59, "%", 1.0, 0.0, 0.0, 200.0, 0 ; * ( 1 byte) unused6-60 = scalar, U08, 60, "RPM", 100.0, 0.0, 100, 25500, 0 unused6-61 = scalar, U08, 61, "RPM", 100.0, 0.0, 100, 25500, 0 unused6-62 = scalar, U08, 62, "RPM", 100.0, 0.0, 100, 25500, 0 @@ -815,6 +815,10 @@ page = 8 field = "Boost solenoid freq.", boostFreq field = "Boost Cut", boostCutType field = "Boost Limit", boostLimit, { boostCutType } + field = "Closed Loop settings" + field = "P", boostKP + field = "I", boostKI + field = "D", boostKD dialog = vvtSettings, "VVT Control" field = "VVT Control Enabled", vvtEnabled diff --git a/speeduino.ino b/speeduino.ino index 3b5c16e..1314672 100644 --- a/speeduino.ino +++ b/speeduino.ino @@ -635,7 +635,7 @@ void loop() if ( (timeToLastTooth < MAX_STALL_TIME) || (toothLastToothTime > currentLoopTime) ) //Check how long ago the last tooth was seen compared to now. If it was more than half a second ago then the engine is probably stopped. toothLastToothTime can be greater than currentLoopTime if a pulse occurs between getting the lastest time and doing the comparison { int lastRPM = currentStatus.RPM; //Need to record this for rpmDOT calculation - currentStatus.RPM = getRPM(); + currentStatus.RPM = currentStatus.longRPM = getRPM(); //Long RPM is included here if(fuelPumpOn == false) { digitalWrite(pinFuelPump, HIGH); fuelPumpOn = true; } //Check if the fuel pump is on and turn it on if it isn't. currentStatus.rpmDOT = ldiv(1000000, (currentLoopTime - previousLoopTime)).quot * (currentStatus.RPM - lastRPM); //This is the RPM per second that the engine has accelerated/decelleratedin the last loop } @@ -656,6 +656,7 @@ void loop() fuelOn = false; if (fpPrimed) { digitalWrite(pinFuelPump, LOW); } //Turn off the fuel pump, but only if the priming is complete fuelPumpOn = false; + TIMSK4 &= ~(1 << OCIE4C); digitalWrite(pinIdle1, LOW); //Turns off the idle control PWM. This REALLY needs to be cleaned up into a general PWM controller class } //Uncomment the following for testing