# Property of PMA Electrical Solutions, LLC. # # Delta MX300 compact multi-drive, embedded RS-485 (COM1) Modbus. # # COVERAGE — the MX300 series only. The suffixes are MODULE TYPES, not drive # variants: MX300-C and MX300-E are the two RECTIFIER modules and MX300-A and # MX300-S the single/double/triple-axis INVERTER modules (printed 1-6, 1-7). # This profile is ONE INVERTER AXIS behind either rectifier. The RS-485 port # (CN3) is on the rectifier: a -C carries Modbus + CANopen, a -E carries # Modbus + EtherCAT / PROFINET (printed 1-7). Chapter 7-2 Modbus is not # scoped to either — only 7-3 CANopen ("MX300-C models only") and 7-4 / 7-5 # EtherCAT and PROFINET ("MX300-E models only") are — so the map below holds # behind both. NOT CLAIMED: MS300, MH300, ME300, MP300, C2000, C2000-HS, # CH2000, CP2000. Delta fault numbering differs between families; every code # below was transcribed from THIS manual's own fault summary. # # THE MX300 IS A MODULAR MULTI-AXIS DRIVE, NOT A SINGLE NODE. One rectifier # module feeds single/double/triple-axis inverter modules, and the RECTIFIER # AXIS AND EVERY INVERTER AXIS EACH HOLD THEIR OWN Pr.09-00 MODBUS ADDRESS # (printed 7-2). This profile describes ONE INVERTER AXIS — the axis that # actually runs a motor. Pointing it at a rectifier axis reads a valid but # different thing: on the rectifier, 2102H/2103H/2106H/210CH/210FH do not # exist, 2101H carries only bit 11, and 2104H is the SUM of the output # currents of all inverter axes (printed 7-11 to 7-13). Do not clone a # rectifier axis onto an inverter axis or the reverse. # # SOURCES — Delta MX300 Series User Manual (Delta Compact Multi-Drive), # DELTA_IA-MDS_MX300_UM_EN_20260312 (downloadcenter.deltaww.com, Download # Center DID 44925), 663 pp. Citations are the manual's own chapter-prefixed # printed page numbers. # p. 5-4 Pr.00-21 operation command source, Pr.00-20 master # frequency command source # p. 7-2 7-1-1 Per-axis Pr.09-00 addressing; Pr.09-05 auto address; # baud and format come from the RECTIFIER axis # p. 7-10 - 7-11 Address list; control command block 20xx # p. 7-11 - 7-14 Status monitor 21xx / 22xx, per-axis availability # p. 8-3 - 8-4 8-1-2 Summary of Fault Codes — the complete table # p. 12-2, 12-15 Pr.00-00 rectifier / inverter module identity code # p. 12-11 Rectifier group 09 summary — the axis that HAS 09-01/09-04 # p. 12-47 Inverter group 09 summary — no 09-01, no 09-04 # p. 13-21 Rectifier Pr.09-01 / Pr.09-04 # p. 13-43 Pr.01-00 Maximum Operation Frequency 0.00-599.00 Hz # p. 13-150 Inverter Pr.09-00 / 09-02 / 09-03 / 09-10 # # DRIVE-SIDE SETUP — THE SETUP PARAMETERS ARE SPLIT ACROSS TWO AXES. # On the INVERTER axis: 00-20 Master frequency command source = 1 (RS-485 # communication input), 00-21 Operation command source = 2 (RS-485 # communication input), 09-00 this axis's node address (DEFAULT 0 = DISABLE, # p. 13-150 — an inverter axis does not answer Modbus until 09-00 is set or # the rectifier's 09-05 auto-allocates it), 09-02 / 09-03 comm-loss treatment. # On the RECTIFIER axis: 09-01 baud and 09-04 protocol = 12 (8,N,1 RTU). # "The RS-485 communication baud rate and communication format of MX300 can be # set by Pr.09-01 and Pr.09-04 of rectifier axis" (p. 7-2), and the inverter # module's own group 09 summary lists NEITHER 09-01 NOR 09-04 (p. 12-47). # Do not send a tech to set baud or framing on the inverter axis; the # parameters are not there and the link will not come up. # THE FACTORY DEFAULT 09-04 IS 1 = 7,N,2 ASCII — the [serial] block below # describes the bus AFTER the rectifier's 09-04 has been set to 12, not as it # ships (p. 13-21). Pr.09-01 on this family tops out at 38.4 kbps. # # Delta documents these as hex addresses that are already 0-based; parameter # Pr.GG-nn is register 0xGGnn (p. 7-10, "the Modbus address of Pr.04-10 is # 040AH"). name = "Delta MX300" vendor = "Delta Electronics" device_type = "vfd" verified = false probe_register = 0x2101 [connection] summary = "Built-in two-wire Modbus RTU is available without an option card." warnings = [] [[connection.methods]] id = "control_terminals_rs485" title = "Built-in RS-485 control terminals" transport = "serial" hardware = "built_in" port = "CN1 terminals SG+, SG-, SGND" connector = "Three control-terminal positions" adapter = "Isolated USB-to-RS-485 adapter, 2-wire half-duplex" cable = "Shielded twisted-pair RS-485 cable, 120 ohm nominal impedance" parts = ["Isolated two-wire RS-485 adapter", "Shielded twisted-pair RS-485 cable, 120 ohm nominal impedance"] steps = ["Lock out line and control power, wait the vendor-specified discharge time, and verify the DC bus is de-energized before opening a cover or landing conductors.", "Land the positive and negative data conductors exactly as shown; connect the cable shield or signal common only where the method identifies it.", "Route the communications cable away from motor and mains conductors. Terminate the two physical ends of a long multidrop trunk only.", "Restore control power with the motor area clear, configure the drive from its keypad, then verify identity and read-only monitor data before enabling remote control."] setup = ["On the inverter axis set 00-20=1, 00-21=2 and a nonzero 09-00 node; set 09-01 baud and 09-04=12 on the rectifier axis."] warnings = ["RS-485 A/B naming is not consistent between manufacturers. Follow the + and - signal mapping in this guide, not the letter printed on an unfamiliar adapter.", "Do not use protective earth as the data return unless the vendor drawing explicitly calls for it."] source = "Delta MX300 User Manual, PDF p. 56 (CN1/CN3 terminal and RJ45 pinout), printed pp. 7-2, 12-47, and 13-150 (setup)" [[connection.methods.wiring]] adapter = "Adapter D+ / +" device = "SG+" signal = "RS-485 data positive" required = true [[connection.methods.wiring]] adapter = "Adapter D- / -" device = "SG-" signal = "RS-485 data negative" required = true [[connection.methods.wiring]] adapter = "Adapter signal ground / shield" device = "SGND" signal = "Signal reference or shield drain" required = false [[connection.methods]] id = "rj45_rs485" title = "Built-in RS-485 modular jack" transport = "serial" hardware = "built_in" port = "CN3 RJ45" connector = "RJ45 (RS-485, not Ethernet)" adapter = "Isolated USB-to-RS-485 adapter, 2-wire half-duplex" cable = "Shielded twisted-pair cable terminated to the documented modular-plug pins" parts = ["Isolated two-wire RS-485 adapter", "Shielded twisted-pair cable terminated to the documented modular-plug pins", "Field-terminated modular plug or documented breakout adapter"] steps = ["Lock out line and control power, wait the vendor-specified discharge time, and verify the DC bus is de-energized before opening a cover or landing conductors.", "Land the positive and negative data conductors exactly as shown; connect the cable shield or signal common only where the method identifies it.", "Route the communications cable away from motor and mains conductors. Terminate the two physical ends of a long multidrop trunk only.", "Restore control power with the motor area clear, configure the drive from its keypad, then verify identity and read-only monitor data before enabling remote control."] setup = ["On the inverter axis set 00-20=1, 00-21=2 and a nonzero 09-00 node; set 09-01 baud and 09-04=12 on the rectifier axis."] warnings = ["A modular communications jack is not automatically Ethernet. Never connect it to a LAN switch unless this guide explicitly identifies a Modbus TCP method.", "RS-485 A/B naming is not consistent between manufacturers. Follow the + and - mapping shown here.", "Pin 8 carries accessory/keypad power and must not be connected to an RS-485 adapter."] source = "Delta MX300 User Manual, PDF p. 56 (CN1/CN3 terminal and RJ45 pinout), printed pp. 7-2, 12-47, and 13-150 (setup)" [[connection.methods.wiring]] adapter = "Adapter D+ / +" device = "RJ45 pin 5 (SG+)" signal = "RS-485 data positive" required = true [[connection.methods.wiring]] adapter = "Adapter D- / -" device = "RJ45 pin 4 (SG-)" signal = "RS-485 data negative" required = true [[connection.methods.wiring]] adapter = "Adapter signal ground / shield" device = "RJ45 pin 3 or 7 (signal ground)" signal = "Signal reference or shield drain" required = false [serial] baudrate = 9600 parity = "N" stopbits = 1 [monitor] # p. 7-12. Bits 1-0 are a 2-bit run state (00 stop, 01 stopping, 10 standby, # 11 running) and bits 4-3 a 2-bit direction-transition field (00 FWD, 01 # REV->FWD, 10 FWD->REV, 11 REV), so neither decodes as an independent flag. # Unlike the CH2000 and C2000-HS, this manual documents NO bit 7 and no # bits 15-13 HOA field on the MX300 — not carried over. drive_status = { address = 0x2101, bits = { 2 = "Jog", 8 = "FreqFromComm", 9 = "FreqFromAnalog", 10 = "CmdFromComm", 11 = "ParamLocked" } } frequency_command = { address = 0x2102, scale = 0.01, unit = "Hz" } output_frequency = { address = 0x2103, scale = 0.01, unit = "Hz" } # p. 7-13: "XX.XX A. When current is higher than 655.35, it shifts the decimal # as XXX.X A. The decimal can refer to High byte of 211F." CONFIG/FRAME- # DEPENDENT — confirm 211F on the unit before trusting 0.01. output_current = { address = 0x2104, scale = 0.01, unit = "A" } dc_bus_voltage = { address = 0x2105, scale = 0.1, unit = "V" } output_voltage = { address = 0x2106, scale = 0.1, unit = "V" } # 0x2107 is the multi-step-speed STEP NUMBER, not a speed. Actual rpm is 0x210C. multistep_step = { address = 0x2107 } # 0x210A is the power factor ANGLE in 0.1 degrees (0.0-180.0), not cos phi. power_factor_angle = { address = 0x210A, scale = 0.1, unit = "deg" } # The manual gives 210B as "XXX.X %" without stating a sign convention (the # signed torque it does document is 2208H). Left unsigned rather than guessed. output_torque = { address = 0x210B, scale = 0.1, unit = "%" } motor_speed = { address = 0x210C, unit = "rpm" } # p. 7-13: 210F is "XXXX.X kW" on the MX300 — one decimal. The CH2000 and # C2000-HS document the SAME address as "X.XXX kW"; carrying that scale here # would read 100x high. output_power = { address = 0x210F, scale = 0.1, unit = "kW" } power_components_temperature = { address = 0x220E, scale = 0.1, unit = "degC" } [control] command_register = 0x2000 # p. 7-11. Fault reset is a DIFFERENT register. On 0x2000, bits 1-0 = 10b is # RUN, so writing 0x0002 there commands an unexpected start in the last # direction. Reset is bit 1 of 0x2002 — and 0x2002 is one of the few control # registers the manual marks as valid on the rectifier axis too. reset_register = 0x2002 speed_register = 0x2001 speed_scale = 0.01 speed_unit = "Hz" # Pr.01-00 range (p. 13-43); the drive's ceiling is whatever 01-00 is set to # (default 60.00 / 50.00). max_ref = 599.0 step_delay = 0.05 # The MX300 adds a bits 14-13 field on 0x2000 that its siblings do not have: # 00b no function, 01b operation command by the digital keypad, 10b operation # command by the Pr.00-21 setting, 11b change the operation source (p. 7-11). # All sequences below leave it at 00b so no write silently re-points the # drive's command source. stop = [0x0001] run_fwd = [0x0012] run_rev = [0x0022] reset = [0x0002] # bit 1 of 0x2002 # On the INVERTER axis 09-03 Modbus time-out detection defaults to 0.0 s # (detection OFF) and 09-02 Modbus transmission fault treatment defaults to # 3 = "No warning, no fault, and continue operation" (p. 13-150; the rectifier # axis carries its own identical pair on p. 13-21). At factory defaults the drive KEEPS # RUNNING when the master goes quiet; the keepalive below proves the link from # this side but is not a stop backstop until 09-02 and 09-03 are commissioned. # The manual also warns that CE10 latches: it "does not clear automatically" # once the link recovers and needs an explicit reset. [control.watchdog] interval_ms = 300 fault = "CE10 Modbus transmission time-out (fault 58) — only if 09-03 > 0.0 s and 09-02 = 1 or 2; latches until reset" backstop_requires_setup = true # Bit 0 of the 2-bit run state: set for 01b "stopping" (still decelerating, # motor turning) and 11b "running". # KNOWN BLIND SPOT — 2101H bits 1-0 are a 2-bit state and RunningCheck is a # SINGLE-BIT test, so no choice of bit covers all three non-stopped states. # Bit 0 reads 0 in 10b "standby" (run command held, RUN indicator ON, no # output). A drive sitting armed at zero output therefore reports Stopped, and # the restore precondition that consumes this will pass on it. Bit 1 would # swap the blind spot to 01b (motor still turning during decel), not remove it. # Do not treat a Stopped here as proof the drive is disarmed. SECOND BLIND # SPOT ON THIS FAMILY: on a RECTIFIER axis 2101H bits 10-0 are not implemented # at all (printed 7-12), so bit 0 reads 0 there unconditionally. # OPEN FOR BENCH: whether 2226H bit 4 ("motor drive did output", printed # p. 7-15) is set in standby — if it is not either, the fix is a masked state # test in core, not a different bit in this file. [running_check] register = 0x2101 bit = 0 # p. 7-12: bit7-0 is the FAULT code and bit15-8 the WARNING code. Without the # mask an active warning corrupts the fault lookup. [faults] register = 0x2100 mask = 0x00FF # Pr.06-17 - Pr.06-22 Fault Record 1-6 -> 0x0611 - 0x0616. Records 7-10 live # at Pr.14-70 - Pr.14-73 and are deliberately not listed here. history = [0x0611, 0x0612, 0x0613, 0x0614, 0x0615, 0x0616] # Transcribed complete from 8-1-2 Summary of Fault Codes, printed pp. 8-3/8-4. # The manual splits code 24 into display sub-codes 24_1 (PTC) and 24_2 # (PT100); the register carries the single code 24. [faults.codes] 0 = "No record" 1 = "ocA over-current during acceleration" 2 = "ocd over-current during deceleration" 3 = "ocn over-current during steady operation" 4 = "GFF ground fault" 6 = "ocS over-current at stop" 7 = "ovA over-voltage during acceleration" 8 = "ovd over-voltage during deceleration" 9 = "ovn over-voltage during constant speed" 10 = "ovS over-voltage at stop" 11 = "LvA low-voltage during acceleration" 12 = "Lvd low-voltage during deceleration" 13 = "Lvn low-voltage at constant speed" 14 = "LvS low-voltage at stop" 15 = "orP phase loss protection" 16 = "oH1 power components overheating" 17 = "oH2 circuit board ambient temperature overheats" 18 = "tH1o IGBT temperature detection failure" 19 = "tH2o capacitor hardware error" 21 = "oL overload" 22 = "EoL1 electronic thermal relay 1 protection" 23 = "EoL2 electronic thermal relay 2 protection" 24 = "oH3 motor overheating (PTC / PT100)" 26 = "ot1 over torque 1" 27 = "ot2 over torque 2" 28 = "uC under current" 31 = "cF2 EEPROM read error" 33 = "cd1 U-phase error" 34 = "cd2 V-phase error" 35 = "cd3 W-phase error" 36 = "Hd0 cc hardware error" 37 = "Hd1 oc hardware error" 38 = "Hd2 ov hardware error" 40 = "AUE auto-tuning error" 41 = "AFE PID off AI2" 48 = "ACE AI2 loss" 49 = "EF external fault" 50 = "EF1 emergency stop" 51 = "bb external base block" 52 = "Pcod password is locked" 54 = "CE1 illegal command" 55 = "CE2 illegal data address" 56 = "CE3 illegal data value" 57 = "CE4 data written to read-only address" 58 = "CE10 Modbus transmission time-out" 63 = "oSL over slip warning" 72 = "STL1 S1 internal circuit detection error" 76 = "STo safe torque off" 77 = "STL2 S2 internal circuit detection error" 79 = "Aoc U-phase over-current before run" 80 = "boc V-phase over-current before run" 81 = "coc W-phase over-current before run" 82 = "oPL1 output phase loss U phase" 83 = "oPL2 output phase loss V phase" 84 = "oPL3 output phase loss W phase" 87 = "oL3 low frequency overload protection" 89 = "roPd rotor position detection error" 101 = "CGdE CANopen guarding error" 102 = "CHbE CANopen heartbeat error" 104 = "CbFE CANopen bus off error" 121 = "CP20 internal communication error" 122 = "CP21 internal communication error" 123 = "CP22 internal communication error" 124 = "CP30 internal communication error" 126 = "CP32 internal communication error" 140 = "Hd6 oc hardware error" 141 = "b4GFF GFF occurs before run" 142 = "AuE1 auto-tuning error" 143 = "AuE2 auto-tuning error" 144 = "AuE3 auto-tuning error" 145 = "MErr error" 215 = "EdtE Ethernet communication time-out" 220 = "PStE PROFINET startup error" 221 = "PSFE PROFINET storage device error" 222 = "PoPE PROFINET operation error" 223 = "PrbE PROFINET program inspection error" 224 = "SToT STO execution time-out" 225 = "STor STO ROM verifying failure" 226 = "SToL STO loss" 227 = "STC1 STO channel 1 error" 228 = "STC2 STO channel 2 error" 229 = "SPC1 STO channel 1 time-out" 230 = "SPC2 STO channel 2 time-out" 231 = "SGbE STO gate buffer check error" 232 = "S18ov STO power 18V over voltage" 233 = "S18uv STO power 18V under voltage" 234 = "S6ov STO power 6V over voltage" 235 = "S6uv STO power 6V under voltage" 236 = "S5ov STO power 5V over voltage" 237 = "S5uv STO power 5V under voltage" 238 = "SWdG STO watchdog" 239 = "SAdE STO ADC sampling failure" 240 = "SEbL STO execution time is too short" 241 = "SEAb STO execution time is too high" 242 = "STo1 safe torque off 1" 243 = "STo2 safe torque off 2" # Pr.00-00 module identity code (read only): "Inverter Module Identity Code" # on an inverter axis (p. 12-15) and "Rectifier Module Identity Code" on the # rectifier axis (p. 12-2). A voltage class and kW enumeration, so it is a # genuine module identity — and it is also what distinguishes the two axis # types, which is exactly the mix-up this guard should catch. [rating] register = 0x0000 words = 1 scale = 1.0 label = "Module identity code (Pr.00-00)" # 01-xx and 02-xx configuration groups, in Delta's 0xGGnn layout. Upper bounds # are the highest indices this manual's parameter tables document: 01-52 # (0x0134) and 02-83 (0x0253). # Group 09 (communications) is DELIBERATELY EXCLUDED: it holds 09-00 node # address, 09-01 baud and 09-04 protocol, and on this family also Pr.09-05, # which RE-NUMBERS every axis behind the rectifier. Cloning that block would # not just move one node — it could renumber a whole module stack. # THE GAP AT 0x0232-0x0236 IS DELIBERATE. 02-50, 02-51 and 02-54 are marked # "Read only" in the inverter module's own summary (printed 12-27); 02-52 and # 02-53 do not exist on this family at all. The three read-only ones report # which source currently owns the terminals and the frequency command, so they # differ between donor and target on almost every pair. Left in range they # would read fine, plan a write, and NAK — landing in RestoreResult::failed # and reporting an otherwise-clean clone as a failure. # NOTE ALSO: group 01 DOES NOT EXIST ON A RECTIFIER AXIS (Chapter 12 lists no # 01-xx under 12-1 Rectifier Module Parameters) and the rectifier's 02-xx runs # to 02-98 with different contents. A restore aimed at the wrong axis type is # caught by the [rating] guard below, not by these ranges. [parameters] ranges = [[0x0100, 0x0134], [0x0200, 0x0231], [0x0237, 0x0253]]