# Property of PMA Electrical Solutions, LLC. # # ABB ACH180 (HVAC micro drive), HVAC control program, embedded fieldbus (EFB) # Modbus RTU on the drive's own EIA-485 terminal on the front of the drive. # # COVERAGE. ACH180 only. This manual is the ACH180 HVAC control program # firmware manual and names no sibling. Nothing is claimed for ACS180, ACS280, # ACS380, ACH480 or ACH580 — several of them are separate documents already in # this repo, and the HVAC program adds an ACH180-specific status word (06.22 # HVAC status word, "ACH180 specific status word", p. 156) that the machinery # programs do not have. The DCU control profile (58.25 = DCU, pp. 446-448) is # deliberately NOT mapped: this file assumes the ABB Drives default. # # COMMUNICATION PATH. No option module and no fieldbus adapter card. The EFB # port is SHARED WITH THE OPTIONAL ASSISTANT CONTROL PANEL through jumper J2 # (p. 430): the panel and Modbus cannot be used at the same time, and J2 must # be in "Modbus Mode". Termination jumper J1 ON only at the two line ends. # Throughput note (p. 429): the drive handles 10 registers per 10 ms time # level, so a 20-register read starts responding ~22 ms after the request. # # SOURCE: ABB firmware manual 3AXD50000955893 Rev B (EN), "ACH180 HVAC control # program firmware manual". # pp. 141-144 group 01 actual values and their FbEq16 scale factors # p. 147 group 04 tripping fault / active faults / stored faults # pp. 150-152 group 05 diagnostics and the 05.80-05.89 fault snapshot # pp. 153-157 group 06 control and status words (06.16, 06.22) # pp. 350-355 group 58 embedded fieldbus defaults, 58.14 loss action # pp. 356-357 58.33 Addressing mode, the Mode 0/1/2 formulas # pp. 390-392 group 99 motor data, 99.06 Motor nominal current # pp. 405-428 warning, fault and pure event message table # pp. 429-434 EFB wiring, setup table, drive control parameter table # pp. 435-445 CW / SW / references / actual values / holding register map # # DRIVE-SIDE SETUP — without these the drive ACKs writes and silently ignores # them (setup tables pp. 431-434): # 58.01 Protocol enable = Modbus RTU (default is None) # 58.03 Node address = 1 (setup table p. 432; the parameter # table p. 350 prints the shipped # default as 0, which is not a legal # node address — set it explicitly) # 58.04 Baud rate = 19.2 kbps (default) — NOT 9600 # 58.05 Parity = 8 EVEN 1 (default) # 58.25 Control profile = ABB Drives (default) — this file's assumption # 58.33 Addressing mode = Mode 0 (default) — the formula below # 58.34 Word order = LO-HI (default; only matters for 32-bit params) # 20.01 Ext1 commands = Embedded fieldbus # 20.06 Ext2 commands = Embedded fieldbus # 28.11 Ext1 frequency ref1 = EFB ref1 (99.04 Motor control mode default is # Scalar, so the FREQUENCY chain is the live one) # 22.11 Ext1 speed ref1 = EFB ref1 (only if 99.04 is set to Vector) # 58.06 Communication control = Refresh settings (validates 58.xx last) # # ADDRESSING. 0-based protocol addresses throughout, never 4xxxx notation. # The manual prints 6-digit 1-based Modbus register numbers. 58.33 Mode 0 # (p. 357): 16-bit register = 400000 + 100 * group + index. The 0-based # protocol address this app uses is that number minus 400001, i.e. # 0-based = 100 * group + index - 1 # par 01.06 Output frequency -> 100*1 + 6 - 1 = 105 # par 04.01 Tripping fault -> 100*4 + 1 - 1 = 400 # par 06.16 Drive status wd 1-> 100*6 + 16 - 1 = 615 # par 99.06 Motor nom current-> 100*99 + 6 - 1 = 9905 # The fixed CW/REF/SW/ACT block at 400001-400006 is documented directly # (p. 445) and maps to 0-based 0-5. Registers 400090-400100 (0-based 89-99) # are Modbus error-code registers, not drive data. # # SCALING IS FIELDBUS (FbEq16), NOT PANEL DECIMALS. Every scale below is the # FIRST number of the manual's "FbEq 16b / 32b" column on pp. 141-144, read # row by row against the PDF. Note that these do NOT all match the panel # decimals: 01.07 Motor current is "1 = 1 A" on the 16-bit path even though # the panel shows 0.01 A, and 01.14 Output power is "1 = 1 kW or hp". # References and the two ACT slots are additionally scaled by group 46 # (46.01 speed / 46.02 frequency, pp. 443-444) and by 58.26-58.29, so they are # CONFIGURATION-DEPENDENT — confirm 46.01/46.02 on the actual unit. # 99.06 carries an explicit "For 16-bit scaling, see parameter 46.05 Current # scaling" note (p. 391); its printed FbEq16 is 1 = 1 A, also config-dependent. # # UNITS ARE SELECTABLE. 01.14 Output power is "kW or hp" per 96.16 Unit # selection (p. 142), and 05.10 / 05.87 temperatures are "°C or °F". The unit # strings below assume the SI default. name = "ABB ACH180" vendor = "ABB" device_type = "vfd" verified = false probe_register = 3 # status word, readable whenever the fieldbus is alive [serial] baudrate = 19200 # 58.04 default 19.2 kbps parity = "E" # 58.05 default "8 EVEN 1" stopbits = 1 [monitor] # Fixed EFB register block, p. 445. Only the 16 least significant bits of the # drive's 32-bit control and status words are visible here. control_word = { address = 0, bits = { 0 = "OFF1", 1 = "OFF2_N", 2 = "OFF3_N", 3 = "INHIBIT_OPERATION_N", 4 = "RAMP_OUT_ZERO_N", 5 = "RAMP_HOLD_N", 6 = "RAMP_IN_ZERO_N", 7 = "RESET", 10 = "REMOTE_CMD", 11 = "EXT_CTRL_LOC" } } reference_1 = { address = 1, signed = true, scale = 0.005, unit = "%" } # 20000 = 100% of 46.01/46.02 status_word = { address = 3, bits = { 0 = "RDY_ON", 1 = "RDY_RUN", 2 = "RDY_REF", 3 = "TRIPPED", 4 = "OFF_2_INACTIVE", 5 = "OFF_3_INACTIVE", 6 = "SWC_ON_INHIB", 7 = "ALARM", 8 = "AT_SETPOINT", 9 = "REMOTE", 10 = "ABOVE_LIMIT" } } # Group 01 actual values, pp. 141-142. FbEq16 taken from the manual's own # column; several are 1:1 and are written as such rather than assumed. # CONFLICT the file follows deliberately: the same rows say "For scaling, see # parameter 46.01/46.02/46.03/46.04" (p. 141), and group 46's own text (p. 343 # ff.) says those parameters define the 16-bit scaling against 20000/10000 — # which for 01.01 would make 1 rpm = 13.3 raw at the 1500 rpm default, a 13x # disagreement with the printed "1 = 1 rpm" FbEq16. The printed FbEq16 column # (the parameter-register path) is used; only 46.05's default (10000 A = # 10000) reconciles with its FbEq16. BENCH-CONFIRM motor_speed, # output_frequency, motor_torque and output_power. motor_speed = { address = 100, signed = true, unit = "rpm" } # 01.01, 1 = 1 rpm output_frequency = { address = 105, signed = true, scale = 0.1, unit = "Hz" } # 01.06, 10 = 1 Hz motor_current = { address = 106, unit = "A" } # 01.07, 1 = 1 A motor_torque = { address = 109, signed = true, scale = 0.1, unit = "%" } # 01.10, 10 = 1 % 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, unit = "kW" } # 01.14, 1 = 1 kW or hp # 04.02 / 04.03 are two further CONCURRENT active faults, not a history (p. 147). active_fault_2 = { address = 401 } active_fault_3 = { address = 402 } # 06.16 Drive status word 1 (p. 153-154). This is where the unconditional # "drive is modulating" bit lives; the ABB Drives profile status word at # address 3 has no such bit, only the tolerance-gated AT_SETPOINT bit 8. drive_status_word_1 = { address = 615, bits = { 0 = "ENABLED", 1 = "INHIBITED", 2 = "DC_CHARGED", 3 = "READY_TO_START", 4 = "FOLLOWING_REFERENCE", 5 = "STARTED", 6 = "MODULATING", 7 = "LIMITING", 8 = "LOCAL_CONTROL", 9 = "NETWORK_CONTROL", 10 = "EXT1_ACTIVE", 11 = "EXT2_ACTIVE", 13 = "START_REQUEST", 14 = "RUNNING" } } # 06.22 HVAC status word (p. 156-157). ACH180-specific; this is the word that # distinguishes the HVAC program from the machinery programs. Bit 3 is not # documented; bits 5 and 6 are printed inconsistently in the manual (a "b5 # Damper control" row followed by a "b5...6 Reserved" row, p. 157) so only # bit 5 is named here. hvac_status_word = { address = 621, bits = { 0 = "HAND_MODE", 1 = "OFF_MODE", 2 = "AUTO_MODE", 4 = "PRE_HEATING", 5 = "DAMPER_CONTROL", 7 = "RUN_PERMISSIVE", 8 = "START_INTERLOCK_1", 9 = "START_INTERLOCK_2", 10 = "START_INTERLOCK_3", 11 = "START_INTERLOCK_4", 12 = "ALL_START_INTERLOCKS" } } # ABB Drives profile, control word bit table pp. 437-439, state transition # diagram pp. 441-442. The master must keep refreshing the control word; see # [control.watchdog] below. [control] command_register = 0 speed_register = 1 speed_scale = 0.005 # write %, 20000 raw = 100% of 46.01 (speed) or 46.02 (frequency) speed_signed = true # direction IS the sign of the reference here speed_unit = "%" # NOT Hz — percent of the drive's scaling parameter max_ref = 100.0 step_delay = 0.05 # 0x0476 clears BOTH OFF1 (bit 0 = "Stop along currently active deceleration # ramp", p. 438) AND INHIBIT_OPERATION (bit 3 = "Proceed to OPERATION # INHIBITED"). OFF2/OFF3 are held high, so neither coast-off nor the # emergency-stop ramp is commanded (the manual prints a WARNING against # routine OFF3 use); the manual does not state whether the OPERATION INHIBITED # path ramps or coasts. Both cleared bits are stop commands either way. stop = [0x0476] # 0x047F = bits 0-6 set with REMOTE_CMD (bit 10) high and EXT_CTRL_LOC (bit 11) # low, i.e. EXT1. The state diagram's progression x110 -> x111 -> 1111 -> # x1 1111 all resolves into this word once bits 0-6 are high (p. 442). run_fwd = [0x0476, 0x047F] # RESET is bit 7 of the SAME control word on a 0->1 edge (p. 439). There is no # separate reset register on this drive, so reset_register is deliberately # absent — inventing one would be fabrication. The sequence pulses bit 7 while # holding OFF2/OFF3 high; OFF1 (bit 0) and INHIBIT_OPERATION (bit 3) stay LOW # throughout, which is why no step can command a run. reset = [0x0476, 0x04F6, 0x0476] # run_rev is deliberately absent. The ABB Drives profile carries direction as # the SIGN OF THE REFERENCE — "a negative reference is formed by calculating # the two's complement from the corresponding positive reference" (p. 443) — # so a "reverse" control word would be byte-identical to forward. Reverse with # a negative reference. # 58.14 Communication loss action DEFAULTS TO "No action", i.e. the drive's own # watchdog is DISABLED out of the box (p. 353) and a dropped master leaves the # motor running. Set 58.14 = Fault to arm it; 58.16 Communication loss time # defaults to 30.0 s. This keepalive is well inside that. [control.watchdog] interval_ms = 300 fault = "6681 EFB communication loss" # 06.16 Drive status word 1 bit 6 "Modulating" — "Drive is modulating (output # stage is being controlled)", p. 153. Chosen over status-word bit 8 # AT_SETPOINT, which is tolerance-gated (speed error 10% max of nominal, p. # 440) and therefore reads 0 during acceleration on a running motor. [running_check] register = 615 bit = 6 # 04.01 Tripping fault; 04.11-04.13 are the stored (non-active) faults (p. 147). [faults] register = 400 history = [410, 411, 412] # ABB reports these as hex codes; TOML keys must be numeric, so the decimal # equivalent is the key and the hex is repeated in the name. Table pp. 405-428. # ONLY TRIP-CAPABLE FAULT CODES ARE LISTED. The same table also carries the # 0xA-prefixed WARNINGS (A2A1, A3A1, A4A1, A7CE EFB comm loss, ...) and the # 0xB-prefixed PURE EVENTS (B681 Hand mode, B689 Modulating started, ...). # Those are reported at 04.06-04.08 Active warning 1-3, NOT at 04.01, so # merging them into this table would decode a warning as a trip. [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 temp difference" 18817 = "0x4981 External temperature 1" 20608 = "0x5080 Fan" 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" 22145 = "0x5681 PU communication" 22160 = "0x5690 PU communication internal" 22161 = "0x5691 Measurement circuit ADC" 22162 = "0x5692 PU board powerfail" 22163 = "0x5693 Measurement circuit DFF" 22167 = "0x5697 Charging" 24961 = "0x6181 FPGA version incompatible" 25088 = "0x6200 Checksum mismatch" 25729 = "0x6481 Task overload" 25735 = "0x6487 Stack overflow" 25761 = "0x64A1 Internal file load" 25766 = "0x64A6 Adaptive program" 25777 = "0x64B1 Internal SSW fault" 25778 = "0x64B2 User set fault" 25825 = "0x64E1 Kernel overload" 25985 = "0x6581 Parameter system" 26001 = "0x6591 Backup/Restore timeout" 26241 = "0x6681 EFB communication loss" 26242 = "0x6682 EFB configuration" 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" 28806 = "0x7086 AI overvoltage" 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 temp" 29456 = "0x7310 Overspeed" 29616 = "0x73B0 Emergency ramp failed" 29680 = "0x73F0 Overfrequency" 32769 = "0x8001 ULC underload" 32770 = "0x8002 ULC overload" 32928 = "0x80A0 AI supervision fault" 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 event 1" 36994 = "0x9082 External event 2" 36995 = "0x9083 External event 3" 36996 = "0x9084 External event 4" 36997 = "0x9085 External event 5" 64129 = "0xFA81 Safe torque off 1" 64130 = "0xFA82 Safe torque off 2" 65377 = "0xFF61 ID run" 65379 = "0xFF63 STO diagnostics" 65422 = "0xFF8E EFB force trip" # 0x64FF Fault reset (25855) is printed in the same table but is an # informative EVENT, not a trip, and is left out for that reason. # 07.03 Drive rating id — "Type of the drive. (Rating ID in brackets)", # group 07 System info, "All parameters in this group are read-only", uint16 # (p. 159). A drive-HARDWARE identity: 99.06 Motor nominal current was # rejected as the guard because it is operator-set motor-nameplate data — two # identical frames with different motors would Mismatch, two different frames # sharing one motor would Match, and a restore overwrites it. The manual # publishes no enumeration of the rating-id values, so this is an equality # guard only. 0-based = 100*7 + 3 - 1 = 702. [rating] register = 702 words = 1 scale = 1.0 unit = "" label = "Drive rating id (07.03)" # [parameters] is deliberately absent. Mode 0 makes groups 1-99 index 1-99 # individually reachable at 100*group+index-1, but this manual documents # backup/restore only as a PANEL feature (the assistant control panel's manual # and automatic backups) and publishes no vendor-blessed safe range for a bulk # Modbus parameter write. A guessed clone range is exactly the kind of gap that # corrupts a replacement drive, so the gap is named instead of filled. [connection] summary = "Use the ACH180 front EIA-485 terminals for built-in Modbus RTU; the same internal interface is shared with the optional assistant panel." warnings = ["Move jumpers only with power removed and after the five-minute discharge wait.","J2 must be in Modbus Mode; the assistant panel and embedded Modbus cannot operate at the same time."] [[connection.methods]] id = "built_in_rs485" title = "Built-in Modbus RTU" transport = "serial" hardware = "built_in" port = "front EIA-485 terminals 25-28" connector = "25 B+, 26 A-, 27 DGND, 28 SHIELD; J1 termination and J2 panel/Modbus selection" adapter = "Isolated USB-to-RS-485 adapter" cable = "Shielded twisted pair, 100-130 ohm characteristic impedance, plus signal ground" parts = ["Isolated USB-to-RS-485 adapter","Shielded twisted pair, 100-130 ohm characteristic impedance, plus signal ground","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 front EIA-485 terminals 25-28.","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 J2 to Modbus Mode and J1 on only at a bus end.","Set 58.01 = Modbus RTU, 58.03 node address, 58.04 baud and 58.05 parity.","Set 58.25 = ABB Drives, select Embedded fieldbus for command/reference sources, then set 58.06 = Refresh settings."] warnings = ["The control panel must be disconnected for Modbus mode."] source = "ABB 3AXD50000955893 Rev B, pp. 37-38 and 429-434." [[connection.methods.wiring]] adapter = "D+ / B / positive" device = "25 B+" signal = "RS-485 positive" [[connection.methods.wiring]] adapter = "D- / A / negative" device = "26 A-" signal = "RS-485 negative" [[connection.methods.wiring]] adapter = "COM / signal common" device = "27 DGND" signal = "Signal reference" [[connection.methods.wiring]] adapter = "Cable shield" device = "28 SHIELD" signal = "Shield" required = false