Compare commits

...

2 Commits

Author SHA1 Message Date
8a7fbdee90 test hal 2026-06-05 18:58:40 +02:00
47fc54647d dokumentacja linuxcnc 2026-06-05 17:55:39 +02:00
5 changed files with 718 additions and 0 deletions

118
hal_configuration.md Normal file
View File

@@ -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`.

30
hal_motion.md Normal file
View File

@@ -0,0 +1,30 @@
pełna instrukcja -> [MOTMOD](https://linuxcnc.org/docs/stable/html/man/man9/motion.9.html#SPINDLE%20PINS)
## SPINDLE PINS
(M is the spindle number (0 ... num_spindles-1))
| name | dir | format | description |
|:-----|:---:|:------:|:------------|
| spindle.M.amp-fault-in | IN | BIT | Should be driven TRUE if an external fault is detected with the amplifier for this spindle. |
| spindle.M.at-speed | IN | BIT | Motion will pause until this pin is TRUE, under the following conditions: before the first feed move after each spindle start or speed change; before the start of every chain of spindle-synchronized moves; and if in CSS mode, at every rapid->feed transition. |
| spindle.M.brake | OUT | BIT | TRUE when the spindle brake should be applied. |
| spindle.M.forward | OUT | BIT | TRUE when the spindle should rotate forward. |
| spindle.M.index-enable | I/O | BIT | For correct operation of spindle synchronized moves, this signal must be hooked to the index-enable pin of the spindle encoder. |
| spindle.M.inhibit | IN | BIT | When TRUE, the spindle speed is set and held to 0. |
| spindle.M.is-oriented | IN | BIT | Acknowledge pin for spindle-orient. Completes orient cycle. If spindle-orient was true when spindle-is-oriented was asserted, the spindle-orient pin is cleared and the spindle-locked pin is asserted. Also, the spindle-brake pin is asserted. |
| spindle.M.locked | OUT | BIT | Spindle orient complete pin. Cleared by any of M3,M4,M5. |
| spindle.M.on | OUT | BIT | TRUE when spindle should rotate. |
| spindle.M.orient | OUT | BIT | Indicates start of spindle orient cycle. Set by M19. Cleared by any of M3,M4,M5.<br>If spindle-orient-fault is not zero during spindle-orient true, the M19 command fails with an error message. |
| spindle.M.orient-angle | OUT | FLOAT | Desired spindle orientation for M19. Value of the M19 R word parameter plus the value of the [RS274NGC]ORIENT_OFFSET INI parameter. |
| spindle.M.orient-fault | IN | S32 | Fault code input for orient cycle. Any value other than zero will cause the orient cycle to abort. |
| spindle.M.orient-mode | OUT | BIT | Desired spindle rotation mode. Reflects M19 P parameter word. |
| spindle.M.reverse | OUT | BIT | TRUE when the spindle should rotate backward. |
| spindle.M.revs | IN | FLOAT | For correct operation of spindle synchronized moves, this signal must be hooked to the position pin of the spindle encoder. |
| spindle.M.speed-cmd-rps | FLOAT | OUT | Commanded spindle speed in units of revolutions per second. |
| spindle.M.speed-in | IN | FLOAT | Actual spindle speed feedback in revolutions per second; used for G96 (constant surface speed) and G95 (feed per revolution) modes. |
| spindle.M.speed-out | OUT | FLOAT | Desired spindle speed in rotations per minute. |
| spindle.M.speed-out-abs | OUT | FLOAT | Desired spindle speed in rotations per minute, always positive regardless of spindle direction. |
| spindle.M.speed-out-rps | OUT | FLOAT | Desired spindle speed in rotations per second. |
| spindle.M.speed-out-rps-abs | OUT | FLOAT | Desired spindle speed in rotations per second, always positive regardless of spindle direction. |

424
mb2hal.md Normal file
View File

@@ -0,0 +1,424 @@
## 1. Introduction
MB2HAL is a generic non-realtime HAL component to communicate with one or more Modbus devices. So far, there are two options to communicate with a Modbus device:
1. One option is to create a HAL component as a driver see VFD Modbus.
2. Another option is to use Classic Ladder which has Modbus built in, see ClassicLadder.
3. Now there is a third option that consists of a "generic" driver configured by text file, this is called MB2HAL.
Why MB2HAL? Consider using MB2HAL if:
1. You have to write a new driver and you dont know anything about programming.
2. You need to use Classic Ladder "only" to manage the Modbus connections.
3. You have to discover and configure first time the Modbus transactions. MB2HAL have debug levels to facilitate the low level protocol debug.
4. You have more than one device to connect. MB2HAL is very efficiently managing multiple devices, transactions and links. Currently I am monitoring two axis drivers using a Rs232 port, a VFD driver using another Rs232 port, and a remote I/O using TCP/IP.
5. You want a protocol to connect your Arduino to HAL. Look the included sample configuration file, sketch and library for Arduino Modbus.
## 2. Usage
1. Create a config file from the example below
- Set component name (optional)
Set HAL_MODULE_NAME=mymodule (default HAL_MODULE_NAME=mb2hal)
- Load the modbus HAL non-realtime component
2. Default component name: loadusr -W mb2hal config=config_file.ini
3. Custom component name: loadusr -Wn mymodule mb2hal config=config_file.ini
## 3. Options
### 3.1 Init Section
[MB2HAL_INIT]
|Value|Type|Required|Description|
|-----|----|--------|-----------|
|INIT_DEBUG|Integer|No|Debug level of init and INI file parsing<br>.0 = silent<br>1 = error messages (default)<br>2 = OK confirmation messages<br>3 = debugging messages<br>4 = maximum debugging messages (only in transactions)
|VERSION|String|No|Version number in the format N.N[NN]. Defaults to 1.0.|
|HAL_MODULE_NAME|String|No|HAL module (component) name. Defaults to "mb2hal".|
|SLOWDOWN|Float|No|Insert a delay of "FLOAT seconds" between transactions in order to not to have a lot of logging and facilitate the debugging. Useful when using DEBUG=3 (NOT INIT_DEBUG=3). It affects ALL transactions. Use "0.0" for normal activity.|
|TOTAL_TRANSACTIONS|Integer|Yes|The number of total Modbus transactions. There is no maximum.|
### 3.2 Transaction Sections
One transaction section is required per transaction, starting at [TRANSACTION_00] and counting up sequentially. If there is a new link (not transaction), you must provide the REQUIRED parameters 1st time. Warning: Any OPTIONAL parameter not specified are copied from the previous transaction.
|Value|Type|Required|Description|
|-----|----|--------|-----------|
|LINK_TYPE|String|Yes|You must specify either a "serial" or "tcp" link for the first transaction. Later transactions will use the previous transaction link if not specified.|
|TCP_IP|IP address|If LINK_TYPE=tcp|The Modbus slave device IP address. Ignored if LINK_TYPE=serial.|
|TCP_PORT|Integer|No|The Modbus slave device TCP port. Defaults to 502. Ignored if LINK_TYPE=serial.|
|SERIAL_PORT|String|If LINK_TYPE=serial|The serial port. For example "/dev/ttyS0". Ignored if LINK_TYPE=tcp.|
|SERIAL_BAUD|Integer|If LINK_TYPE=serial|The baud rate. Ignored if LINK_TYPE=tcp.|
|SERIAL_BITS|Integer|If LINK_TYPE=serial|Data bits. One of 5, 6, 7, 8. Ignored if LINK_TYPE=tcp.|
|SERIAL_PARITY|String|If LINK_TYPE=serial|Data parity. One of: even, odd, none. Ignored if LINK_TYPE=tcp.|
|SERIAL_STOP|Integer|If LINK_TYPE=serial|Stop bits. One of 1, 2. Ignored if LINK_TYPE=tcp.|
|SERIAL_DELAY_MS|Integer|If LINK_TYPE=serial|Serial port delay between transactions of this section only. In ms. Defaults to 0. Ignored if LINK_TYPE=tcp.|
|MB_SLAVE_ID|Integer|Yes|Modbus slave number.|
|FIRST_ELEMENT|Integer|Yes|The first element address.|
|NELEMENTS|Integer|Unless PIN_NAMES is specified|The number of elements. It is an error to specify both NELEMENTS and PIN_NAMES. The pin names will be sequential numbers, e.g. mb2hal.plcin.01.|
|PIN_NAMES|List|Unless NELEMENTS is specified|A list of element names. These names will be used for the pin names, e.g. mb2hal.plcin.cycle_start.<br>**NOTE:** There must be no white space characters in the list. Example: PIN_NAMES=cycle_start,stop,feed_hold|
|MB_TX_CODE|String|Yes|Modbus transaction function code (see specifications):<ul><li> fnct_01_read_coils</li><li>fnct_02_read_discrete_inputs</li><li>fnct_03_read_holding_registers</li><li>fnct_04_read_input_registers</li><li>fnct_05_write_single_coil</li><li>fnct_06_write_single_register</li><li>fnct_15_write_multiple_coils</li><li>fnct_16_write_multiple_registers</li>|
|MB_RESPONSE_TIMEOUT_MS|Integer|No|Response timeout for this transaction. In ms. Defaults to 500 ms. This is how much to wait for 1st byte before raise an error.|
|MB_BYTE_TIMEOUT_MS|Integer|No|Byte timeout for this transaction. In ms. Defaults to 500 ms. This is how much to wait from byte to byte before raise an error.|
|HAL_TX_NAME|String|No|Instead of giving the transaction number, use a name. Example: mb2hal.00.01 could become mb2hal.plcin.01. The name must not exceed 28 characters. NOTE: when using names be careful that you dont end up with two transactions using the same name.|
|MAX_UPDATE_RATE|Float|No|Maximum update rate in Hz. Defaults to 0.0 (0.0 = as soon as available = infinite). NOTE: This is a maximum rate and the actual rate may be lower. If you want to calculate it in ms use (1000 / required_ms). Example: 100 ms = MAX_UPDATE_RATE=10.0, because 1000.0 ms / 100.0 ms = 10.0 Hz.|
|DEBUG|String|No|Debug level for this transaction only. See INIT_DEBUG parameter above.|
### 3.3. Error codes
While debugging transactions, note the returned "ret[]" value correspond to:
Modbus protocol exceptions:
- 0x01 - ILLEGAL_FUNCTION - the FUNCTION code received in the query is not allowed or invalid.
- 0x02 - ILLEGAL_DATA_ADDRESS - the DATA ADDRESS received in the query is not an allowable address for the slave or is invalid.
- 0x03 - ILLEGAL_DATA_VALUE - a VALUE contained in the data query field is not an allowable value or is invalid.
- 0x04 - SLAVE_DEVICE_FAILURE - SLAVE (or MASTER) device unrecoverable FAILURE while attempting to perform the requested action.
- 0x04 - SERVER_FAILURE - (see above).
- 0x05 - ACKNOWLEDGE - This response is returned to PREVENT A TIMEOUT in the master. A long duration of time is required to process the request in the slave.
- 0x06 - SLAVE_DEVICE_BUSY - The slave (or server) is BUSY. Retransmit the request later.
- 0x06 - SERVER_BUSY - (see above).
- 0x07 - NEGATIVE_ACKNOWLEDGE - Unsuccessful programming request using function code 13 or 14.
- 0x08 - MEMORY_PARITY_ERROR - SLAVE parity error in MEMORY.
- 0x0A (-10) - GATEWAY_PROBLEM_PATH - Gateway path(s) not available.
- 0x0B (-11) - GATEWAY_PROBLEM_TARGET - The target device failed to respond (generated by master, not slave).
Program or connection:
- 0x0C (-12) - COMM_TIME_OUT
- 0x0D (-13) - PORT_SOCKET_FAILURE
- 0x0E (-14) - SELECT_FAILURE
- 0x0F (-15) - TOO_MANY_DATAS
- 0x10 (-16) - INVALID_CRC
- 0x11 (-17) - INVALID_EXCEPTION_CODE
## 4. Example config file
```ini
#This .INI file is also the HELP, MANUAL and HOW-TO file for mb2hal.
#Load the Modbus HAL userspace module as the examples below,
#change to match your own HAL_MODULE_NAME and INI file name
#Using HAL_MODULE_NAME=mb2hal or nothing (default): loadusr -W mb2hal config=config_file.ini
#Using HAL_MODULE_NAME=mymodule: loadusr -Wn mymodule mb2hal config=config_file.ini
# ++++++++++++++++++++++++
# Common section
# ++++++++++++++++++++++++
[MB2HAL_INIT]
#OPTIONAL: Debug level of init and INI file parsing.
# 0 = silent.
# 1 = error messages (default).
# 2 = OK confirmation messages.
# 3 = debugging messages.
# 4 = maximum debugging messages (only in transactions).
INIT_DEBUG=3
#OPTIONAL: Set to 1.1 to enable the new functions:
# - fnct_01_read_coils
# - fnct_05_write_single_coil
# - changed pin names (see https://linuxcnc.org/docs/2.9/html/drivers/mb2hal.html#_pins).
VERSION=1.1
#OPTIONAL: HAL module (component) name. Defaults to "mb2hal".
HAL_MODULE_NAME=mb2hal
#OPTIONAL: Insert a delay of "FLOAT seconds" between transactions in order
#to not to have a lot of logging and facilitate the debugging.
#Useful when using DEBUG=3 (NOT INIT_DEBUG=3)
#It affects ALL transactions.
#Use "0.0" for normal activity.
SLOWDOWN=0.0
#REQUIRED: The number of total Modbus transactions. There is no maximum.
TOTAL_TRANSACTIONS=9
# ++++++++++++++++++++++++
# Transactions
# ++++++++++++++++++++++++
#One transaction section is required per transaction, starting at 00 and counting up sequentially.
#If there is a new link (not transaction), you must provide the REQUIRED parameters 1st time.
#Warning: Any OPTIONAL parameter not specified are copied from the previous transaction.
[TRANSACTION_00]
#REQUIRED: You must specify either a "serial" or "tcp" link for the first transaction.
#Later transaction will use the previous transaction link if not specified.
LINK_TYPE=tcp
#if LINK_TYPE=tcp then REQUIRED (only 1st time): The Modbus slave device ip address.
#if LINK_TYPE=serial then IGNORED
TCP_IP=192.168.2.10
#if LINK_TYPE=tcp then OPTIONAL.
#if LINK_TYPE=serial then IGNORED
#The Modbus slave device tcp port. Defaults to 502.
TCP_PORT=502
#if LINK_TYPE=serial then REQUIRED (only 1st time).
#if LINK_TYPE=tcp then IGNORED
#The serial port.
SERIAL_PORT=/dev/ttyS0
#if LINK_TYPE=serial then REQUIRED (only 1st time).
#if LINK_TYPE=tcp then IGNORED
#The baud rate.
SERIAL_BAUD=115200
#if LINK_TYPE=serial then REQUIRED (only 1st time).
#if LINK_TYPE=tcp then IGNORED
#Data bits. One of 5,6,7,8.
SERIAL_BITS=8
#if LINK_TYPE=serial then REQUIRED (only 1st time).
#if LINK_TYPE=tcp then IGNORED
#Data parity. One of: even, odd, none.
SERIAL_PARITY=none
#if LINK_TYPE=serial then REQUIRED (only 1st time).
#if LINK_TYPE=tcp then IGNORED
#Stop bits. One of 1, 2.
SERIAL_STOP=2
#if LINK_TYPE=serial then OPTIONAL:
#if LINK_TYPE=tcp then IGNORED
#Serial port delay between for this transaction only.
#In ms. Defaults to 0.
SERIAL_DELAY_MS=10
#REQUIRED (only 1st time).
#Modbus slave number.
MB_SLAVE_ID=1
#REQUIRED: The first element address (decimal integer).
FIRST_ELEMENT=0
#REQUIRED unless PIN_NAMES is specified: The number of elements.
#It is an error to specify both NELEMENTS and PIN_NAMES
#The pin names will be sequential numbers e.g mb2hal.plcin.01
#NELEMENTS=4
#REQUIRED unless NELEMENTS is specified: A list of element names.
#these names will be used for the pin names, e.g mb2hal.plcin.cycle_start
#NOTE: there must be no white space characters in the list
PIN_NAMES=cycle_start,stop,feed_hold
#REQUIRED: Modbus transaction function code (see www.modbus.org specifications).
# fnct_01_read_coils (01 = 0x01) (new in 1.1)
# fnct_02_read_discrete_inputs (02 = 0x02)
# fnct_03_read_holding_registers (03 = 0x03)
# fnct_04_read_input_registers (04 = 0x04)
# fnct_05_write_single_coil (05 = 0x05) (new in 1.1)
# fnct_06_write_single_register (06 = 0x06)
# fnct_15_write_multiple_coils (15 = 0x0F)
# fnct_16_write_multiple_registers (16 = 0x10)
#
# Created pins:
# fnct_01_read_coils:
# fnct_02_read_discrete_inputs:
# mb2hal.m.n.bit (output)
# mb2hal.m.n.bit-inv (output)
# fnct_03_read_holding_registers:
# fnct_04_read_input_registers:
# mb2hal.m.n.float (output)
# mb2hal.m.n.int (output)
# fnct_05_write_single_coil:
# mb2hal.m.n.bit (input)
# NELEMENTS needs to be 1 or PIN_NAMES must contain just one name.
# fnct_06_write_single_register:
# mb2hal.m.n.float (input)
# mb2hal.m.n.int (input)
# NELEMENTS needs to be 1 or PIN_NAMES must contain just one name.
# Both pin values are added and limited to 65535 (UINT16_MAX). Normally use one and let the other open (read as 0).
# fnct_15_write_multiple_coils:
# mb2hal.m.n.bit (input)
# fnct_16_write_multiple_registers:
# mb2hal.m.n.float (input)
# mb2hal.m.n.int (input)
# Both pin values are added and limited to 65535 (UINT16_MAX). Normally use one and let the other open (read as 0).
#
# m = HAL_TX_NAME or transaction number if not set, n = element number (NELEMENTS) or name from PIN_NAMES
# Example: mb2hal.00.01.<type> (transaction=00, second register=01 (00 is the first one))
# mb2hal.TxName.01.<type> (HAL_TX_NAME=TxName, second register=01 (00 is the first one))
MB_TX_CODE=fnct_03_read_holding_registers
#OPTIONAL: Response timeout for this transaction. In INTEGER ms. Defaults to 500 ms.
#This is how much to wait for 1st byte before raise an error.
MB_RESPONSE_TIMEOUT_MS=500
#OPTIONAL: Byte timeout for this transaction. In INTEGER ms. Defaults to 500 ms.
#This is how much to wait from byte to byte before raise an error.
MB_BYTE_TIMEOUT_MS=500
#OPTIONAL: Instead of giving the transaction number, use a name.
#Example: mb2hal.00.01 could become mb2hal.plcin.01
#The name must not exceed 28 characters.
#NOTE: when using names be careful that you dont end up with two transactions
#using the same name.
HAL_TX_NAME=remoteIOcfg
#OPTIONAL: Maximum update rate in HZ. Defaults to 0.0 (0.0 = as soon as available = infinite).
#NOTE: This is a maximum rate and the actual rate may be lower.
#If you want to calculate it in ms use (1000 / required_ms).
#Example: 100 ms = MAX_UPDATE_RATE=10.0, because 1000.0 ms / 100.0 ms = 10.0 Hz
MAX_UPDATE_RATE=0.0
#OPTIONAL: Debug level for this transaction only.
#See INIT_DEBUG parameter above.
DEBUG=2
#While DEBUGGING transactions note the returned "ret[]" value correspond to:
#/* Modbus protocol exceptions */
#ILLEGAL_FUNCTION -0x01 the FUNCTION code received in the query is not allowed or invalid.
#ILLEGAL_DATA_ADDRESS -0x02 the DATA ADDRESS received in the query is not an allowable address for the slave or is invalid.
#ILLEGAL_DATA_VALUE -0x03 a VALUE contained in the data query field is not an allowable value or is invalid.
#SLAVE_DEVICE_FAILURE -0x04 SLAVE (or MASTER) device unrecoverable FAILURE while attempting to perform the requested action.
#SERVER_FAILURE -0x04 (see above).
#ACKNOWLEDGE -0x05 This response is returned to PREVENT A TIMEOUT in the master.
# A long duration of time is required to process the request in the slave.
#SLAVE_DEVICE_BUSY -0x06 The slave (or server) is BUSY. Retrasmit the request later.
#SERVER_BUSY -0x06 (see above).
#NEGATIVE_ACKNOWLEDGE -0x07 Unsuccessful programming request using function code 13 or 14.
#MEMORY_PARITY_ERROR -0x08 SLAVE parity error in MEMORY.
#GATEWAY_PROBLEM_PATH -0x0A (-10) Gateway path(s) not available.
#GATEWAY_PROBLEM_TARGET -0x0B (-11) The target device failed to repond (generated by master, not slave).
#/* Program or connection */
#COMM_TIME_OUT -0x0C (-12)
#PORT_SOCKET_FAILURE -0x0D (-13)
#SELECT_FAILURE -0x0E (-14)
#TOO_MANY_DATAS -0x0F (-15)
#INVALID_CRC -0x10 (-16)
#INVALID_EXCEPTION_CODE -0x11 (-17)
[TRANSACTION_01]
MB_TX_CODE=fnct_01_read_coils
FIRST_ELEMENT=1024
NELEMENTS=24
HAL_TX_NAME=remoteIOin
MAX_UPDATE_RATE=0.0
DEBUG=1
[TRANSACTION_02]
MB_TX_CODE=fnct_02_read_discrete_inputs
FIRST_ELEMENT=1280
NELEMENTS=8
HAL_TX_NAME=readStatus
MAX_UPDATE_RATE=0.0
[TRANSACTION_03]
MB_TX_CODE=fnct_05_write_single_coil
FIRST_ELEMENT=100
NELEMENTS=1
HAL_TX_NAME=setEnableout
MAX_UPDATE_RATE=0.0
[TRANSACTION_04]
MB_TX_CODE=fnct_15_write_multiple_coils
FIRST_ELEMENT=150
NELEMENTS=10
HAL_TX_NAME=remoteIOout
MAX_UPDATE_RATE=0.0
[TRANSACTION_05]
LINK_TYPE=serial
SERIAL_PORT=/dev/ttyS0
SERIAL_BAUD=115200
SERIAL_BITS=8
SERIAL_PARITY=none
SERIAL_STOP=2
SERIAL_DELAY_MS=50
MB_SLAVE_ID=1
MB_TX_CODE=fnct_03_read_holding_registers
FIRST_ELEMENT=1
NELEMENTS=2
HAL_TX_NAME=XDrive01
MAX_UPDATE_RATE=0.0
DEBUG=1
[TRANSACTION_06]
MB_TX_CODE=fnct_04_read_input_registers
FIRST_ELEMENT=12
NELEMENTS=3
HAL_TX_NAME=XDrive02
MAX_UPDATE_RATE=10.0
DEBUG=1
[TRANSACTION_07]
MB_TX_CODE=fnct_06_write_single_register
FIRST_ELEMENT=20
NELEMENTS=1
HAL_TX_NAME=XDrive03
MAX_UPDATE_RATE=0.0
DEBUG=1
[TRANSACTION_08]
MB_TX_CODE=fnct_16_write_multiple_registers
FIRST_ELEMENT=55
NELEMENTS=8
HAL_TX_NAME=XDrive04
MAX_UPDATE_RATE=10.0
DEBUG=1
```
## 5. Pins
**Note:** `sample` = New in MB2HAL 1.1 (LinuxCNC 2.9) To use these new features you have to set VERSION = 1.1.
- m = Value of HAL_TX_NAME if set or transaction number
- n = Element number (NELEMENTS) or name from PIN_NAMES
Example:
- mb2hal.00.01.int (TRANSACTION_00, second register)
- mb2hal.readStatus.01.bit (HAL_TX_NAME=readStatus, first bit)
**5.1. `fnct_01_read_coils`**
- `mb2hal.m.n.bit` bit out
- `mb2hal.m.n.bit-inv` bit out
**5.2. fnct_02_read_discrete_inputs**
- mb2hal.m.n.`bit` bit out
- `mb2hal.m.n.bit-inv` bit out
**5.3. fnct_03_read_holding_registers**
- mb2hal.m.n.float float out
- mb2hal.m.n.int s32 out
**5.4. fnct_04_read_input_registers**
- mb2hal.m.n.float float out
- mb2hal.m.n.int s32 out
**5.5. `fnct_05_write_single_coil`**
- `mb2hal.m.n.bit` bit in
NELEMENTS needs to be 1 or PIN_NAMES must contain just one name.
**5.6. fnct_06_write_single_register**
- mb2hal.m.n.`float` float in
- `mb2hal.m.n.int s32` in
NELEMENTS needs to be 1 or PIN_NAMES must contain just one name. Both pin values are added and limited to 65535 (UINT16_MAX). Use one and let the other open (read as 0).
**5.7. fnct_15_write_multiple_coils**
- mb2hal.m.n.`bit` bit in
**5.8. fnct_16_write_multiple_registers**
- mb2hal.m.n.float `float` in
- `mb2hal.m.n.int` s32 in
Both pin values are added and limited to 65535 (UINT16_MAX). Use one and let the other open (read as 0).

88
vfd_d100.ini Normal file
View File

@@ -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

58
vfd_test.hal Normal file
View File

@@ -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