3
0
Fork 0
espmega-pro-ecu-genrator/src/GasolineGenerator.cpp

276 lines
No EOL
8.3 KiB
C++

#include "GasolineGenerator.hpp"
GasolineGenerator::GasolineGenerator()
{
}
/**
* @brief Initialize the Gasoline Generator.
*
* @note This does not start the generator, it only initializes the input and output cards,
*
* @param inputCard The digital input card used for monitoring the generator state
* @param outputCard The digital output card used for controlling the generator components
* @param config The configuration settings for the generator, pins are of input and output cards specified earlier.
*/
void GasolineGenerator::initialize(DigitalInputCard *inputCard, DigitalOutputCard *outputCard, const GasolineGeneratorConfig &config)
{
this->config = &config;
this->inputCard = inputCard;
this->outputCard = outputCard;
// Initialize all outputs to safe state
setIgnitionSystem(false);
setStarter(false);
setCarburetorValve(false); // Close for startup // Set debounce time for power output sensor if enabled
if (config.usePowerOutputSensor)
{
this->inputCard->setDebounceTime(config.powerOutputSensorPin, POWER_SENSOR_DEBOUNCE_MS);
}
// Set debounce time for toggle pin if enabled
if (config.useTogglePin)
{
this->inputCard->setDebounceTime(config.togglePin, POWER_SENSOR_DEBOUNCE_MS);
}
// Register input change callback
this->inputCard->registerCallback([this](uint8_t pin, bool state)
{ this->handleInputChanges(pin, state); });
state = GeneratorState::STOPPED;
}
/**
* @brief Main loop for the Gasoline Generator.
* * This function should be called periodically to handle the generator state machine.
*/
void GasolineGenerator::loop()
{
unsigned long currentTime = (xTaskGetTickCount() * 1000) / configTICK_RATE_HZ;
switch (state)
{
case GeneratorState::STARTING:
handleStartupSequence(currentTime);
break;
case GeneratorState::RUNNING: // Monitor engine status and handle any issues
if (config->usePowerOutputSensor)
{
bool hasPowerOutput = inputCard->digitalRead(config->powerOutputSensorPin);
if (!hasPowerOutput)
{
// Engine stopped unexpectedly - no power output detected
isEngineRunning = false;
shutdown();
}
}
break;
case GeneratorState::SHUTTING_DOWN:
// Complete shutdown sequence
state = GeneratorState::STOPPED;
break;
case GeneratorState::STOPPED:
default:
// Nothing to do in stopped state
break;
}
}
/**
* @brief Start the gasoline generator.
*
* This function initiates the startup sequence for the generator.
* It will close the carburetor valve, power up the ignition system,
* and engage the starter relay to start the engine.
*/
void GasolineGenerator::start()
{
if (state != GeneratorState::STOPPED)
{
return; // Already starting or running
}
state = GeneratorState::STARTING;
startupStartTime = (xTaskGetTickCount() * 1000) / configTICK_RATE_HZ;
ignitionStartTime = 0;
isEngineRunning = false;
starterEngaged = false;
// Step 1: Close carburetor valve for rich mixture
setCarburetorValve(false);
// Step 2: Power up ignition system
setIgnitionSystem(true);
ignitionStartTime = (xTaskGetTickCount() * 1000) / configTICK_RATE_HZ;
}
/**
* @brief Shutdown the gasoline generator.
*
* This function stops the generator by turning off all systems,
* including the starter, ignition system, and carburetor valve.
*/
void GasolineGenerator::shutdown()
{
// Turn off all systems
setStarter(false);
setIgnitionSystem(false);
setCarburetorValve(false); // Close carburetor valve
state = GeneratorState::STOPPED;
isEngineRunning = false;
}
/**
* @brief Set the carburetor valve state.
*
* @param open If true, opens the carburetor valve; if false, closes it.
* The actual pin state is reversed based on the configuration.
*/
void GasolineGenerator::setCarburetorValve(bool open)
{
bool pinState = config->carburetorValveReverse ? !open : open;
outputCard->digitalWrite(config->carburetorValvePin, pinState);
}
/**
* @brief Set the ignition system state.
*
* @param enable If true, powers the ignition system; if false, turns it off.
*/
void GasolineGenerator::setIgnitionSystem(bool enable)
{
outputCard->digitalWrite(config->ignitionSystemPowerRelayPin, enable);
}
/**
* @brief Set the starter relay state.
*
* @param enable If true, engages the starter; if false, disengages it.
*/
void GasolineGenerator::setStarter(bool enable)
{
outputCard->digitalWrite(config->starterRelayPin, enable);
starterEngaged = enable;
}
/**
* @brief Handle the startup sequence of the gasoline generator.
*
* This function manages the timing and state transitions during the startup process,
* including engaging the starter and checking for successful engine start.
*
* @param currentTime The current time in milliseconds since system start.
*/
void GasolineGenerator::handleStartupSequence(unsigned long currentTime)
{
// Step 3: After ignition delay, engage starter
if (ignitionStartTime > 0 &&
(currentTime - ignitionStartTime) >= IGNITION_DELAY_MS &&
!starterEngaged)
{
setStarter(true);
} // Check if we have power output AND starter is off (engine is running independently)
if (config->usePowerOutputSensor)
{
bool hasPowerOutput = inputCard->digitalRead(config->powerOutputSensorPin);
if (hasPowerOutput && !starterEngaged && !isEngineRunning)
{
onEngineStarted();
}
}
else
{
// No power sensor - fallback to time-based detection
if ((currentTime - startupStartTime) >= (IGNITION_DELAY_MS + 3000) && !isEngineRunning)
{
onEngineStarted();
}
}
// Timeout protection - stop starter after maximum duration
if (ignitionStartTime > 0 &&
(currentTime - ignitionStartTime) >= (IGNITION_DELAY_MS + STARTER_DURATION_MS))
{
setStarter(false);
if (!isEngineRunning)
{
// Failed to start
shutdown();
}
}
}
/**
* @brief Callback function called when the engine has successfully started.
*
* This function is called when the engine starts successfully after engaging the starter.
* It turns off the starter, opens the carburetor valve, and transitions to the RUNNING state.
*/
void GasolineGenerator::onEngineStarted()
{
isEngineRunning = true;
// Turn off starter
setStarter(false);
// Open carburetor valve for normal operation
setCarburetorValve(true);
state = GeneratorState::RUNNING;
}
/**
* @brief Handle input changes from the digital input card.
*
* This function processes changes in the state of input pins, particularly for the power output sensor
* and toggle switch. It checks if the engine has started or stopped based on the power output sensor state,
* and handles toggle switch presses to start/stop the generator.
*
* @param pin The pin number that changed state.
* @param state The new state of the pin (true for HIGH, false for LOW).
*/
void GasolineGenerator::handleInputChanges(uint8_t pin, bool state)
{
// Handle power output sensor changes
if (pin == config->powerOutputSensorPin)
{
if (state && this->state == GeneratorState::STARTING && !starterEngaged && !isEngineRunning)
{
// Power detected during startup with starter off - engine has started successfully
onEngineStarted();
}
else if (!state && this->state == GeneratorState::RUNNING)
{
// Power lost during operation - engine may have stopped
isEngineRunning = false;
shutdown();
}
}
// Handle toggle pin changes
if (pin == config->togglePin && config->useTogglePin)
{
if (state) // Toggle switch pressed (rising edge)
{
if (this->state == GeneratorState::STOPPED)
{
// Start the generator
start();
}
else if (this->state == GeneratorState::RUNNING)
{
// Stop the generator
shutdown();
}
// Ignore toggle during STARTING and SHUTTING_DOWN states
}
}
}