Add GasolineGenerator class and configuration for generator management
- Implement GasolineGenerator class with methods for initialization, startup, shutdown, and state management. - Introduce GasolineGeneratorConfig structure for configuration parameters. - Update main.cpp to initialize and use the GasolineGenerator instance. - Modify platformio.ini to include build flags for debugging and versioning.
This commit is contained in:
parent
7dbf37007a
commit
6ac762b1ec
6 changed files with 286 additions and 0 deletions
|
@ -13,4 +13,5 @@ platform = espressif32
|
||||||
board = wt32-eth01
|
board = wt32-eth01
|
||||||
framework = arduino
|
framework = arduino
|
||||||
lib_deps = siwats/ESPMegaPROR3@^2.9.5
|
lib_deps = siwats/ESPMegaPROR3@^2.9.5
|
||||||
|
build_flags = -DCORE_DEBUG_LEVEL=0 -DSW_VERSION='"generator-dev-1.0.0"' -DBOARD_MODEL='"ESPMegaPRO R3.3c"'
|
||||||
monitor_speed = 115200
|
monitor_speed = 115200
|
191
src/GasolineGenerator.cpp
Normal file
191
src/GasolineGenerator.cpp
Normal file
|
@ -0,0 +1,191 @@
|
||||||
|
#include "GasolineGenerator.hpp"
|
||||||
|
|
||||||
|
GasolineGenerator::GasolineGenerator()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
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 && config.powerOutputSensorPin >= 0)
|
||||||
|
{
|
||||||
|
this->inputCard->setDebounceTime(config.powerOutputSensorPin, POWER_SENSOR_DEBOUNCE_MS);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Register input change callback
|
||||||
|
this->inputCard->registerCallback([this](uint8_t pin, bool state)
|
||||||
|
{ this->handleInputChanges(pin, state); });
|
||||||
|
|
||||||
|
state = GeneratorState::STOPPED;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GasolineGenerator::loop()
|
||||||
|
{
|
||||||
|
unsigned long currentTime = millis();
|
||||||
|
|
||||||
|
switch (state)
|
||||||
|
{
|
||||||
|
case GeneratorState::STARTING:
|
||||||
|
handleStartupSequence(currentTime);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GeneratorState::RUNNING:
|
||||||
|
// Monitor engine status and handle any issues
|
||||||
|
if (config->usePowerOutputSensor && config->powerOutputSensorPin >= 0)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GasolineGenerator::start()
|
||||||
|
{
|
||||||
|
if (state != GeneratorState::STOPPED)
|
||||||
|
{
|
||||||
|
return; // Already starting or running
|
||||||
|
}
|
||||||
|
|
||||||
|
state = GeneratorState::STARTING;
|
||||||
|
startupStartTime = millis();
|
||||||
|
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 = millis();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GasolineGenerator::shutdown()
|
||||||
|
{
|
||||||
|
// Turn off all systems
|
||||||
|
setStarter(false);
|
||||||
|
setIgnitionSystem(false);
|
||||||
|
setCarburetorValve(false); // Close carburetor valve
|
||||||
|
|
||||||
|
state = GeneratorState::STOPPED;
|
||||||
|
isEngineRunning = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GasolineGenerator::setCarburetorValve(bool open)
|
||||||
|
{
|
||||||
|
bool pinState = config->carburetorValveReverse ? !open : open;
|
||||||
|
outputCard->digitalWrite(config->carburetorValvePin, pinState);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GasolineGenerator::setIgnitionSystem(bool enable)
|
||||||
|
{
|
||||||
|
outputCard->digitalWrite(config->ignitionSystemPowerRelayPin, enable);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GasolineGenerator::setStarter(bool enable)
|
||||||
|
{
|
||||||
|
outputCard->digitalWrite(config->starterRelayPin, enable);
|
||||||
|
starterEngaged = enable;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 && config->powerOutputSensorPin >= 0)
|
||||||
|
{
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GasolineGenerator::onEngineStarted()
|
||||||
|
{
|
||||||
|
isEngineRunning = true;
|
||||||
|
|
||||||
|
// Turn off starter
|
||||||
|
setStarter(false);
|
||||||
|
|
||||||
|
// Open carburetor valve for normal operation
|
||||||
|
setCarburetorValve(true);
|
||||||
|
|
||||||
|
state = GeneratorState::RUNNING;
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
75
src/GasolineGenerator.hpp
Normal file
75
src/GasolineGenerator.hpp
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
#include <DigitalOutputCard.hpp>
|
||||||
|
#include <DigitalInputCard.hpp>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Configuration structure for the Gasoline Generator.
|
||||||
|
*
|
||||||
|
* This structure holds the configuration parameters for the gasoline generator,
|
||||||
|
* including input and output cards, pin assignments, and sensor settings.
|
||||||
|
* It is used to initialize the GasolineGenerator class.
|
||||||
|
* * @note The `inputCard` and `outputCard` should be initialized before passing to the GasolineGenerator.
|
||||||
|
* * @note The `ignitionSystemPowerRelayPin`, `starterRelayPin`, and `carburetorValvePin` should be set to the correct GPIO pin numbers.
|
||||||
|
* * @note The `carburetorValveReverse` flag indicates whether the carburetor valve operates in reverse logic (0=open, 1=closed).
|
||||||
|
**/
|
||||||
|
|
||||||
|
struct GasolineGeneratorConfig
|
||||||
|
{
|
||||||
|
int8_t ignitionSystemPowerRelayPin; // Pin for ignition system power relay
|
||||||
|
int8_t starterRelayPin; // Pin for starter relay
|
||||||
|
int8_t carburetorValvePin; // Pin for carburetor control
|
||||||
|
bool carburetorValveReverse; // If true, 0 means open, 1 means closed else 0 means closed, 1 means open
|
||||||
|
int8_t powerOutputSensorPin = -1; // Pin for monitoring generator power output (-1 to disable)
|
||||||
|
bool usePowerOutputSensor = false; // Enable/disable power output sensor monitoring
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enumeration for the generator states.
|
||||||
|
* This enum defines the possible states of the gasoline generator.
|
||||||
|
*/
|
||||||
|
enum class GeneratorState {
|
||||||
|
STOPPED,
|
||||||
|
STARTING,
|
||||||
|
RUNNING,
|
||||||
|
SHUTTING_DOWN
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gasoline Generator class for managing a gasoline-powered generator.
|
||||||
|
*
|
||||||
|
* This class handles the ignition system, starter relay, and carburetor control
|
||||||
|
* For startup first it closes the carburetor valve, creating a rich air-fuel mixture,
|
||||||
|
* then it powers the ignition system, wait a bit then spin the starter relay to start the engine.
|
||||||
|
* After the engine starts, it opens the carburetor valve to allow normal operation.
|
||||||
|
*/
|
||||||
|
class GasolineGenerator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GasolineGenerator();
|
||||||
|
void initialize(DigitalInputCard* inputCard, DigitalOutputCard* outputCard, const GasolineGeneratorConfig &config);
|
||||||
|
void loop();
|
||||||
|
void start();
|
||||||
|
void shutdown();
|
||||||
|
|
||||||
|
private:
|
||||||
|
const GasolineGeneratorConfig *config = nullptr;
|
||||||
|
DigitalInputCard *inputCard = nullptr;
|
||||||
|
DigitalOutputCard *outputCard = nullptr;
|
||||||
|
GeneratorState state = GeneratorState::STOPPED;
|
||||||
|
unsigned long startupStartTime = 0;
|
||||||
|
unsigned long ignitionStartTime = 0;
|
||||||
|
bool isEngineRunning = false;
|
||||||
|
bool starterEngaged = false;
|
||||||
|
|
||||||
|
static const unsigned long IGNITION_DELAY_MS = 2000; // Time to wait after powering ignition system before engaging starter
|
||||||
|
static const unsigned long STARTER_DURATION_MS = 5000; // Time that the starter should be engaged
|
||||||
|
static const unsigned long CARBURETOR_OPEN_DELAY_MS = 1000; // Time to wait after engine start for the engine to stabilize before opening the carburetor valve
|
||||||
|
static const unsigned long POWER_SENSOR_DEBOUNCE_MS = 500; // Debounce time for power output sensor
|
||||||
|
|
||||||
|
void setCarburetorValve(bool open);
|
||||||
|
void setIgnitionSystem(bool enable);
|
||||||
|
void setStarter(bool enable);
|
||||||
|
void handleStartupSequence(unsigned long currentTime);
|
||||||
|
void onEngineStarted();
|
||||||
|
void handleInputChanges(uint8_t pin, bool state);
|
||||||
|
};
|
0
src/config.hpp
Normal file
0
src/config.hpp
Normal file
17
src/main.cpp
17
src/main.cpp
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
ESPMegaPRO espmega = ESPMegaPRO();
|
ESPMegaPRO espmega = ESPMegaPRO();
|
||||||
|
|
||||||
|
GasolineGenerator generator;
|
||||||
|
|
||||||
void setup()
|
void setup()
|
||||||
{
|
{
|
||||||
// Initialize both displayports
|
// Initialize both displayports
|
||||||
|
@ -48,9 +50,24 @@ void setup()
|
||||||
ESP_LOGV("OS", "Registering Cards with IoT");
|
ESP_LOGV("OS", "Registering Cards with IoT");
|
||||||
espmega.iot->registerCard(0);
|
espmega.iot->registerCard(0);
|
||||||
espmega.iot->registerCard(1);
|
espmega.iot->registerCard(1);
|
||||||
|
|
||||||
|
// Initialize generator
|
||||||
|
|
||||||
|
GasolineGeneratorConfig generatorConfig;
|
||||||
|
generatorConfig.ignitionSystemPowerRelayPin = 0;
|
||||||
|
generatorConfig.starterRelayPin = 1;
|
||||||
|
generatorConfig.carburetorValvePin = 2;
|
||||||
|
generatorConfig.carburetorValveReverse = false;
|
||||||
|
generatorConfig.powerOutputSensorPin = -1;
|
||||||
|
generatorConfig.usePowerOutputSensor = false;
|
||||||
|
|
||||||
|
generator.initialize(&espmega.inputs, &espmega.outputs, generatorConfig);
|
||||||
|
|
||||||
|
ESP_LOGI("OS", "Initialization Complete");
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop()
|
void loop()
|
||||||
{
|
{
|
||||||
espmega.loop();
|
espmega.loop();
|
||||||
|
generator.loop();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
#include "config.hpp"
|
||||||
#include <ESPMegaProOS.hpp>
|
#include <ESPMegaProOS.hpp>
|
||||||
#include <ETH.h>
|
#include <ETH.h>
|
||||||
|
#include "GasolineGenerator.hpp"
|
||||||
|
|
||||||
#define INTERNAL_DISPLAY_UART Serial
|
#define INTERNAL_DISPLAY_UART Serial
|
||||||
#define INTERNAL_DISPLAY_BAUDRATE 115200
|
#define INTERNAL_DISPLAY_BAUDRATE 115200
|
Loading…
Add table
Add a link
Reference in a new issue