The 4.4.0 BETA2 firmware for the Original Prusa MINI/MINI+ is out on our GitHub page and the most important new feature is the support for Wi-Fi connections. And there’s no other way to put it: It took us a long time to deliver what was promised. It’s been a long complicated journey. We hit several dead ends, we had to find workarounds for hardware limitations – and we’re still not done yet. However, the support for wireless upload of G-codes and remote management of the MINI is working and we can finally talk about what we had to do to get it to this stage.

Adding Wi-Fi to the MINI+

The Original Prusa MINI+ is an affordable yet very capable machine. When the hardware team was designing it, the key was to find a balance between the number of features and price. Also, supporting all the encryption models of modern access points would be impossible on the current CPU of the MINI. This is why the Wi-Fi chip wasn’t embedded in the motherboard.

So instead, we went with the idea to add a simple header onto the motherboard that would allow the connection of a cheap ESP-01 board, turning the external microcontroller into a bridge between the wireless network and the USB drive. We did the research and found several open-source projects dealing with the networking capabilities of the ESP-01, so the project was a go.

What’s an ESP-01? It’s an inexpensive Wi-fi module consisting of a TCP/IP stack along with a built-in microcontroller. Its primary function is to bring wireless communication to embedded projects. It acts as a standalone microcontroller so it doesn’t require any other microcontroller (like Arduino or Atmel) in order to use its I/O pins. Basically, it’s a wireless-to-serial bridge with 1MB flash memory, a low-power 32-bit CPU and support for 802.11 b/g/n Wi-Fi networks. It’s been an incredibly popular and affordable solution since 2014. The Original Prusa MINI/MINI+ supports both the ESP-01 and the slightly modified version ESP-01S – more information can be found in the changelog.

We started working on the MINI’s Wi-Fi support near the end of 2020 with the intention to do the programming part properly from the beginning instead of just slapping a bunch of code together and releasing it in a rush because that would mean we would have to rewrite everything from scratch anyway, sooner or later. We assembled a dedicated team that was tasked with a proper analysis of the entire project and prototyping of the wireless solution.

Let’s do it properly

From the start, we were looking for a complex solution that would support not just simple transfers of G-codes via the local network but would also be compatible with our (then upcoming) PrusaLink and Prusa Connect farm management software. The plan was to create a stable TCP/IP stack for Ethernet and Wi-Fi, have the option to use BSD sockets and use an application layer – a website with remote-control capabilities running on an HTTP server directly on the printer. The team got the entire assignment and started working.

One of the key ideas was to keep the current firmware of the ESP-01 intact. There are a number of different ESP-01 variations and programming (and maintaining) our own firmware for these microcontrollers was assumed to be an overkill. There’s already an LwIP stack for the ESP-01, which takes care of SLIP (Serial Line IP via UARTs), NTP and static routing. First, we tried adding a parallel IP stack and LwESP, which is a lightweight ESP AT command parser library. Using an open-source solution seemed like the right way.

However, this is where we started hitting dead ends. There are various firmware versions for the ESP-01, each with a slightly different set of functionalities and varying levels of quality/reliability. It also meant we had to add a massive amount of code in the Buddy’s (MINI motherboard’s) firmware because of the LwESP library. In the end, it would mean to have two parallel IP stacks (one LwIP for ethernet and another one split between Buddy and ESP) and switch between them as necessary.

And there were more problems – only 5 connections, missing support for a UDP server and various other issues. In theory, we could make it work somehow, but testing and debugging it would be a nightmare. However, our colleague from the SLA team found a rather ingenious solution – he put together a special, lightweight custom-made firmware for the ESP-01.

The Eureka! Moment

So, finally, we had a prototype of a tiny special firmware that turned the ESP-01 into a network interface, something similar to the Ethernet chip on the Buddy motherboard. It was something we really needed: a step in the right direction.

And then, our team got a new reinforcement. To quote a classic movie: a person who has forgotten more about networking than all of us will ever know. And also a highly skilled C++ architect! He picked up where the previous attempts ended and started with a brand new analysis. It took him merely a month to implement a flexible and effective HTTP server that is capable of streaming request responses (i.e., it fits the limited RAM no matter how long the response is).

His colleague picked up the custom-made firmware and started evolving the ESP-acting-like-a-network-card prototype. First, he started with the wireless connection and connected the ESP via UART (serial interface) to a standard laptop. This way, we achieved speeds of up to 9/6 Mbit (download/upload). We finally had a reliable wireless connection with a speed surpassing the max throughput of the MINI’s UART interface, which is 4.6 Mbaud.

Connecting the ESP to the physical layer interface in the LwIP stack of the Buddy firmware brought not only code savings, but also eliminated the aforementioned schizophrenia of mixed IP stacks for two different interfaces. Things started looking really good.

Cursed USB drives

We were making great progress. The HTTP server was coming along nicely and we started adding more features – like uploading G-codes from PrusaSlicer and downloading G-codes from the printer. We added a new file browser with thumbnails in the web interface and implemented print start/stop functions (and several others).

By April 2022, we had a stable wireless connection and the firmware was almost ready for release. There was only one thing left to solve. It was, unfortunately, a major issue: ensuring the stability and compatibility of various USB drives – from the cheapest Chinese no-name models to branded USB disks. Just a little curiosity: many of the cheap Chinese no-name disks actually worked more reliably than more expensive models. 🙂 Either way, we had to solve incorrect timeouts in the USB driver first. We managed to tackle that in cooperation with STM. But then there was the other thing, something truly diabolical. While SD cards have very clearly specified response times, USB disks have no such thing. They can go “silent” even for dozens of seconds, plus there’s another thing called “housekeeping”.

To put it simply: USB drives are made to work mostly with standard computers – like laptops, media players and video game consoles. These machines have insane amounts of RAM (more than 1 MB :-)), so when you start to copy files onto a USB drive and it stops responding for a few seconds, there’s still a large buffer that helps to overcome this delay. “Housekeeping” is something the USB drive does automatically, it’s a routine responsible for the internal copying of data blocks to spread the level of wear more or less evenly across the flash memory to prolong the life of the storage device. However, this “sorting” takes some time.

Certain USB drives are so badly designed that they can stop responding for up to 10 seconds. We allocated 10 kB of RAM on the Buddy motherboard to serve as a buffer and thus we suppressed this problem. While it’s theoretically possible to upload G-codes even during active print jobs, it’s not recommended to use this function due to performance issues.

And finally, we had to solve the issue with the FATfs library. This library is primarily used for embedded devices and it tries to keep the filesystem as consistent as possible. This means that every time a fragment of a file is written, the drive’s chip starts updating the main and backup FAT table. This is another performance killer which will eventually lower the lifespan of the USB drive. Luckily, we found a solution: once you start uploading a G-code file, we already know the total file size – so we simply ask the filesystem to reserve space for the entire file first. Once the upload is finished, only then the FAT table is updated.

The road ahead of us

The current 4.4.0 BETA firmware already offers advanced network functionality and reliable G-code upload. However, we still have some work to do. We’re looking into whether we can reliably stream G-code files when the MINI/MINI+ is printing. As explained above, we’re limited by the technology of USB drives and while streaming is theoretically possible, there are still a lot of potential issues.

We’re still improving the code, so the current speeds are just over 100 kB/s depending on the quality of the wireless connection and 300 kB/s on ethernet. There’s still some headroom left. In theory, we should be able to achieve about 460 kB/s raw speed on the UART/ESP. We expect the final speed to be somewhere between 250-350 kB/s when optimized properly.

We would also like to focus on making the entire experience more user-friendly. Right now, you need to copy a special INI file onto the USB drive which is a somewhat barebones solution. It works, but there’s definitely room for improvement. And we want to implement more quality-of-life enhancements – like an actual signal strength indicator, for example. Let us know what else you would like to see!

There are plenty of different USB drives and various models of the ESP-01 module which may affect the speed one way or another. We’ll be very grateful if you decide to test drive the new MINI firmware and let us know what devices (ESP and USB) you are using and what’s your experience with them!

Of course, the entire firmware including the Wi-Fi ESP technology is completely open-source and the source codes are freely available on GitHub. So, if you want to play around with the ESP, feel free to grab the source codes here!

And you can check out the current firmware release on our Github page.