# Property of PMA Electrical Solutions, LLC. # # Allen-Bradley PowerFlex 700H (20C) — Modbus RTU via a 20-COMM-H adapter. # # CLAIMED: PowerFlex 700H only. NOT CLAIMED: # - PowerFlex 700L (20L). It is NOT in the 20-COMM-H compatibility table # (20COMM-UM009D p. 1-2 lists 70, 700EC, 700VC, 700H, 700S, 7000, SMC Flex # — no 700L), and the 700L's own user manual 20L-UM001H lists only # 20-COMM-C / -D / -E as option cards. The 700L has DPI ports, but Rockwell # nowhere states that a 20-COMM-H is qualified on it. Do not assume it. # - PowerFlex 700 (20B), 70 (20A), 700S. The 700 has its own file, # rockwell_powerflex700.toml. Its ADAPTER-side map (control word, status # word, addressing) is byte-identical to this one — same adapter, and # 20COMM-UM009D's tables are headed "PowerFlex 70/700 Example" — but the # 700H's DRIVE-side fault code table is DIFFERENT and is why this is a # separate file. Compare 20C-PM001F p. 64 with 20B-UM002H Table 2: code 9 # is "IGBT OverTemp" here and "Trnsistr OvrTemp" on the 700; 10 is "System # Fault" here and "Heatsink LowTemp" there; 14 "InverterFault", 19 # "Unbalanced", 22 "NP Hz Cnflct", 71 "Periph Loss" do not exist on the 700 # at all, and the 700's per-port 81…86 "Port x DPI Loss" is a single code # 81 "Port DPI Loss" here. Sharing one file would have been wrong. # # COMMUNICATION PATH # The PowerFlex 700H has no embedded Modbus. Modbus RTU requires a 20-COMM-H # RS-485 HVAC adapter in a DPI port, front-panel protocol switch set to Modbus # RTU (20COMM-UM009D p. 1-2; the same switch also selects Metasys N2 and # Siemens P1 FLN). No drive firmware level is stated as a prerequisite. # The adapter mounts differently on a 700H than on a 700 — behind the HIM panel # with a 2.54 cm internal interface cable on Frames 9 and larger # (20COMM-UM009D pp. 2-4…2-5, Figures 2.3/2.4). Physical bracket only; the # protocol is unchanged. # Adapter par 12 [Ref/Fdbk Size] must READ 0 = 16-bit. It is Read Only ("the # drive determines the size", p. B-2); the 16-bit expectation is backed by # 20C-PM001F pp. 45-46 — par 272 [Drive Ref Rslt] / 273 [Drive Ramp Rslt] / # 275 [DPI Port Value] are all ±32767 with no "32" tag. If par 12 reads 1, # a lone write to 0-based 2 lands in reference bits 16…31: do not arm. # Drive par 190 [Direction Mode] must be its default 0 "Unipolar": run_rev # below commands reverse with control-word bits 4-5; in "Bipolar" direction # comes from the SIGN of the reference instead and run_rev does nothing, and # "Reverse Dis" blocks reverse outright (20C-PM001F p. 35; fault 136 # BipolarCnflct, p. 70). Digital inputs 361…366 must not be set to 2-Wire # Control options 7/8/9 or the fieldbus Start is dead (20COMM-UM009D p. C-1 # footnote). # Adapter par 32 [RTU Param Mode] must be its default 0 = 16-bit Mode # (20COMM-UM009D p. B-4). In 32-bit mode the parameter offset DOUBLES and every # address below is wrong. # # SOURCES — Rockwell primary documentation only: # 20C-PM001F-EN-P, PowerFlex 700H AC Drive Programming Manual (March 2012) # pp. 20-21 Metering / Drive Data parameters 001…029 and their units # p. 25 par 090 [Speed Ref A Sel] option list, incl. 18…22 DPI Ports # p. 38 par 209 [Drive Status 1] bit map (status + running_check) # p. 43 par 243/245/…/257 [Fault x Code]; 543… [Fault x Subcode] # p. 46 par 276 [Logic Mask], WITH its bit-to-port assignment # p. 63 the three fault types and how faults are cleared (par 240) # pp. 64-70 Table 1, Fault and Alarm Descriptions # pp. 70-71 Table 2, Fault/Alarm Cross Reference — the complete # name-to-number list transcribed into [faults.codes] below # 20COMM-UM009D-EN-P, 20-COMM-H RS-485 HVAC Adapter User Manual # p. 1-2 Compatible Products table — 700H present, 700L absent # pp. 2-4…2-5 700H Frame 9+ mounting # p. 3-5 par 16 [DPI I/O Cfg] and the drive-side setup below # p. 4-2 the zero-basing rule # p. 4-4 Table 4.C, register map and drive parameter direct access # pp. 4-5…4-7 Table 4.D reference scaling, 4.E logic command bits, # 4.F register outputs (Logic Command / Reference) # pp. 4-7…4-8 Table 4.G logic status bits, 4.H register inputs # p. B-1 par 05 [Net Rate Cfg] default 1 = 9600 # p. B-1 par 07 [Net Parity Cfg] default 0 = None # p. B-2 par 11 [Network Timeout] default 10 s # p. B-3 par 15 [Comm Flt # Action] default 0 = Fault # p. B-4 par 30 [Stop Bits Cfg] default 0 = 1 bit; # par 32 [RTU Param Mode] default 0 = 16-bit Mode # # DRIVE-SIDE / ADAPTER SETUP (without these the drive ACKs and ignores): # - Adapter par 16 [DPI I/O Cfg] bit 0 = 1, "Logic Command/Reference" (the # default), then reset the adapter (20COMM-UM009D p. 3-5). # - Drive par 090 [Speed Ref A Sel] = the adapter's port: 18 "DPI Port 1" … # 22 "DPI Port 5" (20C-PM001F p. 25). Default is 2 "Analog In 2", so the # drive ignores the fieldbus reference until this is changed. # - Drive par 276 [Logic Mask] must have the bit for the adapter's port set, # or that port "will have no control functions except for stop". 20C-PM001F # p. 46 gives the assignment the 700 manual omits: bit 0 = Digital In, # bit 1 = DPI Port 1, bit 2 = Port 2, bit 3 = Port 3, bit 4 = Port 4, # bit 5 = Port 5, bit 6 = Port 6 (default: bits 0-5 set, bit 6 clear). # par 277 [Start Mask], 279 [Direction Mask], 280 [Reference Mask] and 283 # [Fault Clr Mask] use the same bit layout and gate those commands # individually — check all of them before arming. # # ADDRESSING — 0-BASED PROTOCOL ADDRESSES, FC03/06/16 HOLDING REGISTERS. # 20COMM-UM009D p. 4-2: "you must address it to one less than the Modbus # address in the manual", worked there as Logic Command 4x0001 -> 0000. # Table 4.C (p. 4-4) gives drive parameter direct access in 16-bit mode as # "4x1000 + param #", so: # 0-based address = 999 + parameter number # par 001 [Output Freq] -> 4x1001 -> 1001 - 1 = 1000 # par 028 [Rated Amps] -> 4x1028 -> 1028 - 1 = 1027 # par 243 [Fault 1 Code]-> 4x1243 -> 1243 - 1 = 1242 # CAUTION: p. 4-9 restates 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 formula agree, so the worked example is treated as the error; the # same contradiction is flagged in rockwell_powerflex755.toml, # rockwell_smc50.toml and rockwell_smcflex.toml. # BENCH STEP 1, before anything else: read 0-based 1027. The formula returns # par 028 [Rated Amps] (0.0/6553.5 A — matches the nameplate). Under the # p. 4-9 example's reading it would return par 029 [Control SW Ver] # (0.000/255.255 — e.g. raw 4001 for firmware 4.001). If it is the latter, # every address in this file is one too high and [rating] is feeding the # restore guard a firmware version. # # THE STATUS WORD IS READ AS A DRIVE PARAMETER, NOT AS 3x0001. # The adapter's Logic Status Word lives at 3x0001, INPUT register space (FC04); # this app reads holding registers (FC03) only, and 0-based holding register 0 # is the Logic COMMAND. Drive par 209 [Drive Status 1] carries the identical # bit layout (compare 20C-PM001F p. 38 with Table 4.G) and is reachable at # 999 + 209 = 1208. That is what is used below. # # THE 32-BIT METERING PARAMETERS ARE DELIBERATELY ABSENT. # 20C-PM001F pp. 20-21 tag par 002 [Commanded Speed], 009, 010, 011, 022, 023 # and 026 [Rated kW] with "32" — they are 32-bit drive parameters. With the # adapter in its default 16-bit mode a single register cannot carry them, and # neither manual says which half arrives. Reading one as a 16-bit point would # produce a plausible-looking wrong number, so they are omitted rather than # guessed. Every point below is an untagged 16-bit parameter. name = "Allen-Bradley PowerFlex 700H" vendor = "Allen-Bradley" device_type = "vfd" verified = false probe_register = 1000 # par 001 [Output Freq], read-only # 20-COMM-H defaults, 20COMM-UM009D Appendix B. Confirm against the module # actually installed — these are settable and the switch position matters. [serial] baudrate = 9600 parity = "N" stopbits = 1 [monitor] # Metering / Drive Data, 20C-PM001F pp. 20-21. Units are the manual's own # "Units:" line. output_frequency = { address = 1000, signed = true, scale = 0.1, unit = "Hz" } # 001, Min/Max -/+[Maximum Freq] output_current = { address = 1002, scale = 0.1, unit = "A" } # 003 torque_current = { address = 1003, signed = true, scale = 0.1, unit = "A" } # 004, Min/Max Drive Rating x -2/+2 flux_current = { address = 1004, signed = true, scale = 0.1, unit = "A" } # 005, Min/Max Drive Rating x -2/+2 output_voltage = { address = 1005, scale = 0.1, unit = "V" } # 006 output_power = { address = 1006, scale = 0.1, unit = "kW" } # 007 power_factor = { address = 1007, scale = 0.01 } # 008, 0.00/1.00 dc_bus_voltage = { address = 1011, scale = 0.1, unit = "V" } # 012 dc_bus_memory = { address = 1012, scale = 0.1, unit = "V" } # 013 speed_feedback = { address = 1024, signed = true, scale = 0.1, unit = "Hz" } # 025 — valid only while par 079 [Speed Units] = 0 "Hz" (default, but NOT restored by Reset to Defaults, p. 24) rated_volts = { address = 1026, scale = 0.1, unit = "V" } # 027 rated_amps = { address = 1027, scale = 0.1, unit = "A" } # 028 # par 209 [Drive Status 1], 20C-PM001F p. 38. Bits 9-11 encode the local # control port and 12-15 the reference source; they are multi-bit fields, not # flags, so they are left unnamed rather than mislabelled. drive_status_1 = { address = 1208, bits = { 0 = "READY", 1 = "ACTIVE", 2 = "COMMAND_DIR_FWD", 3 = "ACTUAL_DIR_FWD", 4 = "ACCEL", 5 = "DECEL", 6 = "ALARM", 7 = "FAULTED", 8 = "AT_SPEED" } } # par 210 [Drive Status 2], 20C-PM001F p. 38. Bits 14-15 are Reserved. drive_status_2 = { address = 1209, bits = { 0 = "READY", 1 = "ACTIVE", 2 = "RUNNING", 3 = "JOGGING", 4 = "STOPPING", 5 = "DC_BRAKING", 6 = "AUTOTUNING", 8 = "AUTORST_CTDN", 9 = "AUTORST_ACT", 10 = "CURR_LIMIT", 11 = "BUS_FREQ_REG", 12 = "MOTOR_OVERLD", 13 = "DPI_AT_500K" } } last_fault = { address = 1242 } # 243 [Fault 1 Code] # Logic Command register output, 20COMM-UM009D Table 4.F p. 4-7; bit meanings # from 20COMM-UM009D Appendix C pp. C-1/C-2, whose section heading is # "PowerFlex 7-Class Drives (except PowerFlex 700S)" — a direct coverage # statement for the 700H, stronger than the "PowerFlex 70/700 Example" # column of Table 4.E p. 4-6 (which agrees). # 0 Stop 1 Start 2 Jog 3 Clear Faults 4-5 Direction (01=Fwd, 10=Rev) # 6 Local 7 MOP Inc 8-9 Accel sel 10-11 Decel sel 12-14 Ref sel # 15 MOP Dec # Footnotes: a 0 = Not Stop condition must be present BEFORE a 1 = Start will # start the drive, and Start / Clear Faults act on a 0->1 transition. Hence the # leading 0x0000 in every sequence below. # 20COMM-UM009D p. 4-5 ATTENTION: use EITHER the discrete coils (0x000x) OR the # register output (4x0001), never both — "conflicts caused from using both # methods can result in dangerous operation". This profile uses the register. [control] command_register = 0 # Reference. 4x0002 is Reference Lo and 4x0003 is "the whole 16-bit reference"; # Table 4.F footnote 1: "The reference value is sent only when accessing # address 4x0003." A 16-bit reference must therefore be written to 4x0003 -> # 0-based 2. Writing 0-based 1 alone sends nothing. speed_register = 2 # THE REFERENCE IS A 32767-COUNT PERCENT, NOT Hz. 20COMM-UM009D p. 4-5: # "the Reference value is a scaled value; it is not an engineering value", # Table 4.D gives 32767 = 100% of drive par 055 [Maximum Freq], and the result # is then clamped by par 082 [Maximum Speed] — the manual's own example # commands 130 Hz and the motor runs at 60 Hz. Hz per count is therefore # CONFIGURATION-DEPENDENT; read 055 and 082 off the unit before converting. # Adapter par 31 [RTU Ref Adjust] rescales the reference ONLY for broadcast # messages (Modbus address 0, p. B-4), which this app does not send — but # confirm it is at its 100.0% default if anything else on the bus broadcasts. speed_scale = 0.0030518509 # 100.0 / 32767 speed_signed = false # direction is control-word bits 4-5, not the sign speed_unit = "%" max_ref = 100.0 step_delay = 0.05 stop = [0x0001] # bit 0 Stop run_fwd = [0x0000, 0x0012] # Not Stop, then bit 1 Start 0->1 with bits 4-5 = 01 Forward run_rev = [0x0000, 0x0022] # same, bits 4-5 = 10 Reverse # Clear Faults is bit 3 on a 0->1 transition. 0x0008 leaves bit 0 = Not Stop # and bit 1 = 0, so it is not itself a run command on this map. reset = [0x0000, 0x0008, 0x0000] [control.watchdog] # Adapter par 11 [Network Timeout] defaults to 10 s (range 0…180); on expiry # par 15 [Comm Flt Action] (default 0 = "The drive is faulted and stopped") # acts. Keepalive an order of magnitude inside that. # CHECK par 18 [Flt Cfg Logic] BEFORE ARMING: with par 15 = 4 "Send Flt Cfg" # the adapter hands the drive that stored logic command when the network drops. # It is only safe because its factory value has no Start bit. interval_ms = 1000 # The drive-side code for a network-side loss is 71 "Periph Loss" — # 20C-PM001F p. 67: "The communications card has a fault on the network # side." (On the 700H the 700's per-port 71…76 "Port x Adapter" collapses to # this single code, the same collapse the header documents for 81.) Drive # fault 81 "Port DPI Loss" (p. 68) is the DIFFERENT failure of the drive # losing the adapter on the DPI port, and is not reused here. fault = "71 Periph Loss (network-side fault reported via adapter par 11 [Network Timeout] -> par 15 [Comm Flt Action] = Fault)" # par 209 [Drive Status 1] bit 1 "Active" — 20C-PM001F p. 38, and Table 4.G # p. 4-7 gives it as 0 = Not Running, 1 = Running. [running_check] register = 1208 bit = 1 # par 243 [Fault 1 Code] is the most recent; 245/247/…/257 are Fault 2…8 Code # (the even numbers in between are [Fault x Time]). 20C-PM001F p. 43. # Faults are cleared by writing 1 to par 240 [Fault Clear] (p. 63) OR by the # control word's bit 3; this profile uses bit 3 so that clearing needs no # second register. [faults] register = 1242 history = [1244, 1246, 1248, 1250, 1252, 1254, 1256] # 20C-PM001F Table 2 "Fault/Alarm Cross Reference", pp. 70-71 — the complete # published name-to-number list, transcribed in full, plus code 19 # "Unbalanced" which appears in Table 1 (p. 65) but not in Table 2. # Entries that Table 2 marks alarm-only are kept: [Fault x Code] records what # tripped the drive, and reading a name back is safer than a bare number. # Fault SUBCODES (par 543…557, p. 43 and Tables 3-27 pp. 71-76) are NOT here — # this schema has one code per fault and the subcode is a second register. [faults.codes] 1 = "PrechargeActv" 2 = "Auxiliary In" 3 = "Power Loss" 4 = "UnderVoltage" 5 = "OverVoltage" 6 = "Motor Stall" 7 = "MotorOverload" 8 = "HeatsinkOvrTp" 9 = "IGBT OverTemp" 10 = "System Fault" 12 = "OverCurrent" 13 = "Ground Fault" 14 = "InverterFault" 15 = "Load Loss" 16 = "Motor Therm" 17 = "Input Phase" 19 = "Unbalanced" 21 = "OutPhasMissng" 22 = "NP Hz Cnflct" 23 = "MaxFreqCnflct" 24 = "Decel Inhibit" 25 = "OverSpd Limit" 26 = "VHz Neg Slope" 27 = "SpdRef Cnflct" 28 = "BrakResMissng" 29 = "Anlg In Loss" 30 = "MicroWatchdog" 31 = "IGBT Temp Hw" 32 = "Fan Cooling" 33 = "AutoReset Lim" 34 = "CAN Bus Flt" 37 = "HeatsinkUndTp" 44 = "Device Change" 45 = "Device Add" 47 = "NvsReadChksum" 48 = "ParamsDefault" 50 = "MotorCalcData" 54 = "Zero Divide" 59 = "Gate Disable" 60 = "Hrdwr Therm" 63 = "Shear Pin" 65 = "I/O Removed" 70 = "Power Unit" 71 = "Periph Loss" 81 = "Port DPI Loss" 94 = "Hardware Enbl" 95 = "AutoT Rs Stat" 96 = "AutoT Lm Rot" 97 = "AutoT MagRot" 98 = "AutoT Saturat" 99 = "UserSet Timer" 100 = "Param Chksum" 104 = "PwrBrd Chksum" 106 = "MCB-PB Config" 107 = "New IO Option" 113 = "Fatal App" 114 = "AutoT Enable" 120 = "I/O Change" 121 = "I/O Comm Loss" 133 = "DigIn CnflctA" 134 = "DigIn CnflctB" 135 = "DigIn CnflctC" 136 = "BipolarCnflct" 139 = "UserSetCflct" 143 = "TB Man Conflict" 147 = "Start AtPwrUp" 148 = "IntDB OvrHeat" 149 = "Waking" 150 = "Sleep Config" # par 028 [Rated Amps], 20C-PM001F p. 21: "The drive rated output current", # Min/Max 0.0/6553.5 Amps in 0.1 A units, so one 16-bit register holds the # whole value — no 32-bit split here, and the parameter carries no "32" tag. [rating] register = 1027 words = 1 scale = 0.1 unit = "A" label = "Rated Amps" # [parameters] is deliberately ABSENT. 20C-PM001F Chapter 2 lists the writable # parameters, but the per-parameter Default/Min/Max entries were not # transcribed, and a clone/restore range guessed from the group index is # exactly the kind of guess that corrupts a replacement drive. The Datalink # block alone (par 300-317, p. 47) sits inside the same span. Add the ranges # only after reading the parameter tables through. [connection] summary = "The PowerFlex 700H 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 behind the HIM panel; Frame 9+ mounting shown in adapter manual" 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 the 20-COMM-H protocol switch to RTU and its unique node address.", "Set adapter par 16 bit 0 = 1, keep par 32 = 0 (16-bit) and reset it.", "Set drive par 090 to the installed DPI port.", "Enable that port in drive pars 276/277/279/280/283."] 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 and 3-3 to 3-8; 20C-PM001F 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