# Property of PMA Electrical Solutions, LLC. # # Allen-Bradley POWERFLEX 70 (bulletin 20A), Standard Control and Enhanced # Control, reached over a 20-COMM-H adapter running Modbus RTU. # # NOT CLAIMED: the PowerFlex 700, 700S, 700H, 753/755 or 40/400/525. The # 20-COMM-H manual uses "PowerFlex 70/700" as its worked example and the # Logic Command/Status bit tables it prints are titled for both, but every # PARAMETER NUMBER below comes from the PowerFlex 70 user manual alone and the # 700 has its own parameter set. The PowerFlex 750-Series is a different # product with IEEE-754 metering — see rockwell_powerflex755.toml. # # MODBUS PATH ASSUMED BY THIS PROFILE # The PowerFlex 70 has NO embedded Modbus. It speaks DPI and needs a 20-COMM-x # module. This profile assumes the **20-COMM-H RS-485 adapter with its protocol # selector set to Modbus RTU**, on DPI port 5 (adapter par 01 [DPI Port], # default 5), in the adapter's default **16-bit mode**: par 32 [RTU Param # Mode] = 0 is the SETTING; par 12 [Ref/Fdbk Size] and par 13 [Datalink Size] # are READ ONLY ("the drive determines the size", p. B-2) and must be READ — # par 12 must return 0 = 16-bit. If a unit reports 1 (32-bit Reference), # 4x0003 is bits 16…31 (Table 4.F fn. 1, p. 4-7) and speed_register = 2 would # send the reference into the HIGH word. The PowerFlex 70 is 16-bit — par 272 # [Drive Ref Rslt] is Min/Max ±32767 (p. 59) — so the risk is low. # Nothing here applies to a 20-COMM-M (Modbus/TCP) or any other adapter. # # SOURCES — Rockwell primary documentation only: # 20A-UM001P-EN-P, PowerFlex 70 Enhanced Control / Standard Control User # Manual (February 2018) # pp. 21-22 Monitor file A and Drive Data — every [monitor] point, its # units resolution and its signed range # p. 24 par 055 [Maximum Freq], the reference scaling base # p. 32 par 090 [Speed Ref A Sel] option list # p. 48 par 190 [Direction Mode], default "Unipolar" # p. 51 par 209 [Drive Status 1] bit picture # pp. 57-58 par 240 [Fault Clear], pars 243/245/247/249 [Fault 1…4 Code] # p. 59 par 271 [Drive Logic Rslt] — the per-bit confirmation of # the command word (bit 4 Forward, bit 5 Reverse as SINGLE # named bits) # pp. 60-63 Communication file H: par 276 [Logic Mask] and the mask/owner # set, par 298 [DPI Ref Select] # pp. 79-82 Table 1 fault descriptions; Table 2 fault cross-reference # (p. 82) is the numerically sorted list transcribed below # pp. 90-91 Table 13 Logic Command Word, Table 14 Logic Status Word # 20COMM-UM009D-EN-P, 20-COMM-H RS-485 HVAC Adapter User Manual # p. 4-2 the "one less than" addressing rule, supported function codes # pp. 4-2…4-4 Table 4.C, the adapter register map # pp. 4-5…4-8 Table 4.D reference scaling, Table 4.F register outputs, # Table 4.G logic status bits # p. 4-9 the 41000 + param# formula and its own contradictory example # pp. B-1…B-4 adapter parameter defaults: 05, 07, 11, 15, 18, 30, 32 # # ADDRESSING — 0-BASED PROTOCOL ADDRESSES, FC03/06/16 HOLDING REGISTERS. # 20COMM-UM009D p. 4-2 states it outright: "when you create a message, you must # address it to one less than the Modbus address in the manual", worked as # Logic Command 4x0001 -> data address 0000. Table 4.C (p. 4-4) gives drive # parameter direct access as "4x1000 + param #" in 16-bit mode, i.e. parameter # 1 is 4x1001, so: # 0-based address = 999 + parameter number # par 001 [Output Freq] -> 999 + 1 = 1000 # par 028 [Rated Amps] -> 999 + 28 = 1027 # par 209 [Drive Status 1] -> 999 + 209 = 1208 # par 243 [Fault 1 Code] -> 999 + 243 = 1242 # CAUTION: p. 4-9 of the same manual writes the formula as "41000 + (Drive # Parameter #)" and then says parameter 1 is at 41000, one less than its own # formula. Table 4.C and the "one less than" rule agree on 999 + param#, so the # worked example is treated as the error — the identical contradiction is # flagged in rockwell_smcflex.toml and rockwell_smc50.toml. CONFIRM ON HARDWARE # by reading par 029 [Control SW Ver] at 1028 and checking it returns a sane # firmware revision before trusting any other address. Table 4.L (p. 4-13) # settles the base+param# form on the adapter side by enumeration (4x0101 = # adapter par 01 [DPI Port] … with no off-by-one), so the drive-side # 999 + param# is the vendor-supported reading, not a coin flip. # Adapter parameters live at 4x0100 + param# (0-based 99 + param#) and are not # mapped here. Setting adapter par 32 = 1 shifts drive access to 999 + 2*param# # for everything, which this profile does NOT model. # # 32-BIT PARAMETERS ARE NOT REACHABLE IN 16-BIT MODE. 20A-UM001P p. 13: the # "32" symbol marks a 32-bit parameter, and "EC 32" marks one that is 32-bit # ONLY on an Enhanced Control drive. Pars 003, 004, 005 and 007 carry "EC 32" # (16-bit on Standard Control, 32-bit on Enhanced Control); on an EC drive # those points are suspect in 16-bit mode and their resolution also changes # (0.01 A / 0.01 kW instead of 0.1). Pars 009, 010, 014, 026 [Rated kW] and # 242 carry the plain "32" symbol — always 32-bit — and are deliberately # absent. CONFIRM THE FIRMWARE VARIANT before trusting the current # and power points. # # SCALING — 20A-UM001P p. 13: "When sending values through DPI ports, simply # remove the decimal point to arrive at the correct value (for example, to send # 5.00 Hz, use 500)." So the wire value is the parameter's own Units resolution # from pp. 21-22, not a separate fieldbus scale. # # DRIVE-SIDE SETUP — without these the drive ACKs writes and ignores them: # par 090 [Speed Ref A Sel] = 22 "DPI Port 5" (p. 32). Factory default is 2 # "Analog In 2", so out of the box the adapter's Reference is IGNORED. # par 276 [Logic Mask] bit 5 = 1 (DPI Port 5). Unlike the SMC Flex the # factory default already permits port 5 (p. 60 shows default # x x x x x x x x x x 1 x 1 1 1 1), but confirm it — with the bit set, # unplugging the adapter raises fault 85 [Port 5 DPI Loss], and with it # clear the port can only stop the drive. Also read the per-function # masks, same bit layout (p. 60): par 277 [Start Mask] bit 5 gates # run_fwd/run_rev, par 279 [Direction Mask] bit 5 gates the direction # bits, par 283 [Fault Clr Mask] bit 5 gates the reset. (The manual # prints par 276's own gating parameter inconsistently — "598, bit 15" # on p. 60 vs "597, bit 15" on p. 63 — recorded, not resolved.) # adapter par 16 [DPI I/O Cfg] bit 0 "Cmd/Ref" = 1 (default, p. B-3). # par 190 [Direction Mode] = 0 "Unipolar" (default, p. 48) — direction then # comes from the command word, which is what run_rev below assumes. If # someone has set it to 1 "Bipolar", direction becomes the SIGN OF THE # REFERENCE (the ABB pattern) and run_rev must not be used. # # REFERENCE SCALING IS CONFIGURATION-DEPENDENT, LIKE ABB FbEq16. # 20COMM-UM009D p. 4-5 Table 4.D: the Reference "is a scaled value; it is not # an engineering value", 32767 = 100% of par 055 [Maximum Freq], and the result # is then clamped by par 082 [Maximum Speed]. Par 055 defaults to 110.0 Hz or # 130.0 Hz depending on drive rating (20A-UM001P p. 24) and is freely settable # 5.0…400.0 Hz (500.0 EC), so there is NO fixed Hz scale to hard-code. This # profile therefore commands PERCENT, exactly like the ABB profiles: # raw = percent / 100 * 32767, and Hz = percent / 100 * par 055 # On Enhanced Control, par 298 [DPI Ref Select] (p. 60) can move that base from # [Maximum Freq] to [Maximum Speed]; default is "Max Freq". READ 055, 082 AND # 298 OFF THE UNIT BEFORE ARMING — 50% is 65 Hz on one drive and 30 Hz on # another. name = "Allen-Bradley PowerFlex 70" vendor = "Allen-Bradley" device_type = "vfd" verified = false probe_register = 1028 # par 029 [Control SW Ver], read only, no motor needed # 20-COMM-H defaults, 20COMM-UM009D Appendix B: par 05 [Net Rate Cfg] = 1 # (9600), par 07 [Net Parity Cfg] = 0 (None), par 30 [Stop Bits Cfg] = 0 # (1 bit). 4800/9600/19200/38400 and None/Odd/Even are all selectable, so # confirm against the module actually installed. [serial] baudrate = 9600 parity = "N" stopbits = 1 [monitor] # Monitor file A, 20A-UM001P pp. 21-22. output_frequency = { address = 1000, scale = 0.1, signed = true, unit = "Hz" } # par 001, ±[Maximum Freq] commanded_frequency = { address = 1001, scale = 0.1, signed = true, unit = "Hz" } # par 002, ±[Maximum Speed] # par 003. 0.1 A on Standard Control; 0.01 A and 32-bit on Enhanced Control — # see the 32-bit note in the header before trusting this on an EC drive. output_current = { address = 1002, scale = 0.1, unit = "A" } # par 004/005, signed, ±2x drive rating. Same EC caveat. torque_current = { address = 1003, scale = 0.1, signed = true, unit = "A" } flux_current = { address = 1004, scale = 0.1, signed = true, unit = "A" } output_voltage = { address = 1005, scale = 0.1, unit = "V" } # par 006, 0.1V AC # par 007, calculated from autotune values, not measured. Same EC caveat. output_power = { address = 1006, scale = 0.1, unit = "kW" } power_factor = { address = 1007, scale = 0.01 } # par 008, 0.00…1.00 dc_bus_voltage = { address = 1011, scale = 0.1, unit = "V" } # par 012, 0.1V DC dc_bus_memory = { address = 1012, scale = 0.1, unit = "V" } # par 013, 6-minute average # par 028, the DRIVE's rated output current (nameplate of the drive, not the # motor). Also used as [rating] below. rated_amps = { address = 1027, scale = 0.1, unit = "A" } # par 209 [Drive Status 1], p. 51. Bit-for-bit the DPI Logic Status Word of # Table 14 (p. 91) — which is why [running_check] works here and does not on # the SMC Flex: the status word itself is only at 3x0001, an INPUT register # (FC04) that vfd-core cannot read, but the PowerFlex 70 mirrors it into an # ordinary parameter reachable by FC03. Bits 9-11 are the Local Control port # number and 12-15 the reference source; both are multi-bit fields, so they are # left unnamed rather than mislabelled as flags. drive_status_1 = { address = 1208, bits = { 0 = "READY", 1 = "ACTIVE", 2 = "CMD_DIR_FWD", 3 = "ACTUAL_DIR_FWD", 4 = "ACCEL", 5 = "DECEL", 6 = "ALARM", 7 = "FAULT", 8 = "AT_SPEED" } } # par 271 [Drive Logic Rslt], p. 59 — the final logic command after combining # every DPI port and the terminal block. Read it to see whether the word this # profile wrote is the word that actually won. drive_logic_result = { address = 1270 } # par 276 [Logic Mask]. Bit 5 is DPI port 5; read it to confirm the adapter is # permitted to control the drive at all. Bit 0 is the digital inputs. logic_mask = { address = 1275, bits = { 0 = "DIGITAL_IN", 1 = "DPI_PORT_1", 2 = "DPI_PORT_2", 3 = "DPI_PORT_3", 5 = "DPI_PORT_5" } } # DPI Logic Command word: adapter holding register 4x0001 -> 0-based 0 # (20COMM-UM009D Table 4.C/4.F). Bits are 20A-UM001P Table 13 p. 90, identical # to the adapter manual's own PowerFlex 70/700 example (Table 4.E, p. 4-6): # 0 Stop 1 Start (momentary) 2 Jog 3 Clear Faults # 4-5 Direction: 00 none, 01 forward, 10 reverse, 11 hold # 6 Local Control 7 MOP Increment 8-9 Accel Rate 10-11 Decel Rate # 12-14 Reference Select (000 = no command) 15 MOP Decrement # Table 13 footnote 1: "A 0 = Not Stop condition (logic 0) must first be # present before a 1 = Start condition starts the drive. The Start command acts # as a momentary Start command. A 1 starts the drive, but returning to 0 does # not stop the drive." That is why every sequence below opens with 0x0000. # Footnote 2: Start does not function if a digital input (pars 361…366) is # programmed for 2-Wire Control (option 7, 8 or 9). Check the digital inputs. # The reference-select field is left at 000 "No Command" so the drive keeps # using par 090 [Speed Ref A Sel], which the drive-side setup points at DPI # port 5. # # THESE WORD VALUES ARE COMPOSED FROM THE DOCUMENTED BIT POSITIONS — and the # positions are printed twice: Table 13 (p. 90) as a 2-bit Direction field, # and par 271 [Drive Logic Rslt] (p. 59) as SINGLE named bits (bit 4 Forward, # bit 5 Reverse), which independently confirms 0x0010/0x0020. What remains # for a bench is the momentary-start edge behaviour and the mask # interaction, not the bit arithmetic. [control] command_register = 0 # READ-BACK CAVEAT: 4x0003 is documented only under "Write Various Holding # Registers" (Table 4.C/4.F); whether an FC03 read of it returns the buffered # reference is stated nowhere, and core verifies a reference by reading the # SAME register back — so set_reference may report a false "clamped or # ignored" error on this path. The applied reference must then be read from # par 002 [Commanded Freq] at 1001 (or par 272 [Drive Ref Rslt] at 1271). speed_register = 2 # 4x0003, the whole 16-bit Reference in 16-bit mode speed_scale = 0.0030518 # 100% / 32767 raw; write PERCENT of par 055 speed_signed = false # par 190 default "Unipolar": direction is the command word speed_unit = "%" # NOT Hz — percent of [Maximum Freq], see header max_ref = 100.0 step_delay = 0.05 stop = [0x0001] run_fwd = [0x0000, 0x0012] run_rev = [0x0000, 0x0022] # Bit 3 [Clear Faults], pulsed 0 -> 1 -> 0 (20COMM-UM009D Table 4.E fn. 2, # p. 4-6: "To perform this command, the value must change from 0 to 1"). 0x0008 has bit 1 (Start) # clear, so this reset value is NOT itself a run command — the Delta MS300 trap # does not apply. The trailing 0x0000 is what the keepalive latches, so the # drive is not held in a permanent clear-faults state. There is no separate # reset register on this path; par 240 [Fault Clear] at 1239 would be the # parameter-write alternative and is deliberately not used, because a reset # written to a register other than the one the keepalive refreshes has no # read-back path here. reset = [0x0000, 0x0008, 0x0000] # 20COMM-UM009D Appendix B: adapter par 11 [Network Timeout] is 10 s by default # (0…180 s) and par 15 [Comm Flt Action] is 0 = Fault, so a master that goes # quiet trips the drive rather than leaving the motor running. On DPI port 5 # that surfaces as fault 85 [Port 5 DPI Loss] or 75 [Port 5 Adapter] # (20A-UM001P Table 2, p. 82). 2 s keepalive sits well inside the 10 s timeout. # NOTE par 18 [Flt Cfg Logic], factory 0x0000, is the logic command the adapter # sends the drive when [Comm Flt Action] = 4 "Send Flt Cfg" — if someone has # set a Start bit in it, comm loss becomes a START. Check it before arming. [control.watchdog] interval_ms = 2000 fault = "85 Port 5 DPI Loss / 75 Port 5 Adapter" # par 209 [Drive Status 1] bit 1 "Active". 20COMM-UM009D Table 4.G p. 4-7 # glosses this bit for the PowerFlex 70/700 as "0 = Not Running / 1 = Running". [running_check] register = 1208 bit = 1 # par 243 [Fault 1 Code] is the most recent fault; 245/247/249 are the three # older ones (20A-UM001P p. 58, "[Fault 1 Code] = the most recent fault"). # The odd-numbered gaps are [Fault x Time], which are 32-bit and unreachable. [faults] register = 1242 history = [1244, 1246, 1248] # Table 2 - Fault Cross-reference, 20A-UM001P p. 82, transcribed complete. # That table's own footnote: "Fault numbers that are not listed are reserved # for future use", so the gaps below are the manual's gaps, not omissions. # Codes 900…930 are "Fatal Faults" as a block — a diagnostic code range with no # per-code breakdown published — and are not enumerated. # 49, 51 and 52 are queue markers, not trips. [faults.codes] 2 = "Auxiliary Input" 3 = "Power Loss" 4 = "UnderVoltage" 5 = "OverVoltage" 7 = "Motor Overload" 8 = "Heatsink OvrTemp" 9 = "Trnsistr OvrTemp" 10 = "Heatsink LowTemp" 12 = "HW OverCurrent" 13 = "Ground Fault" 15 = "Load Loss" 16 = "Motor Thermistor" 17 = "Input Phase Loss" 24 = "Decel Inhibit" 25 = "OverSpeed Limit" 29 = "Analog In Loss" 33 = "Auto Rstrt Tries" 36 = "SW OverCurrent" 38 = "Phase U to Grnd" 39 = "Phase V to Grnd" 40 = "Phase W to Grnd" 41 = "Phase UV Short" 42 = "Phase VW Short" 43 = "Phase UW Short" 48 = "Params Defaulted" 49 = "Drive Powerup (queue marker, not a trip)" 51 = "Flt QueueCleared (queue marker, not a trip)" 52 = "Faults Cleared (queue marker, not a trip)" 55 = "Cntl Bd Overtemp" 63 = "Shear Pin" 64 = "Drive Overload" 69 = "DB Resistance" 70 = "Power Unit" 71 = "Port 1 Adapter" 72 = "Port 2 Adapter" 73 = "Port 3 Adapter" 74 = "Port 4 Adapter" 75 = "Port 5 Adapter" 77 = "IR Volts Range" 78 = "FluxAmpsRef Rang" 79 = "Excessive Load" 80 = "AutoTune Aborted" 81 = "Port 1 DPI Loss" 82 = "Port 2 DPI Loss" 83 = "Port 3 DPI Loss" 84 = "Port 4 DPI Loss" 85 = "Port 5 DPI Loss" 86 = "Port 6 DPI Loss" 87 = "IXo VoltageRange" 90 = "Encoder Quad Error" 91 = "Encoder Loss" 93 = "Hardware Fault" 100 = "Parameter Chksum" 101 = "UserSet1 Chksum" 102 = "UserSet2 Chksum" 103 = "UserSet3 Chksum" 104 = "Pwr Brd Chksum1" 105 = "Pwr Brd Chksum2" 106 = "Incompat MCB-PB" 107 = "Replaced MCB-PB" 108 = "Anlg Cal Chksum" 111 = "Enable Hardware" 112 = "Power Down Csum" # par 028 [Rated Amps], "The drive rated output current", read only, 0.1 A # resolution (20A-UM001P p. 22). This is the DRIVE's frame rating, not the # installer-entered motor FLA (par 042 [Motor NP FLA]), so it is the right # pre-restore comparison. On Enhanced Control the range widens to 0.0…6553.5 A # but the resolution stays 0.1 A and the parameter stays 16-bit. [rating] register = 1027 words = 1 scale = 0.1 unit = "A" label = "Drive Rated Amps" # NO [parameters] BLOCK, DELIBERATELY. # A clone would have to write the settings groups, and the PowerFlex 70 # interleaves read-only metering (pars 001…029), read-only diagnostics # (pars 209…237), a read-only fault queue (pars 243…250), read-only owner words # (pars 288…297), reserved numbers and 32-bit parameters that a 16-bit adapter # cannot write at all with the writable settings. The per-parameter R/W # behaviour needed to draw safe ranges was not walked end to end for this # profile, so no range is known-safe. Writing a read-only parameter NAKs; # writing a reserved one is undefined. Same posture as rockwell_smcflex.toml. [connection] summary = "The PowerFlex 70 has no compatible embedded Modbus port for this profile; install a Rockwell 20-COMM-H RS-485 adapter and connect it through DPI." warnings = ["Lock out the drive/starter, verify stored energy is discharged, and use ESD precautions before installing the adapter.", "The 20-COMM-H must be set to Modbus RTU, not N2 or P1.", "The optional 20-COMM-M Modbus TCP module is not this profile and is not interchangeable.", "Confirm parameter width/memory-map mode exactly as the profile requires before trusting an address."] [[connection.methods]] id = "20_comm_h_rs485" title = "20-COMM-H Modbus RTU option" transport = "serial" hardware = "option" port = "DPI port 5; adapter mounts inside the drive" connector = "20-COMM-H six-pin network plug: TERM, A, B, COM, SHIELD, GND" adapter = "Isolated USB-to-RS-485 adapter" cable = "Belden 3106A three-wire RS-485 cable or equivalent; Belden 3105A two-wire is allowed where COM is intentionally omitted" parts = ["Rockwell 20-COMM-H RS-485 HVAC adapter", "Drive-specific DPI internal interface cable/carrier", "Isolated USB-to-RS-485 adapter", "Belden 3106A or equivalent", "Six-pin linear plug supplied for the adapter"] steps = ["Remove drive/starter and network power and verify discharge.", "Set the 20-COMM-H node-address switches and the protocol selector to RTU before installation.", "Mount and ground the adapter, then connect its internal interface cable to the documented DPI port.", "Land A, B, COM and shield on the six-pin network plug exactly as shown below.", "At a bus end jumper TERM to A; at one network point only jumper SHIELD to GND.", "Restore control power with the motor inhibited, verify adapter status, and prove a read before enabling control."] setup = ["Set 20-COMM-H protocol switch to RTU and its unique node address.", "Keep adapter par 32 = 0 (16-bit), par 16 bit 0 = 1 and reset the adapter.", "Set drive par 090 = 22 DPI Port 5.", "Verify drive pars 276/277/279/283 permit port 5 and par 190 remains Unipolar."] warnings = ["Do not install/remove the adapter with the drive energized.", "A = TxRxD- and B = TxRxD+ on this adapter; preserve those literal labels.", "Ground the shield at one point on the entire network."] source = "Rockwell 20COMM-UM009D-EN-P, pp. 2-1 to 2-7, 3-3 to 3-8; 20A-UM001P drive setup pages cited in profile." [[connection.methods.wiring]] adapter = "TxRxD- / A / -" device = "20-COMM-H A — TxRxD-" signal = "RS-485 A" [[connection.methods.wiring]] adapter = "TxRxD+ / B / +" device = "20-COMM-H B — TxRxD+" signal = "RS-485 B" [[connection.methods.wiring]] adapter = "COM / signal common" device = "20-COMM-H COM — Signal Common" signal = "Signal reference" [[connection.methods.wiring]] adapter = "Cable shield" device = "20-COMM-H SHIELD" signal = "Shield RC termination" required = false [[connection.methods.wiring]] adapter = "Protective earth at one network point" device = "20-COMM-H GND (jumper to SHIELD at one point only)" signal = "Shield earth bond" required = false