mirror of https://github.com/FOME-Tech/fome-fw.git
Fix afr dropdown, switch AFR to sensor model (#62)
* move presets to ini, like clt/iat * call deinit * init lambda using proper sensors * raw output channel * init lambda test * ve blend 1 should use bias table 1, good eye @nmstec
This commit is contained in:
parent
b2010b6b8e
commit
df03f3c536
|
@ -465,8 +465,7 @@ static void updateRawSensors() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: transition AFR to new sensor model
|
engine->outputChannels.rawAfr = Sensor::getRaw(SensorType::Lambda1);
|
||||||
engine->outputChannels.rawAfr = (engineConfiguration->afr.hwChannel == EFI_ADC_NONE) ? 0 : getVoltageDivided("ego", engineConfiguration->afr.hwChannel);
|
|
||||||
}
|
}
|
||||||
static void updatePressures() {
|
static void updatePressures() {
|
||||||
engine->outputChannels.baroPressure = Sensor::getOrZero(SensorType::BarometricPressure);
|
engine->outputChannels.baroPressure = Sensor::getOrZero(SensorType::BarometricPressure);
|
||||||
|
|
|
@ -3,45 +3,11 @@
|
||||||
*
|
*
|
||||||
* EGO Exhaust Gas Oxygen, also known as AFR Air/Fuel Ratio :)
|
* EGO Exhaust Gas Oxygen, also known as AFR Air/Fuel Ratio :)
|
||||||
*
|
*
|
||||||
* rusEfi has three options for wideband:
|
|
||||||
* 1) integration with external widebands using liner analog signal wire
|
|
||||||
* 2) 8-point interpolation curve to emulate a wide-band with a narrow-band sensor.
|
|
||||||
* 3) CJ125 internal wideband controller is known to work with both 4.2 and 4.9
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
#include "pch.h"
|
#include "pch.h"
|
||||||
|
|
||||||
#include "cyclic_buffer.h"
|
void setEgoSensor(ego_sensor_e type) {
|
||||||
|
auto sensor = &engineConfiguration->afr;
|
||||||
bool hasAfrSensor() {
|
|
||||||
if (engineConfiguration->enableAemXSeries || engineConfiguration->enableInnovateLC2) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return isAdcChannelValid(engineConfiguration->afr.hwChannel);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern float InnovateLC2AFR;
|
|
||||||
|
|
||||||
float getAfr(SensorType type) {
|
|
||||||
#if EFI_AUX_SERIAL
|
|
||||||
if (engineConfiguration->enableInnovateLC2)
|
|
||||||
return InnovateLC2AFR;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
afr_sensor_s * sensor = &engineConfiguration->afr;
|
|
||||||
|
|
||||||
if (!isAdcChannelValid(type == SensorType::Lambda1 ? engineConfiguration->afr.hwChannel : engineConfiguration->afr.hwChannel2)) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
float volts = getVoltageDivided("ego", type == SensorType::Lambda1 ? sensor->hwChannel : sensor->hwChannel2);
|
|
||||||
|
|
||||||
return interpolateMsg("AFR", sensor->v1, sensor->value1, sensor->v2, sensor->value2, volts)
|
|
||||||
+ engineConfiguration->egoValueShift;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void initEgoSensor(afr_sensor_s *sensor, ego_sensor_e type) {
|
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case ES_BPSX_D1:
|
case ES_BPSX_D1:
|
||||||
|
@ -78,8 +44,3 @@ static void initEgoSensor(afr_sensor_s *sensor, ego_sensor_e type) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void setEgoSensor(ego_sensor_e type) {
|
|
||||||
engineConfiguration->afr_type = type;
|
|
||||||
initEgoSensor(&engineConfiguration->afr, type);
|
|
||||||
}
|
|
||||||
|
|
|
@ -12,6 +12,4 @@
|
||||||
#include "global.h"
|
#include "global.h"
|
||||||
#include "engine_configuration.h"
|
#include "engine_configuration.h"
|
||||||
|
|
||||||
float getAfr(SensorType type);
|
|
||||||
bool hasAfrSensor();
|
|
||||||
void setEgoSensor(ego_sensor_e type);
|
void setEgoSensor(ego_sensor_e type);
|
||||||
|
|
|
@ -40,6 +40,7 @@ void deinitVbatt();
|
||||||
void deinitTps();
|
void deinitTps();
|
||||||
void deinitThermistors();
|
void deinitThermistors();
|
||||||
void deinitFluidPressure();
|
void deinitFluidPressure();
|
||||||
|
void deinitLambda();
|
||||||
void deInitFlexSensor();
|
void deInitFlexSensor();
|
||||||
void deInitVehicleSpeedSensor();
|
void deInitVehicleSpeedSensor();
|
||||||
void deinitTurbochargerSpeedSensor();
|
void deinitTurbochargerSpeedSensor();
|
||||||
|
|
|
@ -2,29 +2,13 @@
|
||||||
|
|
||||||
#include "init.h"
|
#include "init.h"
|
||||||
#include "adc_subscription.h"
|
#include "adc_subscription.h"
|
||||||
#include "function_pointer_sensor.h"
|
#include "linear_func.h"
|
||||||
#include "live_data.h"
|
#include "live_data.h"
|
||||||
|
|
||||||
struct GetAfrWrapper {
|
static LinearFunc func;
|
||||||
float getLambda() {
|
|
||||||
return getAfr(SensorType::Lambda1) / 14.7f;
|
|
||||||
};
|
|
||||||
float getLambda2() {
|
|
||||||
return getAfr(SensorType::Lambda2) / 14.7f;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
static GetAfrWrapper afrWrapper;
|
static FunctionalSensor lambdaSensor(SensorType::Lambda1, MS2NT(50));
|
||||||
|
static FunctionalSensor lambdaSensor2(SensorType::Lambda2, MS2NT(50));
|
||||||
static FunctionPointerSensor lambdaSensor(SensorType::Lambda1,
|
|
||||||
[]() {
|
|
||||||
return afrWrapper.getLambda();
|
|
||||||
});
|
|
||||||
|
|
||||||
static FunctionPointerSensor lambdaSensor2(SensorType::Lambda2,
|
|
||||||
[]() {
|
|
||||||
return afrWrapper.getLambda2();
|
|
||||||
});
|
|
||||||
|
|
||||||
#include "AemXSeriesLambda.h"
|
#include "AemXSeriesLambda.h"
|
||||||
|
|
||||||
|
@ -45,6 +29,15 @@ const wideband_state_s* getLiveData(size_t idx) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void initLambdaSensor(FunctionalSensor& sensor, adc_channel_e channel) {
|
||||||
|
if (!isAdcChannelValid(channel)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
AdcSubscription::SubscribeSensor(sensor, channel, 10);
|
||||||
|
sensor.Register();
|
||||||
|
}
|
||||||
|
|
||||||
void initLambda() {
|
void initLambda() {
|
||||||
|
|
||||||
#if EFI_CAN_SUPPORT
|
#if EFI_CAN_SUPPORT
|
||||||
|
@ -61,6 +54,20 @@ void initLambda() {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
lambdaSensor.Register();
|
auto& cfg = engineConfiguration->afr;
|
||||||
lambdaSensor2.Register();
|
float minLambda = (cfg.value1 + engineConfiguration->egoValueShift) / 14.7f;
|
||||||
|
float maxLambda = (cfg.value2 + engineConfiguration->egoValueShift) / 14.7f;
|
||||||
|
|
||||||
|
func.configure(cfg.v1, minLambda, cfg.v2, maxLambda, 0, 5);
|
||||||
|
|
||||||
|
lambdaSensor.setFunction(func);
|
||||||
|
lambdaSensor2.setFunction(func);
|
||||||
|
|
||||||
|
initLambdaSensor(lambdaSensor, engineConfiguration->afr.hwChannel);
|
||||||
|
initLambdaSensor(lambdaSensor2, engineConfiguration->afr.hwChannel2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void deinitLambda() {
|
||||||
|
AdcSubscription::UnsubscribeSensor(lambdaSensor, engineConfiguration->afr.hwChannel);
|
||||||
|
AdcSubscription::UnsubscribeSensor(lambdaSensor2, engineConfiguration->afr.hwChannel2);
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,12 +41,10 @@ void deInitIfValid(const char* msg, adc_channel_e channel) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void initOldAnalogInputs() {
|
static void initOldAnalogInputs() {
|
||||||
initIfValid("AFR", engineConfiguration->afr.hwChannel);
|
|
||||||
initIfValid("AUXF#1", engineConfiguration->auxFastSensor1_adcChannel);
|
initIfValid("AUXF#1", engineConfiguration->auxFastSensor1_adcChannel);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void deInitOldAnalogInputs() {
|
static void deInitOldAnalogInputs() {
|
||||||
deInitIfValid("AFR", activeConfiguration.afr.hwChannel);
|
|
||||||
deInitIfValid("AUXF#1", activeConfiguration.auxFastSensor1_adcChannel);
|
deInitIfValid("AUXF#1", activeConfiguration.auxFastSensor1_adcChannel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,6 +115,7 @@ void stopSensors() {
|
||||||
deinitFluidPressure();
|
deinitFluidPressure();
|
||||||
deinitVbatt();
|
deinitVbatt();
|
||||||
deinitThermistors();
|
deinitThermistors();
|
||||||
|
deinitLambda();
|
||||||
deInitFlexSensor();
|
deInitFlexSensor();
|
||||||
deInitVehicleSpeedSensor();
|
deInitVehicleSpeedSensor();
|
||||||
deinitTurbochargerSpeedSensor();
|
deinitTurbochargerSpeedSensor();
|
||||||
|
|
|
@ -259,9 +259,6 @@ struct pid_s
|
||||||
int16_t maxValue;Output Max Duty Cycle;"", 1, 0, -30000, 30000, 0
|
int16_t maxValue;Output Max Duty Cycle;"", 1, 0, -30000, 30000, 0
|
||||||
end_struct
|
end_struct
|
||||||
|
|
||||||
#define ego_sensor_e_enum "BPSX", "Innovate", "14Point7", "INVALID", "PLX", "Custom"
|
|
||||||
custom ego_sensor_e 1 bits, S08, @OFFSET@, [0:2], @@ego_sensor_e_enum@@
|
|
||||||
|
|
||||||
#define SentEtbType_enum "None", "GM type 1", "Ford type 1"
|
#define SentEtbType_enum "None", "GM type 1", "Ford type 1"
|
||||||
custom SentEtbType 1 bits, S08, @OFFSET@, [0:1], @@SentEtbType_enum@@
|
custom SentEtbType 1 bits, S08, @OFFSET@, [0:1], @@SentEtbType_enum@@
|
||||||
|
|
||||||
|
@ -614,7 +611,7 @@ engineSyncCam_e engineSyncCam;Select which cam is used for engine sync. Other ca
|
||||||
uint16_t autoscale vssGearRatio;Number of turns of your vehicle speed sensor per turn of the wheels. For example if your sensor is on the transmission output, enter your axle/differential ratio. If you are using a hub-mounted sensor, enter a value of 1.0.;"ratio", 0.001, 0, 0, 60, 3
|
uint16_t autoscale vssGearRatio;Number of turns of your vehicle speed sensor per turn of the wheels. For example if your sensor is on the transmission output, enter your axle/differential ratio. If you are using a hub-mounted sensor, enter a value of 1.0.;"ratio", 0.001, 0, 0, 60, 3
|
||||||
uint8_t vssToothCount;Number of pulses output per revolution of the shaft where your VSS is mounted. For example, GM applications of the T56 output 17 pulses per revolution of the transmission output shaft.;"count", 1, 0, 1, 100, 0
|
uint8_t vssToothCount;Number of pulses output per revolution of the shaft where your VSS is mounted. For example, GM applications of the T56 output 17 pulses per revolution of the transmission output shaft.;"count", 1, 0, 1, 100, 0
|
||||||
|
|
||||||
ego_sensor_e afr_type;AFR, WBO, EGO - whatever you like to call it;
|
uint8_t unused499
|
||||||
|
|
||||||
Gpio l9779_cs;
|
Gpio l9779_cs;
|
||||||
|
|
||||||
|
|
|
@ -2420,7 +2420,7 @@ cmd_set_engine_type_default = "@@TS_IO_TEST_COMMAND_char@@@@ts_command_e_TS_
|
||||||
field = "#The X axis of the bias table is controlled by the selected blend"
|
field = "#The X axis of the bias table is controlled by the selected blend"
|
||||||
field = "#parameter below."
|
field = "#parameter below."
|
||||||
field = "Blend parameter", veBlends1_blendParameter
|
field = "Blend parameter", veBlends1_blendParameter
|
||||||
panel = veBlend2Bias
|
panel = veBlend1Bias
|
||||||
|
|
||||||
dialog = veBlend2Cfg, "VE blend 2 config"
|
dialog = veBlend2Cfg, "VE blend 2 config"
|
||||||
field = "#The bias table controls how much of the blend table"
|
field = "#The bias table controls how much of the blend table"
|
||||||
|
@ -2949,14 +2949,17 @@ cmd_set_engine_type_default = "@@TS_IO_TEST_COMMAND_char@@@@ts_command_e_TS_
|
||||||
field = "MAF ADC input", mafAdcChannel
|
field = "MAF ADC input", mafAdcChannel
|
||||||
field = "MAF 2 ADC input", maf2AdcChannel
|
field = "MAF 2 ADC input", maf2AdcChannel
|
||||||
|
|
||||||
; Sensors->EGO sensor
|
|
||||||
dialog = egoSettings_sensor, "EGO sensor"
|
dialog = egoSettings_sensor, "EGO sensor"
|
||||||
field = "Type", afr_type
|
settingSelector = "Common O2 Controllers"
|
||||||
; todo: only use these values for custom!
|
settingOption = "BSPX", afr_v1=0,afr_v2=5,afr_value1=9,afr_value2=19,egoValueShift=0
|
||||||
field = "low voltage", afr_v1
|
settingOption = "Innovate", afr_v1=0,afr_v2=5,afr_value1=7.35,afr_value2=22.39,egoValueShift=0
|
||||||
field = "low value", afr_value1
|
settingOption = "14Point7", afr_v1=0,afr_v2=5,afr_value1=9.996,afr_value2=19.992,egoValueShift=0
|
||||||
field = "high voltage", afr_v2
|
settingOption = "PLX", afr_v1=0,afr_v2=5,afr_value1=10,afr_value2=20,egoValueShift=0
|
||||||
field = "high value", afr_value2
|
|
||||||
|
field = "Low voltage", afr_v1
|
||||||
|
field = "Low AFR", afr_value1
|
||||||
|
field = "High voltage", afr_v2
|
||||||
|
field = "High AFR", afr_value2
|
||||||
field = "Correction", egoValueShift
|
field = "Correction", egoValueShift
|
||||||
|
|
||||||
dialog = egoSettings_IO1, "EGO Sensor 1 I/O"
|
dialog = egoSettings_IO1, "EGO Sensor 1 I/O"
|
||||||
|
|
|
@ -214,10 +214,22 @@ TEST(SensorInit, Clt) {
|
||||||
TEST(SensorInit, Lambda) {
|
TEST(SensorInit, Lambda) {
|
||||||
EngineTestHelper eth(TEST_ENGINE);
|
EngineTestHelper eth(TEST_ENGINE);
|
||||||
|
|
||||||
|
// No channel -> no sensor
|
||||||
initLambda();
|
initLambda();
|
||||||
|
EXPECT_EQ(nullptr, Sensor::getSensorOfType(SensorType::Lambda1));
|
||||||
|
EXPECT_EQ(nullptr, Sensor::getSensorOfType(SensorType::Lambda2));
|
||||||
|
|
||||||
auto s = Sensor::getSensorOfType(SensorType::Lambda1);
|
// Channel -> sensor
|
||||||
ASSERT_NE(nullptr, s);
|
engineConfiguration->afr.hwChannel = EFI_ADC_0;
|
||||||
|
initLambda();
|
||||||
|
EXPECT_NE(nullptr, Sensor::getSensorOfType(SensorType::Lambda1));
|
||||||
|
EXPECT_EQ(nullptr, Sensor::getSensorOfType(SensorType::Lambda2));
|
||||||
|
|
||||||
|
// Channel 2 -> sensor 2
|
||||||
|
engineConfiguration->afr.hwChannel2 = EFI_ADC_1;
|
||||||
|
initLambda();
|
||||||
|
EXPECT_NE(nullptr, Sensor::getSensorOfType(SensorType::Lambda1));
|
||||||
|
EXPECT_NE(nullptr, Sensor::getSensorOfType(SensorType::Lambda2));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(SensorInit, Map) {
|
TEST(SensorInit, Map) {
|
||||||
|
|
Loading…
Reference in New Issue