September 9, 2021 16:02
What?
The Prusa Mini+ has a problem: It has no WiFi. Also the software does not support any wifi module until now - that feature is planned, but not implemented. Additionally the web interface is, let’s say, not really working, as the printer struggles with serving the static contents (like .css
and .js
), which are required to render the site. This issue is also known since release 4.3.0
but also not resolved (#1285).
This article describes how I used an Orange Pi Zero LTS to get the printer on my WiFi, add an wirelessly accessible storage and “fix” the webinterface. For the first point I follow this gerneral idea and for the second we will take a look into NGINX and its caching abilities.
What will you need for this?
- Orange Pi zero LTS with Armbian and a case
- Sandisk class 10 32GB
- LAN & USB cable
- Prusa Mini+
Getting the Orange Pi ready
But before we start some more general words about the Orange Pi: The Orange Pi uses not too much power! It is completly satisfied by using an 5V 2A power supply (or even less, as it works fine on my USB 3.0 - which serves about 5V 500mA), but (at least for me) you have to ensure the utilized cable does also work fine. A not lit up green led on the PCB or missing serial output over the 3-pin header beside the LAN port are indicating critical power issues. Also random crashes or freezes during the boot stage commonly point to an brown-out on the board - I fixed both issues, by just using an other (higher quality) cable. Finally you should make sure to use the correct image (I used the Armbian Buster image, as Bullseye was not stable (user-space) during my experiments) for your specific Orange Pi Model - ask me how I know :)
Let it blink!
For further debugging (also down the road) I strongly recommend you to install this Systemd service unit, which reconfigures the Orange Pis leds to blink periodically and also shine during activity. This is very helpful to detect black- or brown-outs during later use (check your power cables, the printers USB port is powerful enough!). Note that any stop of the leds blinking is only “useful” after the red led started to blink initially.
[Unit]
Description=LED control service
Before=basic.target
After=local-fs.target
DefaultDependencies=no
[Service]
Type=oneshot
RemainAfterExit=yes
# Set the green LED twice, as it seems to be ignored on the first try. Mostly.
ExecStartPre=/usr/bin/bash -c '/usr/bin/echo activity > /sys/class/leds/orangepi\:red\:status/trigger'
ExecStartPre=/usr/bin/bash -c '/usr/bin/echo heartbeat > /sys/class/leds/orangepi\:green\:pwr/trigger'
ExecStart=/usr/bin/bash -c '/usr/bin/echo heartbeat > /sys/class/leds/orangepi\:green\:pwr/trigger'
ExecStop=/usr/bin/bash -c '/usr/bin/echo none > /sys/class/leds/orangepi\:green\:pwr/trigger'
ExecStopPost=/usr/bin/bash -c '/usr/bin/echo heartbeat > /sys/class/leds/orangepi\:red\:status/trigger'
[Install]
WantedBy=basic.target
Configure the LAN port
Set the Orange Pis LAN interface IP to a static one (as there is no DHCP on this site). I recommend to use nmtui
for that and to either create a new profile or to modify the existing one.
Make it a router - setup DHCP!
We will use dnsmasq
for that - make sure to install it beforehand. Then add those lines to the configuration:
port=0
interface=eth0
dhcp-range=192.168.10.50,192.168.10.250,12h
dhcp-host=xx:xx:xx:xx:xx:xx,PrusaMiniPlus,192.168.10.2
Insert the MAC address of your printer on xx:xx:xx:xx:xx:xx
. The config disables any DNS functionality (see here), locks it only to the LAN interface, configures a “static” IP for the printer and configures a dynamic port range (just in case).
Serve the webinterface
I’ve used NGINX for the caching of the webinterface, as it is small, fast and simple (?).
Add this (based on that) into your NGINX configuration (into the html
block).
proxy_cache_path /srv/nginx/cache levels=1:2 keys_zone=STATIC:10m max_size=1g;
server {
listen 80 default_server;
location / {
proxy_pass http://192.168.10.2;
proxy_set_header Host $host;
proxy_buffering on;
proxy_cache STATIC;
proxy_cache_valid 200;
proxy_cache_use_stale error timeout invalid_header updating
http_500 http_502 http_503 http_504;
proxy_read_timeout 600s;
}
error_page 502 /502.html;
location = /502.html {
alias /srv/502.html;
}
}
And then install this as the error page to /srv/502.html
:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Whooops!</title>
<meta http-equiv="refresh" content="60">
<style>
body {
margin:auto;
text-align:center;
}
</style>
</head>
<body>
<h1>Whoops!</h1>
<iframe src="https://giphy.com/embed/pcC2u7rl89b44" width="480" height="270" frameBorder="0" class="giphy-embed" allowFullScreen></iframe>
<p>
I am very sorry to inform you that NGINX failed to communicate with the printer.
This is commonly solved by restarting the printer and making sure it gets the correct ip address.
You may need to make sure to re-apply the <i>lan_settings.ini</i> from the attached virtual USB storage.
</p>
<p>Or maybe the printer is just not running. In that case - did you try to turn it off and on again?</p>
<p>Good luck,</p>
<p>IT Guy</p>
</body>
</html>
Make sure the cache path exist (e.g. /srv/nginx/cache
-> mkdir -p /srv/nginx/cache
) and to also use very high timeout values (again, the printer is messing up the responses)! Then restart NGINX to apply the changed config - the web interface should now load (give it time, reload it multiple times until it works) under port 80.
Simulate an USB stick
Now we let the orange Pi simulate a generic mass storage device with its own web interface.
Force the USB into “peripheral” mode
This step depends on which OS you use. Armbian is already preconfigured to serve a virtual serial console using the USB OTG port, but other systems may not.
If your system is not using the USB port as peripheral
but as otg
or host
you won’t be able to load and activate the kernel module (g_mass_storage
) during the next steps.
You may need to modify your device tree (which is compiled into your kernel) or create an appropiate overlay. Take a look into your /sys/class/firmware/devicetree/[USB_PORT_DRIVER]/dr_mode
to determine the state of your usb port mode. Further references about device trees, overlays and the Orange Pis processor are here, here and here.
Armbian: Disable virtual serial console
For that modify /etc/modules-load.d/modules.conf
and remove or comment (by prepending a #
) g_serial
.
Create the USB image
Let’s create the piusb.img
as FAT32
stick.
sudo fallocate -l 4G /piusb.img
sudo mkdosfs /piusb.img -F 32 -I
Mount that img on boot
So you can add files yourself - extend /etc/fstab
with (make sure the target directory exist and to use the sync
option to make any file modifications instantly visible to the printer):
/piusb.img /mnt/vstick auto defaults,rw,sync 0 0
Start the virtual USB on boot
Add g_mass_storage
into /etc/modules-load.d/modules.conf
and configure the loading options inside /etc/modprobe.d/g_mass_storage.conf
by appending:
options g_mass_storage file=/piusb.img stall=0 ro=1 removable=1
In case you want to know more about those options, use modinfo g_mass_storage
. Or maybe you want to emulate other virtual devices? Try this documentation!
Add an other webinterface
Let’s use Docker (-Compose) for hosting an other web interface with the files from the virtual USB image on port 8080:
version: '3'
services:
fm:
image: filebrowser/filebrowser
restart: always
ports:
- 8080:80
volumes:
- /mnt/vstick:/srv
- ./database.db:/database.db
- ./docker.json:/.filebrowser.json
Make sure to create the database.db and docker.json before you start it, as empty files / directories created by Docker will be contra-productive! To disable any authentication run this after the initial start via docker:
docker run --rm -it -v $(pwd)/database.db:/database.db filebrowser/filebrowser config set --auth.method=noauth
You may set the instance name to “Prusa Mini+” now.
Auto-Import USB files
You may implement this to auto-import any *.gcode
files from connected USB sticks automatically (primary reference is here).
sudo apt-get install autofs
- Insert into
/etc/auto.master
:/mnt/auto /etc/auto.automnt --timeout=5 --ghost
sudo mkdir /mnt/auto
- Now configure what should be mounted into this folder - append into
/etc/auto.automnt
that:stick -fstype=auto,sync :/dev/sda1
- Activate:
sudo systemctl reload autofs
- Add those cronjobs (
root
user) to import files and leave a warning for every user to use the web interface instead the USB stick:* * * * * find /mnt/auto/stick -name "*.gcode" -print0 | xargs -0 mv -v --target-directory=/mnt/loop 0 * * * * echo -e "DO NOT USE THIS STICK\nUse the webinterface to view the progress: http://[ORANGE_PI_IP]/\nAnd also to upload the files: http://[ORANGE_PI_IP]:8080/" > /mnt/auto/stick/README.txt
Prusa Mini+ Setup
Make sure to use a static IP configuration (I strongly recommend that, as it is way more stable), otherwise you have to implement the Dnsmasq part of the Orange Pi setup. This is the lan_settings.ini
which must be installed on your printer using any USB stick (or the virtual stick later on).
[lan_ip4]
type=STATIC
hostname=PrusaMINI
address=192.168.10.2
mask=255.255.255.0
gateway=192.168.10.1