# Property of PMA Electrical Solutions, LLC. # # Danfoss VLT 2800 (VLT 2803-2882). Claims the VLT 2800 only — MG10S202 also # covers the VLT 6000 HVAC and VLT 8000 AQUA, but those are separate profiles # because their readout PARAMETER NUMBERS and status-word layout differ. # # Sources (printed page numbers, not PDF page index): # MG10S202 VLT 2800 / VLT 6000 HVAC / VLT 8000 AQUA Modbus RTU Operating # Instructions (software 2.8x for the 2800) # pp. 10-11 par 500/501/502/570/571 Modbus setup and defaults # p. 16 "Parameter Handling" — the PNU -> register rule and # the conversion-index table # p. 17 Register Maps VLT 2800, and the "shown value - 1" # note that pins the 0-based wire address # p. 20 Process Data / Status Coil Maps # pp. 20-21 Control Word bit descriptions, VLT 2800 # pp. 21-22 Status Word bit descriptions, VLT 2800 # pp. 28-30 supported function codes (01/03/05/06/0F/10) # pp. 32-34 Appendix A worked examples, incl. "the starting # address of a register is the parameter number x 10 - 1" # MG27E402 VLT 2800 Design Guide, Rev. May/2014 # pp. 121-122 parameters 515-544 Data readout, what each returns # p. 140 Tables 5.10/5.12 warning-word and alarm-word bits # p. 151 data-type legend (3=Int16 4=Int32 5=Uint8 # 6=Uint16 7=Uint32) and conversion-index legend # p. 153 Table 5.23 factory settings 500-544 — the per # parameter WIDTH and conversion index used below # # FIELDBUS: Modbus RTU is a firmware protocol on the built-in RS485 port, not # an option card. Drive-side setup, all from MG10S202 p. 10 unless noted: # par 561 Protocol = [3] MODBUS RTU (default is [1] FC protocol) # par 500 Address = 1-247 for Modbus (default 1; LCP only, not settable # over the bus) # par 501 Baudrate = default [5] 9600 Baud (LCP only) # par 570 Parity/framing, par 571 Modbus timeout (default 100 ms) # par 512 Telegram Profile must be FC PROFILE # NOTE the VLT 2800 numbers these differently from the VLT 6000/8000 in the # same manual, where 500 is Protocol and 501 is Address. MG10S202's own value # table for par 500 still carries the 6000/8000 wording ("Parameter 500 # Protocol = ..."); the heading and MG27E402 p. 153 agree that on the 2800, # 500 is Address and 561 is Protocol. # # ADDRESSING: register = parameter_number * 10 - 1. MG10S202 p. 16 states # "The parameter number is translated to Modbus as (10 x parameter number) # DECIMAL", p. 17 adds "the Holding Register number shown must be transmitted # as (shown value - 1)", and the Appendix A Example 4 pins it: par 104 -> # holding register 1040 -> wire address 0x040F = 1039. So par 534 Status word # -> 534 * 10 - 1 = 5339. These are THREE-DIGIT parameter numbers (534, not # 16-03); the FC 100/300 group notation does not apply to this drive. # # WIDTH IS PER PARAMETER — see `words` on each point, taken from the Data type # column of MG27E402 Table 5.23 p. 153. Reading a 16-bit parameter as 2 # registers splices in the neighbouring parameter. # # CONTROL IS DELIBERATELY ABSENT. On this generation the process data is NOT # in the holding-register space. MG10S202 p. 20 maps it to COILS: # coils 1-16 PCD1 control word (master -> slave, function 05 / 0F) # coils 17-32 PCD2 reference (0x4000 = 100% of par 204-205) # coils 33-48 PCD1 status word (slave -> master, function 01) # coils 49-64 PCD2 output frequency # coil 65 write parameters to EEPROM # and Appendix A Example 1 "Start Motor, Run Speed 40%" is a function 0F Force # Multiple Coils write of 0x047C + 0x1999 to coils 0-31. The holding-register # map on p. 17 is parameters only; everything outside the documented parameter # blocks is listed "Reserved", and no CTW/REF register block (the FC family's # 50000/50010) exists on this drive. This schema writes holding registers, not # coils, so the profile ships monitor-only rather than guess a register. # The bit meanings ARE confirmed for this drive (MG10S202 pp. 20-21) if coil # support is ever added: stop 0x043C, start 0x047C, reset = rising edge of # bit 07 then back to 0x043C. # # REVERSE, if control is ever added: control word bit 15 reverses only when # par 506 Reversing routes reversing to serial communication. MG10S202 p. 21 # says the factory setting is digital; MG27E402 p. 153 lists the default as # Logic or. The two primary books DISAGREE, so treat a bus reverse as capable # of silently running the motor FORWARD until settled on the bench. Direction # can also be commanded by a NEGATIVE reference (2's complement, MG10S202 # p. 23) — that path is unaffected by par 506. # # WATCHDOG: par 513 Bus time interval defaults to 1 s but par 514 Bus time # interval function defaults to [0] Off (MG27E402 p. 120), so a running drive # that loses its master keeps running. Set 514 = [2] Stop or [5] Stop and trip # if you need a comm-loss stop. No [control.watchdog] here because there is no # [control] to keep alive. # # UNRESOLVED CONFLICT, read before trusting the numbers below: MG27E402 p. 121 # says of parameters 515-544 "These parameters can be read out via the serial # communication port and the LCP display", and MG10S202 p. 17 maps 05150-05440 # into the holding-register space. But a NOTICE on MG27E402 p. 122 states # "Parameters 515-541 can only be read out via an LCP control unit." Two # statements against one, and the dedicated Modbus manual is the more specific # authority, so the readouts are mapped here — but probe_register is # deliberately the status word so that a drive which refuses them fails the # probe loudly instead of showing empty gauges. name = "Danfoss VLT 2800" vendor = "Danfoss" device_type = "vfd" verified = false probe_register = 5339 # par 534 Status word [connection] summary = "Connect to the VLT 2800's built-in two-wire RS-485 terminals 68/69." warnings = ["Isolate mains and verify the DC link is discharged before opening the drive.", "Use shielded twisted pair and route it away from motor and power conductors."] [[connection.methods]] id = "built_in_rs485" title = "Built-in RS-485 (68/69)" transport = "serial" hardware = "built_in" port = "Terminals 68 (P+), 69 (N-), optional terminal 61 reference/screen" connector = "Control terminal strip" adapter = "Isolated USB-to-RS-485 adapter" cable = "Shielded RS-485 twisted pair" parts = ["Small insulated screwdriver", "120 ohm termination at bus endpoints"] wiring = [{ adapter = "D+ / B+", device = "68 (P+)", signal = "RS-485 positive" }, { adapter = "D- / A-", device = "69 (N-)", signal = "RS-485 negative" }, { adapter = "COM/GND", device = "61", signal = "Optional reference/screen", required = false }] steps = ["De-energize the drive and locate terminals 68 and 69.", "Wire the pair positive-to-68 and negative-to-69; use terminal 61 only if the installation needs the reference/screen path.", "Terminate only at physical bus ends and close the drive before restoring power.", "Connect and select the USB-to-RS-485 serial port."] setup = ["Set parameter 561 Protocol = 3 Modbus RTU, parameter 500 Address, 501 Baudrate, 570 framing, and 571 timeout.", "Keep parameter 512 Telegram Profile at FC PROFILE."] warnings = ["VLT 2800 uses parameter 561 for protocol; do not copy the VLT 6000/8000 parameter numbering.", "This profile is monitor-only because process control is documented as coils, not holding registers."] source = "Danfoss MG10S202, pp. 9-10; MG27E402, p. 153" # MG27E402 p. 153: par 501 Baudrate default 9600 Baud. # MG10S202 p. 11: par 570 Modbus parity and message framing default is # [2] NO PARITY / 1 STOPBIT — NOT the 8E1 the FC 100/300 platform ships. [serial] baudrate = 9600 parity = "N" stopbits = 1 [monitor] # --- 16-bit parameters (words = 1) --- reference_pct = { address = 5149, signed = true, scale = 0.1, unit = "%" } # 515 Int16, conv -1 output_frequency = { address = 5179, signed = true, scale = 0.1, unit = "Hz" } # 518 Int16, conv -1 torque_pct = { address = 5209, signed = true, scale = 0.1, unit = "%" } # 521 Int16, conv -1 motor_voltage = { address = 5239, scale = 0.1, unit = "V" } # 524 Uint16, conv -1 dc_link_voltage = { address = 5249, unit = "V" } # 525 Uint16, conv 0 motor_thermal = { address = 5259, unit = "%" } # 526 Uint8 inverter_thermal = { address = 5269, unit = "%" } # 527 Uint8 external_reference_pct = { address = 5329, scale = 0.1, unit = "%" } # 533 Uint16, conv -1 # par 534 Status word, Uint16. Polarity is read off the Bit=0/Bit=1 columns of # MG10S202 pp. 21-22, not inferred from the names: bit 2 = 1 means the drive # CAN start (0 = it has released the motor), and bit 10 = 1 means the output # frequency is WITHIN par 201/202 (0 = outside). Bits 4, 5 and 12 are unused. status_word = { address = 5339, bits = { 0 = "CtrlReady", 1 = "DriveReady", 2 = "NotCoasting", 3 = "Trip", 6 = "TripLock", 7 = "Warning", 8 = "SpeedEqRef", 9 = "BusControl", 10 = "WithinFreqLimits", 11 = "Running", 13 = "VoltageWarn", 14 = "CurrentLimit", 15 = "ThermalWarn" } } inverter_temp = { address = 5369, unit = "C" } # 537 Uint8 control_word = { address = 5389 } # 539 Uint16 # --- 32-bit parameters (words = 2) --- motor_current = { address = 5199, words = 2, scale = 0.01, unit = "A" } # 520 Uint32, conv -2 power_hp = { address = 5229, words = 2, scale = 0.01, unit = "HP" } # 523 Uint32, conv -2 # par 522 Power [kW] is deliberately absent. MG27E402 p. 153 gives it # conversion index 1 (factor 10), which against a "kW" unit would make a # 0.75 kW drive read as a fraction of a count. The HP readout above has an # unambiguous index (-2) and covers the same measurement, so rather than pick # a scale the manual does not support, this point is left out. [running_check] register = 5339 # par 534 status word, 16-bit bit = 11 # "Motor running" # par 538 Alarm word is a 32-bit BITFIELD, not an enum: several bits can be set # at once, so there is no code table to look up. Bits are from MG27E402 p. 140 # Table 5.12, converted from the hex column (hex 000040 -> bit 6). These names # are the VLT 2800's own and are NOT the FC 202's — bit 6 is the HPFB bus # timeout here, and bits 0, 5, 12, 21-24, 26, 29-31 are unassigned. # # par 540 Warning word is NOT included: despite the similar name its layout # (MG27E402 p. 140 Table 5.10) diverges from the alarm word at nearly every # bit — bit 6 is "current limit" as a warning but "HPFB bus timeout" as an # alarm, bit 10 is "undervolt" vs "earth fault" — so decoding it with these # names would mislabel almost all of it. [faults] register = 5379 # par 538 alarm word words = 2 bitfield = true bits = { 1 = "TripLock", 2 = "AMT_TuningFail", 6 = "HPFB_BusTimeout", 7 = "StdBusTimeout", 8 = "CurrentShortCircuit", 9 = "SwitchModeFault", 10 = "EarthFault", 11 = "OverCurrent", 13 = "MotorThermistor", 14 = "MotorOverload", 15 = "InverterOverload", 16 = "UnderVoltage", 17 = "OverVoltage", 18 = "PhaseLoss", 19 = "LiveZeroError", 20 = "HeatsinkOverTemp", 25 = "ProfibusCommFault", 27 = "InrushFault", 28 = "InternalFault" }