Move AC logic out of FSIO (#2872)
* new impl * remove fsio * inject "is ac active" to fan * include the correct code * include * test * more AC features * AC switch vs. actual AC indicators * include * duh
This commit is contained in:
parent
41060a1235
commit
cd5eb6a77c
|
@ -71,7 +71,7 @@ struct TunerStudioOutputChannels {
|
|||
unsigned int isCltError : 1; // bit 19
|
||||
unsigned int isMapError : 1; // bit 20
|
||||
unsigned int isIatError : 1; // bit 21
|
||||
unsigned int unusedAt22 : 1; // bit 22
|
||||
unsigned int acState : 1; // bit 22 - 1 if AC is engaged, 0 otherwise
|
||||
unsigned int isTriggerError : 1; // bit 23
|
||||
unsigned int hasCriticalError : 1; // bit 24
|
||||
unsigned int isWarnNow : 1; // bit 25
|
||||
|
|
|
@ -729,7 +729,6 @@ void updateTunerStudioState(TunerStudioOutputChannels *tsOutputChannels DECLARE_
|
|||
tsOutputChannels->clutchUpState = engine->clutchUpState;
|
||||
tsOutputChannels->clutchDownState = engine->clutchDownState;
|
||||
tsOutputChannels->brakePedalState = engine->brakePedalState;
|
||||
tsOutputChannels->acSwitchState = engine->acSwitchState;
|
||||
|
||||
#if EFI_ENGINE_CONTROL
|
||||
// tCharge depends on the previous state, so we should use the stored value.
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
#include "ac_control.h"
|
||||
#include "engine.h"
|
||||
|
||||
#include "deadband.h"
|
||||
#include "efi_gpio.h"
|
||||
#include "sensor.h"
|
||||
#include "tunerstudio_outputs.h"
|
||||
|
||||
EXTERN_ENGINE;
|
||||
|
||||
// Deadbands to prevent rapid switching on/off of AC
|
||||
static Deadband<200> maxRpmDeadband;
|
||||
static Deadband<5> maxCltDeadband;
|
||||
static Deadband<5> maxTpsDeadband;
|
||||
|
||||
static bool getAcState(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
|
||||
auto rpm = Sensor::get(SensorType::Rpm).value_or(0);
|
||||
|
||||
// Engine too slow, disable
|
||||
if (rpm < 500) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Engine too fast, disable
|
||||
auto maxRpm = CONFIG(maxAcRpm);
|
||||
if (maxRpm != 0) {
|
||||
if (maxRpmDeadband.gt(rpm, maxRpm)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
auto clt = Sensor::get(SensorType::Clt);
|
||||
|
||||
// No AC with failed CLT
|
||||
if (!clt) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Engine too hot, disable
|
||||
auto maxClt = CONFIG(maxAcClt);
|
||||
if (maxClt != 0) {
|
||||
if (maxCltDeadband.gt(maxClt, clt.Value)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// TPS too high, disable
|
||||
auto maxTps = CONFIG(maxAcTps);
|
||||
if (maxTps != 0) {
|
||||
auto tps = Sensor::get(SensorType::Tps1).value_or(0);
|
||||
|
||||
if (maxTpsDeadband.gt(maxTps, tps)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// All conditions allow AC, simply pass thru switch
|
||||
return ENGINE(acSwitchState);
|
||||
}
|
||||
|
||||
bool updateAc(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
|
||||
bool isEnabled = getAcState(PASS_ENGINE_PARAMETER_SIGNATURE);
|
||||
|
||||
enginePins.acRelay.setValue(isEnabled);
|
||||
|
||||
#if EFI_TUNER_STUDIO
|
||||
tsOutputChannels.acSwitchState = engine->acSwitchState;
|
||||
tsOutputChannels.acState = isEnabled;
|
||||
#endif // EFI_TUNER_STUDIO
|
||||
|
||||
return isEnabled;
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "engine_ptr.h"
|
||||
|
||||
// Returns true if AC is currently active
|
||||
bool updateAc(DECLARE_ENGINE_PARAMETER_SIGNATURE);
|
|
@ -7,13 +7,13 @@
|
|||
|
||||
EXTERN_ENGINE;
|
||||
|
||||
static void fanControl(OutputPin& pin, int8_t fanOnTemp, int8_t fanOffTemp, bool enableWithAc DECLARE_ENGINE_PARAMETER_SUFFIX) {
|
||||
static void fanControl(bool acActive, OutputPin& pin, int8_t fanOnTemp, int8_t fanOffTemp, bool enableWithAc DECLARE_ENGINE_PARAMETER_SUFFIX) {
|
||||
auto [cltValid, clt] = Sensor::get(SensorType::Clt);
|
||||
|
||||
if (!cltValid) {
|
||||
// If CLT is broken, turn the fan on
|
||||
pin.setValue(true);
|
||||
} else if (enableWithAc && ENGINE(acSwitchState)) {
|
||||
} else if (enableWithAc && acActive) {
|
||||
pin.setValue(true);
|
||||
} else if (clt > fanOnTemp) {
|
||||
// If hot, turn the fan on
|
||||
|
@ -26,13 +26,13 @@ static void fanControl(OutputPin& pin, int8_t fanOnTemp, int8_t fanOffTemp, bool
|
|||
}
|
||||
}
|
||||
|
||||
void updateFans(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
|
||||
void updateFans(bool acActive DECLARE_ENGINE_PARAMETER_SUFFIX) {
|
||||
#if EFI_PROD_CODE
|
||||
if (isRunningBenchTest()) {
|
||||
return; // let's not mess with bench testing
|
||||
}
|
||||
#endif
|
||||
|
||||
fanControl(enginePins.fanRelay, CONFIG(fanOnTemperature), CONFIG(fanOffTemperature), CONFIG(enableFan1WithAc) PASS_ENGINE_PARAMETER_SUFFIX);
|
||||
fanControl(enginePins.fanRelay2, CONFIG(fan2OnTemperature), CONFIG(fan2OffTemperature), CONFIG(enableFan2WithAc) PASS_ENGINE_PARAMETER_SUFFIX);
|
||||
fanControl(acActive, enginePins.fanRelay, CONFIG(fanOnTemperature), CONFIG(fanOffTemperature), CONFIG(enableFan1WithAc) PASS_ENGINE_PARAMETER_SUFFIX);
|
||||
fanControl(acActive, enginePins.fanRelay2, CONFIG(fan2OnTemperature), CONFIG(fan2OffTemperature), CONFIG(enableFan2WithAc) PASS_ENGINE_PARAMETER_SUFFIX);
|
||||
}
|
||||
|
|
|
@ -2,4 +2,4 @@
|
|||
|
||||
#include "engine_ptr.h"
|
||||
|
||||
void updateFans(DECLARE_ENGINE_PARAMETER_SIGNATURE);
|
||||
void updateFans(bool acActive DECLARE_ENGINE_PARAMETER_SUFFIX);
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include "dynoview.h"
|
||||
#include "boost_control.h"
|
||||
#include "fan_control.h"
|
||||
#include "ac_control.h"
|
||||
#if EFI_MC33816
|
||||
#include "mc33816.h"
|
||||
#endif // EFI_MC33816
|
||||
|
@ -229,7 +230,8 @@ void Engine::periodicSlowCallback(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
|
|||
runHardcodedFsio(PASS_ENGINE_PARAMETER_SIGNATURE);
|
||||
#endif /* EFI_FSIO */
|
||||
|
||||
updateFans(PASS_ENGINE_PARAMETER_SIGNATURE);
|
||||
bool acActive = updateAc(PASS_ENGINE_PARAMETER_SIGNATURE);
|
||||
updateFans(acActive PASS_ENGINE_PARAMETER_SUFFIX);
|
||||
|
||||
updateGppwm();
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ CONTROLLERSSRC =
|
|||
|
||||
CONTROLLERS_SRC_CPP = \
|
||||
$(CONTROLLERS_DIR)/actuators/electronic_throttle.cpp \
|
||||
$(CONTROLLERS_DIR)/actuators/ac_control.cpp \
|
||||
$(CONTROLLERS_DIR)/actuators/alternator_controller.cpp \
|
||||
$(CONTROLLERS_DIR)/actuators/boost_control.cpp \
|
||||
$(CONTROLLERS_DIR)/actuators/dc_motors.cpp \
|
||||
|
|
|
@ -105,7 +105,6 @@ FsioPointers::FsioPointers() : fsioLogics() {
|
|||
|
||||
static FsioPointers state;
|
||||
|
||||
static LEElement * acRelayLogic;
|
||||
static LEElement * fuelPumpLogic;
|
||||
static LEElement * starterRelayDisableLogic;
|
||||
|
||||
|
@ -497,10 +496,6 @@ void runFsio(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
|
|||
*/
|
||||
enginePins.o2heater.setValue(engine->rpmCalculator.isRunning());
|
||||
|
||||
if (isBrainPinValid(CONFIG(acRelayPin))) {
|
||||
setPinState("A/C", &enginePins.acRelay, acRelayLogic PASS_ENGINE_PARAMETER_SUFFIX);
|
||||
}
|
||||
|
||||
#if EFI_ENABLE_ENGINE_WARNING
|
||||
if (engineConfiguration->useFSIO4ForSeriousEngineWarning) {
|
||||
updateValueOrWarning(MAGIC_OFFSET_FOR_ENGINE_WARNING, "eng warning", &ENGINE(fsioState.isEngineWarning) PASS_ENGINE_PARAMETER_SUFFIX);
|
||||
|
@ -567,7 +562,6 @@ static void showFsio(const char *msg, LEElement *element) {
|
|||
static void showFsioInfo(void) {
|
||||
#if EFI_PROD_CODE || EFI_SIMULATOR
|
||||
efiPrintf("sys used %d/user used %d", sysPool.getSize(), userPool.getSize());
|
||||
showFsio("a/c", acRelayLogic);
|
||||
showFsio("fuel", fuelPumpLogic);
|
||||
|
||||
for (int i = 0; i < CAM_INPUTS_COUNT ; i++) {
|
||||
|
@ -690,8 +684,6 @@ void initFsioImpl(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
|
|||
fuelPumpLogic = sysPool.parseExpression(FUEL_PUMP_LOGIC);
|
||||
#endif /* EFI_FUEL_PUMP */
|
||||
|
||||
acRelayLogic = sysPool.parseExpression(AC_RELAY_LOGIC);
|
||||
|
||||
#if EFI_MAIN_RELAY_CONTROL
|
||||
if (isBrainPinValid(CONFIG(mainRelayPin)))
|
||||
mainRelayLogic = sysPool.parseExpression(MAIN_RELAY_LOGIC);
|
||||
|
@ -767,10 +759,6 @@ void runHardcodedFsio(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
|
|||
if (isBrainPinValid(CONFIG(starterRelayDisablePin))) {
|
||||
enginePins.starterRelayDisable.setValue(engine->rpmCalculator.getRpm() < engineConfiguration->cranking.rpm);
|
||||
}
|
||||
// see AC_RELAY_LOGIC
|
||||
if (isBrainPinValid(CONFIG(acRelayPin))) {
|
||||
enginePins.acRelay.setValue(getAcToggle(PASS_ENGINE_PARAMETER_SIGNATURE) && engine->rpmCalculator.getRpm() > 850);
|
||||
}
|
||||
// see FUEL_PUMP_LOGIC
|
||||
if (isBrainPinValid(CONFIG(fuelPumpPin))) {
|
||||
enginePins.fuelPumpRelay.setValue((getTimeNowSeconds() < engine->triggerActivitySecond + engineConfiguration->startUpFuelPumpDuration) || (engine->rpmCalculator.getRpm() > 0));
|
||||
|
|
|
@ -21,8 +21,6 @@
|
|||
// Human-readable: coolant > 120
|
||||
#define TOO_HOT_LOGIC "coolant 120 >"
|
||||
|
||||
// Human-readable: ac_on_switch & (rpm > 850)
|
||||
#define AC_RELAY_LOGIC "ac_on_switch rpm 850 > &"
|
||||
// Combined RPM, CLT and VBATT warning light
|
||||
|
||||
// Human-readable: (rpm > fsio_setting(2)) | ((coolant > fsio_setting(3)) | (vbatt < fsio_setting(4)))
|
||||
|
|
|
@ -13,8 +13,6 @@ FUEL_PUMP_LOGIC=((time_since_boot >= 0) & (time_since_boot < startup_fuel_pump_d
|
|||
|
||||
TOO_HOT_LOGIC=coolant > 120
|
||||
|
||||
AC_RELAY_LOGIC=ac_on_switch & (rpm > 850)
|
||||
|
||||
# Combined RPM, CLT and VBATT warning light
|
||||
COMBINED_WARNING_LIGHT=(rpm > fsio_setting(2)) | ((coolant > fsio_setting(3)) | (vbatt < fsio_setting(4)))
|
||||
|
||||
|
|
|
@ -1182,7 +1182,10 @@ custom pin_mode_e 1 bits, U08, @OFFSET@, [0:6], @@pin_mode_e_enum@@
|
|||
|
||||
! todo: rename field remove 'ms' since unusual case of dual-purpose field - it could be either ms or percent
|
||||
float tachPulseDuractionMs;;"", 1, 0, 0, 100, 2
|
||||
int unused1708;;"units", 1, 0, -20, 100, 0
|
||||
uint16_t maxAcRpm;+Above this RPM, disable AC. Set to 0 to disable check.;"rpm", 1, 0, 0, 10000, 0
|
||||
uint8_t maxAcTps;+Above this TPS, disable AC. Set to 0 to disable check.;"%", 1, 0, 0, 100, 0
|
||||
uint8_t maxAcClt;+Above this CLT, disable AC to prevent overheating the engine. Set to 0 to disable check.;"deg C", 1, 0, 0, 150, 0
|
||||
|
||||
|
||||
float wwaeTau;+Length of time the deposited wall fuel takes to dissipate after the start of acceleration. ;"Seconds", 1, 0, 0, 3, 2
|
||||
pid_s alternatorControl;
|
||||
|
|
|
@ -199,6 +199,7 @@ enable2ndByteCanID = false
|
|||
; ind_map_error = bits, U32, 0, [20:20], "true", "false";
|
||||
|
||||
ind_iat_error = bits, U32, 0, [21:21], "true", "false";
|
||||
acState = bits, U32, 0, [22:22], "true", "false";
|
||||
ind_isTriggerError = bits, U32, 0, [23:23], "true", "false";
|
||||
ind_hasFatalError=bits, U32, 0, [24:24], "true", "false";
|
||||
ind_isWarnNow =bits, U32, 0, [25:25], "true", "false";
|
||||
|
@ -1203,7 +1204,8 @@ gaugeCategory = DynoView
|
|||
indicator = { clutchUpState }, "clutch", "cltch Up", white, black, red, black
|
||||
indicator = { clutchDownState }, "clutch", "cltch Down", white, black, yellow, black
|
||||
indicator = { brakePedalIndicator }, "brake", "brake down", white, black, red, black
|
||||
indicator = { acSwitchState }, "AC off", "AC on", white, black, blue, white
|
||||
indicator = { acSwitchState }, "AC switch off", "AC switch on", white, black, blue, white
|
||||
indicator = { acState }, "AC off", "AC on", white, black, blue, white
|
||||
indicator = { isIdleClosedLoop }, "not idling", "idling", white, black, green, black
|
||||
indicator = { isIdleCoasting }, "not coasting", "coasting", white, black, green, black
|
||||
|
||||
|
@ -1392,6 +1394,7 @@ menuDialog = main
|
|||
subMenu = starterRelay, "Starter Disable relay"
|
||||
subMenu = fuelPump, "Fuel pump"
|
||||
subMenu = fanSetting, "Fan"
|
||||
subMenu = acSettings, "Air Conditioning"
|
||||
subMenu = tachSettings, "Tachometer"
|
||||
subMenu = malfunction, "Check engine light"
|
||||
subMenu = statusLeds, "Status LEDs"
|
||||
|
@ -2698,11 +2701,13 @@ cmd_set_engine_type_default = "@@TS_IO_TEST_COMMAND_char@@\x00\x31\x00\x00"
|
|||
dialog = acSettings, "A/C Settings"
|
||||
field = "A/C Relay", acRelayPin
|
||||
field = "A/C Relay Mode", acRelayPinMode
|
||||
field = "Max RPM", maxAcRpm
|
||||
field = "Max CLT", maxAcClt
|
||||
field = "Max TPS", maxAcTps
|
||||
|
||||
dialog = fanSetting, "Fan Settings"
|
||||
panel = fan1Settings
|
||||
panel = fan2Settings
|
||||
panel = acSettings
|
||||
|
||||
dialog = fuelPump, "Fuel Pump"
|
||||
field = "Pin", fuelPumpPin
|
||||
|
|
|
@ -9,41 +9,38 @@ TEST(FanControl, fan1) {
|
|||
engineConfiguration->fanOnTemperature = 90;
|
||||
engineConfiguration->fanOffTemperature = 80;
|
||||
engineConfiguration->enableFan1WithAc = false;
|
||||
engine->acSwitchState = false;
|
||||
|
||||
// Cold, fan should be off
|
||||
Sensor::setMockValue(SensorType::Clt, 75);
|
||||
updateFans(PASS_ENGINE_PARAMETER_SIGNATURE);
|
||||
updateFans(false PASS_ENGINE_PARAMETER_SUFFIX);
|
||||
EXPECT_EQ(false, enginePins.fanRelay.getLogicValue());
|
||||
|
||||
// Between thresholds, should still be off
|
||||
Sensor::setMockValue(SensorType::Clt, 85);
|
||||
updateFans(PASS_ENGINE_PARAMETER_SIGNATURE);
|
||||
updateFans(false PASS_ENGINE_PARAMETER_SUFFIX);
|
||||
EXPECT_EQ(false, enginePins.fanRelay.getLogicValue());
|
||||
|
||||
// Hot, fan should turn on
|
||||
Sensor::setMockValue(SensorType::Clt, 95);
|
||||
updateFans(PASS_ENGINE_PARAMETER_SIGNATURE);
|
||||
updateFans(false PASS_ENGINE_PARAMETER_SUFFIX);
|
||||
EXPECT_EQ(true, enginePins.fanRelay.getLogicValue());
|
||||
|
||||
// Between thresholds, should stay on
|
||||
Sensor::setMockValue(SensorType::Clt, 85);
|
||||
updateFans(PASS_ENGINE_PARAMETER_SIGNATURE);
|
||||
updateFans(false PASS_ENGINE_PARAMETER_SUFFIX);
|
||||
EXPECT_EQ(true, enginePins.fanRelay.getLogicValue());
|
||||
|
||||
// Below threshold, should turn off
|
||||
Sensor::setMockValue(SensorType::Clt, 75);
|
||||
updateFans(PASS_ENGINE_PARAMETER_SIGNATURE);
|
||||
updateFans(false PASS_ENGINE_PARAMETER_SUFFIX);
|
||||
EXPECT_EQ(false, enginePins.fanRelay.getLogicValue());
|
||||
|
||||
engineConfiguration->enableFan1WithAc = true;
|
||||
// Now AC is on, fan should turn on!
|
||||
engine->acSwitchState = true;
|
||||
updateFans(PASS_ENGINE_PARAMETER_SIGNATURE);
|
||||
updateFans(true PASS_ENGINE_PARAMETER_SUFFIX);
|
||||
EXPECT_EQ(true, enginePins.fanRelay.getLogicValue());
|
||||
|
||||
// Turn off AC, fan should turn off too.
|
||||
engine->acSwitchState = false;
|
||||
updateFans(PASS_ENGINE_PARAMETER_SIGNATURE);
|
||||
updateFans(false PASS_ENGINE_PARAMETER_SUFFIX);
|
||||
EXPECT_EQ(false, enginePins.fanRelay.getLogicValue());
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue