276 lines
No EOL
8.3 KiB
C++
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
|
|
}
|
|
}
|
|
} |