diff --git a/reference/Speeduino base tune.msq b/reference/Base Tunes/Speeduino base tune.msq similarity index 93% rename from reference/Speeduino base tune.msq rename to reference/Base Tunes/Speeduino base tune.msq index 6fdb3917..0c67171f 100644 --- a/reference/Speeduino base tune.msq +++ b/reference/Base Tunes/Speeduino base tune.msq @@ -1,7 +1,7 @@ - - + + "CAN ID 0" @@ -124,7 +124,7 @@ "Port" "4" "MAP" -"Off" +"Off" "4" "Even fire" "Off" @@ -151,8 +151,8 @@ "Inverted" "Off" 163.0 -255.0 -255.0 +1000.0 +4500.0 0.0 0.0 20.0 @@ -280,7 +280,7 @@ -0.0 +10.0 0.0 5.0 0.0 @@ -873,7 +873,21 @@ "Off" "Off" "Off" +"0x100" +"0x100" +"0x100" +"0x100" +"0x100" +"0x100" +"0x100" +"0x100" "0x706" +"0x100" +"0x100" +"0x100" +"0x100" +"0x100" +"0x100" "0x6FD" "7" "7" @@ -964,7 +978,7 @@ 255.0 255.0 255.0 -100.0 +124.0 @@ -1056,24 +1070,28 @@ 9.0 10.0 - - 25500.0 - 25500.0 - 25500.0 - 25500.0 - 25500.0 - 25500.0 - 25500.0 - 25500.0 - 25500.0 - 25500.0 - 25500.0 - 25500.0 - 25500.0 - 25500.0 - 25500.0 - 25500.0 - 25500.0 +"2 stage" +"34" +20.0 +250.0 +30.0 +18.0 +"30" +"LOW" +0 +3000.0 +6000.0 +6.0 +3.0 +5.0 +"31" +0 +6000.0 +7000.0 +3.0 +1.5 +5.0 + 25500.0 25500.0 25500.0 @@ -1175,7 +1193,7 @@ 25500.0 - 0.0 + 100.0 diff --git a/reference/rxtxSerial.dll b/reference/rxtxSerial.dll deleted file mode 100644 index 9c4fd1c6..00000000 Binary files a/reference/rxtxSerial.dll and /dev/null differ diff --git a/reference/speeduino.ini b/reference/speeduino.ini index 27a51cee..8f287a69 100644 --- a/reference/speeduino.ini +++ b/reference/speeduino.ini @@ -6,7 +6,7 @@ MTversion = 2.25 queryCommand = "Q" - signature = "speeduino 201806-dev" + signature = "speeduino 201806" versionInfo = "S" ;This info is what is displayed to user [TunerStudio] @@ -55,6 +55,7 @@ algorithmUnits = bits, U08, [0:2], "kPa", "% TPS", "%", "% TPS", "INVALID", "INVALID", "INVALID", "INVALID" algorithmLimits= array, U16, [8], "", 1.0, 0, 0, 511, 0, noMsqSave #define all_IO_Pins = "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" + #define IO_Pins_no_def = "INVALID", "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" boostTableLabels = bits, U08, [0:1], "Duty Cycle %", "kPa" @@ -828,7 +829,7 @@ page = 10 flexAdvAdj = array, U08, 69, [6], "Deg", 1.0, 0.0, 0.0, 250.0, 0 n2o_enable = bits , U08, 75, [0:1], "Off","1 Stage","2 stage", "INVALID" - n2o_arming_pin = bits , U08, 75, [2:7], $all_IO_Pins + n2o_arming_pin = bits , U08, 75, [2:7], $IO_Pins_no_def #if CELSIUS n2o_minCLT = scalar, U08, 76, "C", 1.0, -40, -40, 215, 0 #else @@ -839,7 +840,7 @@ page = 10 n2o_maxAFR = scalar, U08, 79, "kPa", 0.1, 0.0, 0.0, 25.5, 1 - n2o_stage1_pin = bits , U08, 80, [0:5], $all_IO_Pins + n2o_stage1_pin = bits , U08, 80, [0:5], $IO_Pins_no_def n2o_pin_polarity = bits , U08, 80, [6:6], "HIGH", "LOW" n2o_unused = bits , U08, 80, [7:7], "INVALID", "INVALID" n2o_stage1_minRPM = scalar, U08, 81, "RPM", 100, 0.0, 1000, 10000, 0 @@ -848,7 +849,7 @@ page = 10 n2o_stage1_adderMax = scalar, U08, 84, "ms", 0.1, 0, 0, 25.5, 1 n2o_stage1_retard = scalar, U08, 85, "Deg", 1.0, 0.0, 0.0, 250.0, 0 - n2o_stage2_pin = bits , U08, 86, [0:5], $all_IO_Pins + n2o_stage2_pin = bits , U08, 86, [0:5], $IO_Pins_no_def n2o_stage2_unused = bits , U08, 86, [6:7], "INVALID", "INVALID", "INVALID", "INVALID" n2o_stage2_minRPM = scalar, U08, 87, "RPM", 100, 0.0, 1000, 10000, 0 n2o_stage2_maxRPM = scalar, U08, 88, "RPM", 100, 0.0, 1000, 10000, 0 @@ -899,6 +900,7 @@ page = 10 requiresPowerCycle = resetControlPin requiresPowerCycle = n2o_enable requiresPowerCycle = n2o_arming_pin + requiresPowerCycle = n2o_pin_polarity defaultValue = pinLayout, 1 defaultValue = TrigPattern, 0 @@ -950,6 +952,8 @@ page = 10 defaultValue = lnchCtrlTPS, 0 defaultValue = resetControl, 0 defaultValue = bootloaderCaps, 0 + defaultValue = taeTaperMin, 1000 + defaultValue = taeTaperMax, 5000 ; defaultValue = obd_address, 0 ;Default pins @@ -1173,6 +1177,7 @@ menuDialog = main flexBoostAdj = "Adjustment, in kPa, to the boost target for the current ethanol %. Negative values are allowed to lower boost at lower ethanol % if necessary." n2o_arming_pin = "Pin that the nitrous arming/enagement switch is on." + n2o_pin_polarity = "Whether Nitrous is active (Armed) when the pin is LOW or HIGH. If LOW is selected, the internal pullup will be used." flatSArm = "The RPM switch point that determines whether an eganged clutch is for launch control or flat shift. Below this figure, an engaged clutch is considered to be for launch, above this figure an active clutch input will be considered a flat shift. This should be set at least several hundred RPM above idle" flatSSoftWin= "The number of RPM below the flat shift point where the softlimit will be applied (aka Soft limit window). Recommended values are 200-1000" @@ -1623,6 +1628,7 @@ menuDialog = main field = "Minimum CLT", n2o_minCLT, { n2o_enable > 0 } field = "Minimum TPS", n2o_minTPS, { n2o_enable > 0 } field = "Maximum MAP", n2o_maxMAP, { n2o_enable > 0 } + field = "Leanest AFR", n2o_maxAFR, { n2o_enable > 0 } dialog = NitrousControl, "Nitrous" panel = NitrousMain, North diff --git a/speeduino/auxiliaries.h b/speeduino/auxiliaries.h index e71bb2de..013164d3 100644 --- a/speeduino/auxiliaries.h +++ b/speeduino/auxiliaries.h @@ -62,7 +62,11 @@ void nitrousControl(); #define VVT_PIN_HIGH() *vvt_pin_port |= (vvt_pin_mask) #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) +#define N2O_STAGE1_PIN_HIGH() *n2o_stage1_pin_port |= (n2o_stage1_pin_mask) +#define N2O_STAGE2_PIN_LOW() *n2o_stage2_pin_port &= ~(n2o_stage2_pin_mask) +#define N2O_STAGE2_PIN_HIGH() *n2o_stage2_pin_port |= (n2o_stage2_pin_mask) +#define READ_N2O_ARM_PIN() ((*n2o_arming_pin_port & n2o_arming_pin_mask) ? true : false) volatile byte *boost_pin_port; volatile byte boost_pin_mask; @@ -70,6 +74,12 @@ volatile byte *vvt_pin_port; volatile byte vvt_pin_mask; volatile byte *fan_pin_port; volatile byte fan_pin_mask; +volatile byte *n2o_stage1_pin_port; +volatile byte n2o_stage1_pin_mask; +volatile byte *n2o_stage2_pin_port; +volatile byte n2o_stage2_pin_mask; +volatile byte *n2o_arming_pin_port; +volatile byte n2o_arming_pin_mask; volatile bool boost_pwm_state; unsigned int boost_pwm_max_count; //Used for variable PWM frequency diff --git a/speeduino/auxiliaries.ino b/speeduino/auxiliaries.ino index be58de38..c40791b7 100644 --- a/speeduino/auxiliaries.ino +++ b/speeduino/auxiliaries.ino @@ -75,6 +75,15 @@ void initialiseAuxPWM() boost_pin_mask = digitalPinToBitMask(pinBoost); vvt_pin_port = portOutputRegister(digitalPinToPort(pinVVT_1)); vvt_pin_mask = digitalPinToBitMask(pinVVT_1); + n2o_stage1_pin_port = portOutputRegister(digitalPinToPort(configPage10.n2o_stage1_pin)); + n2o_stage1_pin_mask = digitalPinToBitMask(configPage10.n2o_stage1_pin); + n2o_stage2_pin_port = portOutputRegister(digitalPinToPort(configPage10.n2o_stage2_pin)); + n2o_stage2_pin_mask = digitalPinToBitMask(configPage10.n2o_stage2_pin); + n2o_arming_pin_port = portInputRegister(digitalPinToPort(configPage10.n2o_arming_pin)); + n2o_arming_pin_mask = digitalPinToBitMask(configPage10.n2o_arming_pin); + + if(configPage10.n2o_pin_polarity == 1) { pinMode(configPage10.n2o_arming_pin, INPUT_PULLUP); } + else { pinMode(configPage10.n2o_arming_pin, INPUT); } #if defined(CORE_STM32) || defined(CORE_TEENSY) //2uS resolution Min 8Hz, Max 5KHz boost_pwm_max_count = 1000000L / (2 * configPage6.boostFreq * 2); //Converts the frequency in Hz to the number of ticks (at 2uS) it takes to complete 1 cycle. The x2 is there because the frequency is stored at half value (in a byte) to allow freqneucies up to 511Hz @@ -98,6 +107,9 @@ void initialiseAuxPWM() if(vvt_pwm_max_count > 0) { Timer1.attachInterrupt(3, vvtInterrupt);} Timer1.resume(); #endif + + currentStatus.nitrous_status = NITROUS_OFF; + } #define BOOST_HYSTER 40 @@ -209,41 +221,47 @@ void vvtControl() void nitrousControl() { + bool nitrousOn = false; //This tracks whether the control gets turned on at any point. if(configPage10.n2o_enable > 0) { - bool isArmed = digitalRead(configPage10.n2o_arming_pin); - if (configPage10.n2o_pin_polarity == 1) { isArmed = !isArmed; } //If nirtrous is active when pin is low, flip the reading (n2o_pin_polarity = 0 = active when High) + bool isArmed = READ_N2O_ARM_PIN(); + if (configPage10.n2o_pin_polarity == 1) { isArmed = !isArmed; } //If nitrous is active when pin is low, flip the reading (n2o_pin_polarity = 0 = active when High) //Perform the main checks to see if nitrous is ready if( (isArmed == true) && (currentStatus.coolant > (configPage10.n2o_minCLT - CALIBRATION_TEMPERATURE_OFFSET)) && (currentStatus.TPS > configPage10.n2o_minTPS) && (currentStatus.O2 < configPage10.n2o_maxAFR) && (currentStatus.MAP < configPage10.n2o_maxMAP) ) { - uint16_t realStage1MinRPM = configPage10.n2o_stage1_minRPM * 100; - uint16_t realStage1MaxRPM = configPage10.n2o_stage1_maxRPM * 100; - uint16_t realStage2MinRPM = configPage10.n2o_stage2_minRPM * 100; - uint16_t realStage2MaxRPM = configPage10.n2o_stage2_maxRPM * 100; + uint16_t realStage1MinRPM = (uint16_t)configPage10.n2o_stage1_minRPM * 100; + uint16_t realStage1MaxRPM = (uint16_t)configPage10.n2o_stage1_maxRPM * 100; + uint16_t realStage2MinRPM = (uint16_t)configPage10.n2o_stage2_minRPM * 100; + uint16_t realStage2MaxRPM = (uint16_t)configPage10.n2o_stage2_maxRPM * 100; if( (currentStatus.RPM > realStage1MinRPM) && (currentStatus.RPM < realStage1MaxRPM) ) { currentStatus.nitrous_status = NITROUS_STAGE1; BIT_SET(currentStatus.status3, BIT_STATUS3_NITROUS); - digitalWrite(configPage10.n2o_stage1_pin, HIGH); + N2O_STAGE1_PIN_HIGH(); + nitrousOn = true; } - if( (currentStatus.RPM > realStage2MinRPM) && (currentStatus.RPM < realStage2MaxRPM) ) + if(configPage10.n2o_enable == NITROUS_STAGE2) //This is really just a sanity check { - currentStatus.nitrous_status = NITROUS_STAGE2; - BIT_SET(currentStatus.status3, BIT_STATUS3_NITROUS); - digitalWrite(configPage10.n2o_stage2_pin, HIGH); + if( (currentStatus.RPM > realStage2MinRPM) && (currentStatus.RPM < realStage2MaxRPM) ) + { + currentStatus.nitrous_status = NITROUS_STAGE2; + BIT_SET(currentStatus.status3, BIT_STATUS3_NITROUS); + N2O_STAGE2_PIN_HIGH(); + nitrousOn = true; + } } } - else + } + + if (nitrousOn == false) { currentStatus.nitrous_status = NITROUS_OFF; BIT_CLEAR(currentStatus.status3, BIT_STATUS3_NITROUS); - digitalWrite(configPage10.n2o_stage1_pin, LOW); - digitalWrite(configPage10.n2o_stage2_pin, LOW); + N2O_STAGE1_PIN_LOW(); + N2O_STAGE2_PIN_LOW(); } - - } } void boostDisable() diff --git a/speeduino/comms.ino b/speeduino/comms.ino index 0adfa8f1..da5af84f 100644 --- a/speeduino/comms.ino +++ b/speeduino/comms.ino @@ -132,7 +132,7 @@ void command() break; case 'Q': // send code version - Serial.print("speeduino 201806-dev"); + Serial.print("speeduino 201806"); break; case 'r': //New format for the optimised OutputChannels @@ -162,7 +162,7 @@ void command() break; case 'S': // send code version - Serial.print("Speeduino 2018.6-dev"); + Serial.print("Speeduino 2018.6"); currentStatus.secl = 0; //This is required in TS3 due to its stricter timings break; diff --git a/speeduino/crankMaths.h b/speeduino/crankMaths.h new file mode 100644 index 00000000..c6537b33 --- /dev/null +++ b/speeduino/crankMaths.h @@ -0,0 +1,7 @@ +#define CRANKMATH_METHOD_INTERVAL_RPM 0 +#define CRANKMATH_METHOD_INTERVAL_TOOTH 1 +#define CRANKMATH_METHOD_ALPHA_BETA 2 +#define CRANKMATH_METHOD_2ND_DERIVATIVE 3 + +unsigned long angleToTime(int16_t angle); +uint16_t timeToAngle(unsigned long time); \ No newline at end of file diff --git a/speeduino/crankMaths.ino b/speeduino/crankMaths.ino new file mode 100644 index 00000000..a9b46a27 --- /dev/null +++ b/speeduino/crankMaths.ino @@ -0,0 +1,43 @@ +/* +* Converts a crank angle into a time from or since that angle occurred. +* Positive angles are assumed to be in the future, negative angles in the past: +* * Future angle calculations will use a predicted speed/acceleration +* * Past angle calculations will use the known speed +* +* Multiple prediction methods will be implemented here for testing: +* * Last interval using both last full revolution and gap between last teeth +* * 2nd derivative prediction (Speed + acceleration) +* * Closed loop error correction (Alpha-beta filter). +*/ + +#define fastDegreesToUS(degrees) (degrees * (unsigned long)timePerDegree) +unsigned long angleToTime(int16_t angle) +{ +//#define degreesToUS(degrees) (decoderIsLowRes == true ) ? ((degrees * 166666UL) / currentStatus.RPM) : (degrees * (unsigned long)timePerDegree) +//#define degreesToUS(degrees) ((degrees * revolutionTime) / 360) +//Fast version of divide by 360: +//#define degreesToUS(degrees) ((degrees * revolutionTime * 3054198967ULL) >> 40) +//#define degreesToUS(degrees) (degrees * (unsigned long)timePerDegree) + return ((angle * revolutionTime) / 360); +} + +/* +* Convert a time (uS) into an angle at current speed +*/ +uint16_t timeToAngle(unsigned long time) +{ + +//#define uSToDegrees(time) (((unsigned long)time * currentStatus.RPM) / 166666) +//Crazy magic numbers method from Hackers delight (www.hackersdelight.org/magic.htm): +//#define uSToDegrees(time) ( (((uint64_t)time * currentStatus.RPM * 211107077ULL) >> 45) ) + return (((unsigned long)time * currentStatus.RPM) / 166666); + +/* + switch(calculationAlgorithm) + { + case CRANKMATH_METHOD_INTERVAL_TOOTH: + returnValue = ((elapsedTime * triggerToothAngle) / toothTime); + } + */ + +} \ No newline at end of file diff --git a/speeduino/decoders.ino b/speeduino/decoders.ino index d774823c..14c8067c 100644 --- a/speeduino/decoders.ino +++ b/speeduino/decoders.ino @@ -44,8 +44,7 @@ As nearly all the decoders use a common method of determining RPM (The time the A common function is simpler degreesOver is the number of crank degrees between tooth #1s. Some patterns have a tooth #1 every crank rev, others are every cam rev. */ -static inline uint16_t stdGetRPM(uint16_t degreesOver=360) -//static inline uint16_t stdGetRPM() +static inline uint16_t stdGetRPM(uint16_t degreesOver) { uint16_t tempRPM = 0; @@ -247,7 +246,7 @@ uint16_t getRPM_missingTooth() else { if(configPage4.TrigSpeed == CAM_SPEED) { tempRPM = stdGetRPM(720); } //Account for cam speed - else { tempRPM = stdGetRPM(); } + else { tempRPM = stdGetRPM(360); } } return tempRPM; } @@ -396,7 +395,7 @@ uint16_t getRPM_DualWheel() if( currentStatus.hasSync == true ) { if(currentStatus.RPM < currentStatus.crankRPM) { tempRPM = crankingGetRPM(configPage4.triggerTeeth); } - else { tempRPM = stdGetRPM(); } + else { tempRPM = stdGetRPM(360); } } return tempRPM; } @@ -534,7 +533,7 @@ uint16_t getRPM_BasicDistributor() uint16_t tempRPM; if( currentStatus.RPM < currentStatus.crankRPM ) { tempRPM = crankingGetRPM(triggerActualTeeth) << 1; } //crankGetRPM uses teeth per 360 degrees. As triggerActualTeeh is total teeth in 720 degrees, we divide the tooth count by 2 - else { tempRPM = stdGetRPM() << 1; } //Multiply RPM by 2 due to tracking over 720 degrees now rather than 360 + else { tempRPM = stdGetRPM(720); } //Multiply RPM by 2 due to tracking over 720 degrees now rather than 360 revolutionTime = revolutionTime >> 1; //Revolution time has to be divided by 2 as otherwise it would be over 720 degrees (triggerActualTeeth = nCylinders) MAX_STALL_TIME = revolutionTime << 1; //Set the stall time to be twice the current RPM. This is a safe figure as there should be no single revolution where this changes more than this @@ -627,7 +626,7 @@ void triggerPri_GM7X() void triggerSec_GM7X() { return; } //Not required uint16_t getRPM_GM7X() { - return stdGetRPM(); + return stdGetRPM(360); } int getCrankAngle_GM7X(int timePerDegree) { @@ -1032,7 +1031,7 @@ uint16_t getRPM_4G63() } else { - if(configPage2.nCylinders == 4) { tempRPM = stdGetRPM(); } + if(configPage2.nCylinders == 4) { tempRPM = stdGetRPM(360); } else if(configPage2.nCylinders == 6) { tempRPM = stdGetRPM(720); } //EXPERIMENTAL! Add/subtract RPM based on the last rpmDOT calc //tempRPM += (micros() - toothOneTime) * currentStatus.rpmDOT @@ -1164,7 +1163,7 @@ void triggerSec_24X() uint16_t getRPM_24X() { - return stdGetRPM(); + return stdGetRPM(360); } int getCrankAngle_24X(int timePerDegree) { @@ -1270,7 +1269,7 @@ void triggerSec_Jeep2000() uint16_t getRPM_Jeep2000() { - return stdGetRPM(); + return stdGetRPM(360); } int getCrankAngle_Jeep2000(int timePerDegree) { @@ -1382,7 +1381,7 @@ void triggerSec_Audi135() uint16_t getRPM_Audi135() { - return stdGetRPM(); + return stdGetRPM(360); } int getCrankAngle_Audi135(int timePerDegree) @@ -1479,7 +1478,7 @@ void triggerPri_HondaD17() void triggerSec_HondaD17() { return; } //The 4+1 signal on the cam is yet to be supported uint16_t getRPM_HondaD17() { - return stdGetRPM(); + return stdGetRPM(360); } int getCrankAngle_HondaD17(int timePerDegree) { @@ -1683,7 +1682,7 @@ uint16_t getRPM_Miata9905() } else { - tempRPM = stdGetRPM() << 1; + tempRPM = stdGetRPM(720); revolutionTime = revolutionTime / 2; MAX_STALL_TIME = revolutionTime << 1; //Set the stall time to be twice the current RPM. This is a safe figure as there should be no single revolution where this changes more than this if(MAX_STALL_TIME < 366667UL) { MAX_STALL_TIME = 366667UL; } //Check for 50rpm minimum @@ -1840,7 +1839,7 @@ uint16_t getRPM_MazdaAU() revolutionTime = revolutionTime * 36; tempRPM = (tempToothAngle * 60000000L) / revolutionTime; } - else { tempRPM = stdGetRPM(); } + else { tempRPM = stdGetRPM(360); } } return tempRPM; } @@ -1912,7 +1911,7 @@ uint16_t getRPM_non360() if( (currentStatus.hasSync == true) && (toothCurrentCount != 0) ) { if(currentStatus.RPM < currentStatus.crankRPM) { tempRPM = crankingGetRPM(configPage4.triggerTeeth); } - else { tempRPM = stdGetRPM(); } + else { tempRPM = stdGetRPM(360); } } return tempRPM; } @@ -2279,7 +2278,7 @@ uint16_t getRPM_Subaru67() if(currentStatus.startRevolutions > 0) { //As the tooth count is over 720 degrees, we need to double the RPM value and halve the revolution time - tempRPM = stdGetRPM() << 1; + tempRPM = stdGetRPM(720); revolutionTime = revolutionTime >> 1; //Revolution time has to be divided by 2 as otherwise it would be over 720 degrees (triggerActualTeeth = nCylinders) } return tempRPM; @@ -2446,7 +2445,7 @@ uint16_t getRPM_Daihatsu() else { tempRPM = 0; } //No sync } else - { tempRPM = stdGetRPM() << 1; } //Multiply RPM by 2 due to tracking over 720 degrees now rather than 360 + { tempRPM = stdGetRPM(720); } //TRacking over 2 crank revolutions return tempRPM; @@ -2575,7 +2574,7 @@ uint16_t getRPM_Harley() } } else { - tempRPM = stdGetRPM(); + tempRPM = stdGetRPM(360); } } return tempRPM; diff --git a/speeduino/globals.h b/speeduino/globals.h index c30453cc..714421dc 100644 --- a/speeduino/globals.h +++ b/speeduino/globals.h @@ -221,7 +221,7 @@ struct table2D flexFuelTable; //6 bin flex fuel correction table for fuel adjus struct table2D flexAdvTable; //6 bin flex fuel correction table for timing advance (2D) struct table2D flexBoostTable; //6 bin flex fuel correction table for boost adjustments (2D) -//These are for the direct port manipulation of the injectors and coils +//These are for the direct port manipulation of the injectors, coils and aux outputs volatile byte *inj1_pin_port; volatile byte inj1_pin_mask; volatile byte *inj2_pin_port; diff --git a/speeduino/maths.h b/speeduino/maths.h index 7b034caf..a48542bd 100644 --- a/speeduino/maths.h +++ b/speeduino/maths.h @@ -4,14 +4,6 @@ int fastMap1023toX(int, int); unsigned long percentage(byte, unsigned long); -//#define degreesToUS(degrees) (decoderIsLowRes == true ) ? ((degrees * 166666UL) / currentStatus.RPM) : (degrees * (unsigned long)timePerDegree) -#define degreesToUS(degrees) ((degrees * revolutionTime) / 360) -#define fastDegreesToUS(degrees) (degrees * (unsigned long)timePerDegree) -//#define degreesToUS(degrees) ((degrees * revolutionTime * 3054198967ULL) >> 40) //Fast version of divide by 360 -//#define degreesToUS(degrees) (degrees * (unsigned long)timePerDegree) - -#define uSToDegrees(time) (((unsigned long)time * currentStatus.RPM) / 166666) -//#define uSToDegrees(time) ( (((uint64_t)time * currentStatus.RPM * 211107077ULL) >> 45) ) //Crazy magic numbers method from Hackers delight (www.hackersdelight.org/magic.htm) #define DIV_ROUND_CLOSEST(n, d) ((((n) < 0) ^ ((d) < 0)) ? (((n) - (d)/2)/(d)) : (((n) + (d)/2)/(d))) //This is a dedicated function that specifically handles the case of mapping 0-1023 values into a 0 to X range diff --git a/speeduino/speeduino.ino b/speeduino/speeduino.ino index 09278a4b..ce20710f 100644 --- a/speeduino/speeduino.ino +++ b/speeduino/speeduino.ino @@ -949,7 +949,6 @@ void loop() //Most boost tends to run at about 30Hz, so placing it here ensures a new target time is fetched frequently enough //currentStatus.RPM = 3000; boostControl(); - nitrousControl(); } //The IAT and CLT readings can be done less frequently (4 times per second) if (BIT_CHECK(LOOP_TIMER, BIT_TIMER_4HZ)) @@ -960,6 +959,7 @@ void loop() readO2(); readO2_2(); readBat(); + nitrousControl(); if(eepromWritesPending == true) { writeAllConfig(); } //Check for any outstanding EEPROM writes. @@ -1073,15 +1073,17 @@ void loop() //Manual adder for nitrous. These are not in correctionsFuel() because they are direct adders to the ms value, not % based if(currentStatus.nitrous_status == NITROUS_STAGE1) { - int16_t adderRange = configPage10.n2o_stage1_maxRPM - configPage10.n2o_stage1_minRPM; - int16_t adderPercent = ((currentStatus.RPM - configPage10.n2o_stage1_minRPM) * 100) / adderRange; //The percentage of the way through the RPM range - currentStatus.PW1 = currentStatus.PW1 + configPage10.n2o_stage1_adderMax + percentage(adderPercent, (configPage10.n2o_stage1_adderMin - configPage10.n2o_stage1_adderMax)); //Calculate the above percentage of the calculated ms value. + int16_t adderRange = (configPage10.n2o_stage1_maxRPM - configPage10.n2o_stage1_minRPM) * 100; + int16_t adderPercent = ((currentStatus.RPM - (configPage10.n2o_stage1_minRPM * 100)) * 100) / adderRange; //The percentage of the way through the RPM range + adderPercent = 100 - adderPercent; //Flip the percentage as we go from a higher adder to a lower adder as the RPMs rise + currentStatus.PW1 = currentStatus.PW1 + (configPage10.n2o_stage1_adderMax + percentage(adderPercent, (configPage10.n2o_stage1_adderMin - configPage10.n2o_stage1_adderMax))) * 100; //Calculate the above percentage of the calculated ms value. } if(currentStatus.nitrous_status == NITROUS_STAGE2) { - int16_t adderRange = configPage10.n2o_stage2_maxRPM - configPage10.n2o_stage2_minRPM; - int16_t adderPercent = ((currentStatus.RPM - configPage10.n2o_stage2_minRPM) * 100) / adderRange; //The percentage of the way through the RPM range - currentStatus.PW1 = currentStatus.PW1 + configPage10.n2o_stage2_adderMax + percentage(adderPercent, (configPage10.n2o_stage2_adderMin - configPage10.n2o_stage2_adderMax)); //Calculate the above percentage of the calculated ms value. + int16_t adderRange = (configPage10.n2o_stage2_maxRPM - configPage10.n2o_stage2_minRPM) * 100; + int16_t adderPercent = ((currentStatus.RPM - (configPage10.n2o_stage2_minRPM * 100)) * 100) / adderRange; //The percentage of the way through the RPM range + adderPercent = 100 - adderPercent; //Flip the percentage as we go from a higher adder to a lower adder as the RPMs rise + currentStatus.PW1 = currentStatus.PW1 + (configPage10.n2o_stage2_adderMax + percentage(adderPercent, (configPage10.n2o_stage2_adderMin - configPage10.n2o_stage2_adderMax))) * 100; //Calculate the above percentage of the calculated ms value. } int injector1StartAngle = 0;