From df03f3c536f54d96e7cf965b1810461842c75bac Mon Sep 17 00:00:00 2001 From: Matthew Kennedy Date: Thu, 9 Mar 2023 11:25:30 -0800 Subject: [PATCH] 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 --- firmware/console/status_loop.cpp | 3 +- firmware/controllers/sensors/impl/ego.cpp | 43 +---------------- firmware/controllers/sensors/impl/ego.h | 2 - firmware/init/init.h | 1 + firmware/init/sensor/init_lambda.cpp | 51 +++++++++++--------- firmware/init/sensor/init_sensors.cpp | 3 +- firmware/integration/rusefi_config.txt | 5 +- firmware/tunerstudio/rusefi.input | 19 +++++--- unit_tests/tests/sensor/test_sensor_init.cpp | 16 +++++- 9 files changed, 60 insertions(+), 83 deletions(-) diff --git a/firmware/console/status_loop.cpp b/firmware/console/status_loop.cpp index 4457f2a29b..20f32275c6 100644 --- a/firmware/console/status_loop.cpp +++ b/firmware/console/status_loop.cpp @@ -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); diff --git a/firmware/controllers/sensors/impl/ego.cpp b/firmware/controllers/sensors/impl/ego.cpp index 57bd577ac0..26a3f98ba2 100644 --- a/firmware/controllers/sensors/impl/ego.cpp +++ b/firmware/controllers/sensors/impl/ego.cpp @@ -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); -} diff --git a/firmware/controllers/sensors/impl/ego.h b/firmware/controllers/sensors/impl/ego.h index 57cfa1390e..f7d11f2b34 100644 --- a/firmware/controllers/sensors/impl/ego.h +++ b/firmware/controllers/sensors/impl/ego.h @@ -12,6 +12,4 @@ #include "global.h" #include "engine_configuration.h" -float getAfr(SensorType type); -bool hasAfrSensor(); void setEgoSensor(ego_sensor_e type); diff --git a/firmware/init/init.h b/firmware/init/init.h index 28632cafab..adc0508bd0 100644 --- a/firmware/init/init.h +++ b/firmware/init/init.h @@ -40,6 +40,7 @@ void deinitVbatt(); void deinitTps(); void deinitThermistors(); void deinitFluidPressure(); +void deinitLambda(); void deInitFlexSensor(); void deInitVehicleSpeedSensor(); void deinitTurbochargerSpeedSensor(); diff --git a/firmware/init/sensor/init_lambda.cpp b/firmware/init/sensor/init_lambda.cpp index c5e52f480c..abf6e65aea 100644 --- a/firmware/init/sensor/init_lambda.cpp +++ b/firmware/init/sensor/init_lambda.cpp @@ -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); } diff --git a/firmware/init/sensor/init_sensors.cpp b/firmware/init/sensor/init_sensors.cpp index 3f27673935..3092f9e7b7 100644 --- a/firmware/init/sensor/init_sensors.cpp +++ b/firmware/init/sensor/init_sensors.cpp @@ -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(); diff --git a/firmware/integration/rusefi_config.txt b/firmware/integration/rusefi_config.txt index 8c27b3aa06..3928cff35a 100644 --- a/firmware/integration/rusefi_config.txt +++ b/firmware/integration/rusefi_config.txt @@ -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; diff --git a/firmware/tunerstudio/rusefi.input b/firmware/tunerstudio/rusefi.input index 2e694e4b45..91938fec45 100644 --- a/firmware/tunerstudio/rusefi.input +++ b/firmware/tunerstudio/rusefi.input @@ -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" diff --git a/unit_tests/tests/sensor/test_sensor_init.cpp b/unit_tests/tests/sensor/test_sensor_init.cpp index 328973f654..8ff49b29e9 100644 --- a/unit_tests/tests/sensor/test_sensor_init.cpp +++ b/unit_tests/tests/sensor/test_sensor_init.cpp @@ -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) {