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:
Matthew Kennedy 2023-03-09 11:25:30 -08:00 committed by GitHub
parent b2010b6b8e
commit df03f3c536
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 60 additions and 83 deletions

View File

@ -465,8 +465,7 @@ static void updateRawSensors() {
}
}
// TODO: transition AFR to new sensor model
engine->outputChannels.rawAfr = (engineConfiguration->afr.hwChannel == EFI_ADC_NONE) ? 0 : getVoltageDivided("ego", engineConfiguration->afr.hwChannel);
engine->outputChannels.rawAfr = Sensor::getRaw(SensorType::Lambda1);
}
static void updatePressures() {
engine->outputChannels.baroPressure = Sensor::getOrZero(SensorType::BarometricPressure);

View File

@ -3,45 +3,11 @@
*
* 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 "cyclic_buffer.h"
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) {
void setEgoSensor(ego_sensor_e type) {
auto sensor = &engineConfiguration->afr;
switch (type) {
case ES_BPSX_D1:
@ -78,8 +44,3 @@ static void initEgoSensor(afr_sensor_s *sensor, ego_sensor_e type) {
break;
}
}
void setEgoSensor(ego_sensor_e type) {
engineConfiguration->afr_type = type;
initEgoSensor(&engineConfiguration->afr, type);
}

View File

@ -12,6 +12,4 @@
#include "global.h"
#include "engine_configuration.h"
float getAfr(SensorType type);
bool hasAfrSensor();
void setEgoSensor(ego_sensor_e type);

View File

@ -40,6 +40,7 @@ void deinitVbatt();
void deinitTps();
void deinitThermistors();
void deinitFluidPressure();
void deinitLambda();
void deInitFlexSensor();
void deInitVehicleSpeedSensor();
void deinitTurbochargerSpeedSensor();

View File

@ -2,29 +2,13 @@
#include "init.h"
#include "adc_subscription.h"
#include "function_pointer_sensor.h"
#include "linear_func.h"
#include "live_data.h"
struct GetAfrWrapper {
float getLambda() {
return getAfr(SensorType::Lambda1) / 14.7f;
};
float getLambda2() {
return getAfr(SensorType::Lambda2) / 14.7f;
}
};
static LinearFunc func;
static GetAfrWrapper afrWrapper;
static FunctionPointerSensor lambdaSensor(SensorType::Lambda1,
[]() {
return afrWrapper.getLambda();
});
static FunctionPointerSensor lambdaSensor2(SensorType::Lambda2,
[]() {
return afrWrapper.getLambda2();
});
static FunctionalSensor lambdaSensor(SensorType::Lambda1, MS2NT(50));
static FunctionalSensor lambdaSensor2(SensorType::Lambda2, MS2NT(50));
#include "AemXSeriesLambda.h"
@ -45,6 +29,15 @@ const wideband_state_s* getLiveData(size_t idx) {
return nullptr;
}
static void initLambdaSensor(FunctionalSensor& sensor, adc_channel_e channel) {
if (!isAdcChannelValid(channel)) {
return;
}
AdcSubscription::SubscribeSensor(sensor, channel, 10);
sensor.Register();
}
void initLambda() {
#if EFI_CAN_SUPPORT
@ -61,6 +54,20 @@ void initLambda() {
}
#endif
lambdaSensor.Register();
lambdaSensor2.Register();
auto& cfg = engineConfiguration->afr;
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);
}

View File

@ -41,12 +41,10 @@ void deInitIfValid(const char* msg, adc_channel_e channel) {
}
static void initOldAnalogInputs() {
initIfValid("AFR", engineConfiguration->afr.hwChannel);
initIfValid("AUXF#1", engineConfiguration->auxFastSensor1_adcChannel);
}
static void deInitOldAnalogInputs() {
deInitIfValid("AFR", activeConfiguration.afr.hwChannel);
deInitIfValid("AUXF#1", activeConfiguration.auxFastSensor1_adcChannel);
}
@ -117,6 +115,7 @@ void stopSensors() {
deinitFluidPressure();
deinitVbatt();
deinitThermistors();
deinitLambda();
deInitFlexSensor();
deInitVehicleSpeedSensor();
deinitTurbochargerSpeedSensor();

View File

@ -259,9 +259,6 @@ struct pid_s
int16_t maxValue;Output Max Duty Cycle;"", 1, 0, -30000, 30000, 0
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"
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
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;

View File

@ -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 = "#parameter below."
field = "Blend parameter", veBlends1_blendParameter
panel = veBlend2Bias
panel = veBlend1Bias
dialog = veBlend2Cfg, "VE blend 2 config"
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 2 ADC input", maf2AdcChannel
; Sensors->EGO sensor
dialog = egoSettings_sensor, "EGO sensor"
field = "Type", afr_type
; todo: only use these values for custom!
field = "low voltage", afr_v1
field = "low value", afr_value1
field = "high voltage", afr_v2
field = "high value", afr_value2
settingSelector = "Common O2 Controllers"
settingOption = "BSPX", afr_v1=0,afr_v2=5,afr_value1=9,afr_value2=19,egoValueShift=0
settingOption = "Innovate", afr_v1=0,afr_v2=5,afr_value1=7.35,afr_value2=22.39,egoValueShift=0
settingOption = "14Point7", afr_v1=0,afr_v2=5,afr_value1=9.996,afr_value2=19.992,egoValueShift=0
settingOption = "PLX", afr_v1=0,afr_v2=5,afr_value1=10,afr_value2=20,egoValueShift=0
field = "Low voltage", afr_v1
field = "Low AFR", afr_value1
field = "High voltage", afr_v2
field = "High AFR", afr_value2
field = "Correction", egoValueShift
dialog = egoSettings_IO1, "EGO Sensor 1 I/O"

View File

@ -214,10 +214,22 @@ TEST(SensorInit, Clt) {
TEST(SensorInit, Lambda) {
EngineTestHelper eth(TEST_ENGINE);
// No channel -> no sensor
initLambda();
EXPECT_EQ(nullptr, Sensor::getSensorOfType(SensorType::Lambda1));
EXPECT_EQ(nullptr, Sensor::getSensorOfType(SensorType::Lambda2));
auto s = Sensor::getSensorOfType(SensorType::Lambda1);
ASSERT_NE(nullptr, s);
// Channel -> sensor
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) {