Table-based flex fuel corrections
Changed the linear low / high flex fuel correction method to a table2D-based one.
This commit is contained in:
parent
fa5d721b98
commit
2350d5d785
|
@ -18,3 +18,5 @@ reference/hardware/v0.4/gerbers/Archive.zip
|
|||
.project
|
||||
.vscode
|
||||
.build
|
||||
.vscode/c_cpp_properties.json
|
||||
.vscode/launch.json
|
||||
|
|
|
@ -158,8 +158,8 @@ page = 1
|
|||
;Page 2 is all general settings (Previously part of page 1)
|
||||
;--------------------------------------------------
|
||||
page = 2
|
||||
flexBoostLow = scalar, S08, 0, "kPa", 1.0, 0.0, -127, 127, 0
|
||||
flexBoostHigh = scalar, U08, 1, "kPa", 1.0, 0.0, 0.0, 255, 0
|
||||
unused2-1 = scalar, S08, 0, "kPa", 1.0, 0.0, -127, 127, 0
|
||||
unused2-2 = scalar, U08, 1, "kPa", 1.0, 0.0, 0.0, 255, 0
|
||||
asePct = scalar, U08, 2, "%", 1.0, 0.0, 0.0, 95.0, 0
|
||||
aseCount = scalar, U08, 3, "s", 1.0, 0.0, 0.0, 255, 0
|
||||
wueRates = array, U08, 4, [10], "%", 1.0, 0.0, 0.0, 255, 0
|
||||
|
@ -236,10 +236,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)
|
||||
|
||||
flexFuelLow = scalar, U08, 57, "%", 1.0, 0.0, 0.0, 250.0, 0
|
||||
flexFuelHigh = scalar, U08, 58, "%", 1.0, 0.0, 0.0, 250.0, 0
|
||||
flexAdvLow = scalar, U08, 59, "Deg", 1.0, 0.0, 0.0, 250.0, 0
|
||||
flexAdvHigh = scalar, U08, 60, "Deg", 1.0, 0.0, 0.0, 250.0, 0
|
||||
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
|
||||
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
|
||||
|
||||
iacCLminDuty = scalar, U08, 61, "%", 1.0, 0.0, 0.0, 100.0, 0 ; Minimum and maximum duty cycles when using closed loop idle
|
||||
iacCLmaxDuty = scalar, U08, 62, "%", 1.0, 0.0, 0.0, 100.0, 0
|
||||
|
@ -705,7 +705,14 @@ page = 10
|
|||
#endif
|
||||
boostSens = scalar, U16, 25, "", 1, 0, 0, 5000, 0
|
||||
boostIntv = scalar, U08, 27, "ms", 1, 0, 0, 250, 0
|
||||
unused11_28_192 = array, U08, 28,[163], "RPM", 100.0, 0.0, 100, 25500, 0
|
||||
|
||||
flexCorrectionBins = array, U08, 28, [6], "%", 1.0, 0.0, 0.0, 250.0, 0
|
||||
; The boost range is obviously arbitrary since int16_t has ~32k in both directions
|
||||
flexCorrectionBoost = array, S16, 34, [6], "kPa", 1.0, 0.0, -500.0, 500.0, 0
|
||||
flexCorrectionFuel = array, U08, 46, [6], "%", 1.0, 0.0, 0.0, 250.0, 0
|
||||
flexCorrectionAdv = array, U08, 52, [6], "Deg", 1.0, 0.0, 0.0, 250.0, 0
|
||||
|
||||
unused11_53_192 = array, U08, 53,[139], "RPM", 100.0, 0.0, 100, 25500, 0
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
|
||||
|
@ -1128,16 +1135,16 @@ menuDialog = main
|
|||
dialog = flexMiddle, ""
|
||||
field = "Low (E0)"
|
||||
field = "", flexFreqLow, { flexEnabled }
|
||||
field = "", flexFuelLow, { flexEnabled }
|
||||
field = "", flexAdvLow, { flexEnabled }
|
||||
field = "", flexBoostLow, { boostEnabled }
|
||||
;field = "", flexFuelLow, { flexEnabled && 0 }
|
||||
;field = "", flexAdvLow, { flexEnabled && 0 }
|
||||
;field = "", flexBoostLow, { boostEnabled }
|
||||
|
||||
dialog = flexRight, ""
|
||||
field = "High (E100)"
|
||||
field = "", flexFreqHigh, { flexEnabled }
|
||||
field = "", flexFuelHigh, { flexEnabled }
|
||||
field = "", flexAdvHigh, { flexEnabled }
|
||||
field = "", flexBoostHigh, { flexEnabled && boostEnabled }
|
||||
;field = "", flexFuelHigh, { flexEnabled && 0 }
|
||||
;field = "", flexAdvHigh, { flexEnabled && 0 }
|
||||
;field = "", flexBoostHigh, { flexEnabled && boostEnabled }
|
||||
|
||||
dialog = flexMain, "Flex Fuel Calibration", xAxis
|
||||
panel = flexLeft
|
||||
|
@ -1151,6 +1158,8 @@ menuDialog = main
|
|||
topicHelp = "http://speeduino.com/wiki/index.php/Flex_Fuel"
|
||||
panel = flexFuelTop
|
||||
panel = flexMain
|
||||
panel = flex_corrections_curve, { flexEnabled }
|
||||
|
||||
|
||||
dialog = tacho, "Tacho"
|
||||
field = "Output pin", tachoPin
|
||||
|
@ -1917,6 +1926,20 @@ cmdtestspk450dc = "E\x03\x0C"
|
|||
xBins = crankingEnrichBins, coolant
|
||||
yBins = crankingEnrichValues
|
||||
;gauge = cltGau25
|
||||
|
||||
; Flex fuel correction curves
|
||||
curve = flex_corrections_curve, "Flex Fuel Corrections"
|
||||
columnLabel = "Ethanol %", "Correction Type"
|
||||
xAxis = 0, 100, 5
|
||||
xBins = flexCorrectionBins, flex
|
||||
yBins = flexCorrectionFuel
|
||||
yBins = flexCorrectionAdv
|
||||
yBins = flexCorrectionBoost, { boostEnabled }
|
||||
lineLabel = "Fuel Adj."
|
||||
lineLabel = "Add'l. Adv."
|
||||
lineLabel = "Add'l. Boost"
|
||||
showTextValues = true
|
||||
size = 640, 480
|
||||
|
||||
; Warmup enrichment VEAL AFR adjustment curve (Not currently working)
|
||||
;curve = warmup_afr_curve, "AFR Target Temperature Adustment"
|
||||
|
|
|
@ -80,8 +80,10 @@ void boostControl()
|
|||
//If flex fuel is enabled, there can be an adder to the boost target based on ethanol content
|
||||
if( configPage1.flexEnabled == 1 )
|
||||
{
|
||||
int16_t boostAdder = (((int16_t)configPage1.flexBoostHigh - (int16_t)configPage1.flexBoostLow) * currentStatus.ethanolPct) / 100;
|
||||
boostAdder = boostAdder + configPage1.flexBoostLow; //Required in case flexBoostLow is less than 0
|
||||
int16_t boostAdder = flexLookupCache.boost = BIT_CHECK(TIMER_mask, BIT_TIMER_4HZ) || !flexLookupCache.boostReady
|
||||
? table2D_getValue(&flexCorrectionBoostTable, currentStatus.ethanolPct)
|
||||
: flexLookupCache.boost;
|
||||
|
||||
currentStatus.boostTarget += boostAdder;
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ Flood clear mode etc.
|
|||
long PID_O2, PID_output, PID_AFRTarget;
|
||||
PID egoPID(&PID_O2, &PID_output, &PID_AFRTarget, configPage3.egoKP, configPage3.egoKI, configPage3.egoKD, REVERSE); //This is the PID object if that algorithm is used. Needs to be global as it maintains state outside of each function call
|
||||
|
||||
|
||||
void initialiseCorrections()
|
||||
{
|
||||
egoPID.SetMode(AUTOMATIC); //Turn O2 PID on
|
||||
|
@ -279,10 +280,11 @@ static inline bool correctionDFCO()
|
|||
static inline byte correctionFlex()
|
||||
{
|
||||
byte flexValue = 100;
|
||||
if(configPage1.flexEnabled == 1)
|
||||
if (configPage1.flexEnabled == 1)
|
||||
{
|
||||
byte flexRange = configPage1.flexFuelHigh - configPage1.flexFuelLow;
|
||||
flexValue = percentage(currentStatus.ethanolPct, flexRange) + 100;
|
||||
flexValue = flexLookupCache.fuel = BIT_CHECK(TIMER_mask, BIT_TIMER_4HZ) || !flexLookupCache.fuelReady
|
||||
? table2D_getValue(&flexCorrectionFuelTable, currentStatus.ethanolPct)
|
||||
: flexLookupCache.fuel;
|
||||
}
|
||||
return flexValue;
|
||||
}
|
||||
|
@ -405,11 +407,10 @@ static inline int8_t correctionFlexTiming(int8_t advance)
|
|||
byte ignFlexValue = advance;
|
||||
if( configPage1.flexEnabled == 1 ) //Check for flex being enabled
|
||||
{
|
||||
byte flexRange = configPage1.flexAdvHigh - configPage1.flexAdvLow;
|
||||
|
||||
if (currentStatus.ethanolPct != 0) { currentStatus.flexIgnCorrection = percentage(currentStatus.ethanolPct, flexRange); }
|
||||
else { currentStatus.flexIgnCorrection = 0; }
|
||||
|
||||
currentStatus.flexIgnCorrection = flexLookupCache.advance = BIT_CHECK(TIMER_mask, BIT_TIMER_4HZ) || !flexLookupCache.advanceReady
|
||||
? table2D_getValue(&flexCorrectionAdvTable, currentStatus.ethanolPct)
|
||||
: flexLookupCache.advance;
|
||||
|
||||
ignFlexValue = advance + currentStatus.flexIgnCorrection;
|
||||
}
|
||||
return ignFlexValue;
|
||||
|
|
|
@ -173,6 +173,9 @@ struct table2D injectorVCorrectionTable; //6 bin injector voltage correction (2D
|
|||
struct table2D IATDensityCorrectionTable; //9 bin inlet air temperature density correction (2D)
|
||||
struct table2D IATRetardTable; //6 bin ignition adjustment based on inlet air temperature (2D)
|
||||
struct table2D rotarySplitTable; //8 bin ignition split curve for rotary leading/trailing (2D)
|
||||
struct table2D flexCorrectionFuelTable; //6 bin flex fuel correction table for fuel adjustments (2D)
|
||||
struct table2D flexCorrectionAdvTable; //6 bin flex fuel correction table for timing advance (2D)
|
||||
struct table2D flexCorrectionBoostTable; //6 bin flex fuel correction table for boost adjustments (2D)
|
||||
|
||||
//These are for the direct port manipulation of the injectors and coils
|
||||
volatile byte *inj1_pin_port;
|
||||
|
@ -309,8 +312,8 @@ struct statuses currentStatus; //The global status object
|
|||
//This mostly covers off variables that are required for fuel
|
||||
struct config1 {
|
||||
|
||||
int8_t flexBoostLow; //Must be signed to allow for negatives
|
||||
byte flexBoostHigh;
|
||||
byte unused2_1;
|
||||
byte unused2_2;
|
||||
byte asePct; //Afterstart enrichment (%)
|
||||
byte aseCount; //Afterstart enrichment cycles. This is the number of ignition cycles that the afterstart enrichment % lasts for
|
||||
byte wueValues[10]; //Warm up enrichment array (10 bytes)
|
||||
|
@ -385,10 +388,10 @@ struct config1 {
|
|||
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 flexFuelLow; //Fuel % to be used for the lowest ethanol reading (Typically 100%)
|
||||
byte flexFuelHigh; //Fuel % to be used for the highest ethanol reading (Typically 163%)
|
||||
byte flexAdvLow; //Additional advance (in degrees) at lowest ethanol reading (Typically 0)
|
||||
byte flexAdvHigh; //Additional advance (in degrees) at highest ethanol reading (Varies, usually 10-20)
|
||||
byte unused2_57;
|
||||
byte unused2_58;
|
||||
byte unused2_59;
|
||||
byte unused2_60;
|
||||
|
||||
byte iacCLminDuty;
|
||||
byte iacCLmaxDuty;
|
||||
|
@ -628,7 +631,13 @@ struct config11 {
|
|||
|
||||
uint16_t boostSens;
|
||||
byte boostIntv;
|
||||
byte unused11_28_192[164];
|
||||
|
||||
uint8_t flexCorrectionBins[6];
|
||||
int16_t flexCorrectionBoost[6];
|
||||
uint8_t flexCorrectionFuel[6]; //Fuel % to be used at current ethanol reading (typically 100% fuel @ 0% eth, 163% @ 100%)
|
||||
uint8_t flexCorrectionAdv[6]; //Additional advance (in degrees) at current ethanol reading (typically 0 @ 0%, 10-20 @ 100%)
|
||||
|
||||
byte unused11_53_192[139];
|
||||
|
||||
#if defined(CORE_AVR)
|
||||
};
|
||||
|
@ -636,6 +645,16 @@ struct config11 {
|
|||
} __attribute__((__packed__)); //The 32 bit systems require all structs to be fully packed
|
||||
#endif
|
||||
|
||||
struct flexCachedLookups
|
||||
{
|
||||
bool fuelReady;
|
||||
bool advanceReady;
|
||||
bool boostReady;
|
||||
byte fuel;
|
||||
byte advance;
|
||||
int16_t boost;
|
||||
};
|
||||
struct flexCachedLookups flexLookupCache = { false, false, false, 0, 0, 0 };
|
||||
|
||||
byte pinInjector1; //Output pin injector 1
|
||||
byte pinInjector2; //Output pin injector 2
|
||||
|
@ -717,4 +736,4 @@ extern byte iatCalibrationTable[CALIBRATION_TABLE_SIZE];
|
|||
extern byte o2CalibrationTable[CALIBRATION_TABLE_SIZE];
|
||||
|
||||
|
||||
#endif // GLOBALS_H
|
||||
#endif // GLOBALS_H
|
||||
|
|
|
@ -201,6 +201,19 @@ void setup()
|
|||
rotarySplitTable.values = configPage11.rotarySplitValues;
|
||||
rotarySplitTable.axisX = configPage11.rotarySplitBins;
|
||||
|
||||
flexCorrectionFuelTable.valueSize = SIZE_BYTE;
|
||||
flexCorrectionFuelTable.xSize = 6;
|
||||
flexCorrectionFuelTable.values = configPage11.flexCorrectionFuel;
|
||||
flexCorrectionFuelTable.axisX = configPage11.flexCorrectionBins;
|
||||
flexCorrectionAdvTable.valueSize = SIZE_BYTE;
|
||||
flexCorrectionAdvTable.xSize = 6;
|
||||
flexCorrectionAdvTable.values = configPage11.flexCorrectionAdv;
|
||||
flexCorrectionAdvTable.axisX = configPage11.flexCorrectionBins;
|
||||
flexCorrectionBoostTable.valueSize = SIZE_INT;
|
||||
flexCorrectionBoostTable.xSize = 6;
|
||||
flexCorrectionBoostTable.values16 = configPage11.flexCorrectionBoost;
|
||||
flexCorrectionBoostTable.axisX = configPage11.flexCorrectionBins;
|
||||
|
||||
//Setup the calibration tables
|
||||
loadCalibration();
|
||||
|
||||
|
@ -1480,4 +1493,4 @@ static inline unsigned int PW(int REQ_FUEL, byte VE, long MAP, int corrections,
|
|||
}
|
||||
}
|
||||
return (unsigned int)(intermediate);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -222,4 +222,4 @@ void oneMSInterval() //Most ARM chips can simply call a function
|
|||
TCNT2 = 131; //Preload timer2 with 100 cycles, leaving 156 till overflow.
|
||||
TIFR2 = 0x00; //Timer2 INT Flag Reg: Clear Timer Overflow Flag
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
void doUpdates()
|
||||
{
|
||||
#define CURRENT_DATA_VERSION 6
|
||||
#define CURRENT_DATA_VERSION 7
|
||||
|
||||
//May 2017 firmware introduced a -40 offset on the ignition table. Update that table to +40
|
||||
if(EEPROM.read(EEPROM_DATA_VERSION) == 2)
|
||||
|
@ -77,6 +77,22 @@ void doUpdates()
|
|||
loadConfig(); //Reload the config after changing everything in EEPROM
|
||||
}
|
||||
|
||||
if (EEPROM.read(EEPROM_DATA_VERSION) == 6) {
|
||||
//Convert whatever flex fuel settings are there into the new tables
|
||||
|
||||
for (uint8_t x = 0; x < 6; x++)
|
||||
{
|
||||
uint8_t pct = x * 20;
|
||||
configPage11.flexCorrectionBins[x] = pct;
|
||||
configPage11.flexCorrectionBoost[x] = percentage(pct, configPage1.unused2_2 - (int8_t)configPage1.unused2_1);
|
||||
configPage11.flexCorrectionFuel[x] = percentage(pct, configPage1.unused2_58 - configPage1.unused2_57);
|
||||
configPage11.flexCorrectionAdv[x] = percentage(pct, configPage1.unused2_60 - configPage1.unused2_59);
|
||||
}
|
||||
|
||||
writeAllConfig();
|
||||
EEPROM.write(EEPROM_DATA_VERSION, 7);
|
||||
}
|
||||
|
||||
//Final check is always for 255 and 0 (Brand new arduino)
|
||||
if( (EEPROM.read(EEPROM_DATA_VERSION) == 0) || (EEPROM.read(EEPROM_DATA_VERSION) == 255) )
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue