Modbus Simulator for VFD Drive Testing: Complete Guide for PLC & Automation Engineers
Variable Frequency Drives (VFDs) and AC inverters are the workhorses of modern industrial motion control—driving pumps, fans, conveyors, extruders, and CNC spindles. Connecting a Programmable Logic Controller (PLC) or SCADA host to a VFD over Modbus RTU (RS-485) or Modbus TCP is the industry standard for digital speed control, telemetry monitoring, and diagnostic retrieval.
However, testing your PLC ladder logic, PID speed regulators, and HMI alarm banners on live 480V motor drives during early development is dangerous, expensive, and logistically impractical. By utilizing ModbusSimulator to emulate your VFD drives in software, you can validate your control architecture, verify scaling equations, and stress-test fault handling routines before high-voltage equipment is powered on.
Why Simulate VFD Inverters in Software?
- Zero Risk to Mechanical Equipment: Eliminate equipment damage from unexpected direction reversals, uncontrolled ramp rates, or torque runaway.
- Safety from Electrical Hazards: Develop and test PLC communications without working inside energized 400V/480V drive cabinets.
- Deterministic Fault Testing: Intentionally trigger drive overcurrent (OC), DC link overvoltage (OV), phase loss, and thermal trip codes to ensure your emergency stop and safety interlocks respond instantaneously.
- Multi-Drive Fleet Testing: Simulate 10, 20, or 32 VFDs on an RS-485 multidrop network to evaluate Modbus polling cycle times, timeout thresholds, and serial communication bus loading.
Standard VFD Modbus Communication Architecture
Regardless of manufacturer (ABB, Danfoss, Schneider Electric, Siemens, Yaskawa, Delta, or Mitsubishi), industrial VFDs communicate over Modbus using standard 16-bit Holding Registers (Function Code 03 to Read, Function Code 06/16 to Write).
The communication protocol structure typically revolves around four core registers:
- Control Word (CW / STW): Master → Drive command register containing bitwise flags for Start, Stop, Direction, Quick Stop, and Fault Reset.
- Main Reference (REF / Speed Setpoint): Master → Drive target speed reference, typically scaled 0–16384 (0–100%) or in direct tenths of a Hertz (0–5000 = 0.00–50.00 Hz).
- Status Word (SW / ZSW): Drive → Master feedback register containing bitwise flags for Ready to Run, Running, At Reference Speed, Tripped, and Warning.
- Main Actual Value (ACT / Speed Feedback): Drive → Master real-time output shaft RPM or motor electrical frequency.
Standard 16-Bit VFD Modbus Register Map
Below is the standard register layout implemented across leading industrial inverters and simulated in ModbusSimulator:
| Modbus Address (0-Based) | PLC Register (1-Based) | Parameter Name | Data Type | Access | Engineering Units / Scaling |
|---|---|---|---|---|---|
0 |
40001 |
Control Word (CW) | UINT16 (Bitfield) | Read / Write | See Bit Breakdown Below |
1 |
40002 |
Speed Setpoint (REF) | INT16 | Read / Write | 0 to 16,384 = 0 to 100.0% Nominal RPM |
2 |
40003 |
Status Word (SW) | UINT16 (Bitfield) | Read Only | Drive State Feedback |
3 |
40004 |
Output Frequency | UINT16 | Read Only | 0.1 Hz (e.g. 500 = 50.0 Hz) |
4 |
40005 |
Output Current | UINT16 | Read Only | 0.1 Amperes RMS (e.g. 142 = 14.2 A) |
5 |
40006 |
Motor Output Voltage | UINT16 | Read Only | 1.0 Volts AC (e.g. 400 = 400 VAC) |
6 |
40007 |
DC Bus Voltage | UINT16 | Read Only | 1.0 Volts DC (e.g. 560 = 560 VDC) |
7 |
40008 |
Motor Output Torque | INT16 | Read Only | 0.1 % Nominal Torque (e.g. 850 = 85.0%) |
8 |
40009 |
Motor Thermal State | UINT16 | Read Only | % Thermal Capacity (0-100%) |
9 |
40010 |
Active Fault Code | UINT16 (Enum) | Read Only | 0 = OK, 1 = Overcurrent, 2 = Overvoltage, 3 = Overtemp |
Deep Dive: Decoding VFD Control Words & Status Words
1. The VFD Control Word Bitmask (Master to Drive)
In standard drives (such as ABB ACS drives following the ABB Drive Profile or Danfoss FC series), setting specific bits enables state transitions in the internal drive state machine:
- Bit 0 (OFF1 / RUN):
1= Normal Ramp Stop → Ready to Start;0= Stop along Deceleration Ramp. - Bit 1 (OFF2 / COAST):
1= Operation permitted;0= Emergency Coast to Stop (Immediate power stage disable). - Bit 2 (OFF3 / QUICK STOP):
1= Operation permitted;0= Fast Emergency Braking Stop along separate Quick Stop Ramp. - Bit 3 (INVERTER ENABLE):
1= Enable IGBT Gate Drivers;0= Inverter output blocked. - Bit 7 (FAULT RESET): Rising Edge (
0 → 1) = Clears latched active drive faults. - Bit 11 (ROTATION DIRECTION):
0= Forward Rotation;1= Reverse Rotation.
0x047E (Ready to switch on) followed by 0x047F (Start / Run enabled). In ModbusSimulator, you can verify this startup sequence step-by-step.
2. The VFD Status Word Bitmask (Drive to Master)
The Status Word provides real-time state feedback for PLC interlocking and SCADA monitoring:
- Bit 0 (RDY_ON):
1= Ready to Switch On (DC Bus charged, no faults). - Bit 1 (RDY_RUN):
1= Ready to Operate (Inverter enabled). - Bit 2 (RUNNING):
1= Modulating output voltage to motor. - Bit 3 (FAULT / TRIPPED):
1= Drive is faulted; check Fault Code register. - Bit 8 (AT_SETPOINT):
1= Actual speed matches speed setpoint within tolerance band. - Bit 9 (REMOTE):
1= Fieldbus Modbus control mode active (Local keypad bypassed).
Step-by-Step: Testing a VFD with ModbusSimulator
Here is how you can set up a complete VFD simulation environment in 3 minutes:
Step 1: Configure the VFD Slave in ModbusSimulator
- Open ModbusSimulator on your Windows machine.
- Select Server (Slave) Mode and choose Modbus TCP (Port 502) or Modbus RTU (Virtual COM Port, 19200 Baud, 8-N-1).
- Set Slave / Unit ID to
1. - Populate the initial holding registers:
- Register
0(Control Word):0 - Register
1(Reference):0 - Register
2(Status Word):0x0031(Ready to switch on) - Register
6(DC Bus Voltage):560(560 VDC nominal)
- Register
- Click Start Server.
Step 2: Connect with Your PLC or Automated Python Test Suite
Below is a production-ready Python test script using pymodbus demonstrating automated VFD startup, ramp testing, telemetry monitoring, and fault injection:
import time
import struct
from pymodbus.client import ModbusTcpClient
def test_vfd_simulation():
# Connect to simulated VFD on localhost
client = ModbusTcpClient(host='127.0.0.1', port=502)
if not client.connect():
print("[-] Failed to connect to Modbus VFD Simulator.")
return
unit_id = 1
print("[+] Connected to Simulated VFD (Unit ID: 1)")
# 1. Check Initial Status Word (Register 40003 / Address 2)
rr = client.read_holding_registers(address=2, count=8, slave=unit_id)
status_word = rr.registers[0]
dc_bus = rr.registers[4]
print(f"[*] Initial Status Word: 0x{status_word:04X} | DC Bus: {dc_bus} V")
# 2. Set Speed Reference to 75.0% (12,288 / 16,384) -> Register 40002 / Address 1
target_speed = 12288
client.write_register(address=1, value=target_speed, slave=unit_id)
print(f"[*] Set Speed Reference to {target_speed} (75.0% Speed / 37.5 Hz)")
# 3. Send Start Command (Control Word = 0x047F) -> Register 40001 / Address 0
client.write_register(address=0, value=0x047F, slave=unit_id)
print("[*] Sent START Command (CW: 0x047F)")
# Simulate motor ramp in the slave registers
print("[*] Monitoring VFD Output Telemetry:")
for freq in [100, 250, 375]: # 10.0 Hz, 25.0 Hz, 37.5 Hz
client.write_register(address=3, value=freq, slave=unit_id) # Output Freq
client.write_register(address=4, value=85, slave=unit_id) # 8.5 Amps
time.sleep(0.5)
# Read back telemetry
telemetry = client.read_holding_registers(address=2, count=5, slave=unit_id).registers
print(f" -> Status: 0x{telemetry[0]:04X} | Freq: {telemetry[1]/10:.1f} Hz | Current: {telemetry[2]/10:.1f} A")
# 4. Inject Drive Overcurrent Fault (Fault Code = 1, Status Bit 3 = 1)
print("[!] INJECTING DRIVE OVERCURRENT FAULT (Fault Code: 1)...")
client.write_register(address=9, value=1, slave=unit_id) # Active Fault = 1 (Overcurrent)
client.write_register(address=2, value=0x0038, slave=unit_id) # Status Bit 3 Set (Tripped)
# Read active fault
fault = client.read_holding_registers(address=9, count=1, slave=unit_id).registers[0]
print(f"[!] Drive Tripped! Latched Fault Code: {fault}")
# 5. Send Fault Reset Pulse (Bit 7 of Control Word)
print("[*] Sending FAULT RESET Command (CW Bit 7 High: 0x04FE)...")
client.write_register(address=0, value=0x04FE, slave=unit_id)
client.write_register(address=9, value=0, slave=unit_id) # Clear Fault
client.write_register(address=2, value=0x0031, slave=unit_id) # Reset to Ready
print("[+] Drive Fault Cleared successfully. VFD returned to Ready state.")
client.close()
if __name__ == '__main__':
test_vfd_simulation()
Common Modbus VFD Commissioning Errors to Avoid
- 0-Based vs 1-Based Modbus Offset: Many European PLCs (e.g. Siemens TIA Portal or CoDeSys) use 1-based indexing (where 40001 is offset 0). If you write speed setpoint to 40002 in your PLC and the drive misinterprets it as the control word, you will get unexpected stops. Read our Modbus Register Types Guide.
- Signed vs Unsigned Speed Values: Negative speed references are frequently used for reverse rotation (-16384 to +16384). Ensure your PLC uses 16-bit signed integer math (
INT) rather thanWORDorUINTto avoid overflow crashes. - Timeout & Comm Loss Behavior: Real VFDs trip with a "Bus Timeout" fault if no Modbus packet is received within a programmed watchdog window (typically 500ms to 2000ms). Test your PLC's polling frequency to prevent nuisance trips during plant runtime.
- RS-485 Termination & Bias Resistors: On Modbus RTU serial multidrop buses, ensure 120Ω end-of-line resistors are installed at both physical ends of the daisy chain. Check out our Modbus Troubleshooting Guide.
Test Your VFD Control Logic with ModbusSimulator Today
Download ModbusSimulator for Windows 10/11. Simulate VFD inverters, multi-axis motor controllers, and full industrial automation plants without hardware.