-
-
Notifications
You must be signed in to change notification settings - Fork 40
Real time provider serial
This page covers shared serial setup and debugging for serial-backed realtime providers.
Applies to:
- TCLab (
serialprovider +driver="tclab") - Firmata and Telemetrix style Arduino workflows (when implemented)
- arduIO style serial transports
BDRealTime selects provider serial, then device drivers are configured in bdsim.toml.
from bdsim.realtime import BDRealTime
rt = BDRealTime(
io_provider="serial",
io_provider_kwargs={"config_path": "bdsim.toml"},
)macOS:
ls -1 /dev/cu.*
ls -1 /dev/tty.*Linux / Raspberry Pi:
ls -1 /dev/ttyUSB*
ls -1 /dev/ttyACM*Tip: unplug and replug the device and compare listings.
Install pyserial in the environment running bdsim:
pip install pyserialMost boards appear as /dev/cu.usb* and are often already usable.
If you get permission denied:
sudo chmod 666 /dev/cu.usbserial-XXXXThis is temporary and resets on reconnect/reboot.
Add your user to dialout (and sometimes tty depending on distro):
sudo usermod -a -G dialout $USER
# optional on some systems
sudo usermod -a -G tty $USERThen log out/in, or reboot.
Check permissions:
ls -l /dev/ttyACM0
ls -l /dev/ttyUSB0[io]
config_version = 1
default_provider = "serial"
[providers.serial]
type = "serial"
shutdown_on_signal = true
safe_shutdown_timeout_s = 0.5
[devices.dev0]
provider = "serial"
driver = "tclab"
port = "/dev/ttyACM0"
baud = 115200
startup_probe = true
startup_timeout_s = 2.0Device-specific channel sections are covered in each provider/driver page.
- Confirm device appears in
/dev/*. - Confirm permissions allow your user to open the port.
- Confirm no other process has the port open.
- Confirm baud and newline/command format for the device.
- Run a direct pyserial smoke test before launching
bdsim.
Example smoke test:
python - <<'PY'
import serial
port = '/dev/ttyACM0'
with serial.Serial(port, 115200, timeout=1) as s:
s.write(b'VER\n')
print(s.readline().decode(errors='replace').strip())
PYNo such file or directory
Wrong port path or device disconnected.
Permission denied
Fix user permissions/groups as above.
- Read timeout
Wrong baud, wrong command format, wrong firmware, or no newline terminator.
- Device resets on connect
Many Arduino-class devices reset on DTR transition when serial opens. Handle startup handshake accordingly.
USB CDC serial (used by most Arduino boards) introduces a round-trip latency of roughly 30–70 ms per transaction on macOS, regardless of baud rate. This dominates the per-tick eval time and sets an upper bound on the usable sample rate.
A serial round-trip (send command → read response) goes through two USB transfers. Each transfer is subject to the USB host's polling interval and any additional buffering in the OS driver:
- The Arduino firmware's CDC TX timeout flushes a USB packet after ~3 ms.
- The macOS
com.apple.driver.usb.cdcdriver adds its own read latency on top. - On an M-series Mac Mini, observed round-trip times are ~35–65 ms per transaction.
The bdsim serial provider uses fire-and-forget writes for analog outputs:
the heater command is sent but the firmware echo is not read back. A
reset_input_buffer() call discards the pending echo before the next read.
This reduces a two-transaction tick (T1 read + Q1 write-with-echo) to a
single round-trip, cutting mean eval time from ~130 ms to ~40 ms.
Practical maximum sample rates on macOS (Arduino UNO, 1 temperature read per tick):
| Mean eval time | Safe clock rate |
|---|---|
| ~130 ms (read + write-with-echo) | ≤ 5 Hz |
| ~40 ms (read + fire-and-forget) | ≤ 20 Hz |
At 10 Hz (100 ms period) with ~40 ms eval time there is comfortable headroom;
20 Hz (50 ms period) is marginal — watch the overrun count in the stats.
On macOS: No straightforward method. The macOS USB CDC driver exposes no
latency-timer API; pyserial has no hook for it. The Arduino UNO's ATmega16U2
firmware hardcodes the USB endpoint interval — changing it requires reflashing
the 16U2.
On Linux: Boards using an FTDI chip expose a latency timer:
cat /sys/bus/usb-serial/devices/ttyUSB0/latency_timer # default 16
echo 1 | sudo tee /sys/bus/usb-serial/devices/ttyUSB0/latency_timerReducing from 16 ms to 1 ms brings round-trip latency down to ~5 ms, enabling 100 Hz+ sample rates.
Arduino Leonardo / Micro / Pro Micro (native USB): The CDC TX timeout is set in the ATmega32U4 firmware and can be patched, but requires firmware modification.
Copyright (c) Peter Corke 2020-
- Home
- API reference (Sphinx)
- Block catalog
- Control Systems Magazine article
- Adding blocks to your model
- Block path
- Connecting blocks
- Compiling
- Running
- Watching a simulation variable
- Simulation results
- Runtime options
- Environment variables
- Discrete-time blocks
- Subsystems
- Figures
- Notebook animation
- Animation and movies
- PID control
- Coding patterns
- Block methods and attributes
- Time stepping: integration, animation & events
- Blocks, wires and plugs
- Graphics blocks
- Evaluation
- Runtimes and simulator state
- Creating a new block
- Related packages
Under development on feat/realtime branch, planned for release before end of 2026.