# 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.