diff --git a/hal_configuration.md b/hal_configuration.md new file mode 100644 index 0000000..6b3d3b2 --- /dev/null +++ b/hal_configuration.md @@ -0,0 +1,118 @@ +# LinuxCNC HAL Configuration for Vevor D100 VFD via mb2hal + +This guide explains how to connect the HAL pins of LinuxCNC to the `mb2hal` component configured in [vfd_d100.ini](file:///home/bartool/local_projects/linuxcnc-modbus/vfd_d100.ini). + +## 1. Required Components + +To achieve correct speed scaling, rotation control, feedback conversion, and "at-speed" detection, we will load the following standard HAL components: +* **`scale`**: Used twice. + 1. `spindle_speed_scale`: Converts commanded RPM (e.g., 24000 RPM) to Modbus frequency units (tenths of Hz, 400.0 Hz = 4000). + 2. `spindle_feedback_scale`: Converts actual speed from RPM (from VFD metrics) to RPS (Revolutions Per Second) required by LinuxCNC. +* **`mux2`**: Used twice. + 1. `spindle_dir_mux`: Selects between `2.0` (Forward) and `4.0` (Reverse). + 2. `spindle_run_mux`: Selects between `8.0` (Stop) and the output of `spindle_dir_mux`. +* **`near`**: Compares commanded speed and actual speed to assert `spindle.0.at-speed`. + +--- + +## 2. Speed Scaling Calculations + +The VFD expects the given frequency in tenths of Hz (e.g., $400.0 \text{ Hz} = 4000$ in register `0201H`). +The motor has a maximum speed of $24000 \text{ RPM}$ at $400 \text{ Hz}$. + +* **Commanded Speed Gain:** + $$Gain = \frac{4000 \text{ (Modbus Units)}}{24000 \text{ (RPM)}} = \frac{1}{6} \approx 0.16666667$$ + +* **Feedback Speed Gain (RPM to RPS):** + $$Gain = \frac{1}{60} \approx 0.01666667$$ + +--- + +## 3. HAL Configuration Snippet + +Add the following lines to your main `.hal` file (e.g. `custom.hal` or `postgui.hal` depending on your setup): + +```hal +# ===================================================================== +# Vevor D100 VFD Modbus (mb2hal) Integration +# ===================================================================== + +# Load the mb2hal component +loadusr -W mb2hal config=vfd_d100.ini + +# Load helper components +loadrt scale names=spindle_speed_scale,spindle_feedback_scale +loadrt mux2 names=spindle_dir_mux,spindle_run_mux +loadrt near names=spindle_at_speed_near + +# Add helper components to the servo thread +addf spindle_speed_scale servo-thread +addf spindle_feedback_scale servo-thread +addf spindle_dir_mux servo-thread +addf spindle_run_mux servo-thread +addf spindle_at_speed_near servo-thread + +# ===================================================================== +# 1. Spindle Run & Direction Logic +# ===================================================================== + +# Direction Mux Input Values: 2.0 = Forward Run, 4.0 = Reverse Run +setp spindle_dir_mux.in0 2.0 +setp spindle_dir_mux.in1 4.0 + +# Run Mux Input Values: 8.0 = Stop, in1 = value from direction mux +setp spindle_run_mux.in0 8.0 + +# Connect selection signals +net spindle-rev-sig spindle.0.reverse => spindle_dir_mux.sel +net spindle-dir-cmd spindle_dir_mux.out => spindle_run_mux.in1 + +net spindle-on-sig spindle.0.on => spindle_run_mux.sel +net spindle-run-cmd spindle_run_mux.out => vfd.control.00.float + +# ===================================================================== +# 2. Spindle Commanded Speed Scaling +# ===================================================================== + +# Gain = 4000 / 24000 = 0.16666667 +setp spindle_speed_scale.gain 0.16666667 +setp spindle_speed_scale.offset 0.0 + +# Connect signals +net spindle-speed-cmd spindle.0.speed-out-abs => spindle_speed_scale.in +net spindle-speed-scaled spindle_speed_scale.out => vfd.speed.00.float + +# ===================================================================== +# 3. Spindle Speed Feedback (RPM to RPS) +# ===================================================================== + +# Gain = 1 / 60 = 0.01666667 (converts RPM to RPS) +setp spindle_feedback_scale.gain 0.01666667 +setp spindle_feedback_scale.offset 0.0 + +# Connect signals +net spindle-rpm-feedback vfd.metrics.rpm.float => spindle_feedback_scale.in +net spindle-rps-feedback spindle_feedback_scale.out => spindle.0.speed-in + +# ===================================================================== +# 4. Spindle "At Speed" Detection +# ===================================================================== + +# Configure allowable difference (e.g., within 5% or 300 RPM) +setp spindle_at_speed_near.difference 300.0 +# We want the speed to be compared on the absolute commanded speed (RPM) +net spindle-speed-cmd => spindle_at_speed_near.in1 +net spindle-rpm-feedback => spindle_at_speed_near.in2 +net spindle-at-speed spindle_at_speed_near.out => spindle.0.at-speed +``` + +--- + +## 4. Troubleshooting & Tuning Tips + +> [!TIP] +> **Modbus Communication Stability** +> If you experience CRC errors or timeouts when the spindle motor starts spinning, it is likely due to Electro-Magnetic Interference (EMI). +> * Ensure your RS485 twisted-pair cable is shielded, and the shield is grounded **only at one end** (usually at the VFD or controller side, not both). +> * Add a $120\ \Omega$ termination resistor across the RX+/TX+ and RX-/TX- terminals at the VFD if it's at the end of the bus. +> * If the VFD takes too long to process requests, you can increase `SERIAL_DELAY_MS` in [vfd_d100.ini](file:///home/bartool/local_projects/linuxcnc-modbus/vfd_d100.ini) to `70` or `100`. diff --git a/vfd_d100.ini b/vfd_d100.ini new file mode 100644 index 0000000..510adc1 --- /dev/null +++ b/vfd_d100.ini @@ -0,0 +1,88 @@ +# Configuration file for mb2hal to communicate with Vevor D100 VFD +# via Modbus RTU (RS485) +# +# Load component using: +# loadusr -W mb2hal config=vfd_d100.ini + +[MB2HAL_INIT] + +# Debug level: 0 = silent, 1 = errors, 2 = OK messages, 3 = debugging, 4 = max debug +INIT_DEBUG=3 + +# Set to 1.1 to enable float/int pin options and specific features +VERSION=1.1 + +# HAL module (component) name. Pins will be prefixed with this name. +HAL_MODULE_NAME=vfd + +# Delay between transactions in seconds (use 0.0 for normal speed) +SLOWDOWN=0.0 + +# Number of transactions defined below +TOTAL_TRANSACTIONS=4 + + +# ===================================================================== +# TRANSACTION 00: Write Main Control Register (0200H / 512 dec) +# ===================================================================== +[TRANSACTION_00] +LINK_TYPE=serial +SERIAL_PORT=/dev/ttyUSB0 +SERIAL_BAUD=9600 +SERIAL_BITS=8 +SERIAL_PARITY=none +SERIAL_STOP=1 +# Delay after transmission in ms (helps with VFD response processing and EMI) +SERIAL_DELAY_MS=50 +MB_SLAVE_ID=1 + +MB_TX_CODE=fnct_06_write_single_register +FIRST_ELEMENT=512 +NELEMENTS=1 +HAL_TX_NAME=control +MAX_UPDATE_RATE=10.0 +MB_RESPONSE_TIMEOUT_MS=500 +MB_BYTE_TIMEOUT_MS=500 +DEBUG=1 + + +# ===================================================================== +# TRANSACTION 01: Write Given Frequency (0201H / 513 dec) +# ===================================================================== +[TRANSACTION_01] +# Link settings (PORT, BAUD, etc.) are inherited from TRANSACTION_00 +MB_TX_CODE=fnct_06_write_single_register +FIRST_ELEMENT=513 +NELEMENTS=1 +HAL_TX_NAME=speed +MAX_UPDATE_RATE=10.0 +DEBUG=1 + + +# ===================================================================== +# TRANSACTION 02: Read Main Control Status (0210H / 528 dec) +# ===================================================================== +[TRANSACTION_02] +MB_TX_CODE=fnct_03_read_holding_registers +FIRST_ELEMENT=528 +NELEMENTS=1 +HAL_TX_NAME=status +MAX_UPDATE_RATE=10.0 +DEBUG=1 + + +# ===================================================================== +# TRANSACTION 03: Read Operating Parameters (0220H - 0223H / 544 - 547 dec) +# ===================================================================== +[TRANSACTION_03] +MB_TX_CODE=fnct_03_read_holding_registers +FIRST_ELEMENT=544 +# Receptors: +# 544 (0220H) = Output Frequency (Hz * 10) +# 545 (0221H) = Set Frequency (Hz * 10) +# 546 (0222H) = Output Current (A * 10) +# 547 (0223H) = Output Speed (RPM) +PIN_NAMES=freq_out,freq_set,current,rpm +HAL_TX_NAME=metrics +MAX_UPDATE_RATE=5.0 +DEBUG=1 diff --git a/vfd_test.hal b/vfd_test.hal new file mode 100644 index 0000000..484fc2d --- /dev/null +++ b/vfd_test.hal @@ -0,0 +1,58 @@ +# Samodzielny plik testowy dla mb2hal i falownika Vevor D100 +# Uruchom w terminalu za pomoca: +# halrun -I -f vfd_test.hal + +# 1. Tworzymy wirtualny watek czasu rzeczywistego (wymagane w halrun) +loadrt threads name1=servo-thread period1=1000000 + +# 2. Ladujemy mb2hal z nasza konfiguracja +loadusr -W mb2hal config=vfd_d100.ini + +# 3. Ladujemy komponenty pomocnicze +loadrt scale names=spindle_speed_scale,spindle_feedback_scale +loadrt mux2 names=spindle_dir_mux,spindle_run_mux +loadrt near names=spindle_at_speed_near + +# 4. Dodajemy funkcje do watku +addf spindle_speed_scale servo-thread +addf spindle_feedback_scale servo-thread +addf spindle_dir_mux servo-thread +addf spindle_run_mux servo-thread +addf spindle_at_speed_near servo-thread + +# 5. Startujemy watki czasu rzeczywistego +start + +# ===================================================================== +# LOGIKA STEROWANIA (Symulacja sygnalow wejsciowych z LinuxCNC) +# ===================================================================== + +# Wartosci sterujace: 2.0 = Forward, 4.0 = Reverse, 8.0 = Stop +setp spindle_dir_mux.in0 2.0 +setp spindle_dir_mux.in1 4.0 +setp spindle_run_mux.in0 8.0 + +# Tworzymy sygnaly i podlaczamy je do wejsc logicznych (bez udzialu 'motion') +net test-spindle-rev spindle_dir_mux.sel +net test-spindle-dir spindle_dir_mux.out => spindle_run_mux.in1 +net test-spindle-on spindle_run_mux.sel +net test-spindle-cmd spindle_run_mux.out => vfd.control.00.float + +# Skalowanie zadanej predkosci: 24000 RPM -> 400.0 Hz (wartosc 4000 w Modbus) +# Gain = 4000 / 24000 = 0.16666667 +setp spindle_speed_scale.gain 0.16666667 +setp spindle_speed_scale.offset 0.0 +net test-speed-rpm spindle_speed_scale.in +net test-speed-scaled spindle_speed_scale.out => vfd.speed.00.float + +# Skalowanie sprzezenia zwrotnego: RPM z VFD -> RPS dla LinuxCNC +setp spindle_feedback_scale.gain 0.01666667 +setp spindle_feedback_scale.offset 0.0 +net test-rpm-feedback vfd.metrics.rpm.float => spindle_feedback_scale.in +net test-rps-feedback spindle_feedback_scale.out + +# Detekcja "At Speed" +setp spindle_at_speed_near.difference 300.0 +net test-speed-rpm => spindle_at_speed_near.in1 +net test-rpm-feedback => spindle_at_speed_near.in2 +net test-at-speed spindle_at_speed_near.out