Skip to content

RS-485 Tools

RS-485 enables half-duplex multi-drop bus communication where multiple devices share a single pair of wires. These tools handle direction control, request/response transactions, and bus scanning.


Configure the hardware RS-485 settings for half-duplex communication. This sets up automatic TX/RX direction switching via the RTS line (DE/RE control) on hardware that supports it.

ParameterTypeDefaultDescription
portstrrequiredDevice path of the port.
enabledboolTrueEnable or disable RS-485 hardware mode.
delay_before_txfloat0.0Delay in seconds before enabling TX. Allows bus settling time.
delay_before_rxfloat0.0Delay in seconds before enabling RX after TX completes.
rts_level_for_txboolTrueRTS level when transmitting. True = high.
rts_level_for_rxboolFalseRTS level when receiving. True = high.
loopbackboolFalseEnable RS-485 loopback mode (see your own transmissions).

Returns: Dict with success, port, rs485_enabled, and the configured settings (rts_level_for_tx, rts_level_for_rx, delay_before_tx, delay_before_rx, loopback). Settings are None when RS-485 is disabled.

# Enable hardware RS-485 with defaults
set_rs485_mode(port="/dev/ttyUSB0")
# Add bus settling delays for long cable runs
set_rs485_mode(
port="/dev/ttyUSB0",
delay_before_tx=0.001,
delay_before_rx=0.001,
)
# Inverted RTS polarity
set_rs485_mode(
port="/dev/ttyUSB0",
rts_level_for_tx=false,
rts_level_for_rx=true,
)
# Disable hardware RS-485 (revert to software control)
set_rs485_mode(port="/dev/ttyUSB0", enabled=false)

Detect whether a serial port’s hardware and driver support automatic RS-485 direction control, or whether software RTS toggling is needed. This tool queries udevadm for USB device information and tests the kernel RS-485 ioctl.

ParameterTypeDefaultDescription
portstrrequiredDevice path to check. The port does not need to be open.

Returns: Dict with success, port, driver (e.g., ftdi_sio, cp210x, ch341), chip (product string if detected), hardware_rs485 (bool), software_fallback (bool), kernel_rs485_ioctl (bool), notes (list of informational strings), and recommendation.

Known hardware support:

DriverChipHardware RS-485
ftdi_sioFT232, FT2232, etc.Yes — auto-direction control
cp210xCP2105, CP2108Yes
cp210xCP2102No — use software RTS control
ch341CH340, CH341No — timing may be unreliable
pl2303PL2303No — use software RTS control
nativettyS, ttyAMAYes — check transceiver wiring
check_rs485_support(port="/dev/ttyUSB0")
# Example response:
# {
# "success": true,
# "port": "/dev/ttyUSB0",
# "driver": "ftdi_sio",
# "chip": "FT232R",
# "hardware_rs485": true,
# "software_fallback": true,
# "kernel_rs485_ioctl": true,
# "notes": ["FTDI chips have hardware RS-485 auto-direction"],
# "recommendation": "Use set_rs485_mode() for automatic DE/RE control"
# }

Send data and receive a response on the RS-485 bus in a single half-duplex transaction. Handles TX-to-RX turnaround timing automatically, including manual RTS control when hardware RS-485 is not available.

ParameterTypeDefaultDescription
portstrrequiredDevice path (must be open in RS-485 mode).
datastrrequiredData string to send.
response_timeoutfloat1.0Maximum time in seconds to wait for a response.
response_terminatorstr | NoneNoneStop reading when this sequence is received.
response_lengthint | NoneNoneExpected response length in bytes. Alternative to response_terminator.
encodingstr"utf-8"Character encoding for send and receive data.
turnaround_delayfloat0.005Delay in seconds after TX completes before switching to RX.

Returns: Dict with success, port, bytes_sent, data_sent, response (decoded string), response_bytes, response_hex, and hardware_rs485 (whether hardware RS-485 was used).

The transaction flow:

  1. Clear the input buffer
  2. Assert RTS for TX (if no hardware RS-485)
  3. Send encoded data and flush
  4. Wait for TX completion + turnaround delay
  5. De-assert RTS for RX (if no hardware RS-485)
  6. Read response using terminator, length, or timeout
# Simple query with timeout-based response
rs485_transact(port="/dev/ttyUSB0", data="?ID\r\n")
# Modbus-style with known response length
rs485_transact(
port="/dev/ttyUSB0",
data="\x01\x03\x00\x00\x00\x01",
response_length=7,
encoding="latin-1",
)
# Wait for a specific terminator
rs485_transact(
port="/dev/ttyUSB0",
data="READ\r\n",
response_terminator="\r\n",
)
# Adjust turnaround for slow devices
rs485_transact(
port="/dev/ttyUSB0",
data="PING",
turnaround_delay=0.01,
response_timeout=2.0,
)

Scan the RS-485 bus for responding devices by sending a probe message to each address in a range. Useful for discovering Modbus or similar addressed devices.

ParameterTypeDefaultDescription
portstrrequiredDevice path (must be open in RS-485 mode).
start_addressint1First address to scan.
end_addressint247Last address to scan. Default 247 is the Modbus maximum.
probe_templatestr"{addr:02x}03000001"Message template with {addr} placeholder for the address. Default is a Modbus “read holding register” frame. Customize for your protocol.
response_timeoutfloat0.1Time in seconds to wait for a response per address.
encodingstr"latin-1"Encoding for the probe string. Use latin-1 for raw byte protocols.

Returns: Dict with success, port, addresses_scanned, devices_found, responding_addresses (list of objects with address, response_length, response_hex), and hardware_rs485.

# Scan the full Modbus range
rs485_scan_addresses(port="/dev/ttyUSB0")
# Scan a known range of addresses
rs485_scan_addresses(
port="/dev/ttyUSB0",
start_address=1,
end_address=10,
)
# Custom probe template for a different protocol
rs485_scan_addresses(
port="/dev/ttyUSB0",
probe_template="{addr:c}ID?\r\n",
response_timeout=0.2,
encoding="ascii",
)
# Faster scan with short timeout
rs485_scan_addresses(
port="/dev/ttyUSB0",
start_address=1,
end_address=32,
response_timeout=0.05,
)