Home        Store        Learn        Blog

Using the routing feature in to connect to USB devices on the Raspberry Pi


Perhaps you can help me out. I’m having some difficulty getting this to work.

What I am trying to do: I have a personal built ROV using the Blue Robotics ArduSub flight control software on a pixhawk cube and the companion computer Raspberry Pi 3B, imaged with the Blue Robotics companion computer software.

I did a custom build for a custom frame. That is all working and I don’t have any problems controlling things from my surface computer.

I am adding sensors through an Adafruit feather M0 Express programmed in circuitpython. My programs are working on the feather. The feather is connected to a MaxBotix 7040 I2C rangefinder. I am able to read and display the output of that device on my serial terminal for the feather.

I also have three ds18x20 one-wire temp sensors that read the temp and also display the data on the serial terminal.

I have an SPI RGB light control module from Adafruit that i have connected also. It is outputting pwm for controlling some high power Led lights with 16bit values. That is working and I can call that function and change the values via a serial connection circuit python and the Mu editor/programing software. Its the 12 channel / 16 bit pwm board.

I also have 6 power relays that are connected to digital pins on the feather. I can turn them on and off by changing values in the files over the serial port.

For inputting data to the programs I am also using a USB to UART cable from Adafruit. It can connect to a terminal over the usb port tty device.

I’m doing this while directly connected via the two USB devices.

What I want to do is connect these serial devices (the usb cable to the feather and the USB to uart cable to the tx and rx pins on the feather.) over the ethernet tether we are using, just like I was directly connected. The routing feature in the companion computer seems to be the way to do this. I have set up this configuration on my desktop, where the serial connections are routed by the pi to the IP address of the companion and a port number.

What I cannot get to work is connecting via terminal (mac) to these USB devices on the companion computer. I am stumped. Can I get some more detailed help on exactly how you can connect to the to talk to the USB devices. Is it specific software, is there a special terminal software, I have tried a lot of things, but cannot talk to the USB devices. I can log into the companion and do things over the regular terminal with ‘ssh pi@’ just fine.

Please help me get this working or point me to a working installation example of using the routing feature with explicit detail on the software used to connect to the routed USB devices.

So much thanks if you can help.


Hello Michael,

We are working at improving that section of the documentation. You can find a draft here. So far we only have commands for Linux (which should apply to Mac as well).

For user interaction, to have a terminal-like experience, netcat is the easier option. For interfacing with software, ideally the software itself should implement the UDP communication. If that is not possible, you can try using socat to create a fake tty device, but that doesn’t always work right.

What is your workflow like? How do you intend to interface with the devices?
Did you write a software for this?
Do you think a Python example showing how to communicate would be useful?

Hi Willian,

Thanks for getting back to me with some help. I really appreciate it.

The draft looks interesting and importantly, has specific examples of how to configure. I’m not a programmer by nature, so the fine details of the syntax sometimes goes over my head. I’m going to try this, on my mac as well as my linux laptop, which will be my actual field control computer.

I’ll explore the netcat and socat to see what I get. I do have sort of a work-around, using the terminal available in the to create two terminal connections and opening ‘screen /dev/ttyUSB0’ for the USB-uart cable and 'screen /dev/ttyACM0 for the USB direct connection to the feather.

My work flow (I’m not sure what you mean by that) for the programming is to work on the lowest level, get something that works for each type of function, and with that working figure out how to pass parameters to the functions over the connection. What I intend to do is to have a stand-alone box that is sending serial communication packets to the UART port on the feather. The feather has a program running that 'uart.read(-something-) and puts it in a list type of sturcture. The thing it reads is probably an array of values derived from hardware. The dedicated box will probably be a beaglebone black (because it has a number of analog i/o pins) making a/d measurements from some analog potentiomenters. these will provide the digital values being put into the packets for the lights control. The beagleblack program will take the values and put them into a packet of values in a list format (byte array) and send that over the serial port, were the feather unpacks those and plugs the values into the functions.

I’ll probably be using python on the BBB and the feather is running circuitpython. Likewise for relays, I’ll have the state of switches (hardware) on the BBB box, read and also packed into the array which will be control the relays via the pins on the feather.

I’m doing the programing myself on the feather, using the tutorials and the onboard circuitpython. available on adafruit. It is a challenge learning how functions work and stuff. My biggest challenge, I think, is to figure out how to pack the data on one end and unpack it into the various variables on the other end. The readout of the sensors and state of the function variables is easily reported to the regular serial terminal with ‘print()’ statements somewhere in the various functions. Those happen every time the loops execute. Basically a ‘while True’ running on a top level program that calls functions in various separate sub-programs. The top level uart.read and then takes the values and does as above.

Right now it is mostly working, it writes out to the terminal and grabs data from the uart, but the data from the uart is formatted funny: "(b’data\r) so I’m going to have to figure out how to strip this to just the data, parse it into individual data fields and then write the various data to each variable I’m using.

Having a the values on the serial terminal read by something like vpython on the surface to create a display would be great. The control box with the switches and pots will likely have a HDMI display on it for the BBB to read from the UDP data and give a readout. No keyboard or anything.

The regular logitec 310 joystick and QGC running on the laptop will control 6 thrusters and 1 motor for a claw arm, plus a relay from the 8 main pwm outputs on the pixhawk, read from the Bar30 pressure sensor, and operate 2 servos to control pan/tilt on the attached USB camera to the RPi, trigger two relays for pneumatics on the claw/arm, read the leak sensor, all on the aux connectors.

I don’t yet know how to get the rangefinder sensor data into QGC so it can enable height-above-bottom hold mode, sending packets to the pixhawk. It is an I2C device, so theoretically It should connect directly to the pixhawk I2C port and just work, but I’m a bit confused on how to configure the parameters for the px4 software to use it.

So yes I write the software, bumbling as I am. It’s itterative/learning. I would love some Python examples of doing this kind of serial read/write stuff on the laptop and also on the BBB.

What I plan to do is publish on these forums all my code for the circuit python devices, all the specific parts I am using and diagrams of how I hook it up, once it is all working. Then of course I have to cram all this stuff into my custom housings, make all the physical wiring connections and that stuff. I plan to order more blue robotics penetrators and some flat windows for my housings. I’’ put up a build log with photos of it all, and the finished project. We will be using this ROV to support a scientific mission to some volcanic lakes, looking for hot spots using a temperature sensor array and taking bottom site samples of water and physical objects, and netting some organic material. The depth for all this is going to be around 20m to 65 or 75 meters.

Hope this answers your questions. I am acutely aware of my newbie status at programming and some things are not obvious because of that. I think the BR ArduSub is a fabulous resource and I realize that low budget operations like this won’t have professional programmers to make stuff like this work. So having concrete examples of working systems like this, (rather than handwaving) makes a massive difference to entry-level hobbyist and experimenters, or low budget scientific applications.

Thanks for your quick reply.


Hi Willian,

I was trying to get the first example of https://github.com/bluerobotics/ardusub-gitbook/pull/72/files

Using the first setup. I put a line in the circuitpython to send some info to uart.read to initiate the communication on that connection, every time it went through the loop.

When I connected or tried to connect with nc -ulp 1245 (#1245 is the port I assigned) It didn’t connect get any information at all, though it accepted data in the terminal window.

When it was just connected to the mac, I connected to /dev/tty.SLAB_USBtoUART and saw that the program was writing to the uart each loop.
So that wasn’t the problem. It doesn’t seem to be sending the stuff out the uart through the Pi, when it does when connected to the mac.

Any suggestions?

Hello Michael,

I’m sorry for the delay.
I have just tested here, with these setup:

And I was able to receive things fine on my topside computer using nc -ulp 5555.
For testing I used the “analogReadSerial” example of Arduino programmed to an Arduino Nano (I changed it to 115200 baud).

What baudrate are you using? There is currently an issue with other baudrates. It has been fixed in master but still is not present on any release. I’m sorry about that!

Please let us know if this works for you or you run into any further issues.

Best regards

Hi Willian,

Thanks for the reply… That helped, primarily the advice about the 115200 baud rate.

What I wound up doing after testing a couple of things is this:

Make sure my uart.read and uart.write were set to 115200 in the circuitpython code.py program running on the Adafruit Feather M0 Express. The Adafruit USBtoUART cable is connected to the tx and rx pins on the Feather. The USB end is connected to /dev/ttyUSB0 on the pi companion. The regular USB connection on the Feather is connected by usb cable to /dev/ttyAMC0 on the pi companion.

On the companion, in the screen, I set I tried what you posted, but couldn’t connect with a straight nc connection from terminal on my imac.

So I backed up and used the original suggestion of using


After rebooting the pi companion with this configuration, I was able to open a terminal window on the imac and open two windows:
$ nc -u 1240


$ nc -u 1245

So this worked. I get the output of both the USB connection to the pi from the Feather and also the USBtoUART connection from the pi to the Feather.

And I can do what I want, type in the one window, the Feather program reads from the uart it and writes it out to the uart window (for confirmation) and also writes it to the regular USB terminal window.

So with this I should be able to send formatted byte strings to the Feather, have the program parse the strings into various variables, apply the variables to the outputs from the Feather and change the state of the outputs.

And do it from ANY device on the 192.168.2.x network! Not just from the primary control computer running QGC.

Thanks for your help!


Thank you very much Willian. I was pulling my hair out :slight_smile:

When will other baud rate be available? I would like to use lower rates to limit bandwidth usage.

Just sharing my setup for testing. (Simulating the BR2 with Rpi)

Got a RPi powered by USB. Connected to my computer via ethernet. I have an arduino Nano connected to the RPi USB port.

I got a temperature probe connected to the arduino and the Arduino is running code to get the temperature. See code here: https://create.arduino.cc/projecthub/TheGadgetBoy/ds18b20-digital-temperature-sensor-and-arduino-9cc806

Implemented the routing as instructed:

Receiving my string via my Data Server Software:

Next step, temperature display UI.


No problem, It took me a while to understand what was going on, too :slightly_smiling_face:

It is already in master, so it will be our next companion release.

Thanks for sharing your setup, that is a great example of how this feature can be used!

Completed the small software last night.

Now showing the temperature in the top right corner:

This routing is such a great feature. I’ve been wanting to play with it for a while. Next project is ping controller with serial altitude output.

If anyone is interested in using a temperature probe and displaying it, let me know and I will upload the code on my website.


Hi etienne,

I would be very interested in using the code you have to display the temp probe data in QGC window.

I’m using three of the same probe to see if we can steer to hotspot on the floor of a volcanic lake. With the three displayed for port, center and starboard, we could steer toward the hottest side and perhaps center on a hotspot to take samples of that area.

I hope you can upload the code so I can see if it would work for me.


Hello Michael,

My application is written in Pascal and is independent from qgroundcontrol.

I only display it with the “top most” argument so it stays on top of all other applications when it loses focus.

I can share the code for the Arduino.

I can share the executable application for displaying, but I can’t share my Pascal code as some of it is proprietary.

Let me know if you’re still interested.