# Property of PMA Electrical Solutions, LLC. # # ABB ACH580 (HVAC drives), HVAC control program, embedded fieldbus (EFB) # Modbus RTU on the control unit's EIA-485 terminal block. No option module is # required for this path; the optional FBA adapters (groups 50-53) and the # BACnet MS/TP and N2 protocols share the same port and are NOT mapped here. # # COVERAGE. ACH580 only. The manual's Modbus device-identification object # (function 2Bh/0Eh, Object ID 04h) returns Product name "ACH580" (p. 308), # which is what makes this an ACH580 document and not a shared 580 document. # Nothing is claimed for ACS580, ACQ580, ACS480 or ACH480 — this manual does # not cover them. Registers 01.102 / 01.174 and similar are printed "Only # visible for ACH580-31 and ACH580-34" (pp. 400, 402) and are not mapped. # # SOURCE: ABB firmware manual 3AXD50000027537 Rev J (EN), "ACH580 HVAC control # program firmware manual". # pp. 285-292 EFB overview, CW/SW/reference concepts, 6-digit addressing # pp. 287-289 group 58 setup table, command and reference source params # pp. 294-295 Control Word, ABB Drives profile (and the DCU alternative) # pp. 298-299 Status Word, ABB Drives profile (and the DCU alternative) # pp. 301-303 state transition diagram and the printed start/stop sequences # pp. 306-308 holding register map, function codes, device identification # p. 313 error code registers 400090-400100 (Modbus transaction only) # pp. 263-279 fault message table (p. 280 begins the LSU aux-code # table, ACH580-31/-34 only, deliberately excluded) # pp. 397-403 group 01 actual values, group 04 warnings and faults # pp. 578-579 group 40 process PID actual values # pp. 605-607 group 46 scaling defaults # pp. 617-623 group 58 defaults and the 58.33 addressing formula # pp. 701-702 99.06 Motor nominal current # # WHY THIS IS NOT profiles/abb_acs580.toml. That file's header claims # "ACS580 / ACQ580 (water) / ACH580 (HVAC) / ACS480". The EFB mechanism is the # same, but the ACH580 HVAC program trips on a fault family the ACS580 table # cannot decode: D40B Damper timeout, D40D Multipump run permissive, D420 # Reverse flow detected, D58B Gas pressure outside range (pp. 275-279), on top # of the D404-D40A pump faults. Default baud is 19.2 kbps, not 9600 (58.04, # p. 618). Same reasoning that produced profiles/abb_acq580.toml. # # DRIVE-SIDE SETUP — without these the drive ACKs writes and ignores them # (setup table pp. 287-289; defaults from the parameter listing pp. 617-623): # 58.01 Protocol enable = Modbus RTU # 58.03 Node address = 1, 58.04 Baud rate = 19.2 kbps, 58.05 Parity = 8 EVEN 1 # 58.06 Communication control = Refresh settings (applies 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 # 58.34 Word order = LO-HI (default; irrelevant to the 16-bit points # mapped here, all of which are single words) # 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 (400001 is # wire address 0). Convert: # 0-based protocol address = printed 6-digit number - 400001 # Parameters, 58.33 Mode 0 (p. 623): printed = 400000 + 100*group + index, # therefore 0-based = 100*group + index - 1. # par 01.06 Output frequency -> 400106 - 400001 = 105 # par 99.06 Motor nominal current -> 409906 - 400001 = 9905 # Mode 0 also exposes a 32-bit window at 420000 + 200*group + 2*index; this # profile uses the 16-bit window only. Never 4xxxx PLC notation. # # SCALING IS FIELDBUS 16-BIT (FbEq16) AND CONFIGURATION-DEPENDENT. Anything # whose Def/FbEq16 column says "See par. 46.0x" is scaled by group 46, so the # numbers below are the manual's DEFAULTS, not fixed constants — confirm # 46.01-46.05 on the actual unit. Defaults (pp. 605-606): # 46.01 Speed scaling 1500.00 rpm (1800.00 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 (pp. 713-764; the 99.06 row is on p. 762) prints the FbEq32 column, # a DIFFERENT number for the same parameter (e.g. 99.06 is 10 = 1 A there but # 1 = 1 A on FbEq16, p. 701). Do not mix the two. name = "ABB ACH580" 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" (pp. 618-619). [serial] baudrate = 19200 parity = "E" stopbits = 1 # Fixed I/O block, p. 306. 400001/400002/400003/400004 are defaults and can be # repointed by 58.101-58.104 Data I/O 1-4; this map assumes the defaults. [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. 397-398). Read-only, filtered by the group 46 # filter times, scaled by the group 46 defaults listed in the header. # 01.06 via 46.02: 20000 = 50.00 Hz -> 0.0025 Hz/count. On a 60 Hz unit # (95.20 b0) it 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, 10000 = 10000 A motor_torque = { address = 109, signed = true, scale = 0.01, unit = "%" } # 01.10 via 46.03, 10000 = 100.0 % dc_voltage = { address = 110, scale = 0.1, unit = "V" } # 01.11, fixed 10 = 1 V output_voltage = { address = 112, unit = "V" } # 01.13, fixed 1 = 1 V output_power = { address = 113, signed = true, scale = 0.1, unit = "kW" } # 01.14 via 46.04, unit per 96.16 # 04.01-04.03 are three CONCURRENT active faults, not a history (pp. 402-403). # 99.06 Motor nominal current (p. 701): FbEq16 "1 = 1 A (see 46.05)" — the # "10 = 1 A" on p. 762 is the FbEq32 column and does NOT apply to this 16-bit # read. Whole-amp resolution at the 46.05 default of 10000 A. motor_nom_current = { address = 9905, scale = 1.0, unit = "A" } active_fault_2 = { address = 401 } active_fault_3 = { address = 402 } # Process PID actuals (pp. 578-579). FbEq16 is 1 = 1 unit and the engineering # unit is whatever 40.79 Set 1 units selects, so no unit string is asserted. # Both read 0 unless the PID is configured. pid_feedback = { address = 4001, signed = true } # 40.02 Process PID feedback actual pid_setpoint = { address = 4002, signed = true } # 40.03 Process PID setpoint actual # ABB Drives profile control word. Sequences printed verbatim on p. 303: # Start: 1142 (476h) -> if MSW bit 0 = 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 MCW 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 laid on top of the stop word. 0x0477 has # INHIBIT_OPERATION (bit 3) low, so neither 0x0477 nor 0x04F7 is a run command. reset = [0x0477, 0x04F7, 0x0477] # run_rev is deliberately absent. The ABB Drives control word has no reverse # bit (p. 294) — reverse is the SIGN OF THE REFERENCE. A reverse control word # would be byte-identical to forward. Reverse with a negative reference. # (The DCU profile, 58.25 = DCU 16-bit, does have a bit 2 REVERSE, p. 295, but # that is a different profile and this map does not assume it.) # 6681 EFB comm loss (p. 268) fires only when 58.14 Communication loss action # is set to Fault; its DEFAULT is "No action" (pp. 287, 620), so on a # factory-configured ACH580 the motor KEEPS RUNNING after the master goes # quiet. The keepalive below proves the link is alive; it is not evidence the # drive has a backstop. 58.16 Communication loss time default is 30.0 s # (pp. 287, 621) — this interval sits far inside it. [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. 298). The ABB Drives status word has # no "modulating" bit — that is DCU profile bit 3 RUNNING (p. 299), and this # map assumes 58.25 = ABB Drives. [running_check] register = 3 bit = 2 # 04.01 Tripping fault; stored (non-active) history is 04.11-04.13 (p. 403). [faults] register = 400 history = [410, 411, 412] # 07.03 Drive rating id, group 07 System info — "Type of the drive. (Rating ID # in brackets.)", READ-ONLY ("All parameters in this group are read-only", # p. 417), FbEq 1=1, List 0…999 (p. 718). A drive-HARDWARE identity, which is # what the restore guard needs: 99.06 Motor nominal current is a motor # parameter that defaults to 0.0 A and reads identical on two different-frame # drives commissioned for the same motor (the manual's own fault 5093 "Rating # ID mismatch" confirms the rating id tracks hardware, p. 269). The value is # an opaque enumeration — an equality guard, not a decoded amp figure. [rating] register = 702 words = 1 scale = 1.0 unit = "" label = "Drive rating id (07.03)" # [parameters] is deliberately absent. Mode 0 puts 16-bit parameters at # 400101-409999 (0-based 100-9998), but this manual publishes no single # writable-parameter table, and the read/write flag lives per-parameter across # the ~400-page listing. Cloning a range that includes read-only or # hardware-identity parameters is exactly the restore hazard the guard exists # to prevent, so no range is asserted. GAP — needs a bench pass. # ABB reports faults as hex codes; TOML keys here are the decimal equivalents. # Taken only from the "Fault messages" table, pp. 263-279 of this manual # (its last row is FF8E on p. 279; p. 280 and p. 282 are LSU auxiliary-code # tables for ACH580-31/-34 only, deliberately excluded). The # WARNING table (pp. 248-262, A-prefixed and its own Dxxx codes such as D50E # Outlet minimum) is a different table and is NOT included — a warning code # read here would be a misdecode. Sub-codes (the four-hex auxiliary codes # printed under many entries) are not represented. [faults.codes] 0 = "No fault" 4224 = "0x1080 Backup/Restore timeout" 4225 = "0x1081 Rating ID 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 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" 18832 = "0x4990 CPTC-02 not found" 18833 = "0x4991 Safe motor temperature" 20608 = "0x5080 Fan" 20609 = "0x5081 Auxiliary fan broken" 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" 20640 = "0x50A0 Fan" 22145 = "0x5681 PU communication" 22146 = "0x5682 Power unit lost" 22161 = "0x5691 Measurement circuit temperature" 22162 = "0x5692 PU board powerfail" 22163 = "0x5693 Measurement circuit ADC" 22167 = "0x5697 Charging feedback" 22168 = "0x5698 Unknown PU fault" 24226 = "0x5EA2 Charging circuit" 24961 = "0x6181 FPGA version" 25088 = "0x6200 Checksum mismatch" 25350 = "0x6306 FBA A mapping file" 25729 = "0x6481 Task overload" 25735 = "0x6487 Stack overflow" 25761 = "0x64A1 Internal file load" 25764 = "0x64A4 Rating ID fault" 25766 = "0x64A6 Adaptive program" 25777 = "0x64B1 Internal SSW fault" 25778 = "0x64B2 User set fault" 25779 = "0x64B3 Macro" 25825 = "0x64E1 Kernel overload" 25855 = "0x64FF Fault reset (event, informative only)" 25985 = "0x6581 Parameter system" 26001 = "0x6591 Backup/Restore" 26017 = "0x65A1 FBA A parameter" 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" 28193 = "0x6E21 Macro" 28801 = "0x7081 Control panel loss" 28805 = "0x7085 Incompatible option module" 28928 = "0x7100 Excitation current" 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" 29456 = "0x7310 Overspeed" 29616 = "0x73B0 Emergency ramp failed" 29680 = "0x73F0 Overfrequency" 29968 = "0x7510 FBA A communication" 30080 = "0x7580 INU-LSU comm loss" 30083 = "0x7583 Line side unit faulted" 30084 = "0x7584 LSU charge failed" 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" 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" 54283 = "0xD40B Damper timeout" 54285 = "0xD40D Multipump run permissive" 54304 = "0xD420 Reverse flow detected" 54667 = "0xD58B Gas pressure outside range" 64129 = "0xFA81 Safe torque off 1" 64130 = "0xFA82 Safe torque off 2" 65377 = "0xFF61 ID run" 65379 = "0xFF63 STO diagnostics failure" 65409 = "0xFF81 FB A force trip" 65422 = "0xFF8E EFB force trip" [connection] summary = "Use the ACH580 built-in Modbus RTU interface at X5 terminals 29-31." warnings = ["The EIA-485 port is also used by BACnet MS/TP and N2; configure exactly one embedded protocol.","Enable bias at one device only and termination at the two physical ends."] [[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; S4 TERM and S5 BIAS" 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 S4 TERM at bus ends only and S5 BIAS at one node only.","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, configure 58.14 loss action, then refresh with 58.06."] warnings = [] source = "ABB 3AXD50000027537 Rev J, pp. 98-102 and 285-289." [[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"