System designHow-to

Serial port forwarding from a robot controller to your vision PC

How serial port forwarding from a robot controller to your vision PC works, which dmesg lines to trust, and why the wrist camera stays on the PC's USB bus.

LumaSpec Vision12 min read Share on LinkedIn

On this page 12 sections
  1. 01The decision: forward the serial port, keep the camera local
  2. 02What you need
  3. 03Find the gripper's serial device on the controller
  4. 04Free the port and forward it
  5. 05Verify the link end to end
  6. 06Keep the wrist camera on the PC's own USB bus
  7. 07The timing budget, with the arithmetic
  8. 08Common mistakes
  9. 09When forwarding is the wrong tool
  10. 10Parts for this set-up
  11. 11Before you order
  12. 12Questions

Grippers and wrist cameras usually hang off the robot controller's USB hub, while the vision code that needs them runs on a separate PC. The controller's Linux sees the gripper's USB-serial converter; your vision PC does not. This guide closes that gap with serial port forwarding: you identify the controller-side serial device from the controller's kernel log, forward it through the robot vendor's ROS driver as a virtual port, and open it on the PC like any local serial device. It also settles the camera question with numbers instead of folklore: a camera reached through the controller returns frames but no parameter control, so it moves to the PC's own USB bus.

The decision: forward the serial port, keep the camera local

A gripper is a register device. It needs a serial line, a few bytes each way and tens of milliseconds of patience. A camera is a stream device: it needs hundreds of megabits and, for inspection, live control of exposure, focus and white balance. Those two needs pull the wiring in opposite directions, so split them.

Forward the gripper's serial port from the controller to the vision PC through the robot vendor's ROS driver, and leave the camera on the PC's own USB bus with its own high-flex cable. A camera left on the controller's hub can return frames, but the bridge does not carry its control interface, so exposure, focus and white balance stay out of reach — and an exposure drift you cannot correct is a rejected batch waiting to happen. If the robot program needs to know when a frame was grabbed, have the PC answer over a socket: the pattern is in trigger a USB camera capture from a robot controller over a socket.

Control bytes tunnelled, images local: that is the same division of labour behind planning who drives what in a vision system and robot gripper architecture.

What you need

  • The robot controller with the USB hub at the wrist, running its own Linux — the gripper's USB-serial converter enumerates there.
  • The robot vendor's ROS driver with tool-communication support, on a distribution it supports. ROS Melodic is covered, as are the newer generations the current driver supports.
  • The gripper maker's ROS package for the PC side, which opens a plain serial port.
  • A vision PC with one free network port for the robot control link plus one per camera and PLC. The vision controllers in the catalog run from 2 to 5+ LAN ports for exactly this split.
  • A drag-chain-rated USB 3 cable for the wrist camera run to the PC, and Ethernet for the robot link. The camera and I/O cables range covers both.

Find the gripper's serial device on the controller

  1. Open a shell on the controller itself over ssh. The hub at the wrist is part of the controller's USB tree, not your PC's.
  2. List the serial devices the kernel has seen: run dmesg | grep tty. Two families of lines matter:
[    3.573559] 00:02: ttyS0 at I/O 0x3f8 (irq = 4, base_baud = 115200) is a 16550A
[   86.551742] cdc_acm 1-2.3.1:1.2: ttyACM0: USB ACM device
[   86.552132] cdc_acm 1-2.3.1:1.5: ttyACM1: USB ACM device
  1. Read the families apart. The ttyS0 line appears seconds after boot and names a 16550A chip at I/O 0x3f8: that is the controller's own console UART, not a peripheral. The same trap exists across industrial Linux boxes, which is why the walkthrough on disabling a controller's own serial ports starts by separating console UARTs from add-on devices. The cdc_acm lines are your hardware: the kernel's cdc_acm driver claimed a USB communications device at USB path 1-2.3.1 and named its two interfaces ttyACM0 and ttyACM1. Those two names are the candidates for the gripper's port.
  2. Match a name to the gripper. Run dmesg | grep tty with the hub unplugged and the cdc_acm lines disappear. Replug the hub alone and both return; replug the gripper alone and one returns. Note the device name and the USB path (1-2.3.1 above): the driver configuration needs the name, and stable naming needs the path.

Free the port and forward it

  1. Deactivate the controller-side software that also opens that serial device — the gripper maker's on-controller service. Behind the USB converter the tool link is a shared RS-485 bus, and two masters interleave each other's bytes into checksum errors and unanswered frames.
  1. Configure the driver's tool communication on the PC. The driver documentation page named setup_tool_communication.md lists the parameters; three of them decide the result: the controller-side device (the ttyACM name you noted), the serial parameters (match the gripper — electric grippers of this class commonly run 115200 baud, 8 data bits, no parity, one stop bit), and the name of the local virtual port the driver creates on your PC. With the robot driver connected, it opens the controller-side device over the control Ethernet link and re-exposes it on the PC.
  2. Point the gripper maker's ROS package at the PC-side virtual port with the same serial parameters. The package cannot tell that the physical converter sits on the controller; it sees a serial device like any other.
  1. Query before you grip. Send the gripper's identification or status read at the configured parameters and check for a clean reply. A garbage or silent reply is almost always parameters, wiring or a second reader on the line — the same chain as in frame grabber serial port communication fails: fix the chain.
  2. Run an open-close cycle at low speed and low force with the area clear, then run 100 cycles. A tunnel that drops bytes shows up inside the first few dozen cycles as checksum or timeout errors, never as a gradual drift.
  3. Log the round-trip time of the status query for a minute and keep the measured value. It is the input your timing budget consumes below.

Keep the wrist camera on the PC's own USB bus

A camera on the controller's hub can usually be made to deliver frames, and for a fixed-configuration camera with locked exposure and fixed focus in unchanging light that can be enough. For an inspection camera it is not: the bridge does not carry the camera's control interface, so exposure, white balance and focus cannot be set from your code. Exposure is the parameter you retune per part, which is exactly what setting camera exposure time through a GenICam API is for. Move the camera to the PC's USB bus, and three details decide the run:

The timing budget, with the arithmetic

For 8N1 framing, every byte costs 10 bits on the wire: 1 start, 8 data, 1 stop.

capacity (bytes/s) = baud / 10 line time (s) = (bytes out + bytes in) × 10 / baud

Worked example at 115200 baud, the common setting for this class of gripper. A 12-byte command out and a 48-byte status frame back give a line time of (12 + 48) × 10 / 115200 = 600 / 115200 = 5.2 ms. Add roughly 2 ms of gripper turnaround (an estimate for this class — your step 10 log replaces it) and about 2 ms for the forwarding round trip across the control link (single-digit milliseconds on a switched 100 Mbit/s LAN). Total: about 9.4 ms per gripper query. Against a 50 ms pick-and-place decision loop (20 Hz), that is 19% of the budget, which is workable. Against an 8 ms servo-synchronous loop (125 Hz), it does not fit: keep force control on the controller and let vision answer at its own rate.

Check the line's capacity the same way: 115200 / 10 = 11520 bytes/s. A 640×480 8-bit frame at 30 fps is 640 × 480 × 30 = 9.2 MB/s of pixels, and 9216000 × 8 / 115200 = 640 times the serial line's bit rate. Images never ride the forwarded port; it is a control channel sized in kilobytes per second, not megabytes.

Common mistakes

  • Two masters on the tool bus. Leaving the on-controller gripper service running alongside the tunnel puts two talkers on one RS-485 line; the symptoms are checksum errors and frames that answer only sometimes.
  • Chasing ttyS0. The 16550A at I/O 0x3f8 that appears at boot is the controller's console. No peripheral lives there.
  • Entering the four serial parameters at only one end. The driver configuration and the gripper package must carry identical settings.
  • Trusting the ttyACM0 name across reboots. Pin it by USB path or serial number with a udev rule.
  • Sharing the robot control port with image traffic. Keep the driver's link on its own network interface; jitter on that link surfaces as timeout variance in the tunnel.
  • Forwarding images through the tunnel. The capacity math above ends that idea in one line.

When forwarding is the wrong tool

Parts for this set-up

The host side decides how clean this stays: one network port for the robot driver, one per camera and PLC, and USB 3 headroom. The MV-VC3301H-128G66 provides 5+ LAN ports, 3-4 USB 3 ports, 4 built-in light channels, 8 GB of memory and an Intel Core i3.

Vision controllersHikrobot MV-VC3301H-128G66 I3-8100, 8GB+128G SSD, No PoE, PCIe expansion supported, Incl. VM6200Pro licenseMV-VC3301H-128G66
LAN ports
5+ LAN ports
USB 3 ports
3-4 USB 3 ports
Light outputs
4 built-in channels
Memory
8 GB
$2,419.00View partBuild a system with it

Cells that also drive PoE cameras or heavier models want more headroom: the MV-VC5525-256G70-NN pairs PoE camera ports and 8 built-in light channels with 32 GB of memory and 5+ LAN ports.

Vision controllersHikrobot MV-VC5525-256G70-NN VC5000 Vision Controller, 12th-I5, 32GB+256G SSD, Supported PCIEMV-VC5525-256G70-NN
LAN ports
5+ LAN ports
USB 3 ports
3-4 USB 3 ports
PoE
PoE camera ports
Light outputs
8 built-in channels
$4,479.00 · quotedView and quoteBuild a system with it

Both cable runs out of this article are high-flex, drag-chain rated and 3 m:

The USB 3 run serves the wrist camera on the PC's bus; the GigE run suits a GigE wrist camera or a longer link to a switch.

Before you order

  • Count network ports: robot link plus every camera plus PLC. A controller with 5+ LAN ports keeps the robot link on its own interface.
  • Note the gripper's serial parameters from its manual before you configure the tunnel, not after the first failed query.
  • Reserve one USB 3 port per camera, and confirm the negotiated speed once the camera is mounted on the wrist.
  • Rate every cable in the moving loop for drag-chain duty, and stay within 3 m for passive USB 3.
  • Agree the ownership change before it happens: on-controller service off, PC node up, operator informed.

Once the port answers on the PC, the rest of the cell is ordinary vision engineering. Pick the host from the vision controllers above, or send the camera and gripper layout through the contact page and we will size the ports and the timing budget with you. The systems how-to collection gathers the neighbouring fixes: USB fallbacks, bandwidth splits and socket triggers.

Questions

Why does ttyACM0 turn into ttyACM1 after I re-plug the hub?

Enumeration order decides the number: the kernel names converters ttyACM0, ttyACM1 in the order their drivers bind, and a different socket, hub port or boot timing changes that order. Pin the name instead of chasing it — a udev rule keyed to the USB path dmesg prints (1-2.3.1 in the example) or to the converter's serial number gives a fixed name such as /dev/gripper across reboots.

Can I forward the gripper port and a second serial tool at the same time?

Yes, one tunnel per device. Each USB serial function enumerates as its own ttyACM device and the driver forwards each separately, so a hub with a gripper and a second tool shows ttyACM0 and ttyACM1. Keep one master per RS-485 bus and budget the line time: two 60-byte transactions at 115200 baud serialize to about 10.4 ms, not 5.2 ms, because the bytes share one line at the controller end.

What serial settings go into the forwarding configuration?

Whatever the gripper documents, set identically at both ends: the controller-side device and line parameters in the driver configuration, and the same parameters in your ROS node. Electric grippers of this class commonly run 115200 baud, 8 data bits, no parity, one stop bit. A mismatch does not raise an error — you get framing garbage or silence — so on a failed first query, check the four parameters before the wiring.

Is any camera usable if it stays on the controller's USB hub?

For frames only. The bridge passes the video stream but not the camera's control interface, so exposure, white balance and focus stay wherever the controller last set them. That is workable for a camera with locked, fixed parameters in unchanging light — a presence check, not a measurement. Anything you expose or focus per part, or any auto-exposure you need to pin, belongs on the vision PC's USB bus where the controls are reachable.

Does this work on ROS 2 as well?

The forwarding lives in the robot vendor's driver, so it works on any ROS generation that driver supports — check the driver's tool-communication documentation rather than the gripper package. Gripper control packages are the thinner end: first-party ROS 2 support has lagged, and where it is missing, community drivers fill the gap. Pick a package that opens a plain serial port, because the forwarded endpoint presents exactly that.