CLT/IAT/Aux in the new sensor world (#1269)

* hook up clt

* init test

* probably fix test

* aux temp

* relax checking

* more significant figures

* remove old aux temp

* hand generate

* claim RAM

* move to ccm

* subscribe

* info printing

* warnings

* raise high voltage failure threshold

* fix test

Co-authored-by: Matthew Kennedy <makenne@microsoft.com>
This commit is contained in:
Matthew Kennedy 2020-04-07 13:07:09 -07:00 committed by GitHub
parent 00417b1040
commit 8006c0a548
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 180 additions and 40 deletions

View File

@ -405,8 +405,8 @@ case DBG_ANALOG_INPUTS2:
return "DBG_ANALOG_INPUTS2";
case DBG_AUX_PID_1:
return "DBG_AUX_PID_1";
case DBG_AUX_TEMPERATURE:
return "DBG_AUX_TEMPERATURE";
case DBG_34:
return "DBG_34";
case DBG_AUX_VALVES:
return "DBG_AUX_VALVES";
case DBG_BENCH_TEST:

View File

@ -718,6 +718,12 @@ void updateTunerStudioState(TunerStudioOutputChannels *tsOutputChannels DECLARE_
// offset 8
tsOutputChannels->intakeAirTemperature = intake;
SensorResult auxTemp1 = Sensor::get(SensorType::AuxTemp1);
tsOutputChannels->auxTemp1 = auxTemp1.Value;
SensorResult auxTemp2 = Sensor::get(SensorType::AuxTemp2);
tsOutputChannels->auxTemp2 = auxTemp2.Value;
SensorResult tps1 = Sensor::get(SensorType::Tps1);
tsOutputChannels->throttlePosition = tps1.Value;
tsOutputChannels->isTpsError = !tps1.Valid;
@ -919,11 +925,6 @@ void updateTunerStudioState(TunerStudioOutputChannels *tsOutputChannels DECLARE_
case DBG_START_STOP:
tsOutputChannels->debugIntField1 = engine->startStopStateToggleCounter;
break;
case DBG_AUX_TEMPERATURE:
// // 68
tsOutputChannels->debugFloatField1 = engine->sensors.auxTemp1;
tsOutputChannels->debugFloatField2 = engine->sensors.auxTemp2;
break;
case DBG_STATUS:
tsOutputChannels->debugFloatField1 = timeSeconds;
tsOutputChannels->debugIntField1 = atoi(VCS_VERSION);

View File

@ -547,8 +547,8 @@ case DBG_ANALOG_INPUTS2:
return "DBG_ANALOG_INPUTS2";
case DBG_AUX_PID_1:
return "DBG_AUX_PID_1";
case DBG_AUX_TEMPERATURE:
return "DBG_AUX_TEMPERATURE";
case DBG_34:
return "DBG_34";
case DBG_AUX_VALVES:
return "DBG_AUX_VALVES";
case DBG_BENCH_TEST:

View File

@ -123,18 +123,6 @@ void EngineState::updateSlowSensors(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
engine->sensors.clt = getCoolantTemperatureM(PASS_ENGINE_PARAMETER_SIGNATURE);
#endif /* EFI_CANBUS_SLAVE */
// todo: reduce code duplication with 'getCoolantTemperature'
if (engineConfiguration->auxTempSensor1.adcChannel != EFI_ADC_NONE) {
engine->sensors.auxTemp1 = getTemperatureC(&engineConfiguration->auxTempSensor1,
&engine->engineState.auxTemp1Curve,
false PASS_ENGINE_PARAMETER_SUFFIX);
}
if (engineConfiguration->auxTempSensor2.adcChannel != EFI_ADC_NONE) {
engine->sensors.auxTemp2 = getTemperatureC(&engineConfiguration->auxTempSensor2,
&engine->engineState.auxTemp2Curve,
false PASS_ENGINE_PARAMETER_SUFFIX);
}
#if EFI_UNIT_TEST
if (!cisnan(engine->sensors.mockClt)) {
engine->sensors.clt = engine->sensors.mockClt;

View File

@ -60,8 +60,6 @@ public:
float mockClt = NAN;
#endif
float clt = NAN;
float auxTemp1 = NAN;
float auxTemp2 = NAN;
Accelerometer accelerometer;

View File

@ -46,8 +46,6 @@ public:
// too much copy-paste here, something should be improved :)
ThermistorMath iatCurve;
ThermistorMath cltCurve;
ThermistorMath auxTemp1Curve;
ThermistorMath auxTemp2Curve;
/**
* MAP averaging angle start, in relation to 'mapAveragingSchedulingAtIndex' trigger index index

View File

@ -670,7 +670,7 @@ typedef enum {
*/
DBG_ANALOG_INPUTS2 = 32,
DBG_DWELL_METRIC = 33,
DBG_AUX_TEMPERATURE = 34,
DBG_34 = 34,
DBG_ETB_LOGIC = 35,
DBG_BOOST = 36,
DBG_START_STOP = 37,

View File

@ -686,7 +686,7 @@ void initEngineContoller(Logging *sharedLogger DECLARE_ENGINE_PARAMETER_SUFFIX)
// help to notice when RAM usage goes up - if a code change adds to RAM usage these variables would fail
// linking process which is the way to raise the alarm
#ifndef RAM_UNUSED_SIZE
#define RAM_UNUSED_SIZE 14200
#define RAM_UNUSED_SIZE 13850
#endif
#ifndef CCM_UNUSED_SIZE
#define CCM_UNUSED_SIZE 4100

View File

@ -27,6 +27,8 @@ protected:
void showInfo(Logging* logger, float testInputValue) const {
// base case does nothing
(void)logger;
(void)testInputValue;
}
};

View File

@ -16,8 +16,8 @@ SensorResult ResistanceFunc::convert(float raw) const {
return {false, 0.0f};
}
// If the voltage is very high (95% VCC), the sensor is open circuit.
if (raw > (m_supplyVoltage * 0.95f)) {
// If the voltage is very high (98% VCC), the sensor is open circuit.
if (raw > (m_supplyVoltage * 0.98f)) {
return {false, 1e6};
}
@ -29,5 +29,5 @@ SensorResult ResistanceFunc::convert(float raw) const {
void ResistanceFunc::showInfo(Logging* logger, float testInputValue) const {
const auto [valid, value] = convert(testInputValue);
scheduleMsg(logger, " %.2f volts -> %.1f ohms, with supply voltage %.2f and pullup %.1f.", testInputValue, value, m_supplyVoltage, m_pullupResistor);
scheduleMsg(logger, " %.2f volts -> %.1f ohms with supply voltage %.2f and pullup %.1f.", testInputValue, value, m_supplyVoltage, m_pullupResistor);
}

View File

@ -6,6 +6,7 @@
#include "thermistors.h"
#include "loggingcentral.h"
#include <math.h>
SensorResult ThermistorFunc::convert(float ohms) const {
@ -45,3 +46,8 @@ void ThermistorFunc::configure(thermistor_conf_s &cfg) {
m_b = u2 - m_c * (l1 * l1 + l1 * l2 + l2 * l2);
m_a = y1 - (m_b + l1 * l1 * m_c) * l1;
}
void ThermistorFunc::showInfo(Logging* logger, float testInputValue) const {
const auto [valid, value] = convert(testInputValue);
scheduleMsg(logger, " %.1f ohms -> valid: %d. %.1f deg C", testInputValue, valid, value);
}

View File

@ -16,6 +16,8 @@ public:
void configure(thermistor_conf_s &cfg);
void showInfo(Logging* logger, float testRawValue) const override;
private:
// Steinhart-Hart coefficients
float m_a;

View File

@ -33,10 +33,13 @@ static const char* s_sensorNames[] = {
"Acc Pedal Primary",
"Acc Pedal Secondary",
"Driver Acc Intent"
"Driver Acc Intent",
"Aux Temp 1",
"Aux Temp 2",
};
static_assert(efi::size(s_sensorNames) == efi::size(s_sensorNames));
static_assert(efi::size(s_sensorNames) == efi::size(s_sensorRegistry));
bool Sensor::Register() {
// Get a ref to where we should be

View File

@ -40,6 +40,9 @@ enum class SensorType : unsigned char {
// This maps to the pedal if we have one, and Tps1 if not.
DriverThrottleIntent,
AuxTemp1,
AuxTemp2,
// Leave me at the end!
PlaceholderLast
};

View File

@ -21,8 +21,10 @@ void reconfigureSensors(DECLARE_ENGINE_PARAMETER_SIGNATURE);
// Sensor init/config
void initTps(DECLARE_ENGINE_PARAMETER_SIGNATURE);
void initOilPressure(DECLARE_ENGINE_PARAMETER_SIGNATURE);
void initNewThermistors(DECLARE_ENGINE_PARAMETER_SIGNATURE);
void initCanSensors(DECLARE_ENGINE_PARAMETER_SIGNATURE);
// Sensor reconfiguration
void reconfigureTps(DECLARE_ENGINE_PARAMETER_SIGNATURE);
void reconfigureThermistors(DECLARE_ENGINE_PARAMETER_SIGNATURE);
void reconfigureOilPressure(DECLARE_ENGINE_PARAMETER_SIGNATURE);

View File

@ -3,4 +3,4 @@ INIT_SRC_CPP = $(PROJECT_DIR)/init/sensor/init_sensors.cpp \
$(PROJECT_DIR)/init/sensor/init_oil_pressure.cpp \
$(PROJECT_DIR)/init/sensor/init_tps.cpp \
$(PROJECT_DIR)/init/sensor/init_can_sensors.cpp \
$(PROJECT_DIR)/init/sensor/init_thermistors.cpp \

View File

@ -15,6 +15,7 @@ void initNewSensors(Logging* logger DECLARE_ENGINE_PARAMETER_SUFFIX) {
initTps(PASS_ENGINE_PARAMETER_SIGNATURE);
initOilPressure(PASS_ENGINE_PARAMETER_SIGNATURE);
initNewThermistors(PASS_ENGINE_PARAMETER_SIGNATURE);
// Init CLI functionality for sensors (mocking)
initSensorCli(logger);
@ -23,6 +24,7 @@ void initNewSensors(Logging* logger DECLARE_ENGINE_PARAMETER_SUFFIX) {
void reconfigureSensors(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
reconfigureTps(PASS_ENGINE_PARAMETER_SIGNATURE);
reconfigureOilPressure(PASS_ENGINE_PARAMETER_SIGNATURE);
reconfigureThermistors(PASS_ENGINE_PARAMETER_SIGNATURE);
}
static Logging* s_logger;

View File

@ -0,0 +1,113 @@
#include "adc_subscription.h"
#include "engine.h"
#include "error_handling.h"
#include "global.h"
#include "functional_sensor.h"
#include "func_chain.h"
#include "linear_func.h"
#include "resistance_func.h"
#include "thermistor_func.h"
EXTERN_ENGINE;
using resist = ResistanceFunc;
using therm = ThermistorFunc;
// Each one could be either linear or thermistor
struct FuncPair {
LinearFunc linear;
FuncChain<resist, therm> thermistor;
};
static CCM_OPTIONAL FunctionalSensor clt(SensorType::Clt, MS2NT(10));
static CCM_OPTIONAL FunctionalSensor iat(SensorType::Iat, MS2NT(10));
static CCM_OPTIONAL FunctionalSensor aux1(SensorType::AuxTemp1, MS2NT(10));
static CCM_OPTIONAL FunctionalSensor aux2(SensorType::AuxTemp2, MS2NT(10));
static FuncPair fclt, fiat, faux1, faux2;
static SensorConverter& configureTempSensorFunction(thermistor_conf_s& cfg, FuncPair& p, bool isLinear) {
if (isLinear) {
p.linear.configure(cfg.resistance_1, cfg.tempC_1, cfg.resistance_2, cfg.tempC_2, -50, 250);
return p.linear;
} else /* sensor is thermistor */ {
p.thermistor.get<resist>().configure(5.0f, cfg.bias_resistor);
p.thermistor.get<therm>().configure(cfg);
return p.thermistor;
}
}
void configTherm(FunctionalSensor &sensor,
FuncPair &p,
ThermistorConf &config,
bool isLinear) {
// Configure the conversion function for this sensor
sensor.setFunction(configureTempSensorFunction(config.config, p, isLinear));
}
static void configureTempSensor(FunctionalSensor &sensor,
FuncPair &p,
ThermistorConf &config,
bool isLinear) {
auto channel = config.adcChannel;
// Only register if we have a sensor
if (channel == EFI_ADC_NONE) {
return;
}
configTherm(sensor, p, config, isLinear);
AdcSubscription::SubscribeSensor(sensor, channel);
// Register & subscribe
if (!sensor.Register()) {
// uhh?
}
}
void initNewThermistors(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
configureTempSensor(clt,
fclt,
CONFIG(clt),
CONFIG(useLinearCltSensor));
configureTempSensor(iat,
fiat,
CONFIG(iat),
CONFIG(useLinearIatSensor));
configureTempSensor(aux1,
faux1,
CONFIG(auxTempSensor1),
false);
configureTempSensor(aux2,
faux2,
CONFIG(auxTempSensor2),
false);
}
void reconfigureThermistors(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
configTherm(clt,
fclt,
CONFIG(clt),
CONFIG(useLinearCltSensor));
configTherm(iat,
fiat,
CONFIG(iat),
CONFIG(useLinearIatSensor));
configTherm(aux1,
faux1,
CONFIG(auxTempSensor1),
false);
configTherm(aux2,
faux2,
CONFIG(auxTempSensor2),
false);
}

View File

@ -199,7 +199,7 @@ float baseFuel;+Base duration of the fuel injection during cranking, this is mod
int16_t rpm;+This sets the RPM limit below which the ECU will use cranking fuel and ignition logic, typically this is around 350-450rpm. \nset cranking_rpm X;"RPM", 1, 0, 0, 3000, 0
end_struct
#define debug_mode_e_enum "Alternator PID", "TPS acceleration enrichment", "INVALID", "Idle Control", "Engine Load accl enrich", "Trigger Counters", "FSIO_ADC", "AUX_PID_1", "VVT input", "Cranking", "Timing", "Closed-loop fuel corr PID", "VSS", "SD card", "sr5", "Knock", "Trigger Sync", "Electronic Throttle", "Executor", "Bench Test / TS commands", "Aux Valves", "Analog inputs #1", "INSTANT_RPM", "FSIO_EXPRESSION", "Status", "CJ125", "CAN", "MAP", "Metrics", "ETB#2", "Ion Sense", "TLE8888", "Analog inputs #2", "Dwell Metric", "Aux Temperature", "ETB Logic", "Boost Control", "Start/Stop", "Launch", "Mode39", "Mode40"
#define debug_mode_e_enum "Alternator PID", "TPS acceleration enrichment", "INVALID", "Idle Control", "Engine Load accl enrich", "Trigger Counters", "FSIO_ADC", "AUX_PID_1", "VVT input", "Cranking", "Timing", "Closed-loop fuel corr PID", "VSS", "SD card", "sr5", "Knock", "Trigger Sync", "Electronic Throttle", "Executor", "Bench Test / TS commands", "Aux Valves", "Analog inputs #1", "INSTANT_RPM", "FSIO_EXPRESSION", "Status", "CJ125", "CAN", "MAP", "Metrics", "ETB#2", "Ion Sense", "TLE8888", "Analog inputs #2", "Dwell Metric", "INVALID", "ETB Logic", "Boost Control", "Start/Stop", "Launch", "Mode39", "Mode40"
custom debug_mode_e 4 bits, U32, @OFFSET@, [0:7], @@debug_mode_e_enum@@
#define vvt_mode_e_enum "First half", "Second half", "2GZ", "Miata NB2", "mode4", "mode5", "mode6", "mode7"

View File

@ -28,15 +28,15 @@ TEST(resistance, OutOfRange)
EXPECT_FALSE(r.Valid);
}
// Something near 0.95 * 5v should be valid
// Something near 0.98 * 5v should be valid
{
auto r = f.convert(0.94f * 5);
auto r = f.convert(0.97f * 5);
EXPECT_TRUE(r.Valid);
}
// Something just above 0.95 * 5v should be invalid
// Something just above 0.98 * 5v should be invalid
{
auto r = f.convert(0.96f * 5);
auto r = f.convert(0.99f * 5);
EXPECT_FALSE(r.Valid);
}
}

View File

@ -15,7 +15,7 @@ static void postToFuncSensor(Sensor* s, float value) {
postToFuncSensor(s, raw); \
auto res = s->get(); \
EXPECT_TRUE(res.Valid); \
EXPECT_NEAR(res.Value, expect, EPS4D); \
EXPECT_NEAR(res.Value, expect, EPS2D); \
}
#define EXPECT_POINT_INVALID(s, raw) \
@ -90,7 +90,7 @@ TEST(SensorInit, DriverIntentNoPedal) {
}
TEST(SensorInit, DriverIntentWith) {
TEST(SensorInit, DriverIntentWithPedal) {
WITH_ENGINE_TEST_HELPER(TEST_ENGINE);
// We have a pedal, so we should get it
@ -133,3 +133,25 @@ TEST(SensorInit, OilPressure) {
EXPECT_POINT_INVALID(s, 0.0f);
EXPECT_POINT_INVALID(s, 5.0f);
}
TEST(SensorInit, Clt) {
WITH_ENGINE_TEST_HELPER(TEST_ENGINE);
// 2003 neon sensor
CONFIG(clt.config) = {0, 30, 100, 32500, 7550, 700, 2700};
initNewThermistors(PASS_ENGINE_PARAMETER_SIGNATURE);
// Ensure the sensors were registered
auto s = const_cast<Sensor*>(Sensor::getSensorOfType(SensorType::Clt));
ASSERT_NE(nullptr, s);
// Test in range
EXPECT_POINT_VALID(s, 4.61648f, 0.0f); // minimum - 0C
EXPECT_POINT_VALID(s, 3.6829f, 30.0f); // mid - 30C
EXPECT_POINT_VALID(s, 1.0294f, 100.0f) // maximium - 100C
// Test out of range
EXPECT_POINT_INVALID(s, 0.0f);
EXPECT_POINT_INVALID(s, 5.0f);
}