Take the Phrozen Arco off the stock Debian Buster / Klipper v0.11 stack — frozen at the factory version, with Buster now end-of-life — and onto a modern, fully self-hosted setup: armbian-mkspi (Debian Bookworm, kernel 6.18) · Klipper v0.13. All your factory hardware and features carry over — the serial touch display, both MCUs, chamber light, input shaper, the optional AMS and the PhrozenGo app — now running on a current, maintained and fully open system.
exclude_object, danger_options, faster) — and,
crucially, you can keep updating it instead of being
locked to the version Phrozen shipped.BED_MESH_CALIBRATE ADAPTIVE=1), so no add-on is needed for
it.http://unleashed.local/ (and
:81) and Fluidd on
unleashed.local:8808, the ports your Arco came with. Both
current, both themed.AMS auto-mode — one OrcaSlicer profile for everything. Slice single-colour or multicolour with the same profile; the printer works out which AMS mode to start in, at print start, on its own. No second profile, no switching in the slicer, no hand-edited G-code. And nothing to set: the printer sees the AMS on its own and keeps its own flag in step, so attaching or removing the unit needs no command and no menu. The flag and your slice are all the printer needs. See OrcaSlicer.
When something goes wrong. These four entries come first in the setup menu. They are the reason you can try this at all:
| Save the whole system | Every file, as one image, onto a USB stick. The same menu restores an image, or takes the printer back to Buster. |
| Save / restore your settings | The numbers your machine measured — configuration, calibration, the web interface’s own settings, your WiFi. Quick, no reboot, and it writes to a USB stick: the copy that survives a reflash. |
| Emergency repair | One action, no diagnosis required, for a printer that is halted, has no display, or whose update is failing. Fixes what it can, then says what broke. |
| Check self-heal guards | Everything this project patches heals itself — but only if a service still carries the guard that does it. A kit update adds none, so a printer that has run a while can be missing one, and nothing else says so. |
Printing, calibration and comfort. Every line here is a switch in the setup menu, except the one marked always on:
G30 |
loads your saved bed mesh — the mesh fix, the factory behaviour that never stuck |
Z_TILT_ADJUST · Z_TILT_LEVEL |
dual-Z alignment, homes first — the second name is the one Mainsail will show as a button |
SCREWS_TILT_CALCULATE |
manual screw bed levelling |
CALIBRATE_SHAPER_NEW |
input-shaper calibration, sweeping to 130 Hz |
PID_BED · PID_NOZZLE |
PID tuning |
BELT_TENSION |
parks where both belt spans are equal — details |
BELT_WARMUP |
belt and stepper warm-up before tensioning |
CLEAN_IDLERS |
turns the idlers in fixed steps, with a Mainsail dialog |
M600 · M601 |
filament change and pause, two-stage |
LOAD_FILAMENT · UNLOAD_FILAMENT |
manual, with priming — single-colour or no AMS |
FILA_STATUS (always on) |
is filament present, and is runout protection actually armed |
ARCO_FILA_EMPTY |
what happens when a print runs with an empty toolhead —
M600 standalone, PAUSE with an AMS, and yours
to rewrite |
TOGGLE_LIGHT |
chamber light — also a real toggle switch in Mainsail, and it follows the display |
AMS_SETUP |
one dialog: which slot serves which tool, and the refeed switch |
AMS_SLOTS · AMS_REFEED |
the same two settings as plain commands |
| board fan (PA2) | PID-controlled instead of always-on |
| piezo beeper (PB2) | short startup chime |
Plus exclude_object and [respond], a
branded Mainsail theme (light / dark),
Fluidd on :8808, ARCO_UPDATE
from the Mainsail console with an entry in Moonraker’s update manager,
and one switch that turns PhrozenGo and the cloud tunnel
off if you would rather run Obico.
They home first, which the factory equivalents do not: a calibration run from an assumed position measures the wrong thing.
CALIBRATE_SHAPER_NEW stops the sweep at 130
Hz. The stock macro runs to 150, and on this machine nothing
above 130 adds anything worth having — the extra range is only time on
the accelerometer. It is not a typo, and it should not be “fixed”.
FILA_STATUS reports what the stock firmware
keeps to itself: whether filament is present, and whether
runout protection is actually armed. Those are two different questions,
and the factory display answers neither.
Optional: Unleashed × KAOS. Chris Sanders’ KAOS — a
motion-safety and multicolour layer for the Arco — has a
sideloader built into the kit, sitting dormant until
you ask for it. KAOS_ON clones KAOS from Chris’s own GitLab
repository, verifies it, and wires it in; KAOS_OFF puts the
printer back exactly as it was and keeps the download cached for an
instant switch back; KAOS_STATUS says which commit is
installed and whether it is active. So the printer needs internet the
first time, and KAOS itself is never redistributed here
— you get it from its author, like Phrozen’s module. KAOS and this kit
each replace some of Phrozen’s macros, and running them naively together
breaks homing. That is why the sideloader exists: it wires the two
together so both keep working. See MANUAL ›
Step 10.
Install the easy way: flash the pre-built image, set WiFi, flash your MCUs — running in minutes.
Disclaimer. Arco Unleashed is an independent, community-made project. It is not developed, supported, sponsored, endorsed by, or affiliated with Phrozen Tech Co., Ltd. or ThroughTek Co., Ltd. No proprietary Phrozen/ThroughTek software is bundled, hosted or mirrored by this project. Phrozen’s parts reach the printer in one of two ways. The owner supplies their own
Arco_FW_V*.zip, obtained from official Phrozen sources and provided on a USB stick. Or, only after the owner confirms, thephrozen_devmodule is downloaded from Phrozen’s own public repository (phrozen3d/klipper, GPL-3.0), pinned to a fixed commit and checksum-verified. Phrozen, Arco and PhrozenGo are trademarks of their respective owners, used here only for identification (nominative fair use).⚠️ Hardware-specific: Phrozen Arco with MKS board (RK3328, STM32F407 + MKS_THR STM32F103), AP6212 WiFi. Not a generic Klipper kit.
⚠️ Warranty: replacing the factory OS/firmware and opening the printer will very likely void your Phrozen warranty. You do this to your own machine at your own risk. Keep a backup of the original eMMC (or the stock image) so you can restore it if you ever need to return the printer to stock.
You get a finished image (a .img.gz, or a pre-flashed
spare eMMC module). The whole software stack is already on it — you only
need to flash it, set WiFi, and flash your printer’s MCUs.
🛑 Phrozen’s gateway is rescued for you — but only if the printer flashes itself. It saves
phrozen_master,phrozen_slave_ota,device_tableand~/hdlDat, which live only in Phrozen’s original OS — the display talks to that gateway, and the AMS work mode lives beside it. You cannot download them, and no Phrozen package contains them. The flash then erases them for good. Without them the display spams connect to the server fail about eleven times a minute, stops returning to its home screen after calibration, and AMS detection hangs.The self-flash tool collects them itself, while the old system is still there, and refuses to flash if it cannot. There is one route where it never runs: pulling the eMMC and writing it from a PC. On that route, MANUAL › A0 has the command to collect the two files by hand.
It is not a backup of the printer. For a way back to the factory system, image the whole eMMC onto the stick first — MANUAL › Step 1, no teardown needed.
The printer flashes itself. You put the image on a USB stick, run one command over SSH, and the printer overwrites its own eMMC on the next boot. No teardown, no PC, nothing to unplug.
Taking the eMMC module out is not part of that. It is there for recovery if a flash ever fails, for setting up a spare module, or for keeping an untouched copy of the factory system — MANUAL › Appendix A.
| QUICKSTART | the condensed checklist — start here if you have done this kind of thing before |
| MANUAL | every screen and screwdriver step pictured, 1 → 10 in order |
| INSTALL-FLOWCHARTS | the same paths as diagrams, including the base-image and revert routes |
Those three are the install instructions. Everything below on this page is reference — the menu, the slicer profile, the optional features — not a fourth copy of the procedure.
⚠️ Bring the printer to Phrozen V199 first. That firmware carries the touch-panel firmware this project expects, and the panel is the one part Arco Unleashed never touches or ships. Start from something older and the display can misbehave — on a machine where the display is how you follow the install.
⚠️
arco-phrozen-ams.tar.gzexists nowhere else. The installer collects it for you while your printer is still the original one, and refuses to flash if it cannot. Only one case needs your hand: if you pull the eMMC and flash it from a PC, collect the file yourself (Appendix A). It is in no download and in none of Phrozen’s packages. Everything else on the stick comes out ofArco-Unleashed-USB.zip— extract it to the top level and you are done.⚠️ Flashing the MCUs is not optional. It is the one step that opens the printer (two buttons inside the toolhead), and until it is done Klipper cannot start and the display sits on an error screen. That is expected, not a fault.
Once it is installed, the printer answers to
unleashed.local —
ssh mks@unleashed.local, or
http://unleashed.local/ for the web interface. If your
network blocks mDNS, the address is also written to
ip.txt on the USB stick at every boot.
The setup menu runs an update check on start (if the kit is a git clone) and only prompts y/n when an update exists.
ESSENTIAL: Flash MCUs (Katapult toolhead + F407 DFU)
MAINTENANCE: Save / restore SETTINGS (the numbers you measured — quick, no reboot)
Save the WHOLE SYSTEM (every file, as one image — reboots)
also: restore an image · go back to Buster
Check self-heal guards (all wired? a kit update adds none)
SOMETHING BROKE: Emergency repair (halted, no display, update failing)
EXTRAS: PhrozenGo / Cloud · AddOn.cfg + Features
Beacon probe (experimental) · Sensorless XY homing (alternative)
UPDATE: check GitHub for a newer version
printer.cfg and halts the printer (Katapult keeps the F103
safe). The smart way is to stay ahead of it — this
option has three parts:
Backup
captures your printer configuration and calibration, the web interface’s
own settings (theme, presets, macro groups, history — none of it in
printer.cfg), your WiFi and the phrozen_dev module;
Restore puts them back. It can also write the backup to a
USB stick, which is the copy that survives a reflash —
the local one lives on the very eMMC it is protecting.
Pre-patch additionally writes your config onto a Phrozen
update stick, so the installer deploys your
printer.cfg instead of Phrozen’s.AddOn.cfg that lost its
[arco_mcu_timing] section, which silently stops the MCU
timing from being applied. Second: root-owned files in
~/klipper or ~/moonraker, which make
Moonraker’s update button fail with a git error that points nowhere near
the actual cause.klipper.service against what the kit’s own installer
writes, so the expected list cannot drift, and offers to install
anything missing. You do not have to do anything about
that: klipper.service runs a series of
ExecStartPre guards before klippy loads, so the restart
that follows any update puts everything straight back. This menu option
is the manual equivalent, idempotent and safe anytime. >
Moonraker’s three actions are not equally harmless.
Update refuses outright on a modified repo > and otherwise
just pulls. Soft recover resets tracked files and leaves
untracked ones alone. > Hard recover runs
git reset --hard + git clean -d -f, so
everything untracked is deleted — > phrozen_dev and our
modules with it. Slow and unnecessary, but not fatal: the guards put our
modules > back automatically, and a copy of your phrozen_dev
is kept outside the Klipper tree for exactly this > case. If it ever
does go wrong, Emergency repair above is the one action
to run. > Klipper is not pinned: it sits on
master with HEAD attached, the repository is clean and
valid, > and Moonraker offers new versions normally — nothing is
greyed out or held back. >
(scripts/pin-klipper-updates.sh can hold a version
deliberately, if you want that.)scripts/phrozengo.sh) — Privacy closes the frpc
SSH tunnel to the vendor’s server; the app still works
via TUTK. OTA toggles Phrozen’s auto-update — turn it
OFF to protect your v0.13 from a hostile Phrozen
firmware update. Disable stops the cloud app entirely (no
phone-home), frees the webcam + resources, and stops Phrozen from
deleting Obico on boot. Defaults are as Phrozen ship
them (all on); local display + light always stay. > ⚠️
Installing Obico? Turn PhrozenGo off first. Phrozen’s
own KlipperScreen launcher runs >
rm -rf ~/moonraker-obico and
~/moonraker-obico-env on every boot, and
PhrozenGo ships > on, so those lines are live on a
fresh printer. Obico installs cleanly, works until the next >
restart, and is then simply gone — with nothing in any log to explain
it. Disable here comments > the lines out. Other Moonraker
add-ons (Spoolman, Mobileraker) are not touched.ams flag in step, within seconds of plugging in or
unplugging. That flag steers OrcaSlicer automatically —
the print mode is picked at print start, see OrcaSlicer. Note: a
factory-NEW AMS additionally needs one-time provisioning (firmware
flash/pairing).scripts/beacon_toggle.sh status|on|off · setup menu →
b
Swaps Phrozen’s piezo probe for a Beacon
eddy-current probe: Z is homed by a virtual endstop, the bed mesh is
scanned instead of poked, and a 15×15 mesh costs less time than
the stock 6×6 did. The config comes from a real conversion contributed
by Philippe Humeau (unPhrozen) — including the gotchas
he paid for, which are written into beacon.cfg where you
need them.
Toggling is reversible: off puts the piezo probe
sections back exactly as they were (verified) and keeps your calibrated
beacon.cfg. It edits only the lines it marked as its own,
so the rest of printer.cfg survives both directions
untouched. on walks five gates before it changes anything,
and each one aborts cleanly:
probe_eddy_current + ldc1612, for LDC1612
probes like BTT Eddy), but Beacon speaks its own protocol over its own
MCU, so it needs the vendor’s out-of-tree module. If it is missing, you
are told what will be downloaded, from where, under which licence and to
which path — and asked. Nothing is redistributed by this kit.BEACON. A
backup is written, and it rolls back if Klipper does not come up.⚠️ Read this before switching
1. It is experimental in the literal sense. No Arco Unleashed developer has run it on a machine. Every number in
beacon.cfg—y_offset,z_positions, mesh bounds — is one other printer’s value, not an Arco constant. Treat them as a starting point and verify each one.2. Do not use the Arco display for anything Z-related afterwards. Not Z-calibration, not auto-levelling, not “probe” or mesh from the touchscreen. Its calibration flow was written for the piezo probe: it declares Z positions instead of measuring them (
SET_KINEMATIC_POSITION), and it loads a stored mesh that was probed against a different Z reference. On a Beacon machine that can drive Z out of safe bounds — it was tested, and it did. Use Mainsail or Fluidd for homing, probing, mesh and Z-offset. Printing from the display is unaffected.3. Verify
z_positionsbefore you trustZ_TILT_ADJUST. The order must match the physical Z motors, not the order of the config sections. Swapped, z_tilt diverges instead of converging and the retries make it worse. Check withSTEPPER_BUZZ STEPPER=stepper_z/stepper_z1and watch which side of the gantry moves.
What it changes. Four things have to
disappear from printer.cfg, which no include can
do. They are: [probe] (claims the same !PB9);
[homing_override] (claims G28 and drives Z
against the piezo); stepper_z’s
position_endstop (Klipper rejects it as unused once the
endstop is virtual); and stepper_z1’s
endstop_pin (a second endstop on a probe-homed rail). Each
is commented with a #:beacon: marker, so off
is a prefix strip. Everything additive lives in beacon.cfg,
included last so its section merges win.
Update safety. The Beacon module is untracked in
Klipper’s tree, so Klipper updates leave it alone; Moonraker is not
involved. A Phrozen update is the dangerous one — it
replaces printer.cfg wholesale, which would put the piezo
config back while a Beacon sits on the toolhead, and the next
G28 would drive Z down waiting for a trigger that cannot
come. So Beacon mode is re-applied by the ExecStartPre
config guard on every Klipper start, keyed off a marker file, before
klippy parses anything. A copy of your beacon.cfg is kept
outside printer_data/ for the same reason.
First steps after switching (in Mainsail/Fluidd, not
on the display): STEPPER_BUZZ both Z steppers →
G28 → Z_TILT_ADJUST → BEACON_CAL
(contact auto-calibration) → BEACON_MESH (re-scan the mesh
— the saved one was probed with the piezo).
scripts/sensorless_toggle.sh status|on|off · setup menu
→ s
X and Y stop by detecting motor load (Trinamic StallGuard) instead of by a microswitch. Z is untouched and keeps its load-cell probe.
The microswitches remain the default and the recommendation. They stop at the same physical place every time, for free, with nothing to tune. If your switches work, leave this off.
What makes it worth shipping is one specific failure: X’s microswitch hangs off the toolhead MCU while the driver’s DIAG line goes to the main MCU. A broken toolhead cable therefore kills the switch but not the sensorless path — the printer homes again without waiting for a spare part.
Proven on hardware here: G28 X, G28 Y and a
full G28 all home on StallGuard, and the disconnected
switches still click at the end of the move. Note that
G28 X brings Y to its endstop and clear first, on switches
and on StallGuard alike — see Homing a single axis below. The
click is the point — the stall happens at the mechanical stop,
so the zero does not shift and the filament cutter (X=319), the wipe
position (Y=322) and any saved mesh stay valid.
on equalises the two homing speeds, installs a
sensorless.cfg that gates StallGuard by velocity, and rolls
everything back if Klipper does not come up. It levels the speeds
down, never up: StallGuard’s reading is velocity-dependent, so
two axes at different speeds cannot share one sensitivity.
off puts the endstop and homing-speed lines back exactly as
they were, and removes the include — verified against the toggle’s own
backup. It edits those lines and nothing else, so anything else in
printer.cfg is carried through both directions untouched. A
Phrozen update replaces printer.cfg. So while sensorless
mode is enabled, the kit re-applies it before every Klipper start.
Otherwise the update would hand you back the dead switch you switched
away from.
⚠️ Read this before switching
1. Watch the first few homings, with
M112in reach. Wrong sensitivity means the carriage grinds into the rail instead of stopping, and on CoreXY that drags the other axis along. Listen for the switch to click: Klipper reports position0whether it reached the wall or tripped 2 mm in, so the sound is the only honest signal you have.2. Sensitivity is
driver_SGT, and the scale is backwards from intuition — LOWER is MORE sensitive. Grinds without stopping → lower it. Stops early with no click → raise it. The shipped1is what this hardware wanted at 30 mm/s and 1.2 A.3. Calibrate at your running current. A value found at a reduced current does not transfer. With too little current the motor slips instead of building the load StallGuard measures, so nothing triggers at all — which looks exactly like “sensorless does not work on this machine”.
G28 X moves Y first. That is deliberate, and it is worth
knowing before it surprises you: Y travels to its endstop and then 50 mm
clear, and only then does X home. G28 Y homes Y alone and
leaves X where it is. A plain G28 is unchanged — same full
sequence, same probe.
The reason is a crash reported from a printer. Park the toolhead at
the back, restart the firmware, send G28 X, and the head is
dragged sideways through the wipe unit at Y=322 on its way to the X
endstop — confirmed on the machine it happened to. Two things make that
possible. Phrozen’s homing section is declared axes: z, so
Klipper never routed a single-axis home through it and the Y-first order
it already contained was skipped. And a firmware restart leaves the
printer looking homed. Instead of clearing the position, it declares
one, so Klipper believes the head sits at the middle of the bed no
matter where it really is, and nothing refuses the move.
Y is homed rather than nudged forward a fixed distance because a homing move watches the endstop while it travels. A plain move does not, and no fixed distance can know how far back the head started.
Same behaviour on microswitches and on StallGuard.
One thing this does not fix: Z. After a firmware
restart the declared height is an assumption, not a measurement, so
home before you move Z. The declaration is deliberately
set to the bottom of the travel, so Klipper refuses anything more than 5
mm downward until a real home. It gives you no protection upward: a
large upward move is still yours to get wrong. G28 works
from anywhere and settles it.
An electric-cobalt comic theme matching the Arco Unleashed branding — navy glass panels, halftone-burst background, the bookworm logo + a Burst “U” favicon.
mainsail-theme/, light / dark +
a switcher. Full details in its README.fluidd-theme/, the same look
ported (both apps are Vuetify, so it is the same design, not a
lookalike). Install with
bash fluidd-theme/setup-fluidd-theme.sh, then reload with
Ctrl+F5 and pick the dark theme. Fluidd has no hook for
a custom logo or favicon, so those stay its own.Mainsail can’t add named themes to its dropdown (that needs
a Mainsail fork/rebuild, which breaks on every update), so the kit ships
two .theme variants + a switcher instead —
update-safe:
| Variant | Base |
|---|---|
| Voron Light | navy #070E1F (default) |
| Voron Dark | near-black #02050c (same accents / logo / favicon) |
| Stock | theme off (plain Mainsail) |
Switch over SSH with
sh ~/printer_data/config/unleashed-theme.sh next, which
cycles light → dark → stock. Or switch with one click in the
Macros panel via SWITCH_THEME (needs the
gcode_shell_command extension;
setup-theme-macros.sh wires it up). Hard-reload after
switching (Ctrl+F5). The active state is kept in
.theme-state and survives reboots. Note: the
.theme overlay is global, so it also tints the built-in
themes — keeping those pristine would need a Mainsail fork (out of
scope, not update-safe).
The Arco is a single-nozzle multicolor printer (filament-swap, like a Bambu AMS).
You need exactly one OrcaSlicer profile. Not one for AMS and one without, and nothing to switch before you slice. Slice single-colour or multicolour as the model needs, send it, and the printer picks the right AMS mode at print start by itself.
That works because the printer makes the decision, not the slicer. It decides from two things: what you sliced — one filament or several, which the start G-code passes through — and whether an AMS is attached, which the printer remembers.
Nothing to set, not even when the hardware changes.
Attaching or removing the AMS used to need a command; it does not any
more. The unit is a USB serial device, the printer watches for it, and
the flag OrcaSlicer reads follows within seconds — no restart, no menu,
nothing to remember. FILA_STATUS shows what the printer
currently thinks, if you want to check.
The flag lives in [save_variables], so it survives
reboots and updates, and arco_tool_gate keeps it honest:
T1–T15 are registered exactly while an AMS is
attached. There is one case it will not act on: a running print. If a
unit drops off the bus mid-job, the tools and the flag stay as they are
until the job has finished. Taking either away underneath a multicolour
print is worse than a stale reading.
Profile. Stock OrcaSlicer already ships the official
Phrozen Arco profile (vendor Phrozen, no
fork needed). The kit adds an enhanced variant in orca/ with the Machine G-code already
filled in — import it via File → Import → Import Configs…. To
set the fields by hand instead, or to check an older profile against the
current one, go to MANUAL ›
Step 9. It gives all four G-code fields in full, with a
screenshot of the tab each belongs in.
All of that happens inside the start G-code:
PHROZEN_AMS_START reads the flag and the print begins in
the right mode. Nothing to pick, nothing to remember — and if you slice
multicolour with no AMS attached, it stops and says so rather than
starting something it cannot finish.
One thing does not announce itself, though: with the AMS fitted and a single-colour slice, the printer runs an endless spool and refills from the other slots when one runs out. Load them with the same colour — otherwise a long print changes shade partway through, and nothing warns you.
The start G-code heats the bed straight to print
temperature and holds the nozzle at a probe-safe 140
°C through home and probe, so it cannot ooze onto the load
cell. G30 then loads your saved
phrozen mesh instantly — calibrating and saving it the
first time, if none exists yet. Homing is automatic. It needs the
auto_mode and ams features in
AddOn.cfg, both on by default, and the
gcode_shell_command extension.
Instead of loading the saved full-bed mesh, Klipper can probe
only the print area on each print. You trade the
instant G30 load for 30–60 s of probing per
print, and get a mesh measured where the part actually sits.
Adaptive meshes are transient (adaptive-XXXX) and never
overwrite your saved phrozen profile, so switching back is
just switching back. It needs OrcaSlicer’s Label objects
checkbox — that is what emits the object bounding boxes adaptive meshing
reads.
How to switch, and the one thing to check on your first slice: MANUAL › Step 9.
You do not need mode-specific Pause or Change
filament G-code. One profile covers both cases, because
the printer-side macros read the ams flag themselves. With
an AMS, a colour change purges the slice’s flush volume through it.
Without one, it runs the full manual retract → load → purge → resume.
Pause behaves the same either way. Stock Klipper has no
M601, so the kit maps Orca’s M601 onto
Klipper’s PAUSE and a pause-at-layer works instead of
hitting Unknown command.
Runout protection depends on the start G-code. The
toolhead sensor is watched by Phrozen’s module, but only once a print
mode has been set — which is what PHROZEN_AMS_START does. A
start G-code without it prints unprotected, and stock
firmware never says so. This kit does: a console warning once the job is
past its start G-code, FILA_STATUS on demand, and
printer['arco_fila_status'] (filament_present,
adc, threshold,
protection_active) for your own macros. It is read-only —
detection and pausing stay with Phrozen’s module.
Three macros for the mechanics, all of them in AddOn.cfg
and all toggleable from the setup menu. They derive their limits from
your own configuration rather than carrying hard-coded coordinates, so a
different bed or a different mesh does not silently inherit numbers
chosen for one machine.
BELT_TENSION — homes, then parks where
both belt spans are equal, which is where you pluck
them. That is not the middle of the bed and not the middle of the
travel: behind the Y rail there is a further 60 mm of belt to the idler
(measured on this machine), so the middle of the span is Y190
where the middle of the travel would be Y160. Park at the wrong place
and two perfectly matched belts read as mismatched. Aim for
equal pitch between the two, not for any particular
frequency — the absolute number depends on span length. Leave the
steppers energised; M84 lets the belts go slack and the
reading is void.
BELT_WARMUP — runs the gantry through
its range to warm the belts and steppers up.
BELT_WARMUP ACCEL=5000 MARGIN=40 SPEED=200 CYCLES=10. It
bounds its own acceleration rather than inheriting the machine’s 40000
ceiling. At the low end it keeps MARGIN off the frame; at
the high end it stays clear of the purge/wipe unit. Those two ends are
not symmetric, so it derives them separately. Previous limits are
restored, and it re-homes at the end rather than trusting the step
count, because a cold-belt warm-up at speed is precisely what can lose
steps.
CLEAN_IDLERS — turns the idler pulleys
a measured amount so you can wipe the deposits off them. Run it with no
arguments and it opens a dialog in Mainsail or Fluidd: pick the
left or right pulleys, and the
toolhead parks at the opposite end so it is not travelling past the hand
holding the cotton bud. A second dialog with a Stop
button replaces it while it runs.
One turn of a 20-tooth GT2 pulley is 40 mm of belt, so the default
1.5 turns is 60 mm — and on CoreXY that is also 60 mm of carriage
travel, with no ratio to correct for. Everything is adjustable:
CLEAN_IDLERS SIDE=left TURNS=1.5 TEETH=20 SPEED=45 PAUSE=3 PAUSE_TURN=1.
It pauses before each forward pass, which is when you
hold the bud against the pulley — not while it moves. At the far end it
pauses only briefly. It refuses while a print is running, and refuses if
the requested turns would carry Y past the purge unit.
config-templates/ printer.cfg + includes + AddOn.cfg + wpa (templates; secrets/serial removed)
scripts/ unleashed_setup.sh the setup MENU; _arco-lib.sh = shared helpers/actions
fetch-phrozen-fw · usb-fw <- installs Phrozen's module: user's USB zip first, else a confirmed fetch from Phrozen's own repo)
apply-phrozen-patches (3 v0.13 sed fixes + the SHAPER_END/BED_PROBE_END cal-handshake macros — only our rules)
apply-phrozen-restore (keeps a copy of YOUR phrozen_dev outside the Klipper tree; puts it back if an update deleted it)
emergency-repair (one action for "something broke" — runs every repair, reports what was wrong)
apt-hold (mask auto-apt/unattended-upgrades + hold kernel/DTB/fw) · fix-gpio-led · resize-emmc · optimize-fs (noatime)
optimize-boot -> 40k real-time tuning: performance governor · klippy CPU3 + F407-IRQ affinity · numpy=1 · F407 USB no-suspend · ImageId
flash_mcus [f407|f103|host] · install-katapult · set-mcu-serial
phrozengo · addon-toggle · addon-features · phrozen-recover · selfupdate
beacon_toggle (EXPERIMENTAL: piezo probe <-> Beacon; reversible printer.cfg surgery)
arco_*.py own Klipper extras, untracked + self-healed by apply-arco-extras (ExecStartPre):
mcu_timing (MCU timing without patching mcu.py) · tool_gate (hide T1-T15 without an AMS)
sdcard_select (SDCARD_SELECT_FILE for the display) · fila_status (filament state, read-only)
arco-firstrun (portal→fetch→install) · wifi-portal/ · tft.sh (boot progress screen)
arco-splash (loading-screen branding)
system/ USB automount (udev rule + mount service) for the gcodes/USB stick path
collect_data_arco.sh grab phrozen_master + ~/hdlDat (Phrozen gateway, NOT in the zip) from YOUR
printer -> USB
mainsail-theme/ optional Arco Unleashed Mainsail theme (Voron Light/Dark + switcher + mainsail-seed)
orca/ OrcaSlicer profile (flag-driven AMS auto-mode; import or copy the start-gcode line)
Arco_FW_V*.zip, obtained by you from
Phrozen), or — after you confirm — straight from Phrozen’s own
public repository. The parts in question are the
phrozen_dev Python module (GPL-3.0, phrozen3d/klipper) and
the proprietary ones: the voronFDM display binary
(Phrozen’s own closed-source C++, not GPL despite the name),
the display .tft and the AMS firmware. This repository
ships the patch rules and its own scripts; the DTB and the WiFi
firmware are in the image, not here. The config
templates under config-templates/ do derive from Phrozen’s
own Arco configuration, which they publish under
AGPL-3.0 (phrozen3d/Phrozen_ARCO)
— the same licence as this project, which is what makes that legitimate.
See THIRD-PARTY-NOTICES.md.Phrozen, Arco and PhrozenGo are trademarks of Phrozen Tech Co., Ltd.; ThroughTek, Kalay and TUTK of ThroughTek Co., Ltd. They are used here only for identification/description (nominative fair use). All trademarks and copyrights remain with their respective owners. Arco Unleashed is an independent, community-made project — not developed, supported, sponsored, endorsed by, or affiliated with Phrozen or ThroughTek. No proprietary Phrozen/ThroughTek software is bundled, hosted or mirrored; Phrozen’s parts come either from the official package the owner obtains from Phrozen and provides on a USB stick, or — only after the owner confirms — from Phrozen’s own public repository. See THIRD-PARTY-NOTICES.md.
Arco Unleashed — Copyright © 2026 solutionphil. Licensed under the GNU Affero General Public License v3.0 (AGPL-3.0) — see LICENSE and NOTICE.
If you redistribute or build on Arco Unleashed, AGPL-3.0 requires you to keep it open (publish your complete source, including for any networked/hosted use), state your changes, and preserve the copyright notice and the “Arco Unleashed” attribution (github.com/solutionphil/arco-unleashed) — this attribution is a stated additional term under AGPL §7(b), in the source and in any user-facing “About”/documentation of your derivative.
Bundled third-party components keep their own licenses (the Klipper MCU firmware is GPL-3.0) — see THIRD-PARTY-NOTICES.md.
⚠️ Working with electricity and electronic components can be dangerous. Always ensure you take the necessary safety precautions when handling electrical devices.
This software and associated documentation are provided “as is” without warranty of any kind, either express or implied, including but not limited to the implied warranties of merchantability and fitness for a particular purpose. In no event shall the authors or copyright holders be liable for any claim, damages, or other liability, whether in an action of contract, tort, or otherwise, arising from, out of, or in connection with the software or the use or other dealings in the software.
Use this software at your own risk. The authors are not responsible for any damage to your equipment, personal injury, or any other consequences resulting from the use of this software.