2021-07-25 22:05:17 -07:00
|
|
|
#include "pch.h"
|
2021-06-27 15:51:34 -07:00
|
|
|
|
2021-07-25 22:05:17 -07:00
|
|
|
#include "ac_control.h"
|
2021-06-27 15:51:34 -07:00
|
|
|
#include "deadband.h"
|
2024-08-21 09:35:35 -07:00
|
|
|
#include "max_limit_with_hysteresis.h"
|
2021-06-27 15:51:34 -07:00
|
|
|
|
2024-08-21 07:48:42 -07:00
|
|
|
namespace {
|
|
|
|
// Deadbands to prevent rapid switching on/off of AC
|
|
|
|
Deadband<200> maxRpmDeadband;
|
|
|
|
Deadband<5> maxCltDeadband;
|
|
|
|
Deadband<5> maxTpsDeadband;
|
|
|
|
Deadband<AcController::PRESSURE_DEADBAND_WIDTH> minPressureDeadband;
|
2024-08-21 09:35:35 -07:00
|
|
|
MaxLimitWithHysteresis acPressureEnableHysteresis;
|
2024-08-21 07:48:42 -07:00
|
|
|
}
|
2021-06-27 15:51:34 -07:00
|
|
|
|
2021-11-25 04:59:31 -08:00
|
|
|
bool AcController::getAcState() {
|
2021-10-05 16:59:07 -07:00
|
|
|
auto rpm = Sensor::getOrZero(SensorType::Rpm);
|
2021-06-27 15:51:34 -07:00
|
|
|
|
2021-10-13 21:47:26 -07:00
|
|
|
engineTooSlow = rpm < 500;
|
|
|
|
|
|
|
|
if (engineTooSlow) {
|
2021-06-27 15:51:34 -07:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2021-11-17 00:54:21 -08:00
|
|
|
auto maxRpm = engineConfiguration->maxAcRpm;
|
2021-10-13 21:47:26 -07:00
|
|
|
engineTooFast = maxRpm != 0 && maxRpmDeadband.gt(rpm, maxRpm);
|
|
|
|
if (engineTooFast) {
|
|
|
|
return false;
|
2021-06-27 15:51:34 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
auto clt = Sensor::get(SensorType::Clt);
|
|
|
|
|
2021-10-13 21:47:26 -07:00
|
|
|
noClt = !clt;
|
2021-06-27 15:51:34 -07:00
|
|
|
// No AC with failed CLT
|
2021-10-13 21:47:26 -07:00
|
|
|
if (noClt) {
|
2021-06-27 15:51:34 -07:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Engine too hot, disable
|
2021-11-17 00:54:21 -08:00
|
|
|
auto maxClt = engineConfiguration->maxAcClt;
|
2021-10-16 16:03:36 -07:00
|
|
|
engineTooHot = (maxClt != 0) && maxCltDeadband.gt(clt.Value, maxClt);
|
2021-10-13 21:47:26 -07:00
|
|
|
if (engineTooHot) {
|
|
|
|
return false;
|
2021-06-27 15:51:34 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// TPS too high, disable
|
2021-11-17 00:54:21 -08:00
|
|
|
auto maxTps = engineConfiguration->maxAcTps;
|
2021-10-16 16:03:36 -07:00
|
|
|
tpsTooHigh = maxTps != 0 && maxTpsDeadband.gt(Sensor::getOrZero(SensorType::Tps1), maxTps);
|
2021-10-13 21:47:26 -07:00
|
|
|
if (tpsTooHigh) {
|
2021-06-27 15:51:34 -07:00
|
|
|
return false;
|
|
|
|
}
|
2024-06-18 03:14:31 -07:00
|
|
|
|
|
|
|
const auto acPressure= Sensor::get(SensorType::AcPressure);
|
|
|
|
if (acPressure.Valid) {
|
|
|
|
const auto minAcPressure = static_cast<float>(engineConfiguration->minAcPressure);
|
|
|
|
acPressureTooLow = minPressureDeadband.lt(acPressure.Value, minAcPressure);
|
|
|
|
if (acPressureTooLow) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
const auto maxAcPressure = static_cast<float>(engineConfiguration->maxAcPressure);
|
2024-08-21 09:35:35 -07:00
|
|
|
acPressureTooHigh = acPressureEnableHysteresis.checkIfLimitIsExceeded(
|
|
|
|
acPressure.Value,
|
|
|
|
maxAcPressure,
|
|
|
|
engineConfiguration->acPressureEnableHyst
|
|
|
|
);
|
2024-06-18 03:14:31 -07:00
|
|
|
if (acPressureTooHigh) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-08 18:28:38 -07:00
|
|
|
if (isDisabledByLua) {
|
|
|
|
return false;
|
|
|
|
}
|
2021-06-27 15:51:34 -07:00
|
|
|
|
|
|
|
// All conditions allow AC, simply pass thru switch
|
2021-10-13 21:47:26 -07:00
|
|
|
return acButtonState;
|
2021-06-27 15:51:34 -07:00
|
|
|
}
|
|
|
|
|
2021-11-25 04:59:31 -08:00
|
|
|
void AcController::onSlowCallback() {
|
2021-11-16 01:15:29 -08:00
|
|
|
bool isEnabled = getAcState();
|
2021-06-27 15:51:34 -07:00
|
|
|
|
2021-11-25 04:59:31 -08:00
|
|
|
m_acEnabled = isEnabled;
|
|
|
|
|
2022-08-31 16:01:42 -07:00
|
|
|
if (!isEnabled) {
|
|
|
|
// reset the timer if AC is off
|
|
|
|
m_timeSinceNoAc.reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
float acDelay = engineConfiguration->acDelay;
|
|
|
|
if (acDelay == 0) {
|
|
|
|
// Without delay configured, enable immediately
|
|
|
|
acCompressorState = isEnabled;
|
|
|
|
} else {
|
|
|
|
acCompressorState = isEnabled && m_timeSinceNoAc.hasElapsedSec(acDelay);
|
|
|
|
}
|
|
|
|
|
|
|
|
enginePins.acRelay.setValue(acCompressorState);
|
2021-11-25 04:59:31 -08:00
|
|
|
}
|
2021-06-27 15:51:34 -07:00
|
|
|
|
2021-11-25 04:59:31 -08:00
|
|
|
bool AcController::isAcEnabled() const {
|
|
|
|
return m_acEnabled;
|
2021-06-27 15:51:34 -07:00
|
|
|
}
|