You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
It looks like the code is confusing EGO correction with AFR target table consideration for REQ_FUEL calculation.
In correction.ino EGO correction is computed for AFR closed loop control and this is fine. But in speeduino.ino PW() function line 1998 use the O2 value from the sensor to perform de correction.
From my point of view when configPage2.includeAFR == true the SW should just consider the AFR target table and configPage2.stoich to perfom its calculation of REQ_FUEL but not the reading from O2 sensor.
In addition this compensation should be available even if no O2 sensor is present in the configuration.
Below is my change proposal:
uint16_t PW(int REQ_FUEL, byte VE, long MAP, int corrections, int injOpen)
{
//Standard float version of the calculation
//return (REQ_FUEL * (float)(VE/100.0) * (float)(MAP/100.0) * (float)(TPS/100.0) * (float)(corrections/100.0) + injOpen);
//Note: The MAP and TPS portions are currently disabled, we use VE and corrections only
uint16_t iVE, iCorrections;
uint16_t iMAP = 100;
uint16_t iAFR = 147;
//100% float free version, does sacrifice a little bit of accuracy, but not much.
iVE = ((unsigned int)VE << 7) / 100;
if ( configPage2.multiplyMAP == true ) {
iMAP = ((unsigned int)MAP << 7) / currentStatus.baro; //Include multiply MAP (vs baro) if enabled
}
if ( configPage2.includeAFR == true ) { // no matter if O2 sensor is present because closed loop is made in correction.ino
iAFR = ((unsigned int)configPage2.stoich << 7) / currentStatus.afrTarget; //Include AFR (vs target) if enabled
}
iCorrections = (corrections << 7) / 100;
unsigned long intermediate = ((long)REQ_FUEL * (long)iVE) >> 7; //Need to use an intermediate value to avoid overflowing the long
if ( configPage2.multiplyMAP == true ) {
intermediate = (intermediate * (unsigned long)iMAP) >> 7;
}
if ( configPage2.includeAFR == true ) { // no matter if O2 sensor is present because closed loop is made in correction.ino
intermediate = (intermediate * (unsigned long)iAFR) >> 7; //EGO type must be set to wideband for this to be used
}
intermediate = (intermediate * (unsigned long)iCorrections) >> 7;
if (intermediate != 0)
{
//If intermeditate is not 0, we need to add the opening time (0 typically indicates that one of the full fuel cuts is active)
intermediate += injOpen; //Add the injector opening time
if ( intermediate > 65535)
{
intermediate = 65535; //Make sure this won't overflow when we convert to uInt. This means the maximum pulsewidth possible is 65.535mS
}
}
return (unsigned int)(intermediate);
}
The text was updated successfully, but these errors were encountered:
Really easy to implement from the Speeduino trunk source code. It is already implemented and tested from my side... But problem is more about, not anyone agree with this feature (as discrbed). A discussion took place on this topic on Speeduino forum. If everyone, agree with this, it can be merge to Speeduino trunk at any time.
It looks like the code is confusing EGO correction with AFR target table consideration for REQ_FUEL calculation.
In correction.ino EGO correction is computed for AFR closed loop control and this is fine. But in speeduino.ino PW() function line 1998 use the O2 value from the sensor to perform de correction.
From my point of view when configPage2.includeAFR == true the SW should just consider the AFR target table and configPage2.stoich to perfom its calculation of REQ_FUEL but not the reading from O2 sensor.
In addition this compensation should be available even if no O2 sensor is present in the configuration.
Below is my change proposal:
uint16_t PW(int REQ_FUEL, byte VE, long MAP, int corrections, int injOpen)
{
//Standard float version of the calculation
//return (REQ_FUEL * (float)(VE/100.0) * (float)(MAP/100.0) * (float)(TPS/100.0) * (float)(corrections/100.0) + injOpen);
//Note: The MAP and TPS portions are currently disabled, we use VE and corrections only
uint16_t iVE, iCorrections;
uint16_t iMAP = 100;
uint16_t iAFR = 147;
//100% float free version, does sacrifice a little bit of accuracy, but not much.
iVE = ((unsigned int)VE << 7) / 100;
if ( configPage2.multiplyMAP == true ) {
iMAP = ((unsigned int)MAP << 7) / currentStatus.baro; //Include multiply MAP (vs baro) if enabled
}
if ( configPage2.includeAFR == true ) { // no matter if O2 sensor is present because closed loop is made in correction.ino
iAFR = ((unsigned int)configPage2.stoich << 7) / currentStatus.afrTarget; //Include AFR (vs target) if enabled
}
iCorrections = (corrections << 7) / 100;
unsigned long intermediate = ((long)REQ_FUEL * (long)iVE) >> 7; //Need to use an intermediate value to avoid overflowing the long
if ( configPage2.multiplyMAP == true ) {
intermediate = (intermediate * (unsigned long)iMAP) >> 7;
}
if ( configPage2.includeAFR == true ) { // no matter if O2 sensor is present because closed loop is made in correction.ino
intermediate = (intermediate * (unsigned long)iAFR) >> 7; //EGO type must be set to wideband for this to be used
}
intermediate = (intermediate * (unsigned long)iCorrections) >> 7;
if (intermediate != 0)
{
//If intermeditate is not 0, we need to add the opening time (0 typically indicates that one of the full fuel cuts is active)
intermediate += injOpen; //Add the injector opening time
if ( intermediate > 65535)
{
intermediate = 65535; //Make sure this won't overflow when we convert to uInt. This means the maximum pulsewidth possible is 65.535mS
}
}
return (unsigned int)(intermediate);
}
The text was updated successfully, but these errors were encountered: