back to projects

AMS-X

An open modular filament system, driven over MQTT.

Stock hardware caps multi-material at four spools and asks a human to stand there for every change. None of that protocol is published, so the command set was pulled apart against a live machine.

  • Python
  • FastAPI
  • MQTT
  • ESP32
  • 3MF
one swap, end to end five states, each confirmed
  1. 01 retract server → printer
  2. 02 select server → spool module
  3. 03 feed spool module
  4. 04 sense sensor → server
  5. 05 resume server → printer

the printer already knows how to pause for a filament change. these are the steps something has to drive while it waits.

closed source? not any more

Four slots is a hardware answer to a software problem.

A model with six materials doesn’t need a bigger changer. It needs something to sit at the printer and swap spools on cue. The machine already knows how to pause for a filament change and resume afterwards — what it doesn’t have is anyone to talk to.

AMS-X is that someone: a server that reads the sliced job, knows exactly which layer needs which material, and drives the printer’s own change routine rather than writing gcode for the hotend.

stock
4 spools. Past the fourth, somebody stands at the printer and swaps them by hand.
AMS-X
n spools. Bolt on another module and the server drives the swap, one module per spool.
server
Python, FastAPI
control
MQTT over TLS, reverse-engineered
file transfer
FTPS, on the local network
plan source
the sliced .3mf, parsed server-side
spool module
an interface — human today
next
stepper, TMC2209 over ESP32

one swap, five states

Each step waits to be confirmed.

The server sends one message at a time and watches the machine’s own reports until the guard for that state holds. Nothing runs on a timer.

coming soon The player arrives with the footage. Every state is written out below, in order.

  1. 01 retract

    The plan says this layer changes material — so pause, and wait to be told it happened.

    The server never assumes a command landed. It asks the printer to pause, then watches the report stream until the machine itself says it is paused.

    actor
    server → printer
    guard
    report.layer_num === plan[i].layer

    device/+/request

    { "print": {
        "command":     "pause",
        "sequence_id": "2041"
    } }

    expects

    { "print": { "gcode_state": "PAUSE" } }
  2. 02 select

    Ask the spool module for the material the next layers need.

    The spool module is an interface, not a device. Today a human implements it; next it is a stepper driven by a TMC2209 on an ESP32, and nothing above this line changes.

    actor
    server → spool module
    guard
    plan[i].to in module.inventory

    http · spool module

    POST /spool/select
    { "slot": 3, "material": "PETG-clear" }

    expects

    { "ok": true, "slot": 3 }
  3. 03 feed

    Drive the new filament up to the extruder.

    Feed length and rate come from the module profile, not from the printer. The server is coordinating here — it is not authoring motion for the hotend.

    actor
    spool module
    guard
    module.state === "SELECTED"

    http · spool module

    POST /spool/feed
    { "mm": 620, "rate_mm_s": 12 }

    expects

    { "fed_mm": 620, "state": "FED" }
  4. 04 sense

    Confirm the filament is actually there before anything resumes.

    Nothing here runs on a timer. The runout sensor has to report present and settled, or the cycle stops and the print stays paused.

    actor
    sensor → server
    guard
    sensor.present && sensor.settled

    http · spool module

    GET /spool/sense

    expects

    { "present": true, "settled": true }
  5. 05 resume

    Hand control back and let the printer run its own change routine.

    This is the whole design decision: AMS-X drives the machine’s built-in filament-change behaviour instead of writing hotend gcode around it. Less to get wrong, and it survives firmware updates.

    actor
    server → printer
    guard
    all previous states confirmed

    device/+/request

    { "print": {
        "command":     "resume",
        "sequence_id": "2042"
    } }

    expects

    { "print": {
        "gcode_state": "RUNNING",
        "layer_num":   48
    } }
A full swap cycle, filmed — coming soon.

Where it is

running

The protocol half. The server parses the sliced job, talks to the printer over its own MQTT channel, drives pause and resume, and confirms every step against the machine’s report before the next one. None of those commands are documented anywhere — they came off a live machine.

on the bench

The spool module. Four motors turning on a desk, with the drive and guide parts being printed now. The swap step is a human implementing the same interface until they go on — nothing above that line changes when they do.