@@ -9,10 +9,10 @@
|
|||||||
|
|
||||||
[platformio]
|
[platformio]
|
||||||
|
|
||||||
default_envs = MVG_SC_EC_M505_TCP ; Select here the name of the configuration you want to download
|
default_envs = BKR_ABB_EMax2_TCP ; Select here the name of the configuration you want to download
|
||||||
|
|
||||||
[env]
|
[env]
|
||||||
upload_port = COM26
|
upload_port = COM19
|
||||||
|
|
||||||
[common_env_options]
|
[common_env_options]
|
||||||
framework = arduino
|
framework = arduino
|
||||||
@@ -254,3 +254,10 @@ extends = common_env_options
|
|||||||
build_flags = -D USE_MODBUS_IP,
|
build_flags = -D USE_MODBUS_IP,
|
||||||
build_src_filter = -<*> +<EPMS/MVG/MVG_SC_EC_M505_TCP>
|
build_src_filter = -<*> +<EPMS/MVG/MVG_SC_EC_M505_TCP>
|
||||||
|
|
||||||
|
[env:GEN_CAT_GCCP_TCP]
|
||||||
|
platform = espressif32
|
||||||
|
board = dfrobot_firebeetle2_esp32e
|
||||||
|
extends = common_env_options
|
||||||
|
build_flags = -D USE_MODBUS_IP,
|
||||||
|
build_src_filter = -<*> +<EPMS/GEN/GEN_CAT_GCCP_TCP>
|
||||||
|
|
||||||
|
|||||||
@@ -38,6 +38,13 @@
|
|||||||
*/
|
*/
|
||||||
template<>
|
template<>
|
||||||
RunningState<ModbusIP>::RunningState() {
|
RunningState<ModbusIP>::RunningState() {
|
||||||
|
addStrategy("V_AB", new SingleValueStrategy(4800.0F, 5.0f, 1000));
|
||||||
|
addStrategy("V_BC", new SingleValueStrategy(4800.0F, 5.0f, 1000));
|
||||||
|
addStrategy("V_CA", new SingleValueStrategy(4800.0F, 5.0f, 1000));
|
||||||
|
|
||||||
|
addStrategy("Amps A", new SingleValueStrategy(1.0f, 10.0f, 1000));
|
||||||
|
addStrategy("Amps B", new SingleValueStrategy(1.0f, 10.0f, 1000));
|
||||||
|
addStrategy("Amps C", new SingleValueStrategy(1.0f, 10.0f, 1000));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -57,7 +64,48 @@ template<>
|
|||||||
State<ModbusIP>* RunningState<ModbusIP>::update(Equipment<ModbusIP>* equipment) {
|
State<ModbusIP>* RunningState<ModbusIP>::update(Equipment<ModbusIP>* equipment) {
|
||||||
// STATE control, add conditions if change to a different state is needed
|
// STATE control, add conditions if change to a different state is needed
|
||||||
Serial.println("Running update function");
|
Serial.println("Running update function");
|
||||||
|
float State_Ctrl = getPointValue(equipment, "PxControl");
|
||||||
|
if (State_Ctrl == 0.0f){
|
||||||
|
return new StandbyState<ModbusIP>();
|
||||||
|
}
|
||||||
|
if (State_Ctrl == 1.0f){
|
||||||
|
setBitValue(equipment, "CB_Position", 0, true);
|
||||||
|
setBitValue(equipment, "CB_Position", 12, false);
|
||||||
|
}
|
||||||
|
if (State_Ctrl == 2.0f){
|
||||||
|
return new StandbyState<ModbusIP>();
|
||||||
|
}
|
||||||
|
|
||||||
|
float volts_AB = getPointValue(equipment, "V_AB");
|
||||||
|
float volts_BC = getPointValue(equipment, "V_BC");
|
||||||
|
float volts_AC = getPointValue(equipment, "V_CA");
|
||||||
|
|
||||||
|
setPointValue(equipment, "V_AN", volts_AB/1.732f);
|
||||||
|
setPointValue(equipment, "V_BN", volts_BC/1.732f);
|
||||||
|
setPointValue(equipment, "V_CN", volts_AC/1.732f);
|
||||||
|
|
||||||
|
|
||||||
|
int I_load = getPointValue(equipment, "PxLoad");
|
||||||
|
int I_rating = getPointValue(equipment, "PxRating");
|
||||||
|
float load = static_cast<float>(I_load);
|
||||||
|
float rating = static_cast<float>(I_rating);
|
||||||
|
float real_load = rating * (load/100.0f);
|
||||||
|
setPointValue(equipment, "Amps A", real_load * 10.0f);
|
||||||
|
setPointValue(equipment, "Amps B", real_load * 10.0f);
|
||||||
|
setPointValue(equipment, "Amps C", real_load * 10.0f);
|
||||||
|
setPointValue(equipment, "Amps G", volts_AB * 0.037f);
|
||||||
|
setPointValue(equipment, "Amps N", volts_BC * 0.034f);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
float kva = (1.732f * ((volts_AB + volts_BC + volts_AC)/4.0f) * real_load * (0.92f))/100000.0f;
|
||||||
|
float kw = (1.732f * ((volts_AB + volts_BC + volts_AC)/4.0f) * real_load )/10000.0f;
|
||||||
|
|
||||||
|
setPointValue(equipment, "kW", kw);
|
||||||
|
setPointValue(equipment, "kVA", kva);
|
||||||
|
setPointValue(equipment, "kVA2", kva);
|
||||||
|
setPointValue(equipment, "kWh", 1724.0f);
|
||||||
// Apply any strategies defined for the standby state
|
// Apply any strategies defined for the standby state
|
||||||
_applyStrategies(equipment);
|
_applyStrategies(equipment);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|||||||
@@ -56,7 +56,18 @@ template<>
|
|||||||
State<ModbusIP>* StandbyState<ModbusIP>::update(Equipment<ModbusIP>* equipment) {
|
State<ModbusIP>* StandbyState<ModbusIP>::update(Equipment<ModbusIP>* equipment) {
|
||||||
// STATE control, add conditions if change to a different state is needed
|
// STATE control, add conditions if change to a different state is needed
|
||||||
Serial.println("Standby update function");
|
Serial.println("Standby update function");
|
||||||
|
float State_Ctrl = getPointValue(equipment, "PxControl");
|
||||||
|
if (State_Ctrl == 1.0f){
|
||||||
|
return new RunningState<ModbusIP>();
|
||||||
|
}
|
||||||
|
if (State_Ctrl == 0.0f){
|
||||||
|
setBitValue(equipment, "CB_Position", 0, false);
|
||||||
|
setBitValue(equipment, "CB_Position", 12, false);
|
||||||
|
}
|
||||||
|
if (State_Ctrl == 2.0f){
|
||||||
|
setBitValue(equipment, "CB_Position", 0, false);
|
||||||
|
setBitValue(equipment, "CB_Position", 12, true);
|
||||||
|
}
|
||||||
// Apply any strategies defined for the standby state
|
// Apply any strategies defined for the standby state
|
||||||
_applyStrategies(equipment);
|
_applyStrategies(equipment);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@@ -72,6 +83,21 @@ template<>
|
|||||||
void StandbyState<ModbusIP>::enterState(Equipment<ModbusIP>* equipment) {
|
void StandbyState<ModbusIP>::enterState(Equipment<ModbusIP>* equipment) {
|
||||||
// Logic to run when the equipment enters this state
|
// Logic to run when the equipment enters this state
|
||||||
Serial.println("Enter Standby State...");
|
Serial.println("Enter Standby State...");
|
||||||
|
setPointValue(equipment, "V_AB", 0.0f);
|
||||||
|
setPointValue(equipment, "V_BC", 0.0f);
|
||||||
|
setPointValue(equipment, "V_CA", 0.0f);
|
||||||
|
setPointValue(equipment, "V_AN", 0.0f);
|
||||||
|
setPointValue(equipment, "V_BN", 0.0f);
|
||||||
|
setPointValue(equipment, "V_CN", 0.0f);
|
||||||
|
setPointValue(equipment, "Amps A", 0.0f);
|
||||||
|
setPointValue(equipment, "Amps B", 0.0f);
|
||||||
|
setPointValue(equipment, "Amps C", 0.0f);
|
||||||
|
setPointValue(equipment, "Amps G", 0.0f);
|
||||||
|
setPointValue(equipment, "Amps N", 0.0f);
|
||||||
|
setPointValue(equipment, "kW", 0.0f);
|
||||||
|
setPointValue(equipment, "k_VA", 0.0f);
|
||||||
|
setPointValue(equipment, "k_VA2", 0.0f);
|
||||||
|
setPointValue(equipment, "kWh", 0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -21,10 +21,10 @@
|
|||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
#include <ModbusIP_ESP8266.h>
|
#include <ModbusIP_ESP8266.h>
|
||||||
const char *ssid = "ArduinoWifiB"; /**< @brief The SSID of the WiFi network. */
|
const char *ssid = "wifi"; /**< @brief The SSID of the WiFi network. */
|
||||||
const char *password = "123abc456"; /**< @brief The password for the WiFi network. */
|
const char *password = "password"; /**< @brief The password for the WiFi network. */
|
||||||
IPAddress local_IP(172, 17, 32, 90); /**< @brief The static IP address for the device. */
|
IPAddress local_IP(192, 168, 1, 170); /**< @brief The static IP address for the device. */
|
||||||
IPAddress gateway(172, 17, 32, 1); /**< @brief The gateway IP address. */
|
IPAddress gateway(192, 168, 1, 1); /**< @brief The gateway IP address. */
|
||||||
IPAddress subnet(255, 255, 255, 0); /**< @brief The subnet mask. */
|
IPAddress subnet(255, 255, 255, 0); /**< @brief The subnet mask. */
|
||||||
|
|
||||||
ModbusIP mb;
|
ModbusIP mb;
|
||||||
@@ -63,23 +63,25 @@ modbusMap mb_map[] = {
|
|||||||
// Convert from ESP8266 to traditional Modbus addressing: subtract 30001/40001.
|
// Convert from ESP8266 to traditional Modbus addressing: subtract 30001/40001.
|
||||||
|
|
||||||
// Input Registers (3x) - Floating Point (MSB & LSB)
|
// Input Registers (3x) - Floating Point (MSB & LSB)
|
||||||
{IR, 40, 0, "CB_Position" }, // 300041.0 - Circuit Breaker Position
|
{HR, 9, 0, "PxControl"}, //Open-Close Cmd
|
||||||
{IR, 40, 0, "CB_Trip" }, // 300041.12 - Circuit Breaker Tripped
|
{HR, 10, 0, "PxLoad"}, //Adjustble Load
|
||||||
{IR_LONG, 100, 0, "Amps_A" }, //DWORD
|
{HR, 11, 0, "PxRating"}, //Max amp to calculate kw, kVA, etc
|
||||||
{IR_LONG, 102, 0, "Amps_B" }, //DWORD
|
{IR, 39, 0, "CB_Position" }, // 300041.0 - Circuit Breaker Position || 300041.12 - Circuit Breaker Tripped
|
||||||
{IR_LONG, 104, 0, "Amps_C" }, //DWORD
|
{IR_LONG, 99, 0, "Amps A" }, //DWORD
|
||||||
{IR_LONG, 106, 0, "Amps_N" }, //DWORD
|
{IR_LONG, 101, 0, "Amps B" }, //DWORD
|
||||||
{IR_LONG, 108, 0, "Amps_G" }, //DWORD
|
{IR_LONG, 103, 0, "Amps C" }, //DWORD
|
||||||
{IR, 150, 0, "V_AN" }, //WORD
|
{IR_LONG, 105, 0, "Amps N" }, //DWORD
|
||||||
{IR, 151, 0, "V_BN" }, //WORD
|
{IR_LONG, 107, 0, "Amps G" }, //DWORD
|
||||||
{IR, 152, 0, "V_CN" }, //WORD
|
{IR, 149, 0, "V_AN" }, //WORD
|
||||||
{IR, 154, 0, "V_AB" }, //WORD
|
{IR, 150, 0, "V_BN" }, //WORD
|
||||||
{IR, 155, 0, "V_BC" }, //WORD
|
{IR, 151, 0, "V_CN" }, //WORD
|
||||||
{IR, 156, 0, "V_CA" }, //WORD
|
{IR, 153, 0, "V_AB" }, //WORD
|
||||||
{IR_LONG, 222, 0, "k_VA" }, //LONG
|
{IR, 154, 0, "V_BC" }, //WORD
|
||||||
{IR_LONG, 206, 0, "kW" }, //LONG
|
{IR, 155, 0, "V_CA" }, //WORD
|
||||||
{IR_LONG, 304, 0, "kWh" }, //LONG
|
{IR_LONG, 221, 0, "k_VA" }, //LONG
|
||||||
{IR, 253, 0, "k_VA" }, //SHORT
|
{IR_LONG, 205, 0, "kW" }, //LONG
|
||||||
|
{IR_LONG, 303, 0, "kWh" }, //LONG
|
||||||
|
{IR, 252, 0, "k_VA2" }, //SHORT
|
||||||
};
|
};
|
||||||
//Size of modbus map used in FOR cycles, automatically calculated.
|
//Size of modbus map used in FOR cycles, automatically calculated.
|
||||||
|
|
||||||
|
|||||||
@@ -60,6 +60,7 @@
|
|||||||
*/
|
*/
|
||||||
modbusMap mb_map[] = {
|
modbusMap mb_map[] = {
|
||||||
// ESP8266 Modbus server uses 0-based addressing, while Modbus Poll uses 1-based addressing.
|
// ESP8266 Modbus server uses 0-based addressing, while Modbus Poll uses 1-based addressing.
|
||||||
|
|
||||||
{HR, 48899, 0, "Alm01" }, // 448900
|
{HR, 48899, 0, "Alm01" }, // 448900
|
||||||
{HR, 48898, 0, "Alm02" }, // 448899
|
{HR, 48898, 0, "Alm02" }, // 448899
|
||||||
{HR, 48905, 0, "Alm03" }, // 448906
|
{HR, 48905, 0, "Alm03" }, // 448906
|
||||||
|
|||||||
33
src/EPMS/GEN/GEN_CAT_GCCP_TCP/README.md
Normal file
33
src/EPMS/GEN/GEN_CAT_GCCP_TCP/README.md
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
# EQUIPMENT_TYPE MANUFACTURER MODEL TCP
|
||||||
|
|
||||||
|
## Brief Introduction
|
||||||
|
Equipment specifc details that make it different from other devices
|
||||||
|
|
||||||
|
## List of Equipmentt
|
||||||
|
This cofiguration has been used for these models:
|
||||||
|
* **Model**: 09-15-22
|
||||||
|
* **Model**: 09-15-23
|
||||||
|
* **Model**: 09-15-25
|
||||||
|
|
||||||
|
## Hardware Prerequisites
|
||||||
|
|
||||||
|
The code is written for an ESP8266/ESP32-style microcontroller with WiFi capabilities.
|
||||||
|
* **Microcontroller**: [Firebeetle 2 ESP32.](https://www.dfrobot.com/product-2231.html)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## States and Strategies
|
||||||
|
Provide a brief description of what variables and strategies were used in this configuraiton
|
||||||
|
|
||||||
|
### Standby State
|
||||||
|
* **Equipment running**: set to 0
|
||||||
|
* **Common Alarm**: set to 0
|
||||||
|
* **SAT temperature**: set to 85
|
||||||
|
|
||||||
|
### Running State
|
||||||
|
* **Equipment running**: set to 1
|
||||||
|
* **SAT temperature**: **Ramp Strategy** set to 65 deg setpoint
|
||||||
|
|
||||||
|
### Fail State
|
||||||
|
* **Commong Alarm**: set to 1
|
||||||
|
* **SAT temperature**: **Ramp Strategy** set to 105 deg setpointset
|
||||||
81
src/EPMS/GEN/GEN_CAT_GCCP_TCP/State_Fail.cpp
Normal file
81
src/EPMS/GEN/GEN_CAT_GCCP_TCP/State_Fail.cpp
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
/**
|
||||||
|
* @file State_Fail.cpp
|
||||||
|
* @brief Implementation of the FailState class.
|
||||||
|
* @author Emmanuel Hernandez Cruz
|
||||||
|
* @date 2025-09-05
|
||||||
|
*
|
||||||
|
* This file contains the implementation for the FailState, which defines
|
||||||
|
* the behavior of the equipment when it has entered a fault condition.
|
||||||
|
*/
|
||||||
|
#include "ModbusPoints/Modbus_Point.h"
|
||||||
|
#include "Equipment/Equipment.h"
|
||||||
|
#include "Strategies/Strategy_Ramp.h"
|
||||||
|
#include "Strategies/Strategy_SingleValue.h"
|
||||||
|
#include "Strategies/Strategy_PID.h"
|
||||||
|
#include "States/State_Standby.h"
|
||||||
|
#include "States/State_Running.h"
|
||||||
|
#include "States/State_Fail.h"
|
||||||
|
#if defined(USE_MODBUS_IP)
|
||||||
|
#include <ModbusIP_ESP8266.h>
|
||||||
|
#else
|
||||||
|
#include <ModbusRTU.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Constructs a new FailState object with a list of active alarms.
|
||||||
|
*
|
||||||
|
* This constructor receives a list of alarm descriptions and creates strategies
|
||||||
|
* to set the corresponding Modbus points to a value of 1, indicating an
|
||||||
|
* active alarm. It also initializes a PID strategy for the 'CW Valve Position'
|
||||||
|
* to maintain its state during the fault.
|
||||||
|
* @param activeAlarms A vector of strings, where each string is the
|
||||||
|
* description of a Modbus point to be set as an active alarm.
|
||||||
|
*/
|
||||||
|
template<>
|
||||||
|
FailState<ModbusIP>::FailState(const std::vector<std::string>& activeAlarms) {
|
||||||
|
// Simulate a failure: set common alarm and a specific fan alarm.
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Executes the fail state's logic for one update cycle.
|
||||||
|
*
|
||||||
|
* This method checks the "Alarm Reset" Modbus point for a command to
|
||||||
|
* transition back to Standby, which would typically happen after a fault
|
||||||
|
* is cleared by a user. If no transition is requested, it continues to apply
|
||||||
|
* the failure strategies (e.g., keeping alarm bits active).
|
||||||
|
*
|
||||||
|
* @param equipment Pointer to the Equipment instance.
|
||||||
|
* @return A pointer to a new State if a transition should occur, otherwise nullptr.
|
||||||
|
*/
|
||||||
|
template<>
|
||||||
|
State<ModbusIP>* FailState<ModbusIP>::update(Equipment<ModbusIP>* equipment) {
|
||||||
|
// STATE control, add conditions if change to a different state is needed
|
||||||
|
Serial.println("Fail update function");
|
||||||
|
|
||||||
|
_applyStrategies(equipment);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Logic to execute once when entering the fail state.
|
||||||
|
* Sets the "Alarm Common" point to 1 to indicate a general fault condition.
|
||||||
|
* @param equipment Pointer to the Equipment instance.
|
||||||
|
*/
|
||||||
|
template<>
|
||||||
|
void FailState<ModbusIP>::enterState(Equipment<ModbusIP>* equipment) {
|
||||||
|
// Logic to run when the equipment enters this state
|
||||||
|
Serial.println("Enter Fail State...");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Logic to execute once when exiting the fail state.
|
||||||
|
* Clears the "Alarm Common" point to 0 before transitioning to the next state.
|
||||||
|
* @param equipment Pointer to the Equipment instance.
|
||||||
|
*/
|
||||||
|
template<>
|
||||||
|
void FailState<ModbusIP>::exitState(Equipment<ModbusIP>* equipment) {
|
||||||
|
// Cleanup logic to run when the equipment leaves this state
|
||||||
|
Serial.println("Exit Fail State...");
|
||||||
|
}
|
||||||
92
src/EPMS/GEN/GEN_CAT_GCCP_TCP/State_Running.cpp
Normal file
92
src/EPMS/GEN/GEN_CAT_GCCP_TCP/State_Running.cpp
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
/**
|
||||||
|
* @file State_Running.cpp
|
||||||
|
* @brief Implementation of the RunningState class.
|
||||||
|
* @author Emmanuel Hernandez Cruz
|
||||||
|
* @date 2025-09-05
|
||||||
|
*
|
||||||
|
* This file contains the implementation for the RunningState, which defines
|
||||||
|
* the behavior of the equipment when it is actively running.
|
||||||
|
*/
|
||||||
|
#include "ModbusPoints/Modbus_Point.h"
|
||||||
|
#include "ModbusPoints/Modbus_FloatDecorator.h"
|
||||||
|
#include "Equipment/Equipment.h"
|
||||||
|
#include "Strategies/Strategy_Ramp.h"
|
||||||
|
#include "Strategies/Strategy_Random.h"
|
||||||
|
#include "Strategies/Strategy_Saw.h"
|
||||||
|
#include "Strategies/Strategy_SingleValue.h"
|
||||||
|
#include "Strategies/Strategy_Square.h"
|
||||||
|
#include "Strategies/Strategy_PID.h"
|
||||||
|
#include "Strategies/Strategy_Totalizer.h"
|
||||||
|
#include "States/State_Standby.h"
|
||||||
|
#include "States/State_Running.h"
|
||||||
|
#include "States/State_Fail.h"
|
||||||
|
#include "States/State.h"
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
#if defined(USE_MODBUS_IP)
|
||||||
|
#include <ModbusIP_ESP8266.h>
|
||||||
|
#else
|
||||||
|
#include <ModbusRTU.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Constructs a new RunningState object.
|
||||||
|
*
|
||||||
|
* This constructor initializes behavior strategies active during the running
|
||||||
|
* state, such as a PID controller for the 'CW Valve Position' and totalizers
|
||||||
|
* for the run-hours of each EC fan.
|
||||||
|
*/
|
||||||
|
template<>
|
||||||
|
RunningState<ModbusIP>::RunningState() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Executes the running state's logic for one update cycle.
|
||||||
|
*
|
||||||
|
* This method first checks for state transition commands:
|
||||||
|
* 1. It reads the "ON/OFF Command By BMS" point. If it's 0, it transitions to StandbyState.
|
||||||
|
* 2. It reads the "Fault Code" point. If it's non-zero, it transitions to FailState,
|
||||||
|
* passing the corresponding alarm description.
|
||||||
|
*
|
||||||
|
* If no transition occurs, it applies the strategies defined for the running state.
|
||||||
|
*
|
||||||
|
* @param equipment Pointer to the Equipment instance.
|
||||||
|
* @return A pointer to a new State if a transition should occur, otherwise nullptr.
|
||||||
|
*/
|
||||||
|
template<>
|
||||||
|
State<ModbusIP>* RunningState<ModbusIP>::update(Equipment<ModbusIP>* equipment) {
|
||||||
|
// STATE control, add conditions if change to a different state is needed
|
||||||
|
Serial.println("Running update function");
|
||||||
|
float Mode = getPointValue(equipment, "PxMode");
|
||||||
|
if (static_cast<int>(Mode) == 2 ){
|
||||||
|
return new StandbyState<ModbusIP>();
|
||||||
|
}
|
||||||
|
// Apply any strategies defined for the standby state
|
||||||
|
_applyStrategies(equipment);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Logic to execute once when entering the running state.
|
||||||
|
* Sets the "Run Status" for all EC fans to 1 to indicate they are active.
|
||||||
|
* @param equipment Pointer to the Equipment instance.
|
||||||
|
*/
|
||||||
|
template<>
|
||||||
|
void RunningState<ModbusIP>::enterState(Equipment<ModbusIP>* equipment) {
|
||||||
|
// Logic to run when the equipment enters this state
|
||||||
|
Serial.println("Enter Running State...");
|
||||||
|
// You could also update a Modbus register to show the "standby" state
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Logic to execute once when exiting the running state.
|
||||||
|
* Sets the "Run Status" for all EC fans to 0 before transitioning to the next state.
|
||||||
|
* @param equipment Pointer to the Equipment instance.
|
||||||
|
*/
|
||||||
|
template<>
|
||||||
|
void RunningState<ModbusIP>::exitState(Equipment<ModbusIP>* equipment) {
|
||||||
|
// Cleanup logic to run when the equipment leaves this state
|
||||||
|
Serial.println("Exit Running State...");
|
||||||
|
|
||||||
|
}
|
||||||
89
src/EPMS/GEN/GEN_CAT_GCCP_TCP/State_Standby.cpp
Normal file
89
src/EPMS/GEN/GEN_CAT_GCCP_TCP/State_Standby.cpp
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
/**
|
||||||
|
* @file State_Standby.cpp
|
||||||
|
* @brief Implementation of the StandbyState class.
|
||||||
|
* @author Emmanuel Hernandez Cruz
|
||||||
|
* @date 2025-09-05
|
||||||
|
*
|
||||||
|
* This file contains the implementation for the StandbyState, which defines
|
||||||
|
* the behavior of the equipment when it is in an idle or standby mode.
|
||||||
|
*/
|
||||||
|
#include "ModbusPoints/Modbus_Point.h"
|
||||||
|
#include "ModbusPoints/Modbus_FloatDecorator.h"
|
||||||
|
#include "Equipment/Equipment.h"
|
||||||
|
#include "Strategies/Strategy_Ramp.h"
|
||||||
|
#include "Strategies/Strategy_Random.h"
|
||||||
|
#include "Strategies/Strategy_Saw.h"
|
||||||
|
#include "Strategies/Strategy_SingleValue.h"
|
||||||
|
#include "Strategies/Strategy_Square.h"
|
||||||
|
#include "Strategies/Strategy_PID.h"
|
||||||
|
#include "States/State_Standby.h"
|
||||||
|
#include "States/State_Running.h"
|
||||||
|
#include "States/State_Fail.h"
|
||||||
|
#include "States/State.h"
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
#if defined(USE_MODBUS_IP)
|
||||||
|
#include <ModbusIP_ESP8266.h>
|
||||||
|
#else
|
||||||
|
#include <ModbusRTU.h>
|
||||||
|
#endif
|
||||||
|
/**
|
||||||
|
* @brief Constructs a new StandbyState object.
|
||||||
|
*
|
||||||
|
* In this state, the equipment is idle. This constructor initializes strategies
|
||||||
|
* to bring the system to a safe, idle condition. It sets a stable value for
|
||||||
|
* the SAT reading and creates ramp strategies to bring the CW valve and all
|
||||||
|
* EC fan speeds down to zero.
|
||||||
|
*/
|
||||||
|
template<>
|
||||||
|
StandbyState<ModbusIP>::StandbyState() {
|
||||||
|
// You can add initialization code here if needed
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Executes the standby state's logic for one update cycle.
|
||||||
|
*
|
||||||
|
* This method applies the strategies defined for the standby state (e.g.,
|
||||||
|
* ramping values to zero).
|
||||||
|
*
|
||||||
|
* @warning This method currently does not check for a command to transition to the
|
||||||
|
* Running state. This logic needs to be added to allow the unit to start.
|
||||||
|
* @return A pointer to a new State if a transition should occur, otherwise nullptr.
|
||||||
|
*/
|
||||||
|
template<>
|
||||||
|
State<ModbusIP>* StandbyState<ModbusIP>::update(Equipment<ModbusIP>* equipment) {
|
||||||
|
// STATE control, add conditions if change to a different state is needed
|
||||||
|
Serial.println("Standby update function");
|
||||||
|
float Mode = getPointValue(equipment, "PxMode");
|
||||||
|
if (static_cast<int>(Mode) == 2 ){
|
||||||
|
return new RunningState<ModbusIP>();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply any strategies defined for the standby state
|
||||||
|
_applyStrategies(equipment);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Logic to execute once when entering the standby state.
|
||||||
|
* This method performs cleanup by setting all alarm points and all EC fan
|
||||||
|
* run status points to 0.
|
||||||
|
* @param equipment Pointer to the Equipment instance.
|
||||||
|
*/
|
||||||
|
template<>
|
||||||
|
void StandbyState<ModbusIP>::enterState(Equipment<ModbusIP>* equipment) {
|
||||||
|
// Logic to run when the equipment enters this state
|
||||||
|
Serial.println("Enter Standby State...");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Logic to execute once when exiting the standby state.
|
||||||
|
* @param equipment Pointer to the Equipment instance.
|
||||||
|
*/
|
||||||
|
template<>
|
||||||
|
void StandbyState<ModbusIP>::exitState(Equipment<ModbusIP>* equipment) {
|
||||||
|
// Cleanup logic to run when the equipment leaves this state
|
||||||
|
Serial.println("Exit Standby State...");
|
||||||
|
}
|
||||||
133
src/EPMS/GEN/GEN_CAT_GCCP_TCP/config.h
Normal file
133
src/EPMS/GEN/GEN_CAT_GCCP_TCP/config.h
Normal file
@@ -0,0 +1,133 @@
|
|||||||
|
/**
|
||||||
|
* @file config.h
|
||||||
|
* @brief Main configuration file for the GEN CAT EMCP4
|
||||||
|
* @author Zach Gutierrez
|
||||||
|
* @date 2025-09-02
|
||||||
|
*
|
||||||
|
* This file contains two important configurations: WiFi network parameters
|
||||||
|
* and the Modbus register map for the device.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CONFIG_H
|
||||||
|
#define CONFIG_H
|
||||||
|
|
||||||
|
#include "core.h"
|
||||||
|
#include "Equipment/Equipment.h"
|
||||||
|
|
||||||
|
#if defined(USE_MODBUS_IP)
|
||||||
|
/**
|
||||||
|
* @defgroup ModbusTCPConfig Modbus IP Configuration
|
||||||
|
* @brief Parameters for Modbus TCP communication.
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#include <ModbusIP_ESP8266.h>
|
||||||
|
const char *ssid = "wifi_name"; /**< @brief The SSID of the WiFi network. */
|
||||||
|
const char *password = "wifi_password"; /**< @brief The password for the WiFi network. */
|
||||||
|
IPAddress local_IP(192, 168, 1, 234); /**< @brief The static IP address for the device. */
|
||||||
|
IPAddress gateway(192, 168, 1, 1); /**< @brief The gateway IP address. */
|
||||||
|
IPAddress subnet(255, 255, 255, 0); /**< @brief The subnet mask. */
|
||||||
|
|
||||||
|
ModbusIP mb;
|
||||||
|
#else
|
||||||
|
/**
|
||||||
|
* @defgroup ModbusRTUConfig Modbus RTU Configuration
|
||||||
|
* @brief Parameters for serial Modbus RTU communication.
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#include <ModbusRTU.h>
|
||||||
|
const int BAUDRATE = 19200; /**< @brief The serial communication speed in bits per second. */
|
||||||
|
const int RX_PIN = 17; /**< @brief The GPIO pin used for receiving data (RX). */
|
||||||
|
const int TX_PIN = 16; /**< @brief The GPIO pin used for transmitting data (TX). */
|
||||||
|
const int RST_PIN = 4; /**< @brief The GPIO pin connected to the RS485 driver's DE/RE pins for direction control. */
|
||||||
|
const int MODBUS_ID = 1; /**< @brief The unique slave ID for this device on the Modbus bus. */
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
/** @brief Global instance of the Modbus RTU server. */
|
||||||
|
ModbusRTU mb;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup ModbusMapConfig Modbus Map Configuration
|
||||||
|
* @brief Defines the Modbus register map and related parameters for the emulator.
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @brief The Modbus map for the Equipment device.
|
||||||
|
* This array defines all the Modbus points available on the emulated device.
|
||||||
|
* The `description` field is crucial as it's used to look up points within the application logic.
|
||||||
|
*/
|
||||||
|
modbusMap mb_map[] = {
|
||||||
|
// ESP8266 Modbus server uses 0-based addressing, while Modbus Poll uses 1-based addressing.
|
||||||
|
{HR, 9, 0, "PxMode" }, // 448900 High_Coolant_Temp_Warning
|
||||||
|
{HR, 10, 0, "Px01" }, // 448899 Low_Coolant_Temp
|
||||||
|
{HR, 11, 0, "Px02" }, // 448906 Unexpected_Engine_Shutdown
|
||||||
|
|
||||||
|
{HR, 48900, 0, "Alm01" }, // 448900 High_Coolant_Temp_Warning
|
||||||
|
{HR, 48899, 0, "Alm02" }, // 448899 Low_Coolant_Temp
|
||||||
|
{HR, 48906, 0, "Alm03" }, // 448906 Unexpected_Engine_Shutdown
|
||||||
|
{HR, 48897, 0, "Alm04" }, // 448897 Emergency_Stop
|
||||||
|
{HR, 48901, 0, "Alm05" }, // 448901 High_Coolant_Temp_Alarm
|
||||||
|
{HR, 48904, 0, "Alm06" }, // 448904 Engine_Overspeed
|
||||||
|
{HR, 48902, 0, "Alm07" }, // 448902 Low_Oil_Pressure_Warning
|
||||||
|
{HR, 48903, 0, "Alm08" }, // 448903 Low_Oil_Pressure_Alarm
|
||||||
|
{HR, 48908, 0, "Fuel_LoLo" }, // 448908 Fuel_LoLo
|
||||||
|
{HR, 48913, 0, "Alm10" }, // 448913 Low_Battery_Voltage
|
||||||
|
{HR, 48898, 0, "Alm11" }, // 448898 Engine_Overcrank
|
||||||
|
{HR, 48915, 0, "Fuel_Hi" }, // 448915 Fuel_Hi
|
||||||
|
{HR, 48907, 0, "Fuel_Lo" }, // 448907 Fuel_Lo
|
||||||
|
{HR, 48912, 0, "Alm14" }, // 448912 High_Battery_Voltage
|
||||||
|
{HR, 48905, 0, "Common_Alarm" }, // 448905 Common_Alarm
|
||||||
|
{HR, 48914, 0, "Batt_Charge_Fail" }, // 448914 Battery_Charger_Failure
|
||||||
|
{HR, 48916, 0, "EPS_Supp_Load" }, // 448916 EPS_Supplying_Load
|
||||||
|
{HR, 8655, 0, "Bkr_State" }, // 48655 Gen_Breaker_State
|
||||||
|
{HR, 1025, 0, "Oil Pressure" }, // 41025 Engine_Oil_Pressure
|
||||||
|
{HR, 1026, 0, "Coolant Temp" }, // 41026 Coolant_Temperature_degC
|
||||||
|
{HR, 1027, 0, "Oil_Temp_degC" }, // 41027 Oil_Temperature_degC
|
||||||
|
{HR, 1030, 0, "Battery_Voltage" }, // 41030 Battery_Voltage
|
||||||
|
{HR, 1031, 0, "Engine_Speed" }, // 41031 Engine_Speed
|
||||||
|
{HR, 1032, 0, "Freq" }, // 41032 Freq
|
||||||
|
{HR, 1033, 0, "Volts_AN" }, // 41033 Volts_AN
|
||||||
|
{HR, 1035, 0, "Volts_BN" }, // 41035 Volts_BN
|
||||||
|
{HR, 1037, 0, "Volts_CN" }, // 41037 Volts_CN
|
||||||
|
{HR, 1039, 0, "Volts_AB" }, // 41039 Volts_AB
|
||||||
|
{HR, 1041, 0, "Volts_BC" }, // 41041 Volts_BC
|
||||||
|
{HR, 1043, 0, "Volts_CA" }, // 41043 Volts_CA
|
||||||
|
{HR, 1045, 0, "Amps_A" }, // 41045 Amps_A
|
||||||
|
{HR, 1047, 0, "Amps_B" }, // 41047 Amps_B
|
||||||
|
{HR, 1049, 0, "Amps_C" }, // 41049 Amps_C
|
||||||
|
{HR, 1053, 0, "kW_A" }, // 41053 kW_A
|
||||||
|
{HR, 1055, 0, "kW_B" }, // 41055 kW_B
|
||||||
|
{HR, 1057, 0, "kW_C" }, // 41057 kW_C
|
||||||
|
{HR, 1289, 0, "L_Exhaust_degC" }, // 41289 Left_Exhaust_Temp_degC
|
||||||
|
{HR, 1290, 0, "R_Exhaust_degC" }, // 41290 Right_Exhaust_Temp_degC
|
||||||
|
{HR, 1355, 0, "Percent_Load" }, // 41355 Percent_Load
|
||||||
|
{HR, 1537, 0, "kW_Tot" }, // 41537 kW
|
||||||
|
{HR, 1539, 0, "kVA_A" }, // 41539 kVA_A
|
||||||
|
{HR, 1541, 0, "kVA_B" }, // 41541 kVA_B
|
||||||
|
{HR, 1543, 0, "kVA_C" }, // 41543 kVA_C
|
||||||
|
{HR, 1545, 0, "kVA_Tot" }, // 41545 kVA
|
||||||
|
{HR, 1553, 0, "kVAR_Tot" }, // 41553 kVAR
|
||||||
|
{HR, 1558, 0, "PF_Tot" }, // 41558 PF
|
||||||
|
{HR, 1799, 0, "TTL_Run_Hours" }, // 41799 TTL_Run_Hours
|
||||||
|
{HR, 1801, 0, "kWh_Tot" }, // 41801 kWh
|
||||||
|
{HR, 1809, 0, "TTL_Starts" }, // 41809 TTL_Engine_Starts
|
||||||
|
{HR, 48909, 0, "Auto_Mode" }, // 448909 Auto_Mode
|
||||||
|
{HR, 48910, 0, "Stop_Mode" }, // 448910 Stop_Mode
|
||||||
|
{HR, 48911, 0, "Manual_Mode" }, // 448911 Manual_Mode
|
||||||
|
{HR, 772, 0, "Gen_Sts" } // 400772 Generator Status
|
||||||
|
};
|
||||||
|
//Size of modbus map used in FOR cycles, automatically calculated.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The total number of entries in the `mb_map` array.
|
||||||
|
* This is calculated at compile time and used for iterating over the map.
|
||||||
|
*/
|
||||||
|
const int map_size = sizeof(mb_map) / sizeof(mb_map[0]);
|
||||||
|
|
||||||
|
/** @brief The main loop update interval in milliseconds. */
|
||||||
|
int interval = 250;
|
||||||
|
/** @} */ // End of ModbusMapConfig group
|
||||||
|
|
||||||
|
#endif // CONFIG_H
|
||||||
86
src/EPMS/GEN/GEN_CAT_GCCP_TCP/main.cpp
Normal file
86
src/EPMS/GEN/GEN_CAT_GCCP_TCP/main.cpp
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
/**
|
||||||
|
* @file main.cpp
|
||||||
|
* @brief Main execution program for the CRAH Unit (TCP) Emulator.
|
||||||
|
* @author Emmanuel Hernandez Cruz
|
||||||
|
* @date 2025-09-02
|
||||||
|
*
|
||||||
|
* @details This file contains the main execution program for an Arduino-based emulator of a CRAH unit.
|
||||||
|
* The program uses a Wi-Fi connection to communicate via the Modbus IP protocol.
|
||||||
|
*
|
||||||
|
* The setup() function initializes the following:
|
||||||
|
* - Serial communication for debugging.
|
||||||
|
* - Wi-Fi connection using credentials from config.h.
|
||||||
|
* - A Modbus TCP server.
|
||||||
|
* - Modbus points (Coils, Holding Registers, etc.) based on a predefined map in config.h.
|
||||||
|
*
|
||||||
|
* The loop() function continuously:
|
||||||
|
* - Services the Modbus TCP server to handle incoming requests.
|
||||||
|
* - Periodically calls the main update loop for the emulated equipment, which
|
||||||
|
* manages state transitions and behavior strategies.
|
||||||
|
*
|
||||||
|
* @see config.h for Wi-Fi and Modbus configuration.
|
||||||
|
* @see Equipment.h for the main equipment logic.
|
||||||
|
* @see State.h for different equipment states.
|
||||||
|
* @see Strategies/Strategy_Behavior.h for value generation strategies.
|
||||||
|
* @see Modbus_Point.h for the base class for all Modbus points.
|
||||||
|
*/
|
||||||
|
//=================================================================================================================================
|
||||||
|
//Libraries and declaration of variables.
|
||||||
|
#include <WiFi.h>
|
||||||
|
#include "config.h"
|
||||||
|
#include "ModbusPoints/Modbus_PointFactory.h"
|
||||||
|
#if defined(USE_MODBUS_IP)
|
||||||
|
#include <ModbusIP_ESP8266.h>
|
||||||
|
#else
|
||||||
|
#include <ModbusRTU.h>
|
||||||
|
#endif
|
||||||
|
//=================================================================================================================================
|
||||||
|
/**
|
||||||
|
* @brief Initializes the application.
|
||||||
|
* @details This function runs once at startup. It configures the serial communication,
|
||||||
|
* Wi-Fi, and the Modbus server. It also creates and initializes all the Modbus points
|
||||||
|
* based on the `mb_map` array in `config.h`.
|
||||||
|
*/
|
||||||
|
void setup() {
|
||||||
|
Serial.begin(115200); //Serial comm start
|
||||||
|
WiFi.config(local_IP, gateway, subnet); // Wifi service start
|
||||||
|
WiFi.begin(ssid, password);
|
||||||
|
while (WiFi.status() != WL_CONNECTED) {
|
||||||
|
delay(1000);
|
||||||
|
Serial.print(".");
|
||||||
|
}
|
||||||
|
Serial.println("Connected!!");
|
||||||
|
mb.server(); //Modbus server start
|
||||||
|
Serial.println("Server Created");
|
||||||
|
Serial.println(map_size);
|
||||||
|
for(int i = 0; i < map_size; i++){
|
||||||
|
Modbus_Point<ModbusIP>* point = createModbus_Point(&mb, mb_map[i].category, mb_map[i].address, mb_map[i].value, mb_map[i].description);
|
||||||
|
if (point) {
|
||||||
|
point->addToModbusServer();
|
||||||
|
EquipmentInstance.addModbus_Point(mb_map[i].description, point);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Serial.println("All modbus Points created");
|
||||||
|
Serial.println("Setup function ended");
|
||||||
|
}
|
||||||
|
//=================================================================================================================================
|
||||||
|
/**
|
||||||
|
* @brief The main application loop.
|
||||||
|
* @details This function runs repeatedly after setup() has completed. It performs two main actions:
|
||||||
|
* 1. It continuously services the Modbus server by calling `mb.task()` to handle
|
||||||
|
* incoming requests from a Modbus master.
|
||||||
|
* 2. At a fixed interval (defined in `config.h`), it calls `EquipmentInstance.update()`
|
||||||
|
* to run the emulator's internal state machine and behavior logic.
|
||||||
|
*/
|
||||||
|
void loop() {
|
||||||
|
mb.task();
|
||||||
|
unsigned long currentMillis = millis();
|
||||||
|
if (currentMillis - previousMillis >= interval) {
|
||||||
|
previousMillis = currentMillis;
|
||||||
|
unsigned long startTime = millis();
|
||||||
|
EquipmentInstance.update();
|
||||||
|
unsigned long endTime = millis();
|
||||||
|
unsigned long elapsedTime = endTime - startTime;
|
||||||
|
Serial.printf("Control Execution time: %d ms\n", elapsedTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user