Making your CNC accessible over wifi

(Note that I have included Amazon links for various pieces of hardware. If you are willing to wait a few weeks, buying direct from China on eBay for example can be significantly cheaper. Amazon is convenient but not always cheapest.)

There are several ways of configuring your CNC in order to access it remotely, as well as being able to switch conveniently between controlling it from Windows, and from a Linux system (probably a Raspberry Pi 3) which is permanently connected to your CNC.

The soulutions described here all involve attaching a Raspberry Pi directly to your CNC with a USB cable. The Raspberry Pi supports Wifi, so you do not need to be next to the Pi to use it. You can connect to it using SSH from any other computer, and/or you can run CNCjs on the Pi and access the CNCjs front end from a web browser on another computer. The other computer can be remote and connected over wifi or it could be local and connected by an ethernet cable. In my case the other computer is my Windows portable.

The Raspberry Pi on its own may be enough if you don't use any programs that are only available on Windows and which drive the CNC directly. But if you do use programs like that (for instance, Lightburn or LaserGRBL), you'll want the ability to switch between Linux and Windows at will.

The most trivial configuration to allow this of course is to simply unplug the CNC from the Linux, and plug it in to the Windows system instead. Depending on the physical layout of your work area, this could be a simple sensible option.

If your windows system is going to be permanently installed near your CNC, the simplest configuration that doesn't involve continually unplugging it is to plug the Windows system into the Linux and the Linux into the CNC. The Linux system will pass through all commands from the Windows system. To connect the Windows to the Linux, you'll need a USB Serial crossover cable, which you'll have to make. Software supplied here (proxymux) will allow either system to talk to the CNC without unplugging.

However if you want to use your windows system wirelessly, you'll need to build a special device, using a Raspberry Pi Zero W, which will plug in to your Windows system and act as if it were a USB Serial port. Software running on the Zero will forward the applications data to the CNC over Wifi using the serialtowifi program. The linux system receives that data and passes it to the CNC over the USB serial using the proxymux program.

(In the unlikely event that a specific recommendation from this project is ever widely adopted, Windows software could potentially connect to the proxymux program directly over WiFi, using a TCP/IP connection to port 3018. This would remove the need for the Pi Zero hack...)

There's a catch...

If you run any software on the Linux system that is attached directly to the CNC, and that software grabs exclusive control of the USB port connected to the CNC, none of the other software talked about here will be able to access the CNC. What I've done on my system as a short term workaround while I find a way to handle this issue is to have a second Raspberry Pi in the mix. This one runs any linux software that requires talking directly to a USB port. It connects to the other Raspberry Pi which is the one running the proxymux software, and it is that one which connects to the CNC. These two Raspberry Pi's are connected with a USB to USB null modem serial cable (though in a later release I hope to make that connection over wifi or a short piece of ethernet cable, if only to reduce the cost of this setup). My windows system connects to the proxymux machine over wifi. I don't currently have a solution for the case where both the Windows system and the Linux system run software that requires USB output, and is totally wired. CNCjs is an example of a Linux-hosted program that outputs GCODE to a USB serial port. Currently to use CNCjs as well as a Windows system without the need to swap plugs or start and stop programs, you would need the configuration with two Raspberry Pies (and the Pi Zero wifi dongle). That said, this is a fairly obscure configuration and not one that would be needed by the majority of users, who simply want to use their Windows software remotely from the CNC.

The Software

proxymux: this routes data from an input stream to the USB port which is connected to the CNC. The data can come from either a second USB Serial input on the Pi or from a network connection to port 3018. There may be multiple network connections. The multiplexing feature of this software is this: the last client to send data to the CNC - whether that client is the other USB port or one of the network connections - causes subsequent replies from the CNC to be directed back to that client. So as long as any other clients are quiet and don't send anything while they're idle, things just work out right. However if an idle client insists on sending periodic status requests (such as the gcode '?' command for example) then it may steal the focus back from the active program, which would be problematic.

serialtowifi: this has to be started up at boot time on the Zero. There are also some changes that need to be made in /boot/config.txt and /boot/cmdline.txt to put the Zero into 'gadget mode' in order to successfully act as a serial device. Note that the Pi Zero gadget doesn't require an external power supply - it just plugs directly in to the USB socket of your windows machine. The only downside of these gadgets is that the mechanical USB connection can be easily nudged, causing the Zero to reboot. This is not helped by the fact that the most common of the gadget addon boards essentially attaches the Zero upside-down.

Pi Zero wireless dongle

First, get your Pi Zero W. Then attach it to a USB add-on board. As well as installing the serialtowifi software, you'll need to modify two files in /boot as per these instructions.

Cable hack

As far as I have been able to find, there is only one supplier of pre-made USB to USB null-modem serial cables, and that is FTDI. They are relatively expensive and if the two computers you are trying to link are right next to each other, they're a bit on the long side. To connect two adjacent machines, it might be neater (and certainly cheaper) to make your own cable from two USB-serial modules connected back to back. UPDATE: There's now a USB to USB serial cable available through Amazon at a much better price than the FTDI one: https://www.amazon.com/gp/product/B08FM7C2TS (currently $19). However there's a caveat: it uses a PL2303GT chip which is not well supported in older versions of Raspbian - you may need to do a rpi-update to upgrade the firmware, before it will work.

There are lots of USB to serial adaptors avaiable, but I picked the ones below to link to because they come with a male USB A plug built in. Others would need an adaptor cable. Take two units and connect them back to back with the RX/TX swapped over. Done!

Here are units using 5 different kinds of serial chips. Some chips may work better in some computers than others, or may be supported by built-in software rather than requiring the addition of extra drivers. I have not tested any of these myself yet. Do report back to me which ones work with various systems.

An alternative to using a pre-made cable or building one of your own is to connect two USB to RS232 cables. These will have a USB on one end and a DB9 on the other. If you get one cable with a built-in null modem configuration, and made sure that one cable has a male DB9 and the other has a a female DB9, you could be able to plug them together and have them just work. This is actually what I have myself - not because it's the best option but because I already had the cables available.

Here is a USB to DB9 female with crossover and here is a USB to DB9 regular male. There are many combinations of such cables to be found, some long, some a few inches. Find a pair that work for you if you go this route.

You could also use two USB to DB9 male adapters and a DB9 female to female crossover cable.


The programs in this directory are:

serialtowifi:

This program requires a special hardware host - it needs a Pi Zero W configured in gadget mode. The PiZero Gadget can be plugged in the side of any computer with USB, in particular a Windows computer (usually a portable), for the purpose of using any of the Windows-based programs which will only talk to a CNC over a serial port connection. The Pi Zero impersonates a serial port, and this program forwards any data from the Windows machine to the CNC via the ProxyMux server over Wifi. Replies are returned back to the client program on the Windows machine.

proxymux: (previously a derivation of usbproxy)

This can either run on a single Pi, connected as ProxyMux<->CNC, or on a second Pi, connected as Controller<->ProxyMux<->CNC. It implements several functions:

Note that to connect the two Pies together via serial over USB, you need to use two USB<->Serial adapters and a null-modem cable. These can be bought off-the-shelf, though a hardware hacker could easily make a cable from components that would be shorter and simpler. (At some point I'll add a photo of my cabling solution to this page) Potentially this connection could be made over wired ethernet or WiFi as well, and save the cost of the USB null-modem serial cable, but that is for another day. (A cable like this would still be needed for the simpler Windows Portable<->ProxyMux<->CNC configuration)

Although proxymux is not required (a basic system is just Controller<->CNC), by inserting this module on a second Pi (Controller<->ProxyMux<->CNC), you open up the possibility of adding wireless clients. If you do not want to drive the CNC from Linux, you don't actually need the Controller machine, and can use only ProxyMux<->CNC, with the proxy machine's only purpose to be the receiver for the WiFi connection from the Pi Zero.

The configuration I use is:

 Windows Portable <-> Gadget <-\
                                \
                                 |-> ProxyMux <-> CNC
				/
                  Controller <-/

With this setup, I seldom need to start and stop any programs, or disconnect any wires. I can do everything from my Windows portable, whether it is a program like LightBurn which talks to the CNC over USB Serial (faked by the PiZero Gadget), or CNCjs on a web page (talking to the server end on "Controller"), or any of the linux-hosted utilities I use including my own 'gcode4' sender and "conversational machining" front end, which I access over ssh (Putty on Windows).

NOTE: proxymux was recently completely rewritten in order to add the ability to allow multiple network connections. (the first version only supported one network connection and one USB connection, and didn't handle dropped connections very well - they took a long time to reconnect. The newer version handles that issue completely differently and is much more robust).

gcode4:

This is a gcode sender with "conversational machining" support. You can send a gcode file with it, or type raw gcode, or invoke a limited number of procedures which have been written in C and built in to this program. It communicates with a CNC on the USB serial port. (If there is more than one port on the Pi, you can specify the port number as a parameter). This program will be modified soon to allow connecting to the CNC over a TCP/IP connection instead of the USB serial port.

NOTE: gcode4 is the author's plaything and the conversational machining extensions are somewhat idiosyncratic. The program is not really recommended for anyone except dedicated C hackers who should replace the extended commands with commands of their own choosing. Look on the code more as a framework for writing similar programs than as an actual program for using yourself.

wired-forwarder: (previously called usbproxy)

Use this if you are only using the one Pi, as your CNC controller, and you want to drive the CNC from Windows. Plug your windows machine into the Pi, and run this. You cannot run gcode4, or any other program which accesses the CNC at the same time. If you use cncjs, you cannot 'connect' from any cncjs client while wired-forwarder is running. Note that a better mechanism for connecting Windows clients is described above, but requires an extra Pi.

This program predates proxymux which implements the same functionality plus more. It is probably more sensible to use proxymux instead. wired-forwarder's only advantage over proxymux is that with only one input and one output, there is no need to be careful about which you assign to which USB port. The traffic is symmetrical. Whereas with proxymux you do need to know which of the two USB ports the CNC is connected to, in order to direct content that came in over wifi to the CNC and not to the other USB client.

Bonus hack!

With an 8 Megapixel camera and a long cable, you can watch your CNC in real time. (Not that you should ever leave your CNC unattended, but if you're going to do it anyway you might as well keep an eye on it...) (Or you can go the cheap route with a 5MP camera...)

All of the above are working to some extent but are not in what I would consider to be final release state. For example, proxymux assumes that the two USB ports will be connected to the CNC and another computer in the way that they are in my setup. I have not yet added a command-line parameter to tell the program which USB input is which (or to work it out at run-time by attempting to talk to the CNC and guess which port it is on). Use this software at your own risk and expect to put some effort into configuring it for now. It should improve over time as I make it more convenient for end users.