# Property of PMA Electrical Solutions, LLC. # # ABB ACQ80 (solar / grid pump drive), standard control program, embedded # fieldbus (EFB) Modbus RTU on the EIA-485 terminal block of the RIIO-01 # module attached to the control unit (p. 342). # # COVERAGE: ACQ80 only, standard control program. This manual's Modbus device # identification reads back product name "ACQ80" (p. 363). Nothing is claimed # about ACQ580, ACS580, ACH580 or any other family — those are different # firmware with different fault tables, and the ACQ80's table (below) is # provably not the ACQ580's. No option adapter is documented as an alternative # path here; chapter 10 (p. 369) lists FPBA/FCAN/FECA/FENA/FSCA for other # protocols, which this profile does not cover. # # SOURCE: ABB firmware manual ISPKA218x (EN, 2023-03-27), # "ACQ80 drives standard control program firmware manual", 390 pp. # Printed page number == PDF page index in this document; no offset. # pp. 83-84 group 01 actual values and their FbEq16 # pp. 89-90 group 04 fault / warning code parameters # pp. 217-223 group 58 EFB parameter listing (defaults, 58.33 addressing) # pp. 226-228 group 79 solar status words, 79.10 Operating mode # pp. 229-238 group 80 flow calculation, group 81 sensor actuals # p. 265 99.06 Motor nominal current # pp. 322-338 fault message table, including the D4xx pump/solar faults # pp. 342-346 EFB wiring and the setup-parameter table # pp. 348-350 6-digit register addressing, control profiles, act scaling # pp. 351-356 Control Word / Status Word bit tables (ABB Drives profile) # pp. 358-359 state transition diagram (ABB Drives profile) # pp. 360-361 references and the default holding-register map # pp. 362-363 function codes, exception codes, device identification # # THERE IS NO WRITABLE SPEED REFERENCE ON THIS DRIVE. p. 360: "The references # are provided by MPPT and does not depend on any user settings." p. 344 and # p. 360 list 58.26/58.27 EFB ref1/ref2 type as "Not applicable. Speed # reference is provided by MPPT." The parameter listing CONTRADICTS this for # 58.26 specifically: p. 221 documents it as a functional scaling selector # (default Speed or frequency, scaled value shown by 03.09), and p. 346 # allows routing 03.09 into any signal selector. No speed_register is mapped # because the DEFAULT configuration does not consume one — a documented # absence recorded with its contradiction, not a missing lookup. # Start, stop and fault reset over the Control Word do work. # # DRIVE-SIDE SETUP — without these the drive ACKs writes and ignores them # (pp. 344-346): # 58.01 Protocol enable = Modbus RTU [1] # 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 [0] (default) — this map assumes it # 58.33 Addressing mode = Mode 0 (default) — this map assumes it # 79.10 Operating mode = Embedded fieldbus [5] (start/stop source; # the DEFAULT is "Manual In 1 Start; stop", i.e. DI1 — p. 227-228) # 96.07 Parameter save manually = Save (persist fieldbus-written params) # # ADDRESSING. The manual prints 6-digit Modbus holding-register numbers # (400001-465536). Convert: # 0-based protocol address = printed 6-digit number - 400001 # Parameters, 58.33 Mode 0 (p. 223): printed = 400000 + 100*group + index, # so 0-based = 100*group + index - 1. # Control Word, fixed 400001 -> 400001 - 400001 = 0 # par 01.06 Output frequency -> 100*1 + 6 - 1 = 105 # par 79.01 Solar status word1 -> 100*79 + 1 - 1 = 7900 # Mode 0 also exposes a separate 32-bit window at 420000 + 200*group + # 2*index; this profile uses the 16-bit window only, so 58.34 Word order # (default LO-HI) does not apply to anything read here. # # SCALING IS FIELDBUS 16-BIT (FbEq16), NOT PANEL DECIMALS. The group-01/79/ # 80/81 registers below are parameter-mapped and use the FbEq16 printed # alongside each parameter (pp. 83-84, 229-238). The "Additional parameter # data" table (p. 297 ff.) prints a DIFFERENT number for the same parameters # (81.01 is "1 = 1 bar" on p. 237 and "100 = 1" on p. 297) because that table # is FbEq32 for the 32-bit window. Do not mix the two. # The fieldbus ACT1/ACT2 words at registers 4 and 5 are a separate thing: # p. 360 scales them by 99.08, 99.09, 46.03 and 46.04 depending on 58.28/ # 58.29, so they are configuration-dependent and are NOT mapped here. # Group 46 defaults ARE printed in the parameter listing, pp. 205-206: # 46.01 Speed scaling = 1500.00 rpm, 46.02 Frequency scaling = 50.00 Hz, # 46.03 Torque scaling = 100.0%, 46.04 Power scaling = 1000.00 kW/hp, # 46.05 Current scaling = 10000 A. Still configuration-dependent, which is # why the ACT1/ACT2 words at registers 4/5 stay unmapped (58.28/58.29 select # which of 99.08/99.09/46.03/46.04 applies, p. 360). name = "ABB ACQ80" vendor = "ABB" device_type = "vfd" verified = false probe_register = 3 # status word, readable whenever the fieldbus is alive # 58.04 default "19.2 kbps [3]", 58.05 default "8 EVEN 1 [2]" (pp. 217, 344). [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" } } 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. 83-84). Scale is the printed FbEq16. 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 unit # 04.01-04.03 are three CONCURRENT active faults, not a history (p. 89). active_fault_2 = { address = 401 } # 04.02 active_fault_3 = { address = 402 } # 04.03 # --- solar / pump signals, the reason this is not a general-purpose map --- # 79.01/79.02 are the ACQ80's own condensed status words (pp. 226-227). Bit 4 # of 79.01 is dry-run detection and bit 12 of 79.02 is cloud detection; there # is no equivalent on a general-purpose ABB drive. solar_status_word_1 = { address = 7900, bits = { 0 = "RDY_ON", 1 = "READY_RUN", 2 = "RUNNING", 3 = "FAULT", 4 = "DRY_RUN", 5 = "DC_OVER_VOLT", 6 = "DC_UNDER_VOLT", 7 = "MINIMUM_SPEED", 8 = "SHORT_CIRCUIT", 9 = "EARTH_FAULT", 10 = "MOTOR_PHASE_LOSS", 11 = "SUPPLY_PHASE_LOSS", 12 = "MOTOR_STALL", 13 = "OVER_CURRENT", 14 = "EXT_FAULT1", 15 = "LONG_START_DELAY" } } solar_status_word_2 = { address = 7901, bits = { 0 = "EXT_FAULT2", 1 = "AI1_SUPERVISION", 3 = "PANEL_LOSS", 4 = "DEVICE_OVERTEMP", 5 = "ID_RUN_FAILED", 6 = "OUTPUT_WIRING", 7 = "SAFE_TORQUE_OFF", 8 = "MOTOR_OVERTEMP", 9 = "START_ENABLE", 11 = "TANK_FILLING_ON", 12 = "CLOUD_DETECTED" } } # Groups 80/81 read 0 unless the corresponding function is configured, and the # engineering units are user-selected (81.20 Pressure unit, 96.16 Unit # selection). The unit strings below are the manual's defaults, not a promise. # 80.01 is calculated from the PQ curve only when 80.13 Flow function = PQ # curve (values displayed per p. 231; 80.13 itself pp. 232-233, default PQ # curve) — with no flow feedback configured it stays at zero. calculated_flow = { address = 8000, signed = true, scale = 0.01, unit = "m3/h" } # 80.01, 100 = 1 actual_flow_pct = { address = 8001, signed = true, scale = 0.01, unit = "%" } # 80.02, 100 = 1% pump_head = { address = 8004, unit = "m" } # 80.05, 1 = 1 m inlet_pressure = { address = 8100, unit = "bar" } # 81.01, 1 = 1 bar (p. 237) outlet_pressure = { address = 8101, unit = "bar" }# 81.02, 1 = 1 bar (p. 237) # ABB Drives profile control word. UNLIKE the ACQ580 manual (which prints a # literal start/stop/reset sequence on its p. 242), this manual prints NO # literal sequence — only the bit table (pp. 351-352) and the state transition # diagram (pp. 358-359). The words below are DERIVED from those two pages, not # copied, and each is annotated with the state it satisfies. Bits 4/5/6 # (RAMP_OUT_ZERO, RAMP_HOLD, RAMP_IN_ZERO) are held at 1 = normal operation # throughout; bit 10 REMOTE_CMD = 1 = fieldbus control. # 0x0476 = ...x1xx xxxx x110 READY TO SWITCH ON (bit0=0, bit1=1, bit2=1) # 0x0477 = ...x1xx xxxx x111 READY TO OPERATE (bit0=1) # 0x047F = ...x1xx xxx1 1111 OPERATION ENABLED (bit3=1) -> running [control] command_register = 0 step_delay = 0.05 # Stop by clearing OFF1_CONTROL: p. 351 bit 0 = 0 is "Stop along currently # active deceleration ramp". 0x0476 is the same word the start sequence begins # from, i.e. the stopped-but-ready state. stop = [0x0476] run_fwd = [0x0476, 0x0477, 0x047F] # Reset is a RISING EDGE of bit 7 (p. 352), only effective while a fault is # active. The edge is applied on top of the stopped word 0x0476, which has # both OFF1_CONTROL and INHIBIT_OPERATION low, so neither 0x0476 nor 0x04F6 # is a run command. No separate reset_register exists on this drive. reset = [0x0476, 0x04F6, 0x0476] # run_rev is deliberately absent. The ABB Drives control word has no reverse # bit (pp. 351-352); on this drive there is no writable reference to sign # either, since MPPT owns the speed setpoint (p. 360). Reverse is not # available over Modbus and is not faked here. # THE MANUAL CONTRADICTS ITSELF ON COMM-LOSS DEFAULTS: # parameter listing, pp. 219-220: 58.14 = No action, 58.16 = 60.0 s # setup table, p. 344: 58.14 = Fault [1], 58.16 = 3.0 s # Assume the worse case — that monitoring is disabled and the pump keeps # running after the master goes quiet — and keep the keepalive well inside the # shorter of the two timeouts. 6681 EFB comm loss (p. 331) only fires if 58.14 # is actually set away from No action; this keepalive proves the link is live, # it is not evidence the drive has a backstop. [control.watchdog] interval_ms = 500 fault = "6681 EFB comm loss (only if 58.14 is set to Fault; the parameter listing prints the default as No action)" # SW bit 2 RDY_REF = OPERATION ENABLED (p. 355). The ABB Drives status word # has no "modulating" bit — that 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 (p. 89). [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. 322-338). That table is longer # than this list and the warning (Axxx) table is not included at all. [faults.codes] 0 = "No fault" 4225 = "0x1081 Rating ID fault" 8976 = "0x2310 Overcurrent" 9008 = "0x2330 Earth leakage" 9024 = "0x2340 Short circuit" 9089 = "0x2381 IGBT overload" 9106 = "0x2392 BU earth leakage" 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" 17137 = "0x42F1 IGBT temperature" 17168 = "0x4310 Excess temperature" 17280 = "0x4380 Excess temperature difference" 20608 = "0x5080 Fan" 20624 = "0x5090 STO hardware failure" 20625 = "0x5091 Safe torque off" 20627 = "0x5093 Rating ID mismatch" 20640 = "0x50A0 Fan" 26241 = "0x6681 EFB comm loss" 26242 = "0x6682 EFB config file" 26243 = "0x6683 EFB invalid parameterization" 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" 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" # --- pump / solar family (pp. 337-338). NOTE THE SHAPE OF THIS BLOCK: the # ACQ580 has a contiguous D401-D40A water family including D402 High level, # D403 Low level, D404 Running dry and D405 Pipe fill-timeout. The ACQ80 fault # table prints NO D402-D405 at all; dry run is D4B0 here, at a different code, # and D4B1 PV max volt is solar-only and has no ACQ580 equivalent. This is why # the ACQ580 map cannot decode this drive. 54273 = "0xD401 Max cleaning fault" 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" 54448 = "0xD4B0 Running dry" 54449 = "0xD4B1 PV max volt (DC bus above 79.43 PV cell max voltage)" 64129 = "0xFA81 Safe torque off 1" 64130 = "0xFA82 Safe torque off 2" 65377 = "0xFF61 ID run" # 99.06 Motor nominal current (addr 9905, p. 265) was REJECTED as a rating # guard: it is the MOTOR nameplate value the operator types in — part of the # configuration a restore would be writing, not an identity of the drive # hardware. The guard below reads 07.03 Drive rating id instead — "Type of # the drive. (Rating ID in brackets.)", group 07 System info, "All parameters # in this group are read-only" (p. 99; additional data p. 278: List, 1 = 1). # An opaque equality guard at 0-based 100*7 + 3 - 1 = 702. [rating] register = 702 words = 1 scale = 1.0 unit = "" label = "Drive rating id (07.03)" # NOT INCLUDED: no [parameters] ranges — the writable range for clone/restore # was not mined from the parameter listing (pp. 83-270). [connection] summary = "The ACQ80 embedded Modbus RTU interface is the RIIO-01 EIA-485 terminal block." warnings = ["The optional FSCA path is a separate fieldbus-adapter interface and is not the embedded register path described by this profile."] [[connection.methods]] id = "built_in_rs485" title = "Built-in Modbus RTU" transport = "serial" hardware = "built_in" port = "RIIO-01 terminal block X5 on the control unit" connector = "X5:29 B+, 30 A-, 31 DGND; serial termination switch" 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 RIIO-01 terminal block X5 on the control unit.","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 termination on at each physical bus end.","Set 58.01 = Modbus RTU and match 58.03/58.04/58.05.","Set 79.10 = Embedded fieldbus, choose the required EFB references, and apply the group 58 settings."] warnings = [] source = "ABB ISPKA218x (2023-03-27), pp. 58 and 342-346." [[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"