# Property of PMA Electrical Solutions, LLC. # # Eaton PowerXL DC1 compact variable frequency drive, over the drive's OWN # RJ45 COM port. No option module: MN040018EN §2.3 (printed p. 11) states # "The integrated RJ45 port (COM port) in DA1 and DC1 variable frequency # drives and DE1 variable speed starters supports the Modbus RTU protocol, # allowing for a direct network connection without the need for an additional # interface module." RS485- is pin 7, RS485+ is pin 8; pins 4/5 are the keypad # "OP bus" and pins 1/2 are CAN, so a cable landed on the wrong pair is silent # rather than wrong. # # THIS PROFILE CLAIMS THE PLAIN DC1 ONLY — NOT DC1…E1. # Eaton documents them as separate register tables and they genuinely diverge. # MN040018EN Table 19 (DC1) vs Table 20 (DC1…E1), printed pp. 52-56: # * Register 141 is P-13 "Last fault" on DC1 and P-13 "Application Mode # Macro" on DC1…E1. This profile reads faults from that register, so # pointing it at a DC1…E1 reads a macro number and names the wrong fault. # * Output process data IDs 9 (Torque) and 10 (Output power) are marked # "DA1, DC1…E1 only" (printed p. 31) and are therefore absent below. # * The fault codes in Table 11 are tagged per device series; only the rows # that name a bare "DC1" are transcribed here. # DA1 and DE1 share this manual but are different drives and are not claimed. # # SOURCES — Eaton primary documentation only: # MN040018EN (09/16) "PowerXL Modbus RTU Communication manual for Variable # Frequency Drives / Variable Speed Starters DA1, DC1, DE1" # printed p. 11 §2.3, integrated RJ45 port, no option module, pinout # printed p. 12 §2.3.1 DI1 enable requirement; §2.3.2 fixed data format # printed p. 16 Table 2, communication parameters for DC1 # printed p. 26 §2.6.1.2, supported function codes # printed p. 28 §2.6.3, register mapping and the decimal-point note # printed p. 29 §2.6.4 input process data; §2.6.4.1 command word bits # printed p. 30 §2.6.4.2, speed reference range and scaling # printed p. 31 §2.6.5 output process data; §2.6.5.1 status word bits # printed pp. 32-33 Table 11, fault messages with numeric codes # printed p. 33 §2.6.5.2, actual speed range and scaling # printed p. 34 §2.6.5.3 current; §2.6.5.6 digital inputs # printed p. 37 DC1 type-code nibbles, Tables 14 and 15 # printed p. 39 §2.6.5.10, drive recognition value (DC1 = 10) # printed pp. 40-41 §2.6.6.1 and §2.6.6.2, the worked telegrams that fix # the addressing rule below # printed pp. 52-53 Table 19, parameters for DC1 # MN04020004Z-EN (11/16) "PowerXL DC1 Variable Frequency Drives - # Parameter Manual" # printed pp. 19-20 §3.2.4 and §3.2.5, terminal roles under P-12 = 3 and 4 # printed pp. 29-30 Table 22, DC1 display messages # printed p. 36 P-12 and P-13 # printed p. 41 P-36, the packed RS485 address / baud / timeout word # # ############ ADDRESSING — 0-BASED, AND EATON PROVES IT WITH TELEGRAMS ####### # Eaton numbers everything in this manual as a 1-based "ID" / "Modbus # Register". The conversion is stated twice, in worked frames, not in prose: # # §2.6.6.1 (printed p. 40), reading the status word: # Master request: 01 03 0005 0001 940B # "0005 -> 5dec: The ID is 6, since the motor controller has an offset # of +1." # §2.6.6.2 (printed p. 41), writing the control word: # Master request: 01 06 0000 0001 480A # "0000 -> 0: The ID of the register for the writing operation is 1, since # the master controller has an offset of +1." # "0001 Content (2 byte) for register 0000 0000 0000 001bin -> RUN" # # So, everywhere in this file: # 0-based protocol address = the manual's ID / Modbus Register number - 1 # ID 1 Command -> 0 # ID 2 Speed reference -> 1 # ID 6 Status/fault word -> 5 # ID 141 P-13 Last fault -> 140 # There is no 4xxxx or 3xxxx notation anywhere in MN040018EN; do not introduce # one. §2.6.3 also warns that "The interface driver in certain controllers # (e.g. PLCs) may have an offset of +1", which is the same statement seen from # the PLC side — it does not mean a second offset on top of this one. # # FUNCTION CODES: §2.6.1.2 (printed p. 26) lists exactly two — 03 Read Holding # Registers and 06 Write Single Register. Nothing on this drive lives in the # FC04 input-register space, so vfd-core's holding-register-only reads reach # every value in this file. Two consequences worth knowing: a read request is # capped at 11 registers (core reads points one at a time, so this never # bites), and there is no FC16, so every write is one register at a time. # ############################################################################ # # ############ DRIVE-SIDE SETUP — TWO THINGS, ONE OF THEM IS A WIRE ########## # 1. P-12 "Local ProcessData Source" (ID 140 -> address 139) must be 3 or 4. # Factory default is 0 = Terminal Control, and on 0 the drive answers # Modbus reads normally while ignoring the command word entirely. # 3 = Modbus Control, ramps from P-03/P-04 # 4 = Modbus Control, ramp times via Modbus (ID 4 -> address 3) # This profile assumes 3. Under 4 the drive takes its ramps from a register # this profile never writes, so it would inherit whatever was last there. # # 2. DI1 (terminal 2) MUST BE HELD HIGH. This is a wire, not a parameter, and # it is the single most common reason a correctly-addressed DC1 accepts # every write and never turns. MN040018EN §2.3.1 (printed p. 12): "If using # Modbus, there must always be a high signal at DI1." MN04020004Z Tables 12 # and 13 (printed pp. 19-20) confirm it from the other direction — under # P-12 = 3 and P-12 = 4, DI1 is START for every permissible P-15 value, and # every other P-15 value is "Not permissible". # Status word bit 7 reports this as "HardwareRelease"; if it reads 0, stop # debugging the register map and go look at terminal 2. # # Also note from those same tables: no P-15 setting puts REV on a terminal # under Modbus control. Direction comes only from command bit 1. # ############################################################################ name = "Eaton PowerXL DC1" vendor = "Eaton" device_type = "vfd" verified = false probe_register = 5 # ID 6 status/fault word, readable whenever the port is up [connection] summary = "Use the DC1's integrated RJ45 COM port; only pins 7 and 8 are Modbus RS-485." warnings = ["Isolate and discharge the drive before handling control wiring.", "Pins 1/2 are CAN and pins 4/5 are the keypad OP bus; a generic Ethernet cable or Ethernet adapter is not a Modbus connection."] [[connection.methods]] id = "integrated_rj45_rs485" title = "Integrated RJ45 Modbus RTU" transport = "serial" hardware = "built_in" port = "RJ45 COM port: pin 7 RS485-, pin 8 RS485+" connector = "Integrated 8P8C/RJ45 COM socket" adapter = "Isolated USB-to-RS-485 adapter plus an RJ45 breakout wired only to pins 7/8" cable = "Eaton DX-CBL-RJ45 cable/splitter system or a verified shielded RJ45 breakout cable" parts = ["RJ45 breakout or DX-SPL-RJ45 splitter", "EASY-NT-R 120 ohm termination at each physical end"] wiring = [{ adapter = "D- / A-", device = "RJ45 pin 7, RS485-", signal = "RS-485 negative" }, { adapter = "D+ / B+", device = "RJ45 pin 8, RS485+", signal = "RS-485 positive" }] steps = ["Isolate the drive and identify the integrated COM socket, not an Ethernet jack.", "Use a verified breakout to connect only RJ45 pin 7 negative and pin 8 positive; leave all other pairs untouched.", "Install EASY-NT-R termination only at the two physical ends of a splitter/cable network.", "Restore power and select the USB-to-RS-485 adapter's serial port."] setup = ["Set P-12 = 3 Modbus Control and configure P-36 address/baud/timeout.", "Hold DI1 terminal 2 high; Modbus commands are rejected without this physical enable."] warnings = ["The DC1-specific and shared manuals disagree on default baud; try 115200, then 9600 before changing wiring.", "This profile is for plain DC1, not DC1…E1."] source = "Eaton MN040018EN, printed pp. 11-16; MN04020004Z-EN, printed pp. 19-20 and 41" # BAUD DEFAULT: THE TWO MANUALS DISAGREE. Take a failure to connect as this, # not as wiring. # MN04020004Z printed p. 41 (DC1-specific, 11/16): P-36 "RS485-0 Baudrate", # range 0-6, DS = 6, and 6 = 115.2 kbit/s. # MN040018EN Table 2, printed p. 16 (multi-drive, 09/16): "Baud Rate", # values 2..6, DS = 2, and 2 = 9.6 kbit/s. # The value below follows the newer, DC1-specific parameter manual. If the # link does not come up at 115200, try 9600 before suspecting anything else. # # Parity and stop bits are NOT a guess and NOT adjustable: MN040018EN §2.3.2 # (printed p. 12) — "The data format is fixed for DC1 variable frequency # drives and DE1 variable speed starters and cannot be changed. No parity, # 1 start bit, 1 stop bit, 8 data bits." [serial] baudrate = 115200 parity = "N" stopbits = 1 # SCALING RULE FOR THIS WHOLE DRIVE, MN040018EN §2.6.3 (printed p. 28): # "The decimal point is not taken into account when processing values! For # example, if the motor current (Register 8) shown on the display is 0.3 A, it # will be transmitted as 003dec via Modbus." So the fieldbus value is the # panel reading with the decimal point removed, and the scaling column in the # process-data tables is the authority for where it goes back. [monitor] # ID 6. §2.6.5.1 (printed p. 31): "Device status and fault message information # is provided in the status word (bit 0 to bit 7) and fault word (bit 8 to bit # 15)." Only bits 0-7 are flags and only those are named — bits 8-15 are a # NUMBER, not a bitfield, and naming them would print nonsense flags. The # fault number is read from its own register in [faults] below. # Bit 2 is direction: 0 = clockwise (FWD), 1 = anticlockwise (REV). # Bit 7 is documented for DC1/DE1 as "Hardware release: no / yes" — the DI1 # enable described in the setup block above. On DA1 the same bit is STO, which # is one more reason this profile does not claim DA1. status_word = { address = 5, bits = { 0 = "Ready", 1 = "Run", 2 = "DirectionREV", 3 = "Fault", 4 = "AtReference", 5 = "ZeroSpeed", 6 = "SpeedControlActive", 7 = "HardwareRelease" } } # ID 7 "Actual speed", scaling factor 0.1, Hz (printed pp. 31 and 33). # SIGNED IS A DECODE CHOICE, NOT A CLAIM: Eaton documents the range as P-02 # (f-min) to P-01 (f-max), both non-negative, and does not say whether reverse # is reported as a negative. Full scale is 500.0 Hz = raw 5000, an order of # magnitude below 32767, so reading it signed cannot corrupt any legitimate # value and correctly shows a negative if the drive does return one. output_frequency = { address = 6, scale = 0.1, signed = true, unit = "Hz" } # ID 8, one decimal place — "Example: 34 = 3.4 A" (printed p. 34). motor_current = { address = 7, scale = 0.1, unit = "A" } # ID 11 (printed p. 34): "This value indicates the digital inputs' state. The # lowest bit indicates the state of DI1." Only DI1 is named, because only DI1 # is named in the manual — and it happens to be the one that matters, since it # is the hardware enable. digital_inputs = { address = 10, bits = { 0 = "DI1 (Modbus enable)" } } # ID 13 and 14. Table 19 calls the unit of ID 13 "kW bzw. HP" — which of the # two depends on the drive's country-specific setting, readable from the # phases nibble of the type code (Table 14, printed p. 37). Left unitless # rather than asserting kW on a drive that may be reporting HP. drive_power = { address = 12 } voltage_range = { address = 13, unit = "V" } # ID 17 (printed p. 39): "DA1: 5632 / DC1: 10 / DE1: 8 / DE11: 9". A constant, # and the cheapest way to confirm this profile is pointed at a DC1 at all — # if this does not read 10, nothing else in this file applies. drive_recognition = { address = 16 } # # Table 19 monitor parameters (printed p. 52), P0-xx group. These are outside # the process-data image but inside the same holding-register space. dc_bus_voltage = { address = 22, unit = "V" } # reg 23, P0-08, 230 = 230 V heatsink_temperature = { address = 23, signed = true, unit = "C" } # reg 24, P0-09, range -10..150 run_hours = { address = 24, unit = "h" } # reg 25, P0-10 t-Run (h) # # NOT INCLUDED, DELIBERATELY: Table 19 registers 20 and 21 (P0-01/P0-02 analog # inputs) print a scaling of "4096 = 100.0 %" against a value range of 0-1000 # in the same row. Those two cannot both be true and the manual does not # resolve it, so the analog inputs are omitted rather than shipped with a # coin-flip scale. Registers 15 and 16 (software versions) are omitted as # uninteresting, not as unknown — they are "two decimal places" WORDs. # ID 1 "Fieldbus command", §2.6.4.1 (printed p. 29): # bit 0 0 = Stop 1 = Operational (run) # bit 1 0 = Clockwise (FWD) 1 = Anticlockwise (REV) # bit 2 0 = no action 1 = Reset Fault # bit 3 0 = no action 1 = Coast to stop # bit 4 not used # bit 5 0 = no action 1 = Quick stop (ramp 2) # bit 6 0 = no action 1 = Fixed frequency FF1 # bit 7 0 = no action 1 = Overwrite setpoint value with 0 # bits 8-15 not used # Eaton's own write example confirms the low bit: value 0x0001 is annotated # "0000 0000 0000 001bin -> RUN" (printed p. 41). # # Each sequence writes the WHOLE word, so bits 3, 5, 6 and 7 are cleared by # every command here. That is intentional — a stale coast-to-stop or # overwrite-setpoint-with-0 bit left set by another master would otherwise # make a correct run command do nothing visible. [control] command_register = 0 step_delay = 0.05 # All bits clear: bit 0 = 0 is Stop, and stop mode follows P-05. stop = [0x0000] # Bit 0 only. Direction bit clear = clockwise. run_fwd = [0x0001] # Bits 1 and 0. Reverse IS a real command bit on this drive — it is not the # sign of the reference (ID 2 is documented over f-min..f-max, both # non-negative) and it is not available on any terminal under Modbus control, # so run_rev is genuinely distinct from run_fwd rather than a duplicate. run_rev = [0x0003] # Bit 2 pulsed, then released. SAFE BY INSPECTION: bit 0 is clear in BOTH # steps, so neither 0x0004 nor 0x0000 is a run command. This is the Delta # MS300 trap — there, the reset value written to the run register starts the # motor — and it does not exist here, which is why reset_register is not set. reset = [0x0004, 0x0000] # ID 2 "Fieldbus speed reference value", scaling factor 0.1, Hz (printed # pp. 29-30). The drive clamps to P-02 (f-min) .. P-01 (f-max), so writing 0 # on a drive with a non-zero f-min still turns the motor. # max_ref is the absolute documented ceiling for P-01 (Table 19: P-02 to # 5 x P-09, max 500.0 Hz), NOT the 50.0 Hz factory f-max. It is a typo guard, # not a speed limit; the drive's own P-01 is the limit that matters. speed_register = 1 speed_scale = 0.1 speed_unit = "Hz" max_ref = 500.0 # GOING QUIET STOPS THIS DRIVE — it does not keep running like a Danfoss. # The timeout is packed into P-36 (ID 164 -> address 163) as "Modbus RTU0 COM # Timeout", range 0-8, and MN04020004Z printed p. 41 gives its factory default # as 4, which that same table defines as "t 3000 ms" — the "t" prefix meaning # "the drive will trip if time exceeded" (values 5-8 are the "r" variants that # ramp to stop instead, and 0 is "no action"). # MN040018EN Table 2 (printed p. 16) prints the same default as "3000 ms", # which agrees. # 500 ms of keepalive gives six chances inside the 3 s window. # # THE FAULT NAME IS A GAP. MN04020004Z Table 22 (printed p. 30) lists the DC1 # display message for this condition as "SC-trp / Serial communication lost", # but neither manual gives a NUMERIC code for it under a bare "DC1" — Table 11 # code 50 "Sc-FO1 / No valid Modbus frame was received within the time # specified" is tagged "DA1, DC1…E1", not DC1. So expect the trip, expect the # display to read SC-trp, and do not expect [faults.codes] below to name it. [control.watchdog] interval_ms = 500 fault = "SC-trp serial communication lost (P-36 Modbus RTU0 COM Timeout, factory default 4 = trip after 3000 ms)" # Status word bit 1, "Stop / Running operation message (RUN)" (printed p. 31). [running_check] register = 5 bit = 1 # Table 19 (printed p. 52) register 141 = P-13 "Last fault", ro, U16, and # MN04020004Z printed p. 36 confirms P-13 "Last fault / last fault", DS 0. # # INFERENCE, STATED PLAINLY: Eaton publishes exactly one numeric fault table # for these drives — Table 11, printed pp. 32-33 — and documents it as the # decode for the FAULT WORD in bits 8-15 of ID 6. It does not restate that # P-13 uses the same numbering. Using Table 11 numbers against P-13 is the # obvious reading and is what this profile does, but it is not something the # manual says in one sentence. # BENCH CROSS-CHECK, ONE FAULT: force any trip, then read address 140 and # address 5 together. Table 11 holds if (register 5 >> 8) == register 140. # If they disagree, the fault word is authoritative and this register is # wrong — core's `mask` is an AND with no shift, so it cannot pull the high # byte out of address 5 on its own, and that case needs a code change rather # than a profile edit. [faults] register = 140 # MN040018EN Table 11, printed pp. 32-33, decimal column. # ONLY the rows whose "Device series" column names a bare "DC1" are here. # Excluded on purpose, with reasons: # 15 "h O-I" tagged DA1, DE1 — not DC1 # 19, 21, 22, 23, 26, 40-44, 49, 50, 51 tagged "DA1, DC1…E1" — the # enhanced variant this profile does not claim # 20, 24, 25, 29-35, 52, 53, 60, 61, 70-74 tagged DA1 only # A DC1 that trips one of the excluded codes will read "unknown code" here. # That is the intended failure: an unnamed fault is recoverable, a # confidently mislabelled one sends someone to the wrong terminal. # # The manual's own hex column is unreliable and is why the decimal column was # used — it prints 16 as "0A" (0A is already 10) and 19 as "12" (12 is already # 18). The decimal column is self-consistent. [faults.codes] 0 = "no-Flt - no fault logged" 1 = "OI-b - excessively high braking current" 2 = "OL-br - thermal overload on braking resistor" 3 = "O-I - overcurrent at drive output" 4 = "I.t-trP - motor overload" 5 = "PS-trp - overcurrent (hardware)" 6 = "O.Volt - overvoltage in DC link" 7 = "VVolt - undervoltage in DC link" 8 = "O-t - overtemperature at heat sink" 9 = "V-t - under-temperature" 10 = "P-dEf - parameter default settings have been loaded" 11 = "E-trip - external fault/warning" 12 = "SC-ObS - communication error with external operating unit or PC" 13 = "FlT-dc - excessively high DC link voltage ripple" 14 = "P-LOss - incoming power phase failure (three-phase units)" 16 = "Th-flt - malfunctioning heat sink thermistor" 17 = "dAtA-F - error in internal memory" 18 = "4-20 F - analog input current outside the specified range" # ID 12 "Type", the drive's part number as four hex nibbles (printed p. 37): # nibble 3 frame size 1 = FS1, 2 = FS2, 3 = FS3, 4 = FS4 # nibble 2 voltage class 0 = 115 V, 1 = 230 V, 2 = 230 V, 3 = 400 V # nibble 1 input/output phases and kW-vs-HP country setting (Table 14) # nibble 0 output index into the ratings table (Table 15) # Not a scaled number — comparing it between two drives is the point. Two DC1s # with the same type code are the same frame, voltage class and rating, which # is exactly the precondition a config clone needs. Read it as hex. [rating] register = 11 label = "DC1 type code (hex: frame size / voltage class / phases / output index)" # Table 19, printed pp. 52-53: the DC1 parameter block is Modbus registers # 129 (P-01) through 183 (P-55), i.e. addresses 128-182. Two holes, both # deliberate: # # address 140 (register 141, P-13 "Last fault") is READ-ONLY. Including it # would put a fault number in the backup file and NAK on every restore. # # address 163 (register 164, P-36) packs the RS485 slave address, the baud # rate and the Modbus timeout into ONE word. Restoring it would rewrite the # target drive's own node address partway through the restore and drop the # connection that was performing it — and a replacement drive needs its own # address anyway. Set it by hand on the keypad. # # §2.6.3 (printed p. 28) gives the DC1 parameter group as "129 - 197", but # Table 19 only documents through 183. The undocumented tail 184-197 is left # out: a clone that writes registers no manual describes is how a # commissioning tool bricks a drive. [parameters] ranges = [[128, 139], [141, 162], [164, 182]]