I recently purchased a new Zoncn NZ100 Variable Frequency Drive to drive a three phase motor used on a CNC. My intention is to integrate it into the controller that controls the CNC over Modbus, which the VFD supports using RS-485.
However, to communicate with it, one must know the registers of the VFD. This isn’t outlined, or even mentioned, in its manual.
Luckily, there are other VFDs which have documented their protocols better, for instance the SKI-780, Salicru CV-50, GS20 and NZ100’s big brother Z2000. The NZ100 implements the Modbus interface as a bit of a mix. Not quite like the Z2000, which surprised me. I thought I had it when I found its manual. However, when I commanded it to start by setting register 0x2000 to 1 as documented on p.176 in the Z2000 manual, nothing happened. The VFD didn’t do anything if I set 0x1000 to a percentage of the desired maximum speed and starting it from the VFD’s control panel, either.
I started looking at the available Modbus documentation for similar VFDs. I tried writing to registers suggested by the documentation of those. All these documents gave me enough hints to be able to figure out how the NZ100 is controlled. Here’s my findings:
The desired output frequency is set in units of 1/10 Hz (instead of 1/100 Hz as is customary) in register 0x2001. An output frequency of 50.0Hz is thus written as 500. The VFD will limit the output frequency according to the values set in parameter P105 (max frequency) and P106 (min frequency).
On the topic of the documented parameters Pxxx: Parameter P105 is available at register address 0xF105. The register P212 is located at 0xF20C. The entire set of parameters outlined in the manual is located according to this pattern. To write a new value without persisting it to the unit’s EEPROM i.e. writing it to RAM, change the F into a 0. Note that reads are invalid at this address. It may be desirable to write to RAM instead of EEPROM, as the write cycles on the EEPROM is limited.
In practice, register 0x2000 and 0x2001 are used to control the frequency and operation of the drive, according to the following table:
Register address | Purpose | Unit |
0x2000 | Operation mode Bit 0-1 00: no function 01: Stop 10: Run 11: Jog+Run Bit 2-3 Reserved Bit 4-5 00: no function 01: FWD 10: REV 11: no function In practice: 0x0001 STOP 0x0022 Run Reverse 0x0012 Run Forward This register is “edge triggered” meaning that in order to stop the drive, you must send a value setting the Stop bit. It’s not enough to clear the Run bit. | N/A |
0x2001 | Desired output frequency | 0.1 Hz |
Example conversations
Modbus RTU frame format is quite straight-forward. It’s a multi-drop bus, so there’s one client device that initiates communication and one or more servers that each carry a unique address and responds to the requests. In this example, the VFD acts as a Modbus Server on address 1.
The first byte of each frame is the destination address. The second byte is a function code. These VFDs only implements the Modbus function code 3: read holding register and function code 6: write holding register. As a proprietary addition, a temporary write i.e. write to RAM can be performed by issuing a write request using function code 7.
Read P215 Rated Motor Frequency
Part of Data Package | Description | Value |
01 | Slave address | 0x01 (1) |
03 | Function code | 0x03 (3) – Read Holding Registers |
F2 0F | Starting address | Physical: 0xF20F (61967) Logical: 0xF210 (61968) |
00 01 | Quantity | 0x0001 (1) |
86 B1 | CRC | 0x86B1 (34481) |
Part of Data Package | Description | Value |
01 | Slave address | 0x01 (1) |
03 | Function code | 0x03 (3) – Read Holding Registers |
02 | Byte count | 0x02 (2) |
01 F4 | Register value | 0x01F4 (500) |
B8 53 | CRC | 0xB853 (47187) |
Read P212 Rated RPM @ Rated Motor Frequency
Together with P215, P212 helps us figure out what RPM a specific frequency results in. By dividing P212 with P215 (in Hz), we get the number of RPMs for each Hz. My spindle outputs 3000 RPM @ 50.0Hz, which translates to 60RPM/Hz. At the spindle’s maximum frequency, 400Hz, it rotates at 60*400 = 24000 RPM.
Part of Data Package | Description | Value |
01 | Slave address | 0x01 (1) |
03 | Function code | 0x03 (3) – Read Holding Registers |
F2 0C | Starting address | Physical: 0xF20C (61964) Logical: 0xF20D (61965) |
00 01 | Quantity | 0x0001 (1) |
76 B1 | CRC | 0x76B1 (30385) |
Part of Data Package | Description | Value |
01 | Slave address | 0x01 (1) |
03 | Function code | 0x03 (3) – Read Holding Registers |
02 | Byte count | 0x02 (2) |
0B B8 | Register value | 0x0BB8 (3000) |
BF 06 | CRC | 0xBF06 (48902) |
Read P105 Maximum Frequency
Part of Data Package | Description | Value |
01 | Slave address | 0x01 (1) |
03 | Function code | 0x03 (3) – Read Holding Registers |
F1 05 | Starting address | Physical: 0xF105 (61701) Logical: 0xF106 (61702) |
00 01 | Quantity | 0x0001 (1) |
A6 F7 | CRC | 0xA6F7 (42743) |
Part of Data Package | Description | Value |
01 | Slave address | 0x01 (1) |
03 | Function code | 0x03 (3) – Read Holding Registers |
02 | Byte count | 0x02 (2) |
0F A0 | Register value | 0x0FA0 (4000) |
BD CC | CRC | 0xBDCC (48588) |
Read P106 Minimum Frequency
Part of Data Package | Description | Value |
01 | Slave address | 0x01 (1) |
03 | Function code | 0x03 (3) – Read Holding Registers |
F1 06 | Starting address | Physical: 0xF106 (61702) Logical: 0xF107 (61703) |
00 01 | Quantity | 0x0001 (1) |
56 F7 | CRC | 0x56F7 (22263) |
Part of Data Package | Description | Value |
01 | Slave address | 0x01 (1) |
03 | Function code | 0x03 (3) – Read Holding Registers |
02 | Byte count | 0x02 (2) |
03 E8 | Register value | 0x03E8 (1000) |
B8 FA | CRC | 0xB8FA (47354) |
Read 0x3000 (status)
Part of Data Package | Description | Value |
01 | Slave address | 0x01 (1) |
03 | Function code | 0x03 (3) – Read Holding Registers |
30 00 | Starting address | Physical: 0x3000 (12288) Logical: 0x3001 (12289) |
00 01 | Quantity | 0x0001 (1) |
8B 0A | CRC | 0x8B0A (35594) |
Unconfirmed, but following the Z2000’s description of the status register: 1 – Running (Forward), 2 – Running (Reverse), 3 – Stopped
Part of Data Package | Description | Value |
01 | Slave address | 0x01 (1) |
03 | Function code | 0x03 (3) – Read Holding Registers |
02 | Byte count | 0x02 (2) |
00 03 | Register value | 0x0003 (3) |
F8 45 | CRC | 0xF845 (63557) |
Read 0x2000 – Desired Output Frequency
Part of Data Package | Description | Value |
01 | Slave address | 0x01 (1) |
03 | Function code | 0x03 (3) – Read Holding Registers |
20 01 | Starting address | Physical: 0x2001 (8193) Logical: 0x2002 (8194) |
00 01 | Quantity | 0x0001 (1) |
DE 0A | CRC | 0xDE0A (56842) |
Part of Data Package | Description | Value |
01 | Slave address | 0x01 (1) |
03 | Function code | 0x03 (3) – Read Holding Registers |
02 | Byte count | 0x02 (2) |
0F A0 | Register value | 0x0FA0 (4000) |
BD CC | CRC | 0xBDCC (48588) |
Write 0x2000 Operating Mode
Part of Data Package | Description | Value |
01 | Slave address | 0x01 (1) |
06 | Function code | 0x06 (6) – Write Single Register |
20 00 | Register address | Physical: 0x2000 (8192) Logical: 0x2001 (8193) |
00 01 | Register value | 0x0001 (1) |
43 CA | CRC | 0x43CA (17354) |
Part of Data Package | Description | Value |
01 | Slave address | 0x01 (1) |
06 | Function code | 0x06 (6) – Write Single Register |
20 00 | Register address | Physical: 0x2000 (8192) Logical: 0x2001 (8193) |
00 01 | Register value | 0x0001 (1) |
43 CA | CRC | 0x43CA (17354) |
Write 0x2001 Desired Output Frequency
This message tells the VFD that the desired output frequency is 150Hz. At 60RPM/Hz, that is 9000 RPM.
Part of Data Package | Description | Value |
01 | Slave address | 0x01 (1) |
06 | Function code | 0x06 (6) – Write Single Register |
20 01 | Register address | Physical: 0x2001 (8193) Logical: 0x2002 (8194) |
05 DC | Register value | 0x05DC (1500) |
D1 03 | CRC | 0xD103 (53507) |
The VFD confirms by echoing the write request.
Part of Data Package | Description | Value |
01 | Slave address | 0x01 (1) |
06 | Function code | 0x06 (6) – Write Single Register |
20 01 | Register address | Physical: 0x2001 (8193) Logical: 0x2002 (8194) |
05 DC | Register value | 0x05DC (1500) |
D1 03 | CRC | 0xD103 (53507) |
Write 0x2000 Operating Mode
This is the write that starts the spindle. As outlined above, the written value 0x0012 tells the VFD it should Run Clockwise.
Part of Data Package | Description | Value |
01 | Slave address | 0x01 (1) |
06 | Function code | 0x06 (6) – Write Single Register |
20 00 | Register address | Physical: 0x2000 (8192) Logical: 0x2001 (8193) |
00 12 | Register value | 0x0012 (18) |
02 07 | CRC | 0x0207 (519) |
The VFD confirms by echoing the write request.
Part of Data Package | Description | Value |
01 | Slave address | 0x01 (1) |
06 | Function code | 0x06 (6) – Write Single Register |
20 00 | Register address | Physical: 0x2000 (8192) Logical: 0x2001 (8193) |
00 12 | Register value | 0x0012 (18) |
02 07 | CRC | 0x0207 (519) |