Complete (untested) sequential fuel trim

This commit is contained in:
Josh Stewart 2016-10-27 17:27:08 +11:00
parent 5463dba01c
commit 0a38467fc6
5 changed files with 56 additions and 45 deletions

View File

@ -236,7 +236,7 @@ void sendValues(int packetlength, byte portNum)
response[17] = currentStatus.corrections; //Total GammaE (%)
response[18] = currentStatus.VE; //Current VE 1 (%)
response[19] = currentStatus.afrTarget;
response[20] = (byte)(currentStatus.PW / 100); //Pulsewidth 1 multiplied by 10 in ms. Have to convert from uS to mS.
response[20] = (byte)(currentStatus.PW1 / 100); //Pulsewidth 1 multiplied by 10 in ms. Have to convert from uS to mS.
response[21] = currentStatus.tpsDOT; //TPS DOT
response[22] = currentStatus.advance;
response[23] = currentStatus.TPS; // TPS (0% to 100%)
@ -679,12 +679,37 @@ void sendPage(bool useChar)
}
case seqFuelPage:
{
byte response[200]; //The size is: (6x6 + 6 + 6) * 4 + 8 (Leftover values)
if(useChar)
{
currentTable = trim1Table;
currentTitleIndex = 121;
//Do.... Something?
}
else
{
//Need to perform a translation of the values[MAP/TPS][RPM] into the MS expected format
byte response[192]; //Bit hacky, but the size is: (6x6 + 6 + 6) * 4 = 192
for (int x = 0; x < 200; x++) { 0; }
//trim1 table
for (int x = 0; x < 36; x++) { response[x] = trim1Table.values[5 - x / 6][x % 6]; }
for (int x = 36; x < 42; x++) { response[x] = byte(trim1Table.axisX[(x - 36)] / 100); }
for (int y = 42; y < 48; y++) { response[y] = byte(trim1Table.axisY[5 - (y - 42)]); }
//trim2 table
for (int x = 48; x < 84; x++) { response[x] = trim2Table.values[5 - x / 6][x % 6]; }
for (int x = 84; x < 90; x++) { response[x] = byte(trim2Table.axisX[(x - 84)] / 100); }
for (int y = 90; y < 96; y++) { response[y] = byte(trim2Table.axisY[5 - (y - 90)]); }
//trim3 table
for (int x = 96; x < 132; x++) { response[x] = trim3Table.values[5 - x / 6][x % 6]; }
for (int x = 132; x < 138; x++) { response[x] = byte(trim3Table.axisX[(x - 132)] / 100); }
for (int y = 138; y < 144; y++) { response[y] = byte(trim3Table.axisY[5 - (y - 138)]); }
//trim4 table
for (int x = 144; x < 180; x++) { response[x] = trim4Table.values[5 - x / 6][x % 6]; }
for (int x = 180; x < 186; x++) { response[x] = byte(trim4Table.axisX[(x - 180)] / 100); }
for (int y = 186; y < 192; y++) { response[y] = byte(trim4Table.axisY[5 - (y - 186)]); }
Serial.write((byte *)&response, sizeof(response));
break;
return;
}
break;
}
default:
{

View File

@ -56,7 +56,7 @@ void updateDisplay()
case 1:
display.print("PW: ");
display.setCursor(28,0);
display.print(currentStatus.PW);
display.print(currentStatus.PW1);
break;
case 2:
display.print("Adv: ");
@ -101,7 +101,7 @@ void updateDisplay()
case 1:
display.print("PW: ");
display.setCursor(28,11);
display.print(currentStatus.PW);
display.print(currentStatus.PW1);
break;
case 2:
display.print("Adv: ");

View File

@ -145,7 +145,7 @@ struct statuses {
volatile byte squirt;
volatile byte spark;
byte engine;
unsigned int PW; //In uS
unsigned int PW1; //In uS
unsigned int PW2; //In uS
unsigned int PW3; //In uS
unsigned int PW4; //In uS

View File

@ -94,7 +94,7 @@
endianness = little
nPages = 9
burnCommand = "B"
pageSize = 288, 64, 288, 64, 288, 64, 64, 160, 200
pageSize = 288, 64, 288, 64, 288, 64, 64, 160, 192
pageActivationDelay = 10
pageActivate = "P\001", "P\002", "P\003", "P\004", "P\005", "P\006", "P\007", "P\010", "P\011"
pageReadCommand = "V", "V", "V", "V", "V", "V", "V", "V", "V"
@ -496,23 +496,6 @@ page = 9
#elif ALPHA_N
fuelTrim4loadBins = array, U08, 186,[ 6], "TPS", 1.0, 0.0, 0.0, 255.0, 0
#endif
fuelTrimEnabled = bits, U08, 192, [0:0], "No", "Yes"
unused9-192b = bits, U08, 192, [1:1], "No", "Yes"
unused9-192c = bits, U08, 192, [2:2], "No", "Yes"
unused9-192d = bits, U08, 192, [3:3], "No", "Yes"
unused9-192e = bits, U08, 192, [4:4], "No", "Yes"
unused9-192f = bits, U08, 192, [5:5], "No", "Yes"
unused9-192g = bits, U08, 192, [6:6], "No", "Yes"
unused9-192h = bits, U08, 192, [7:7], "No", "Yes"
unused9-193 = scalar, U08, 193, "RPM", 100.0, 0.0, 100, 25500, 0
unused9-194 = scalar, U08, 194, "RPM", 100.0, 0.0, 100, 25500, 0
unused9-195 = scalar, U08, 195, "RPM", 100.0, 0.0, 100, 25500, 0
unused9-196 = scalar, U08, 196, "RPM", 100.0, 0.0, 100, 25500, 0
unused9-197 = scalar, U08, 197, "RPM", 100.0, 0.0, 100, 25500, 0
unused9-198 = scalar, U08, 198, "RPM", 100.0, 0.0, 100, 25500, 0
unused9-199 = scalar, U08, 199, "RPM", 100.0, 0.0, 100, 25500, 0
;-------------------------------------------------------------------------------

View File

@ -837,7 +837,7 @@ void loop()
{
//We reach here if the time between teeth is too great. This VERY likely means the engine has stopped
currentStatus.RPM = 0;
currentStatus.PW = 0;
currentStatus.PW1 = 0;
currentStatus.VE = 0;
toothLastToothTime = 0;
currentStatus.hasSync = false;
@ -955,14 +955,14 @@ void loop()
{
//Speed Density
currentStatus.VE = get3DTableValue(&fuelTable, currentStatus.MAP, currentStatus.RPM); //Perform lookup into fuel map for RPM vs MAP value
currentStatus.PW = PW_SD(req_fuel_uS, currentStatus.VE, currentStatus.MAP, currentStatus.corrections, inj_opentime_uS);
currentStatus.PW1 = PW_SD(req_fuel_uS, currentStatus.VE, currentStatus.MAP, currentStatus.corrections, inj_opentime_uS);
currentStatus.advance = get3DTableValue(&ignitionTable, currentStatus.MAP, currentStatus.RPM); //As above, but for ignition advance
}
else
{
//Alpha-N
currentStatus.VE = get3DTableValue(&fuelTable, currentStatus.TPS, currentStatus.RPM); //Perform lookup into fuel map for RPM vs TPS value
currentStatus.PW = PW_AN(req_fuel_uS, currentStatus.VE, currentStatus.TPS, currentStatus.corrections, inj_opentime_uS); //Calculate pulsewidth using the Alpha-N algorithm (in uS)
currentStatus.PW1 = PW_AN(req_fuel_uS, currentStatus.VE, currentStatus.TPS, currentStatus.corrections, inj_opentime_uS); //Calculate pulsewidth using the Alpha-N algorithm (in uS)
currentStatus.advance = get3DTableValue(&ignitionTable, currentStatus.TPS, currentStatus.RPM); //As above, but for ignition advance
}
@ -1035,14 +1035,15 @@ void loop()
if( !BIT_CHECK(currentStatus.engine, BIT_ENGINE_CRANK) )
{
unsigned long pwLimit = percentage(configPage1.dutyLim, revolutionTime); //The pulsewidth limit is determined to be the duty cycle limit (Eg 85%) by the total time it takes to perform 1 revolution
if (currentStatus.PW > pwLimit) { currentStatus.PW = pwLimit; }
if (currentStatus.PW1 > pwLimit) { currentStatus.PW1 = pwLimit; }
}
//***********************************************************************************************
//BEGIN INJECTION TIMING
//Determine next firing angles
int PWdivTimerPerDegree = div(currentStatus.PW, timePerDegree).quot; //How many crank degrees the calculated PW will take at the current speed
currentStatus.PW2, currentStatus.PW3, currentStatus.PW4 = currentStatus.PW1; // Initial state is for all pulsewidths to be the same (This gets changed below)
int PWdivTimerPerDegree = div(currentStatus.PW1, timePerDegree).quot; //How many crank degrees the calculated PW will take at the current speed
injector1StartAngle = configPage1.inj1Ang - ( PWdivTimerPerDegree ); //This is a little primitive, but is based on the idea that all fuel needs to be delivered before the inlet valve opens. See http://www.extraefi.co.uk/sequential_fuel.html for more detail
if(injector1StartAngle < 0) {injector1StartAngle += CRANK_ANGLE_MAX_INJ;}
//Repeat the above for each cylinder
@ -1072,15 +1073,17 @@ void loop()
injector4StartAngle = (configPage1.inj4Ang + channel4InjDegrees - ( PWdivTimerPerDegree ));
if(injector4StartAngle > CRANK_ANGLE_MAX_INJ) {injector4StartAngle -= CRANK_ANGLE_MAX_INJ;}
injector1StartAngle += 360;
injector2StartAngle += 360;
injector3StartAngle += 360;
injector4StartAngle += 360;
if(configPage3.fuelTrimEnabled)
{
unsigned long pw1percent = 100 + get3DTableValue(&trim1Table, currentStatus.MAP, currentStatus.RPM);
unsigned long pw2percent = 100 + get3DTableValue(&trim2Table, currentStatus.MAP, currentStatus.RPM);
unsigned long pw3percent = 100 + get3DTableValue(&trim3Table, currentStatus.MAP, currentStatus.RPM);
unsigned long pw4percent = 100 + get3DTableValue(&trim4Table, currentStatus.MAP, currentStatus.RPM);
//currentStatus.PW = currentStatus.PW * (100 + get3DTableValue(&trim1Table, currentStatus.MAP, currentStatus.RPM) ); //Perform lookup into fuel map for RPM vs MAP value
if (pw1percent != 100) { currentStatus.PW1 = (pw1percent * currentStatus.PW1) / 100; }
if (pw2percent != 100) { currentStatus.PW2 = (pw2percent * currentStatus.PW2) / 100; }
if (pw3percent != 100) { currentStatus.PW3 = (pw3percent * currentStatus.PW3) / 100; }
if (pw4percent != 100) { currentStatus.PW4 = (pw4percent * currentStatus.PW4) / 100; }
}
}
break;
@ -1199,7 +1202,7 @@ void loop()
int crankAngle = getCrankAngle(timePerDegree);
if (crankAngle > CRANK_ANGLE_MAX_INJ ) { crankAngle -= 360; }
if (fuelOn && currentStatus.PW > 0 && !BIT_CHECK(currentStatus.squirt, BIT_SQUIRT_BOOSTCUT))
if (fuelOn && currentStatus.PW1 > 0 && !BIT_CHECK(currentStatus.squirt, BIT_SQUIRT_BOOSTCUT))
{
if (injector1StartAngle <= crankAngle && fuelSchedule1.schedulesSet == 0) { injector1StartAngle += CRANK_ANGLE_MAX_INJ; }
if (injector1StartAngle > crankAngle)
@ -1208,7 +1211,7 @@ void loop()
{
setFuelSchedule1(openInjector1and4,
((unsigned long)(injector1StartAngle - crankAngle) * (unsigned long)timePerDegree),
(unsigned long)currentStatus.PW,
(unsigned long)currentStatus.PW1,
closeInjector1and4
);
}
@ -1216,7 +1219,7 @@ void loop()
{
setFuelSchedule1(openInjector1,
((unsigned long)(injector1StartAngle - crankAngle) * (unsigned long)timePerDegree),
(unsigned long)currentStatus.PW,
(unsigned long)currentStatus.PW1,
closeInjector1
);
}
@ -1246,7 +1249,7 @@ void loop()
{
setFuelSchedule2(openInjector2and3,
((unsigned long)(tempStartAngle - tempCrankAngle) * (unsigned long)timePerDegree),
(unsigned long)currentStatus.PW,
(unsigned long)currentStatus.PW2,
closeInjector2and3
);
}
@ -1254,7 +1257,7 @@ void loop()
{
setFuelSchedule2(openInjector2,
((unsigned long)(tempStartAngle - tempCrankAngle) * (unsigned long)timePerDegree),
(unsigned long)currentStatus.PW,
(unsigned long)currentStatus.PW2,
closeInjector2
);
}
@ -1272,7 +1275,7 @@ void loop()
{
setFuelSchedule3(openInjector3,
((unsigned long)(tempStartAngle - tempCrankAngle) * (unsigned long)timePerDegree),
(unsigned long)currentStatus.PW,
(unsigned long)currentStatus.PW3,
closeInjector3
);
}
@ -1289,7 +1292,7 @@ void loop()
{
setFuelSchedule4(openInjector4,
((unsigned long)(tempStartAngle - tempCrankAngle) * (unsigned long)timePerDegree),
(unsigned long)currentStatus.PW,
(unsigned long)currentStatus.PW4,
closeInjector4
);
}
@ -1306,7 +1309,7 @@ void loop()
{
setFuelSchedule5(openInjector5,
((unsigned long)(tempStartAngle - tempCrankAngle) * (unsigned long)timePerDegree),
(unsigned long)currentStatus.PW,
(unsigned long)currentStatus.PW1,
closeInjector5
);
}