ignition controller detects rising edge on voltage (#3636)

* ignition controller detects rising edge on voltage

* update test

* comment

* ignore negative transients

* tweak

* test
This commit is contained in:
Matthew Kennedy 2021-12-07 18:28:04 -08:00 committed by GitHub
parent aae32fd3ca
commit 91ec135cf8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 81 additions and 17 deletions

View File

@ -4,10 +4,10 @@
#include "fuel_pump.h"
void FuelPumpController::onSlowCallback() {
auto uptime = getTimeNowSeconds();
auto timeSinceIgn = m_ignOnTimer.getElapsedSeconds();
// If the ECU just started, turn on the fuel pump to prime
isPrime = uptime >= 0 && uptime < engineConfiguration->startUpFuelPumpDuration;
// If the ignition just turned on, turn on the fuel pump to prime
isPrime = timeSinceIgn >= 0 && timeSinceIgn < engineConfiguration->startUpFuelPumpDuration;
// If there was a trigger event recently, turn on the pump, the engine is running!
auto timeSinceTrigger = engine->triggerCentral.getTimeSinceTriggerEvent(getTimeNowNt());
@ -21,3 +21,9 @@ void FuelPumpController::onSlowCallback() {
engine->outputChannels.isFuelPumpOn = isPumpOn;
#endif
}
void FuelPumpController::onIgnitionStateChanged(bool ignitionOn) {
if (ignitionOn) {
m_ignOnTimer.reset();
}
}

View File

@ -3,6 +3,11 @@
#include "engine_module.h"
#include "fuel_pump_generated.h"
struct FuelPumpController : public EngineModule, public fuel_pump_control_s {
class FuelPumpController : public EngineModule, public fuel_pump_control_s {
public:
void onSlowCallback() override;
void onIgnitionStateChanged(bool ignitionOn) override;
private:
Timer m_ignOnTimer;
};

View File

@ -6,8 +6,6 @@ void MainRelayController::onSlowCallback() {
isBenchTest = engine->isInMainRelayBench();
#if EFI_MAIN_RELAY_CONTROL
hasIgnitionVoltage = Sensor::getOrZero(SensorType::BatteryVoltage) > 5;
mainRelayState = isBenchTest | hasIgnitionVoltage;
#else // not EFI_MAIN_RELAY_CONTROL
mainRelayState = !isBenchTest;
@ -15,3 +13,7 @@ void MainRelayController::onSlowCallback() {
enginePins.mainRelay.setValue(mainRelayState);
}
void MainRelayController::onIgnitionStateChanged(bool ignitionOn) {
hasIgnitionVoltage = ignitionOn;
}

View File

@ -5,4 +5,5 @@
struct MainRelayController : public EngineModule, public main_relay_s {
void onSlowCallback() override;
void onIgnitionStateChanged(bool ignitionOn) override;
};

View File

@ -34,6 +34,7 @@
#include "ac_control.h"
#include "type_list.h"
#include "boost_control.h"
#include "ignition_controller.h"
#include "alternator_controller.h"
#ifndef EFI_UNIT_TEST
@ -154,6 +155,7 @@ public:
#endif /* EFI_ALTERNATOR_CONTROL */
FuelPumpController,
MainRelayController,
IgnitionController,
AcController,
EngineModule // dummy placeholder so the previous entries can all have commas
> engineModules;

View File

@ -21,6 +21,7 @@ CONTROLLERS_SRC_CPP = \
$(CONTROLLERS_DIR)/actuators/idle_thread_io.cpp \
$(CONTROLLERS_DIR)/actuators/idle_hardware.cpp \
$(CONTROLLERS_DIR)/actuators/idle_thread.cpp \
$(CONTROLLERS_DIR)/actuators/ignition_controller.cpp \
$(CONTROLLERS_DIR)/actuators/main_relay.cpp \
$(CONTROLLERS_DIR)/actuators/pwm_tester.cpp \
$(CONTROLLERS_DIR)/actuators/vvt.cpp \

View File

@ -10,4 +10,7 @@ public:
// Called approx 200Hz
virtual void onFastCallback() { }
// Called whenever the ignition switch state changes
virtual void onIgnitionStateChanged(bool ignitionOn) { }
};

View File

@ -0,0 +1,26 @@
#include "pch.h"
void IgnitionController::onSlowCallback() {
// default to 0 if failed sensor to prevent accidental ign-on if battery
// input misconfigured (or the ADC hasn't started yet)
auto hasIgnVoltage = Sensor::get(SensorType::BatteryVoltage).value_or(0) > 5;
if (hasIgnVoltage) {
m_timeSinceIgnVoltage.reset();
}
if (hasIgnVoltage == m_lastState) {
// nothing to do, states match
return;
}
// Ignore low voltage transients - we may see this at the start of cranking
// and we don't want to
if (!hasIgnVoltage && !m_timeSinceIgnVoltage.hasElapsedSec(0.2f)) {
return;
}
// Store state and notify other modules of the change
m_lastState = hasIgnVoltage;
engine->engineModules.apply_all([&](auto& m) { m.onIgnitionStateChanged(hasIgnVoltage); });
}

View File

@ -0,0 +1,14 @@
#pragma once
#include "engine_module.h"
#include "timer.h"
class IgnitionController : public EngineModule {
public:
void onSlowCallback() override;
private:
Timer m_timeSinceIgnVoltage;
bool m_lastState = false;
};

View File

@ -254,9 +254,10 @@ TEST(fsio, testLogicExpressions) {
extern int timeNowUs;
TEST(fsio, fuelPump) {
// this will init fuel pump fsio logic
EngineTestHelper eth(TEST_ENGINE);
FuelPumpController dut;
// Mock a fuel pump pin
engineConfiguration->fuelPumpPin = GPIOA_0;
// Re-init so it picks up the new config
@ -264,27 +265,30 @@ TEST(fsio, fuelPump) {
// ECU just started, haven't seen trigger yet
timeNowUs = 0.5e6;
engine->module<FuelPumpController>().unmock().onSlowCallback();
dut.onIgnitionStateChanged(true);
dut.onSlowCallback();
// Pump should be on!
EXPECT_TRUE(efiReadPin(GPIOA_0));
// Long time since ecu start, haven't seen trigger yet
timeNowUs = 60e6;
engine->module<FuelPumpController>().unmock().onSlowCallback();
dut.onIgnitionStateChanged(true);
timeNowUs += 10e6;
dut.onSlowCallback();
// Pump should be off!
EXPECT_FALSE(efiReadPin(GPIOA_0));
// Long time since ecu start, just saw a trigger!
timeNowUs = 10e6;
dut.onIgnitionStateChanged(true);
timeNowUs += 10e6;
engine->triggerCentral.handleShaftSignal(SHAFT_PRIMARY_FALLING, timeNowUs * US_TO_NT_MULTIPLIER);
engine->module<FuelPumpController>().unmock().onSlowCallback();
dut.onSlowCallback();
// Pump should be on!
EXPECT_TRUE(efiReadPin(GPIOA_0));
// ECU just started, and we just saw a trigger!
timeNowUs = 10e6;
dut.onIgnitionStateChanged(true);
engine->triggerCentral.handleShaftSignal(SHAFT_PRIMARY_FALLING, timeNowUs * US_TO_NT_MULTIPLIER);
engine->module<FuelPumpController>().unmock().onSlowCallback();
dut.onSlowCallback();
// Pump should be on!
EXPECT_TRUE(efiReadPin(GPIOA_0));
}

View File

@ -7,13 +7,13 @@ TEST(MainRelay, mr) {
MainRelayController dut;
// Low battery voltage, MR is off
Sensor::setMockValue(SensorType::BatteryVoltage, 1);
// Ignition is off, MR is off
dut.onIgnitionStateChanged(false);
dut.onSlowCallback();
EXPECT_EQ(enginePins.mainRelay.getLogicValue(), false);
// Ignition is now on, MR is on
Sensor::setMockValue(SensorType::BatteryVoltage, 12);
dut.onIgnitionStateChanged(true);
dut.onSlowCallback();
EXPECT_EQ(enginePins.mainRelay.getLogicValue(), true);
}