Can I Use Octoprint with a Networked Serial Port?

| Comments

The short answer is yes! Holy crap! I have my Prusa MK3S plugged into the USB port on my oldest OpenWRT router, and I am running Octoprint in a virtual machine on my homelab server. I have run five print jobs for a total of around five hours of print time, and I even slept through the night before starting the later jobs.

Everything is working great. Almost everything.

This is not a tutorial!

I don’t think I am doing this correctly. I am using socat on each end to move the serial port data across the network, and it is doing an absolutely fantastic job when the connection is active.

Hacker 3 Stable Diffusion

If the Octoprint server’s socat process dies, the socat process on the OpenWRT box just keeps on running, and it won’t let a new socat process connect. That means if I reboot the Octoprint server, I will have to ssh to the OpenWRT end to restart socat.

The man page for socat is a mile long. It is likely that I am missing something obvious. If I ever do find it, that might be the time for a tutorial.

Why on Earth would I run Octoprint this way?

The majority of Octoprint users run Octoprint on a Raspberry Pi. I have never done this here at home. When I bought my first 3D printer, I already had my little virtual machine host sitting next to the table where the printer was going to live. No reason to add a Raspberry Pi to the mix when I can just spin up a fresh VM for Octoprint.

I am trying to make my home office quieter for recording podcasts, so I have been considering the idea of moving my homelab server into the room with my network cupboard. How can I move my Octoprint server to the opposite side of the house?!

I could buy a Raspberry Pi, but they’re pretty expensive and hard to come by. I also thought about trying Octo4a on an old Android phone, but I’d need to buy cabling to let me charge the phone and plug it into my Prusa MK3S at the same time.

Then I remembered that I now have a spare OpenWRT router left over from my WiFi upgrade shenanigans, and it has a USB port. I was hoping I could add some extra gigabit switch ports to my office, gain the use of an extra WiFi access point to roam to, and extend my Octoprint server’s serial port all the way across the house.

The old D-Link tube router that I am using is roughly equivalent to the GL.iNet Mango OpenWRT travel router that I carry in my laptop bag. They have similar CPU, RAM, and storage specs, though the Mango lacks a 5.8 GHz radio and only has a pair of 10/100 Ethernet ports. It is nice to know that if I didn’t already have the D-Link ready to go ,that I could have bought another Mango for about $20.

Should anyone else do this?

Do you know what is awesome about the OctoPi disk images for the Raspberry Pi? You don’t need to be proficient with Linux, command lines, or shell scripts to get it up and running. You follow a short tutorial, plug a micro SD card into your Pi, and you’re off to the races.

I’ve been running Linux at home since the mid-nineties, and I was doing professional Linux work by the late nineties. Getting this up and printing didn’t take much more than ten minutes.

My Prusa MK3S and OpenWRT Serial Port Extender

Getting my init scripts to do the right thing on the router took longer than I’d like to admit. I needed to make sure socat didn’t try to start before Tailscale was downloaded and running, and I needed to make sure socat would restart itself if things went weird.

The number of times I had a typo in a path or accidentally left a wrong socat option on a command line was ridiculously high, and I have to wait two minutes every time I rebooted the router for a test. Those two-minute waits add up fast!

Is this a workout for the OpenWRT router from a decade ago?!

Not in the slightest. My old 16 MHz 80386SX in the early nineties didn’t even break a sweat transferring data over a modem at 115,200 baud. Sure, the fastest modem I had on that machine was a 14,400 baud, but it could go quite a lot faster when compressing text with v.42bis.

The MIPS processor in my D-Link DIR-860L is orders of magnitude faster. We could probably hang several printers off the back of this router if we used a USB hub, but I only have the one 3D printer.

socat on the D-Link doesn’t even register as using any CPU according to top.

Could I put a camera on the OpenWRT router?!

Maybe, but I don’t even want to try. I haven’t bothered with having a camera on my 3D printer in years. I don’t use Octolapse. I just print stuff.

You can connect a UVC webcam to an OpenWRT router, and there’s even an mjpeg-streamer package available. I don’t know how much horsepower you need to run mjpeg-streamer on a MIPS router, but it should be easy to point Octoprint and mjpeg-streamer on the router. If it works.

I would be trying this out today if I knew where my spare USB hub went to!

How long can your virtual serial cable be?!

I had to be silly, so I figured I should pretend to be one of those hackers from the movies who bounces their connection through all sorts of cities and satellites. I don’t have any satellites, and I don’t have all that many physical locations on my Tailscale network, but I pushed things as far as I could!

I added two more nodes to my socat loop. I ran a 3D printing job from Octoprint on my homelab server in Plano to a Digital Ocean droplet in New York. That node pointed its instance of socat at my Raspberry Pi at Brian Moses’s house, and that one finished the loop by pointing to my OpenWRT router here in Plano, TX.

What should have been a 13-minute print job took about an hour. My virtual serial cable would have been something like 3,000 miles long. Octoprint was about 80 ms away from the Prusa MK3S. Math says that we may have literally added 80 ms of print time to each of the 34,000 lines of gcode. How cool is that?!

The printer stuttered a lot, and the print was extremely ugly on account of all the short pauses. There were no smooth printing moves.

Was it slow and stuttering because of flow control on the serial port? Do you think finding a way to disable flow control in Octoprint would help with this symptom? Do you think the problem was that I added in an extra hop? I imagine things would be a lot better if I were running Octoprint in New York and printing in Plano with only a single socat connection between them. That would at least cut the latency in half!

This was silly. There’s probably no good reason to do this other than to say I 3D-printed an object over a 3,000-mile serial cable.

How do you make socat work?

I’ll say it one more time. I don’t think I am doing this quite correctly. These commands are working exceedingly well as long as I don’t have to reboot anything. I am pretty sure that if the power went out, everything would start up and connect correctly, but if I reboot one half, I almost definitely have to go in and restart the other machine’s socat process.

This is the script I am running on the OpenWRT router:

while true;
   /usr/bin/socat -d -d /dev/ttyACM0,b115200,raw,echo=0 TCP-LISTEN:9998,bind=,fork
  sleep 5;

You can leave out the bind option. I am using that to make sure socat is only listening on my Tailscale interface.

My socat process will error out over and over again until Tailscale starts. I thought about adding some logic to wait for the tailscale0 interface to show up before firing up socat, but I want socat restarting if it dies. I figured it’d be OK to be lazy and kill two birds with just the one loop.

Here is the script on my Octoprint server:

sleep 20

while true; do 
  socat TCP: PTY,link=/dev/ttyACM1,raw,crnl,mode=666; 
  sleep 2;

I have forgotten why there is a 20-second sleep at the beginning of this script. Was I working around a problem, or was I hoping this would cover up a problem that doesn’t even exist anymore? I would comment that out and reboot everything to test it out for you, but my printer is in the middle of a job!

UPDATE: Maybe this is less fragile than I think it is!

I moved my homelab server out of my office last night. I don’t have a shelf for it yet, the cables are all just running out of the network cupboard’s doors, and the machine is just sitting on top of a cardboard box to keep it off the floor. We wouldn’t want a leaky washing machine getting my server wet!

It took me long enough to power the server down, unplug everything from the UPS, and finagle the UPS out from behind my desk that by the time I got the server booted up and the Octoprint virtual machine going, the socat process in the Octoprint’s init script was able to connect to the OpenWRT router without a problem.

I don’t know how long it takes for the socat server to time out, but it definitely times out for me in some number of minutes. That means that as long as I am not too efficient in restarting my Octoprint server, I shouldn’t have to restart the socat server manually.


I am happy enough with how this all worked out. When it is working, it sure seems to work absolutely perfectly. I no longer have any reason to keep my homelab server in my office, and I am super excited that I will be able to eliminate the noise of four extra hard drives constantly seeking. Not only that, but I’ve added an extra 450 megabit of WiFi bandwidth to this corner of my house.

I will do my best to remember to report back in a few months if things manage to keep working this smoothly. If there’s a problem, I’ll be sure to report back immediately!