updated and added registers to match UDT
copy-pasted develop version of code, added tags required for UDT.
This commit is contained in:
@@ -14,7 +14,7 @@
|
||||
default_envs = PHX3_VFD_ABB_ACH580_RTU ; Select here the name of the configuration you want to download
|
||||
|
||||
[env]
|
||||
upload_port = COM9
|
||||
upload_port = COM11
|
||||
|
||||
[common_env_options]
|
||||
framework = arduino
|
||||
|
||||
@@ -32,9 +32,7 @@
|
||||
*/
|
||||
template<>
|
||||
FailState<ModbusRTU>::FailState(const std::vector<std::string>& activeAlarms) {
|
||||
addStrategy("Motor Speed Used", new RampStrategy(0.0f, 200.0f, 1000 ));
|
||||
addStrategy("Speed Feedback", new RampStrategy(0.0f, 200.0f, 1000 ));
|
||||
addStrategy("Motor Speed estimated", new RampStrategy(0.0f, 200.0f, 1000 ));
|
||||
addStrategy("Motor Current", new RampStrategy(0.0f, 20.0f, 1000 ));
|
||||
addStrategy("Motor Torque", new RampStrategy(0.0f, 20.0f, 1000 ));
|
||||
addStrategy("Inverter Temperature", new RampStrategy(0.0f, 1.0f, 1000 ));
|
||||
@@ -42,7 +40,11 @@ FailState<ModbusRTU>::FailState(const std::vector<std::string>& activeAlarms) {
|
||||
addStrategy("Output Frequency", new SingleValueStrategy(0.1f, 0.2f, 1000 ));
|
||||
addStrategy("Output Voltage", new SingleValueStrategy(0.1f, 0.1f, 1000 ));
|
||||
addStrategy("DC Voltage", new SingleValueStrategy(0.1f, 0.1f, 1000 ));
|
||||
addStrategy("Output Power", new SingleValueStrategy(0.1f, 0.1f, 1000 ));
|
||||
addStrategy("Motor Shaft Power", new SingleValueStrategy(0.1f, 0.1f, 1000 ));
|
||||
|
||||
addStrategy("AI1 Scaled", new RampStrategy(0.0f, 2.0f, 1000 ));
|
||||
addStrategy("AI2 Scaled", new RampStrategy(0.0f, 5.0f, 1000 ));
|
||||
addStrategy("AO1 Actual", new RampStrategy(0.0f, 2.0f, 1000 ));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -77,7 +79,17 @@ template<>
|
||||
void FailState<ModbusRTU>::enterState(Equipment<ModbusRTU>* equipment) {
|
||||
// Logic to run when the equipment enters this state
|
||||
Serial.println("Enter Fail State...");
|
||||
/**
|
||||
setPointValue(equipment, "Speed Scaling", 1800);
|
||||
setPointValue(equipment, "Frequency Scaling", 60);
|
||||
setPointValue(equipment, "Nominal Current", 65);
|
||||
setPointValue(equipment, "Nominal Voltage", 480);
|
||||
setPointValue(equipment, "Nominal Frequency", 60);
|
||||
setPointValue(equipment, "Nominal Speed", 1800);
|
||||
setPointValue(equipment, "Nominal Power", 50);
|
||||
*/
|
||||
setPointValue(equipment, "Run Status", 0);
|
||||
setPointValue(equipment, "DI Status", 0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -41,19 +41,21 @@
|
||||
*/
|
||||
template<>
|
||||
RunningState<ModbusRTU>::RunningState() {
|
||||
addStrategy("Motor Speed Used", new RampStrategy(1800.0f, 100.0f, 1000));
|
||||
addStrategy("Speed Feedback", new RampStrategy(1800.0f, 100.0f, 1000));
|
||||
addStrategy("Motor Speed estimated", new RampStrategy(1800.0f, 100.0f, 1000));
|
||||
addStrategy("Motor Current", new RampStrategy(65.0f, 7.0f, 1000));
|
||||
addStrategy("Motor Torque", new RampStrategy(90.0f, 10.0f, 1000));
|
||||
addStrategy("Inverter Temperature", new SquareStrategy(40.0f, 80.0f, 1000));
|
||||
addStrategy("Inverter Temperature", new RampStrategy(70.0f, 1.0f, 1000));
|
||||
|
||||
addStrategy("Output Frequency", new RampStrategy(60.0f, 3.0f, 1000 ));
|
||||
addStrategy("Output Voltage", new RampStrategy(480.0f, 15.0f, 1000 ));
|
||||
addStrategy("DC Voltage", new RampStrategy(678.0f, 20.0f, 1000 ));
|
||||
addStrategy("Output Power", new RampStrategy(36.7f, 2.0f, 1000 ));
|
||||
addStrategy("Inverter kWh cnt", new TotalizerStrategy(1000));
|
||||
addStrategy("Hours Run", new TotalizerStrategy(1000));
|
||||
addStrategy("Motor Shaft Power", new RampStrategy(36.7f, 2.0f, 1000 ));
|
||||
addStrategy("Inverter MWh counter", new TotalizerStrategy(1000));
|
||||
addStrategy("Inverter kWh counter", new TotalizerStrategy(1000));
|
||||
|
||||
addStrategy("AI1 Scaled", new RampStrategy(10.0f, 1.0f, 1000 ));
|
||||
addStrategy("AI2 Scaled", new RampStrategy(20.0f, 1.0f, 1000 ));
|
||||
addStrategy("AO1 Actual", new RampStrategy(10.0f, 1.0f, 1000 ));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -89,30 +91,20 @@ State<ModbusRTU>* RunningState<ModbusRTU>::update(Equipment<ModbusRTU>* equipmen
|
||||
float voltage_update = speed_pct * 480;
|
||||
float dc_voltage_update = speed_pct * 678;
|
||||
float current_update = speed_pct * speed_pct * 65;
|
||||
float torque_update = speed_pct * speed_pct * 100; // This is a % of nominal motor torque
|
||||
float torque_update = speed_pct * speed_pct * 100 * 10; // This is a % of nominal motor torque, x10 b/c is scaled by 100 in actual equipment, this register is only 10x
|
||||
float freq_update = speed_pct * 60;
|
||||
float power_update = speed_pct * speed_pct * speed_pct * 36.77f; // 50 hp ~ 36.77kW
|
||||
|
||||
float currentSP = getPointValue(equipment, "Speed Cmd");
|
||||
Strategy_Behavior* motorSpeedUsed = getStrategy("Motor Speed Used");
|
||||
// 2. Check if the strategy exists
|
||||
if (motorSpeedUsed) {
|
||||
// 3. Cast it to a RampStrategy pointer and call setSetpoint.
|
||||
static_cast<RampStrategy*>(motorSpeedUsed)->setTarget(currentSP);
|
||||
}
|
||||
float AI1_update = speed_pct *10;
|
||||
float AI2_update = speed_pct *20;
|
||||
float AO1_update = speed_pct *10;
|
||||
|
||||
Strategy_Behavior* speedFeedback = getStrategy("Speed Feedback");
|
||||
if (speedFeedback) {
|
||||
static_cast<RampStrategy*>(speedFeedback)->setTarget(currentSP);
|
||||
}
|
||||
|
||||
// To have Motor Speed estimated slightly different - for purposes of differentiating in Ignition
|
||||
float rpm_est = currentSP * 0.98f;
|
||||
Strategy_Behavior* motorSpeedEst = getStrategy("Motor Speed estimated");
|
||||
if (motorSpeedEst) {
|
||||
static_cast<RampStrategy*>(motorSpeedEst)->setTarget(rpm_est);
|
||||
}
|
||||
|
||||
Strategy_Behavior* frequencystrategy = getStrategy("Output Frequency");
|
||||
if (frequencystrategy) {
|
||||
static_cast<RampStrategy*>(frequencystrategy)->setTarget(freq_update);
|
||||
@@ -138,11 +130,26 @@ State<ModbusRTU>* RunningState<ModbusRTU>::update(Equipment<ModbusRTU>* equipmen
|
||||
static_cast<RampStrategy*>(voltagestrategy)->setTarget(voltage_update);
|
||||
}
|
||||
|
||||
Strategy_Behavior* powerstrategy = getStrategy("Output Power");
|
||||
Strategy_Behavior* powerstrategy = getStrategy("Motor Shaft Power");
|
||||
if (powerstrategy) {
|
||||
static_cast<RampStrategy*>(powerstrategy)->setTarget(power_update);
|
||||
}
|
||||
|
||||
Strategy_Behavior* AI1strategy = getStrategy("AI1 Scaled");
|
||||
if (AI1strategy) {
|
||||
static_cast<RampStrategy*>(AI1strategy)->setTarget(AI1_update);
|
||||
}
|
||||
|
||||
Strategy_Behavior* AI2strategy = getStrategy("AI2 Scaled");
|
||||
if (AI2strategy) {
|
||||
static_cast<RampStrategy*>(AI2strategy)->setTarget(AI2_update);
|
||||
}
|
||||
|
||||
Strategy_Behavior* AO1strategy = getStrategy("AO1 Actual");
|
||||
if (AO1strategy) {
|
||||
static_cast<RampStrategy*>(AO1strategy)->setTarget(AO1_update);
|
||||
}
|
||||
|
||||
// Apply any strategies defined for the standby state
|
||||
_applyStrategies(equipment);
|
||||
return nullptr;
|
||||
@@ -158,6 +165,7 @@ void RunningState<ModbusRTU>::enterState(Equipment<ModbusRTU>* equipment) {
|
||||
// Logic to run when the equipment enters this state
|
||||
Serial.println("Enter Running State...");
|
||||
setPointValue(equipment, "Run Status", 1);
|
||||
setPointValue(equipment, "DI Status", 1);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -30,9 +30,7 @@
|
||||
*/
|
||||
template<>
|
||||
StandbyState<ModbusRTU>::StandbyState() {
|
||||
addStrategy("Motor Speed Used", new RampStrategy(0.0f, 200.0f, 1000 ));
|
||||
addStrategy("Speed Feedback", new RampStrategy(0.0f, 200.0f, 1000 ));
|
||||
addStrategy("Motor Speed estimated", new RampStrategy(0.0f, 200.0f, 1000 ));
|
||||
addStrategy("Motor Current", new RampStrategy(0.0f, 20.0f, 1000 ));
|
||||
addStrategy("Motor Torque", new RampStrategy(0.0f, 20.0f, 1000 ));
|
||||
addStrategy("Inverter Temperature", new RampStrategy(0.0f, 1.0f, 1000 ));
|
||||
@@ -40,7 +38,11 @@ StandbyState<ModbusRTU>::StandbyState() {
|
||||
addStrategy("Output Frequency", new SingleValueStrategy(0.1f, 0.2f, 1000 ));
|
||||
addStrategy("Output Voltage", new SingleValueStrategy(0.1f, 0.1f, 1000 ));
|
||||
addStrategy("DC Voltage", new SingleValueStrategy(0.1f, 0.1f, 1000 ));
|
||||
addStrategy("Output Power", new SingleValueStrategy(0.1f, 0.1f, 1000 ));
|
||||
addStrategy("Motor Shaft Power", new SingleValueStrategy(0.1f, 0.1f, 1000 ));
|
||||
|
||||
addStrategy("AI1 Scaled", new RampStrategy(0.0f, 2.0f, 1000 ));
|
||||
addStrategy("AI2 Scaled", new RampStrategy(0.0f, 5.0f, 1000 ));
|
||||
addStrategy("AO1 Actual", new RampStrategy(0.0f, 2.0f, 1000 ));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -85,6 +87,7 @@ void StandbyState<ModbusRTU>::enterState(Equipment<ModbusRTU>* equipment) {
|
||||
// Logic to run when the equipment enters this state
|
||||
Serial.println("Enter Standby State...");
|
||||
setPointValue(equipment, "Run Status", 0);
|
||||
setPointValue(equipment, "DI Status", 0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
*
|
||||
* This file contains important configurations for the Modbus RTU communication
|
||||
* and the specific register map for the emulated device.
|
||||
* These are 32-bit modbus registers.
|
||||
* These are 16-bit modbus registers.
|
||||
* Added "Run Status" and "Fault Status" to simulated hard IO points and send feedback to PLC during simulation.
|
||||
*/
|
||||
|
||||
@@ -56,32 +56,38 @@
|
||||
*/
|
||||
modbusMap mb_map[] =
|
||||
{
|
||||
{HR, 149, 1800, "Speed Cmd"}, // arbitrary register number - receive signal from PLC (hardwire IO in field); expecting rpm (1800 rpm max)
|
||||
{HR, 151, 0, "Start/Stop"}, // arbitrary register number - receive signal from PLC (hardwire IO in practice)
|
||||
{HR, 149, 1650, "Speed Cmd"}, // arbitrary register number - receive signal from PLC (hardwire IO in field); expecting rpm (1800 rpm max)
|
||||
{HR, 151, 1, "Start/Stop"}, // arbitrary register number - receive signal from PLC (hardwire IO in practice)
|
||||
{HR, 152, 0, "HOA Command"}, // arbitrary register number - not used in program
|
||||
{HR, 154, 0, "Run Status"}, // arbitrary register number - 0:off, 1:on (simulated hardwire IO) sending feedback to PLC during simulation.
|
||||
{HR, 155, 1, "Fault Status"}, // arbitrary register number - 0:faulted, 1:not faulted (simulated hardwire IO). When = 0, will turn off VFD.
|
||||
{HR, 156, 0, "Speed Feedback"}, // arbitrary register number - send signal to PLC (simulated hardwire IO). Will be equal to Motor Speed Used register
|
||||
// {HR, 156, 0, "Speed Feedback"}, // arbitrary register number - send signal to PLC (simulated hardwire IO). Will be equal to Motor Speed Used register
|
||||
|
||||
{HR_FLOAT, 20201, 0, "Motor Speed Used"}, // RJD: 1800 rpm max
|
||||
{HR_FLOAT, 20203, 0, "Motor Speed estimated"}, // RJD: 1800 rpm max
|
||||
{HR_FLOAT, 20211, 0, "Output Frequency"}, // 60 Hz @100% speed
|
||||
{HR_FLOAT, 20213, 0, "Motor Current"}, // RJD: Changed from HR_10x to HR, 65 FLA
|
||||
{HR_FLOAT, 20219, 0, "Motor Torque"}, // % of nominal torque
|
||||
{HR_FLOAT, 20221, 0, "DC Voltage"}, // approx 678 VDC @100% speed
|
||||
{HR_FLOAT, 20225, 0, "Output Voltage"}, // RJD: 480 VAC
|
||||
{HR_FLOAT, 20227, 0, "Output Power"}, //max 372580 // RJD: Changed from HR_10x to HR, 50 hp ~ 36.77 kW
|
||||
{HR_FLOAT, 20239, 0, "Inverter kWh cnt"},
|
||||
{HR_FLOAT, 21005, 0, "Hours Run"},
|
||||
{HR_FLOAT, 21021, 0, "Inverter Temperature"}, // RJD: Changed from HR_10x to HR, % of fault limit
|
||||
{HR, 100, 0, "Speed Feedback"}, // 1800 rpm max
|
||||
{HR, 105, 0, "Output Frequency"}, // 60 Hz @100% speed
|
||||
{HR, 106, 0, "Motor Current"}, // 65 FLA
|
||||
{HR_10x, 109, 0, "Motor Torque"}, // % of nominal torque
|
||||
{HR_10x, 110, 0, "DC Voltage"}, // approx 678 VDC @100% speed
|
||||
{HR, 112, 0, "Output Voltage"}, // 480 VAC
|
||||
{HR_10x, 116, 0, "Motor Shaft Power"}, // 50 hp ~ 36.77 kW
|
||||
{HR, 118, 0, "Inverter MWh counter"},
|
||||
{HR, 119, 0, "Inverter kWh counter"},
|
||||
{HR, 510, 0, "Inverter Temperature"}, // RJD: Changed from HR_10x to HR, % of fault limit
|
||||
{HR, 519, 0, "Diagnostic Word"}, // not used in program. Bit 9:Drive Over-Temp Alarm
|
||||
|
||||
{HR, 1000, 0, "DI Status"}, // Bit 0: input 1, Bit 1: Input 2
|
||||
{HR, 1211, 0, "AI1 Scaled"}, // output frequency/speed reference, 0-10V
|
||||
{HR, 1221, 0, "AI2 Scaled"}, // actual feedback 0-20mA
|
||||
{HR, 1310, 0, "AO1 Actual"}, // output frequency 0-10V
|
||||
{HR, 1910, 0, "External Control Location"}, // not used in program. Bit 13, 0:false, 1:true
|
||||
{HR, 4600, 1800, "Speed Scaling"}, // 1800 rpm
|
||||
{HR, 4601, 60, "Frequency Scaling"}, // 60 Hz
|
||||
{HR, 9905, 65, "Nominal Current"}, // 65 A
|
||||
{HR_10x, 9906, 4800, "Nominal Voltage"}, // 480 V
|
||||
{HR_10x, 9907, 600, "Nominal Frequency"}, // 60 Hz
|
||||
{HR, 9908, 1800, "Nominal Speed"}, // 1800 rpm
|
||||
{HR_10x, 9909, 500, "Nominal Power"}, // 50 hp
|
||||
|
||||
{HR, 21243, 0, "HOA Status Word"}, // not used in program
|
||||
{HR, 20801, 0, "Trip Fault"}, // not used in program
|
||||
{HR, 20821, 0, "Last Fault"}, // not used in program
|
||||
{HR, 20823, 0, "2nd to last Fault"}, // not used in program
|
||||
{HR, 20825, 0, "3rd to last Fault"}, // not used in program
|
||||
{HR, 21221, 0, "Main Status Word"}, // not used in program
|
||||
{HR, 21231, 0, "Drive Status Word 1"}, // not used in program
|
||||
};
|
||||
//Size of modbus map used in FOR cycles, automatically calculated.
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user