# Property of PMA Electrical Solutions, LLC. # # ABB ACS380 running the MACHINERY control program, embedded fieldbus (EFB) # Modbus RTU. Claims the ACS380 only. No sibling model is claimed here: the # ACS580/ACH580/ACQ580 have their own firmware manual and their own profile, # and the ACS380 claim that used to sit in profiles/abb_acs580.toml was removed # as unverified. Nothing in this file was taken from that manual. # # COMMUNICATION PATH (doc p.547-548): embedded Modbus RTU on the EIA-485 # terminal (B+ / A- / BGND) of the BMIO-01 I/O-and-Modbus module. Available on # the standard variant ACS380-04xS, or on the configured variant ACS380-04xC # only with option +L538 (the BMIO-01 module). An ACS380-04xC without +L538 has # no embedded Modbus. The alternate embedded protocol, CANopen on a BCAN-11 # (+K495), is a different hardware option and is NOT covered here (p.575-576). # # SOURCE: ABB firmware manual "ACS380 machinery control program", # 3AXD50000029275 Rev J, EN, effective 2025-11-30 (title page, PDF p.3). # Section -> PDF page of that document: # [serial], 58.xx setup ....... p.406-418 # control word / sequences .... p.556-559, p.564-565 # status word ................. p.560-561 # holding register map ........ p.569-570 # addressing mode 58.33 ....... p.417 # reference scaling ........... p.566 (diagram), p.387-388 (group 46) # [monitor] group 01 .......... p.132-135 # [faults] group 04 ........... p.137-138 # fault code table ............ p.527-546 # # DRIVE-SIDE SETUP. Select the "Modbus RTU" control macro from the panel; the # drive then sets 20.01 Ext1 commands = Embedded fieldbus, 22.11 Ext1 speed ref1 # = EFB ref1, 28.11 Ext1 frequency ref1 = EFB ref1 and 58.01 = Modbus RTU # (p.549). Then set 58.03 node address, 58.04 baud, 58.05 parity, and apply with # 58.06 = Refresh settings. Leave 58.25 Control profile = ABB Drives (0) — this # file is the ABB Drives profile; the DCU profile (58.25 = 5 per the parameter # listing p.413; the EFB chapter p.555 says 3 — the manual is inconsistent, # read the value off the drive) has a different control and status word layout # entirely (p.558-559). # TRAP: that same macro sets 31.11 Fault reset selection = DI1 (p.549), and # control word bit 7 is "effective only if the fieldbus interface is set as the # source for this signal" (p.557). Until 31.11 points at the EFB, the drive # ACKs the reset word and does nothing. Same caveat applies to bit 6. # # ADDRESSING. The manual writes Modbus holding registers as 6-digit decimal, # 400001...465536 (p.554-555). Conversion used here: # 0-based protocol address = (6-digit register) - 400001 # Fixed block (p.569-570): 400001 CW -> 0, 400002 Ref1 -> 1, 400003 Ref2 -> 2, # 400004 SW -> 3, 400005 Act1 -> 4, 400006 Act2 -> 5. # Parameters land in 400101...465536 per 58.33 Addressing mode, default Mode 0, # 16-bit: register = 400000 + 100 * group + index (p.417). Combined: # 0-based address = 100 * group + index - 1 # par 01.06 Output frequency -> 400000 + 100 + 6 = 400106 -> 400106 - 400001 = 105 # par 04.01 Tripping fault -> 400000 + 400 + 1 = 400401 -> 400401 - 400001 = 400 # 32-bit parameters live in a DIFFERENT Mode 0 window (420000 + 200 * group + # 2 * index) and are not used by this profile — every point below is 16-bit. # # SCALING IS FIELDBUS FbEq16, NOT PANEL DECIMALS, and several points are scaled # by group 46 parameters, so they depend on how the drive is configured. Group # 46 defaults (p.387-388): 46.01 Speed scaling 1500.00 rpm, 46.02 Frequency # scaling 50.00 Hz, 46.03 Torque scaling 100.0%, 46.04 Power scaling 100.00, # 46.05 Current scaling 100 A. Speed and frequency map onto 20000, torque and # power onto 10000 (p.566), and current onto 10000 (46.05, p.388 — the p.566 # diagram covers only 46.01…46.04). The scales marked # CONFIG-DEPENDENT below are computed from those DEFAULTS — read 46.01-46.05 on # the actual unit before trusting them. The %-of-nominal and voltage points have # fixed FbEq16 factors and are the ones to trust first. name = "ABB ACS380" vendor = "ABB" device_type = "vfd" verified = false probe_register = 3 # status word, readable whenever the fieldbus is alive # 58.04 default 19.2 kbps, 58.05 default "8 EVEN 1" (p.407-408). [serial] baudrate = 19200 parity = "E" stopbits = 1 [monitor] control_word = { address = 0, bits = { 0 = "OFF1_CONTROL", 1 = "OFF2_CONTROL", 2 = "OFF3_CONTROL", 3 = "INHIBIT_OPERATION", 4 = "RAMP_OUT_ZERO", 5 = "RAMP_HOLD", 6 = "RAMP_IN_ZERO", 7 = "RESET", 8 = "JOGGING_1", 9 = "JOGGING_2", 10 = "REMOTE_CMD", 11 = "EXT_CTRL_LOC" } } reference_1 = { address = 1, signed = true, scale = 0.005, unit = "%" } # 20000 = 100% status_word = { address = 3, bits = { 0 = "RDY_ON", 1 = "RDY_RUN", 2 = "RDY_REF", 3 = "TRIPPED", 4 = "OFF_2_STATUS", 5 = "OFF_3_STATUS", 6 = "SWC_ON_INHIB", 7 = "ALARM", 8 = "AT_SETPOINT", 9 = "REMOTE", 10 = "ABOVE_LIMIT" } } # 01.06. CONFIG-DEPENDENT: 20000 = par 46.02, default 50.00 Hz -> 0.0025 Hz/count. output_frequency = { address = 105, signed = true, scale = 0.0025, unit = "Hz" } # 01.07. CONFIG-DEPENDENT: 10000 = par 46.05, default 100 A -> 0.01 A/count. motor_current = { address = 106, scale = 0.01, unit = "A" } motor_current_pct_motor = { address = 107, scale = 1.0, unit = "%" } # 01.08, fixed 1 = 1% motor_current_pct_drive = { address = 108, scale = 1.0, unit = "%" } # 01.09, fixed 1 = 1% # 01.10. CONFIG-DEPENDENT: 10000 = par 46.03, default 100.0% -> 0.01 %/count. motor_torque = { address = 109, signed = true, scale = 0.01, unit = "%" } dc_voltage = { address = 110, scale = 0.1, unit = "V" } # 01.11, fixed 10 = 1 V output_voltage = { address = 112, scale = 1.0, unit = "V" } # 01.13, fixed 1 = 1 V # 01.14. CONFIG-DEPENDENT: 10000 = par 46.04, default 100.00 kW -> 0.01 kW/count. output_power = { address = 113, signed = true, scale = 0.01, unit = "kW" } output_power_pct = { address = 114, signed = true, scale = 0.1, unit = "%" } # 01.15, fixed 10 = 1% # 04.02 / 04.03 are the 2nd and 3rd CONCURRENT active faults, not a history (p.137-138). active_fault_2 = { address = 401 } active_fault_3 = { address = 402 } # ABB Drives profile (58.25 = 0). Word values are the manual's own literal # sequence example, p.564-565: # Start: 476h -> NOT READY TO SWITCH ON; if SW bit0 = 1 then 477h -> READY TO # SWITCH ON (stopped), then 47Fh -> OPERATION (running) # Stop: 477h = stop according to 21.03 Stop mode # (47Eh = OFF1 ramp stop, if a deterministic ramp stop is wanted # regardless of how 21.03 is set) # Fault reset: rising edge of control word bit 7 # The master must keep refreshing the control word or the drive trips # 6681 EFB comm loss (58.14 default Fault, 58.16 default 3.0 s, p.410-412). [control] command_register = 0 speed_register = 1 speed_scale = 0.005 # write %, 20000 raw = 100% of the active group-46 scaling speed_signed = true # direction IS the sign of the reference here speed_unit = "%" # NOT Hz — percent of 46.01 (speed) or 46.02 (frequency) max_ref = 100.0 step_delay = 0.05 stop = [0x0477] run_fwd = [0x0476, 0x0477, 0x047F] # Reset is bit 7 rising ON TOP of the stopped word. Do NOT drop OFF1/OFF2/OFF3 # low to build a reset value — those are Emergency OFF and Emergency stop # (p.556-557), and 31.11 must point at the EFB for bit 7 to do anything at all. reset = [0x0477, 0x04F7, 0x0477] # run_rev is deliberately absent. On the ABB Drives profile direction is the # SIGN OF THE REFERENCE (p.566), not a control word bit, so a "reverse" command # word would be byte-identical to forward. Reverse with a negative reference. [control.watchdog] interval_ms = 300 fault = "6681 EFB comm loss" # 06.16 Drive status word 1, bit 6 "Modulating — 1 = Drive is modulating # (output stage is being controlled)" (p.146), read-only, reachable at # 100*6 + 16 - 1 = 615 under any control profile. Chosen over the ABB Drives # status word: its bit 8 is AT_SETPOINT (false during every ramp) and bit 2 # RDY_REF reports operation enabled, not output. Do NOT use 06.16 bit 14 # "Running" — p.146 defines it to include "Not started or start inhibited + # in ramp stop". [running_check] register = 615 bit = 6 # 04.01 Tripping fault; trip log store is 04.11-04.13 (p.138). [faults] register = 400 history = [410, 411, 412] # ABB reports faults as hex codes; TOML keys must be numeric, so these are the # decimal equivalents with the hex printed in the name. From the Fault messages # table, doc p.527-546. Warnings (Axxx codes) are a separate table and are not # included. Auxiliary/sub-codes (e.g. the 0001-0013 codes under FF61 ID run) # are reported in a separate word and are not in this table. [faults.codes] 0 = "No fault" 8833 = "0x2281 Calibration" 8976 = "0x2310 Overcurrent" 9008 = "0x2330 Earth leakage" 9024 = "0x2340 Short circuit" 9089 = "0x2381 IGBT overload" 12592 = "0x3130 Input phase loss" 12673 = "0x3181 Output wiring or earth fault" 12816 = "0x3210 DC link overvoltage" 12832 = "0x3220 DC link undervoltage" 13185 = "0x3381 Output phase loss" 13189 = "0x3385 Autophasing" 16656 = "0x4110 Control board temperature" 16912 = "0x4210 IGBT overtemperature" 17040 = "0x4290 Cooling" 17137 = "0x42F1 IGBT temperature" 17168 = "0x4310 Excess temperature" 17280 = "0x4380 Excess temperature difference" 18817 = "0x4981 External temperature 1" 18818 = "0x4982 External temperature 2" 20624 = "0x5090 STO hardware failure" 20625 = "0x5091 Safe torque off" 20626 = "0x5092 PU logic error" 20627 = "0x5093 Rating ID mismatch" 20628 = "0x5094 Measurement circuit temperature" 20632 = "0x5098 I/O communication loss" 20640 = "0x50A0 Fan" 22145 = "0x5681 PU communication" 22146 = "0x5682 Power unit lost" 22160 = "0x5690 PU communication internal" 22161 = "0x5691 Measurement circuit ADC" 22162 = "0x5692 PU board powerfail" 22163 = "0x5693 Measurement circuit DFF" 22167 = "0x5697 Charging feedback" 24961 = "0x6181 FPGA version incompatible" 25088 = "0x6200 Checksum mismatch" 25350 = "0x6306 FBA A mapping file" 25729 = "0x6481 Task overload" 25735 = "0x6487 Stack overflow" 25761 = "0x64A1 Internal file load" 25766 = "0x64A6 Adaptive program file incompatible or corrupted" 25778 = "0x64B2 User set fault" 25825 = "0x64E1 Kernel overload" 25985 = "0x6581 Parameter system" 26017 = "0x65A1 FBA A parameter conflict" 26241 = "0x6681 EFB comm loss" 26242 = "0x6682 EFB config file" 26243 = "0x6683 EFB invalid parameterization" 26244 = "0x6684 EFB load fault" 26245 = "0x6685 EFB fault 2" 26246 = "0x6686 EFB fault 3" 26754 = "0x6882 Text 32-bit table overflow" 26757 = "0x6885 Text file overflow" 28801 = "0x7081 Control panel loss" 28802 = "0x7082 I/O module comm loss" 28806 = "0x7086 I/O module AI Over voltage" 28807 = "0x7087 I/O module configuration" 28961 = "0x7121 Motor stall" 28962 = "0x7122 Motor overload" 29057 = "0x7181 Brake resistor" 29059 = "0x7183 BR excess temperature" 29060 = "0x7184 Brake resistor wiring" 29073 = "0x7191 BC short circuit" 29074 = "0x7192 BC IGBT excess temperature" 29090 = "0x71A2 Mechanical brake closing failed" 29091 = "0x71A3 Mechanical brake opening failed" 29093 = "0x71A5 Mechanical brake opening not allowed" 29441 = "0x7301 Motor speed feedback" 29456 = "0x7310 Overspeed" 29569 = "0x7381 Encoder" 29616 = "0x73B0 Emergency ramp failed" 29680 = "0x73F0 Overfrequency" 29968 = "0x7510 FBA A communication" 32769 = "0x8001 ULC underload fault" 32770 = "0x8002 ULC overload fault" 32928 = "0x80A0 AI supervision" 32944 = "0x80B0 Signal supervision 1" 32945 = "0x80B1 Signal supervision 2" 32946 = "0x80B2 Signal supervision 3" 32947 = "0x80B3 Signal supervision 4" 32948 = "0x80B4 Signal supervision 5" 32949 = "0x80B5 Signal supervision 6" 36993 = "0x9081 External fault 1" 36994 = "0x9082 External fault 2" 36995 = "0x9083 External fault 3" 36996 = "0x9084 External fault 4" 36997 = "0x9085 External fault 5" 53504 = "0xD100 Torque prove" 53505 = "0xD101 Brake slip" 53506 = "0xD102 Brake safe closure" 53509 = "0xD105 Speed match" 53512 = "0xD108 Stop limits I/O error" 53514 = "0xD10A Brake not selected" 64129 = "0xFA81 Safe torque off 1" 64130 = "0xFA82 Safe torque off 2" 65377 = "0xFF61 ID run" 65409 = "0xFF81 FB A force trip" 65422 = "0xFF8E EFB force trip" # 07.03 Drive rating id (p.153; appendix p.485: type List, 1=1, 16-bit), # group 07 System info, "All parameters in this group are read-only". # 0-based = 100*7 + 3 - 1 = 702. The enumeration values are not published in # this manual, so this is an identity match only, not a decoded amp rating — # which is all the restore guard compares. [rating] register = 702 words = 1 scale = 1.0 unit = "" label = "Drive rating id (07.03)" [connection] summary = "The ACS380 supports embedded Modbus RTU through the BMIO-01 I/O-and-Modbus module." warnings = ["BMIO-01 is standard on ACS380-04xS, requires option +L538 on ACS380-04xC, and is not available on ACS380-04xE; verify the type code before wiring."] [[connection.methods]] id = "built_in_rs485" title = "Built-in Modbus RTU" transport = "serial" hardware = "built_in" port = "BMIO-01 EIA-485 terminal group" connector = "Terminals marked B+, A-, BGND, Shield with termination selector" adapter = "Isolated USB-to-RS-485 adapter" cable = "Shielded twisted-pair RS-485 cable with signal common" parts = ["Isolated USB-to-RS-485 adapter","Shielded twisted-pair RS-485 cable with signal common","Termination hardware if required"] steps = ["Lock out all power, verify the motor cannot start, and wait for the DC bus to discharge.","Open the control compartment and locate BMIO-01 EIA-485 terminal group.","Land the conductors exactly as shown below, preserving the shield through each daisy-chain node.","Enable termination only if this device is at a physical end of the RS-485 trunk.","Restore control power with the motor inhibited and verify a read before enabling fieldbus control."] setup = ["Fit/verify BMIO-01 and enable termination only at a bus end.","Select the Modbus RTU control macro or set 58.01 and the group 58 serial parameters manually.","Verify command/reference sources and set 31.11 to the required EFB communication-loss event."] warnings = [] source = "ABB 3AXD50000029275, pp. 38 and 547-557." [[connection.methods.wiring]] adapter = "D+ / B / positive" device = "B+" signal = "RS-485 positive" [[connection.methods.wiring]] adapter = "D- / A / negative" device = "A-" signal = "RS-485 negative" [[connection.methods.wiring]] adapter = "COM / signal common" device = "BGND" signal = "Bus reference" [[connection.methods.wiring]] adapter = "Cable shield" device = "Shield" signal = "Shield bond" required = false