# Property of PMA Electrical Solutions, LLC. # # ABB ACQ580 (drives for water), pump control program, embedded fieldbus (EFB) # Modbus RTU on control-unit terminal block X5 (B+ / A- / DGND). # # SOURCE: ABB firmware manual 3AXD50000035867 Rev E (EN, 2020-09-14), # "ACQ580 Pump control program firmware manual", 586 pp. Applies to pump # control program version 2.12 and later (p. 13). # pp. 224-228 X5 wiring, group 58 setup, command/reference source params # pp. 229-232 EFB basics, 6-digit register addressing, control profiles # pp. 233-239 Control Word / Status Word bit tables (ABB Drives profile) # p. 242 printed start / stop / reset control-word sequences # pp. 243-245 reference and actual-value scaling, holding-register map # pp. 246-249 function codes, exception codes, coils # pp. 288-293 group 01 actual values, group 04 warnings and faults # pp. 437 group 40 process PID actual values # pp. 462-463 group 46 scaling defaults (46.01-46.05) # pp. 474-479 group 58 defaults, 58.33 addressing formula # pp. 499-503 group 80 flow calculation, group 81 sensor actuals # pp. 204-215 fault message table, including the D4xx water faults # # THIS IS NOT THE ACS580 MAP. (profiles/abb_acs580.toml once claimed # "ACS580 / ACQ580 / ACH580 / ACS480" coverage; that header has since been # narrowed to the ACS580-01/-04/-07.) The ACQ580 firmware differs in ways # that matter: # * a whole D401-D40A water/pump fault family (dry run, level, pipe fill, # flow, inlet/outlet pressure) that the ACS580 fault table cannot decode # * parameter groups 80 Flow calculation, 81 Sensor settings, 82 Pump # protections, 83 Pump cleaning, which are the signals worth reading here # * default baud rate 19.2 kbps, not 9600 (58.04, p. 476) # * coil references 000009 / 000010 are printed as "Not for ACQ580" (p. 248) # Only the ACQ580 is claimed here. This manual covers ACQ580-01/-04/-07 and # the regenerative -31/-34; it does not cover ACS580, ACH580 or ACS480, so # nothing about those families is asserted. # # DRIVE-SIDE SETUP — without these the drive ACKs writes and ignores them: # 58.01 Protocol enable = Modbus RTU # 58.03 Node address, 58.04 Baud rate, 58.05 Parity (match the master) # 58.06 Communication control = Refresh settings (apply 58.xx changes) # 58.25 Control profile = ABB Drives (default) — this map assumes it # 58.33 Addressing mode = Mode 0 (default) — this map assumes it # 20.01 Ext1 commands = Embedded fieldbus (start/stop source) # 22.11 Ext1 speed ref1 = EFB ref1 (speed control mode) # 28.11 Ext1 frequency ref1 = EFB ref1 (frequency control mode) # # ADDRESSING. The manual prints 6-digit holding-register numbers. Convert: # 0-based protocol address = printed 6-digit number - 400001 # Parameters, 58.33 Mode 0: printed = 400000 + 100*group + index, so # 0-based = 100*group + index - 1. # par 01.06 Output frequency -> 100*1 + 6 - 1 = 105 # par 80.01 Actual flow -> 100*80 + 1 - 1 = 8000 # Mode 0 also exposes a separate 32-bit window at 420000 + 200*group + # 2*index; this profile uses the 16-bit window only. # # SCALING IS FIELDBUS 16-BIT (FbEq16), NOT PANEL DECIMALS, and several values # are scaled by group 46 parameters, so they depend on drive configuration — # confirm 46.01-46.05 on the actual unit. Manual defaults (pp. 462-463): # 46.01 Speed scaling 1500 rpm (1800 if 95.20 b0) = 20000 # 46.02 Frequency scaling 50.00 Hz (60.00 if 95.20 b0) = 20000 # 46.03 Torque scaling 100.0 % = 10000 # 46.04 Power scaling 1000.00 unit = 10000 # 46.05 Current scaling 10000 A = 10000 # The "Additional parameter data" table (p. 547 ff.) prints FbEq32, which is a # different number (100 = 1) and applies to the 32-bit window, not to these # registers. Do not mix the two. name = "ABB ACQ580" vendor = "ABB" device_type = "vfd" verified = false probe_register = 3 # status word, readable whenever the fieldbus is alive # 58.04 default "Modbus RTU: 19.2 kbps", 58.05 default "8 EVEN 1" (p. 476). [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", 10 = "REMOTE_CMD", 11 = "EXT_CTRL_LOC" } } reference_1 = { address = 1, signed = true, scale = 0.005, unit = "%" } # 20000 = 46.01/46.02 reference_2 = { address = 2, signed = true, scale = 0.005, unit = "%" } 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" } } # Group 01 actual values (pp. 288-291). Scales are the FbEq16 defaults above. # 01.06 via 46.02: 20000 = 50.00 Hz. On a 60 Hz unit (95.20 b0) this is # 20000 = 60.00 Hz and the scale is 0.003 — CONFIG-DEPENDENT. output_frequency = { address = 105, signed = true, scale = 0.0025, unit = "Hz" } motor_current = { address = 106, scale = 1.0, unit = "A" } # 01.07 via 46.05 motor_torque = { address = 109, signed = true, scale = 0.01, unit = "%" } # 01.10 via 46.03 dc_voltage = { address = 110, scale = 0.1, unit = "V" } # 01.11, 10 = 1 V output_voltage = { address = 112, unit = "V" } # 01.13, 1 = 1 V output_power = { address = 113, signed = true, scale = 0.1, unit = "kW" } # 01.14 via 46.04 # 04.01-04.03 are three CONCURRENT active faults, not a history (p. 293). active_fault_2 = { address = 401 } active_fault_3 = { address = 402 } # --- water / pump signals, the reason this profile is not the ACS580 one --- # All of these read 0 unless the corresponding function is configured, and # their engineering units are user-selected (81.20 pressure unit, 81.21 flow # unit, 81.22 length unit, 96.16 unit selection). The unit strings below are # the manual's defaults, not a guarantee. pid_feedback = { address = 4001, signed = true, unit = "bar" } # 40.02, FbEq16 1 = 1 bar pid_setpoint = { address = 4002, signed = true, unit = "bar" } # 40.03, FbEq16 1 = 1 bar # 80.01 FbEq16 is 1 = 1 m3/h, so the 16-bit window saturates at 32767 m3/h # even though the parameter itself ranges to 200000. actual_flow = { address = 8000, signed = true, unit = "m3/h" } # 80.01 actual_flow_pct = { address = 8001, signed = true, scale = 0.01, unit = "%" } # 80.02, 100 = 1% pump_head = { address = 8004, unit = "m" } # 80.05, FbEq16 1 = 1 m inlet_pressure = { address = 8100, unit = "bar" } # 81.01, FbEq16 1 = 1 bar outlet_pressure = { address = 8101, unit = "bar" } # 81.02, FbEq16 1 = 1 bar # ABB Drives profile control word, sequences printed verbatim on p. 242: # Start: 1142 (476h) -> if SW bit0 = 1 -> 1150 (47Eh) -> 1151 (47Fh) # Stop: 1143 (477h) = stop per 21.03 Stop mode (the manual's "Preferred") # 1150 (47Eh) OFF1 ramp, 1149 (47Dh) OFF2 coast, 1147 (47Bh) OFF3 # Fault reset: rising edge of control-word bit 7 [control] command_register = 0 speed_register = 1 speed_scale = 0.005 # write %, 20000 raw = 100% of 46.01 (speed) or 46.02 (freq) speed_signed = true # direction IS the sign of the reference here speed_unit = "%" # NOT Hz — percent of the drive's active reference scaling max_ref = 100.0 step_delay = 0.05 stop = [0x0477] run_fwd = [0x0476, 0x047E, 0x047F] # Reset is a rising edge of bit 7 on top of the stop word. 0x0477 has # INHIBIT_OPERATION low, so neither the base word nor 0x04F7 is a run command. reset = [0x0477, 0x04F7, 0x0477] # run_rev is deliberately absent. On the ABB Drives profile the direction # comes from the SIGN OF THE REFERENCE (p. 234, DCU bit 2 note; ABB Drives CW # has no reverse bit), so a "reverse" control word is byte-identical to # forward. Reverse with a negative reference. # 6681 EFB comm loss exists (p. 210) but ONLY fires when 58.14 Communication # loss action is set to Fault or Fault always. Its DEFAULT is "No action" # (pp. 226, 477) — on a factory-configured ACQ580 the motor keeps running # after the master goes quiet. The keepalive here is what keeps the link # provably alive; it is not evidence that the drive has a backstop. # Timeout is 58.16, printed as 10.0 s in the parameter table (p. 477) and as # 30.0 s in the setup table (p. 226) — the manual contradicts itself, so this # interval is set well inside the shorter of the two. [control.watchdog] interval_ms = 500 fault = "6681 EFB comm loss (only if 58.14 = Fault; default No action keeps running)" # SW bit 2 RDY_REF = OPERATION ENABLED (p. 237). The ABB Drives status word # has no "modulating" bit — that one is DCU profile bit 3, and this map # assumes 58.25 = ABB Drives. [running_check] register = 3 bit = 2 # 04.01 Tripping fault; stored history is 04.11-04.13 (pp. 293). [faults] register = 400 history = [410, 411, 412] # ABB reports faults as hex codes; TOML keys here are the decimal equivalents. # Taken only from this manual's fault table (pp. 204-215); it is longer than # this and the warning (Axxx) table is not included at all. [faults.codes] 0 = "No fault" 8976 = "0x2310 Overcurrent" 9008 = "0x2330 Earth leakage" 9024 = "0x2340 Short circuit" 9089 = "0x2381 IGBT overload" 12592 = "0x3130 Input phase loss" 12673 = "0x3181 Wiring or earth fault" 12816 = "0x3210 DC link overvoltage" 12832 = "0x3220 DC link undervoltage" 13185 = "0x3381 Output phase loss" 16656 = "0x4110 Control board temperature" 16912 = "0x4210 IGBT overtemperature" 17040 = "0x4290 Cooling" 17168 = "0x4310 Excess temperature" 17280 = "0x4380 Excess temperature difference" 20625 = "0x5091 Safe torque off" 26241 = "0x6681 EFB comm loss" 28801 = "0x7081 Control panel loss" 28961 = "0x7121 Motor stall" 28962 = "0x7122 Motor overload" 29456 = "0x7310 Overspeed" 29680 = "0x73F0 Overfrequency" 29968 = "0x7510 FBA A communication" 32928 = "0x80A0 AI supervision" 36993 = "0x9081 External fault 1" 54273 = "0xD401 Max cleaning fault" 54274 = "0xD402 High level" 54275 = "0xD403 Low level" 54276 = "0xD404 Running dry" 54277 = "0xD405 Pipe fill-timeout" 54278 = "0xD406 Maximum flow protection" 54279 = "0xD407 Minimum flow protection" 54280 = "0xD408 Outlet minimum pressure" 54281 = "0xD409 Outlet maximum pressure" 54282 = "0xD40A Inlet minimum pressure" 64129 = "0xFA81 Safe torque off 1" 64130 = "0xFA82 Safe torque off 2" 65377 = "0xFF61 ID run" [connection] summary = "Use the ACQ580 built-in EIA-485 interface on X5 for Modbus RTU." warnings = ["Tie cable shields through at each drive but do not terminate them on the drive SCR point; ABB shows the shield grounded only at the controller.","Enable termination at both bus ends and bias at one device only."] [[connection.methods]] id = "built_in_rs485" title = "Built-in Modbus RTU" transport = "serial" hardware = "built_in" port = "control-unit terminal block X5" connector = "X5:29 B+, 30 A-, 31 DGND with TERM and BIAS switches" 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 control-unit terminal block X5.","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 = ["Set TERM at the two bus ends and BIAS at one device.","Set 58.01 = Modbus RTU, 58.03 node, 58.04 baud, 58.05 parity and 58.25 = ABB Drives.","Select Embedded fieldbus for command/reference sources and apply with 58.06 = Refresh settings."] warnings = ["Follow ABB's shield diagram; do not land the shield on a nearby SCR terminal."] source = "ABB 3AXD50000035867 Rev E, pp. 224-228." [[connection.methods.wiring]] adapter = "D+ / B / positive" device = "X5:29 B+" signal = "RS-485 positive" [[connection.methods.wiring]] adapter = "D- / A / negative" device = "X5:30 A-" signal = "RS-485 negative" [[connection.methods.wiring]] adapter = "COM / signal common" device = "X5:31 DGND" signal = "Signal reference" [[connection.methods.wiring]] adapter = "Cable shield" device = "Shield tied through; grounded at controller only" signal = "Shield continuity" required = false