# Vevor D100 VFD - Modbus RTU Reverse Engineering Notes

## Hardware

* VFD: Vevor D100
* Interface: RS485
* Connection: USB-RS485 adapter
* LinuxCNC version: 2.9.8

## Communication Settings

Configured on VFD:

| Parameter     | Value      |
| ------------- | ---------- |
| Slave Address | 1          |
| Baud Rate     | 9600       |
| Data Bits     | 8          |
| Parity        | None       |
| Stop Bits     | 1          |
| Protocol      | Modbus RTU |

---

# Addressing

The VFD documentation uses hexadecimal Modbus addresses.

Practical testing with `mbpoll` showed that mbpoll uses addresses shifted by +1 relative to the addresses shown in the manual.

Formula:

```text
mbpoll_address = documented_hex_address + 1
```

Examples:

| Documentation | Hex | mbpoll |
| ------------- | --- | ------ |
| 0200H         | 512 | 513    |
| 0201H         | 513 | 514    |
| 0210H         | 528 | 529    |
| 0220H         | 544 | 545    |
| 0221H         | 545 | 546    |
| 0222H         | 546 | 547    |
| 0223H         | 547 | 548    |

---

# Frequency Command

Parameter:

```text
0201H = Given Frequency
```

mbpoll address:

```text
514
```

Manual example:

```text
01 06 02 01 0B B8
```

which means:

```text
3000 decimal = 300.0 Hz
```

---

## F169

Parameter:

```text
F169 = Given decimal point of communication frequency
```

Configured value:

```text
F169 = 0
```

Meaning:

```text
0201 = frequency * 10
```

Examples:

| Frequency | Register Value |
| --------- | -------------- |
| 10.0 Hz   | 100            |
| 25.0 Hz   | 250            |
| 50.0 Hz   | 500            |
| 100.0 Hz  | 1000           |
| 300.0 Hz  | 3000           |

---

# Verified Read Registers

## 0210H - Main Control Status

mbpoll:

```text
529
```

Documentation:

```text
0210H
Main control bit
BIT0-BIT15 mapping parameter address 0000H-000FH
```

Verified values:

### Stopped

```text
0210 = 0
```

Binary:

```text
0000 0000 0000 0000
```

### Running Forward

```text
0210 = 9
```

Binary:

```text
0000 0000 0000 1001
```

Meaning:

```text
BIT0 = Operation
BIT3 = In operation
```

### Running Reverse

```text
0210 = 13
```

Binary:

```text
0000 0000 0000 1101
```

Meaning:

```text
BIT0 = Operation
BIT2 = Reverse
BIT3 = In operation
```

### Stopped After Reverse

```text
0210 = 4
```

Binary:

```text
0000 0000 0000 0100
```

Meaning:

```text
BIT2 = Reverse selected
```

---

## 0220H Block

mbpoll start address:

```text
545
```

Read command:

```bash
mbpoll -m rtu -a 1 -b 9600 -P none -t 4 -r 545 -c 4 /dev/ttyUSB0
```

Mapping:

| Address | Function         |
| ------- | ---------------- |
| 0220H   | Output Frequency |
| 0221H   | Set Frequency    |
| 0222H   | Output Current   |
| 0223H   | Output Speed     |

mbpoll:

| Address | Register         |
| ------- | ---------------- |
| 545     | Output Frequency |
| 546     | Set Frequency    |
| 547     | Output Current   |
| 548     | Output Speed     |

Verified example while running:

| Register | Value |
| -------- | ----- |
| 545      | 1266  |
| 546      | 1267  |
| 547      | 214   |
| 548      | 7602  |

Interpreted as:

| Parameter        | Value    |
| ---------------- | -------- |
| Output Frequency | 126.6 Hz |
| Set Frequency    | 126.7 Hz |
| Output Current   | 21.4 A   |
| Output Speed     | 7602 RPM |

---

# 0200H Main Control Register

Documentation:

```text
0200H Main control bit
BIT0-BIT7 mapping parameter address 0048H-004FH
```

Bit mapping:

| Coil | Name                   | Bit  | Decimal |
| ---- | ---------------------- | ---- | ------- |
| 0048 | Operation              | BIT0 | 1       |
| 0049 | Forward                | BIT1 | 2       |
| 004A | Reverse                | BIT2 | 4       |
| 004B | Stop                   | BIT3 | 8       |
| 004C | Forward/Reverse Switch | BIT4 | 16      |
| 004D | JOG                    | BIT5 | 32      |
| 004E | JOG Forward            | BIT6 | 64      |
| 004F | JOG Reverse            | BIT7 | 128     |

---

# Verified Control Commands

Control register:

```text
0200H
```

mbpoll address:

```text
513
```

---

## Forward Run

Command:

```bash
mbpoll -m rtu -a 1 -b 9600 -P none -t 4 -r 513 /dev/ttyUSB0 2
```

Writes:

```text
0200 = 2
```

Result:

```text
Forward Run
```

---

## Reverse Run

Command:

```bash
mbpoll -m rtu -a 1 -b 9600 -P none -t 4 -r 513 /dev/ttyUSB0 4
```

Writes:

```text
0200 = 4
```

Result:

```text
Reverse Run
```

---

## Stop

Command:

```bash
mbpoll -m rtu -a 1 -b 9600 -P none -t 4 -r 513 /dev/ttyUSB0 8
```

Writes:

```text
0200 = 8
```

Result:

```text
Stop
```

---

## Toggle Direction

Command:

```bash
mbpoll -m rtu -a 1 -b 9600 -P none -t 4 -r 513 /dev/ttyUSB0 16
```

Writes:

```text
0200 = 16
```

Result:

```text
Toggle Direction
```

Important:

The toggle works only on a rising edge.

To trigger it again:

```text
0200 = 0
0200 = 16
```

must be sent.

---

# LinuxCNC Relevant Registers

## Write

| Function        | Documented | mbpoll |
| --------------- | ---------- | ------ |
| Main Control    | 0200H      | 513    |
| Given Frequency | 0201H      | 514    |

## Read

| Function         | Documented | mbpoll |
| ---------------- | ---------- | ------ |
| Status           | 0210H      | 529    |
| Output Frequency | 0220H      | 545    |
| Set Frequency    | 0221H      | 546    |
| Output Current   | 0222H      | 547    |
| Output Speed     | 0223H      | 548    |

---

# RapidChange ATC Notes

Useful registers for future ATC implementation:

## Current

```text
0222H
```

Can potentially be used to detect:

```text
tool tightening
tool loosening
stall condition
```

based on current increase.

## Status

```text
0210H
```

Can be used instead of fixed delays.

Example:

Wait until:

```text
BIT3 = 0
```

before moving after spindle stop.

This is more reliable than:

```text
G4 P2
```

fixed delay logic.

---

# Known Issues

RS485 communication becomes less reliable when spindle is running.

Observed:

```text
Timeouts
CRC errors
Dropped frames
```

Likely causes:

* EMI from spindle motor cables
* insufficient cable separation
* missing shield grounding
* missing termination resistor

Communication is stable when spindle is stopped.
