Files
p5-wallplotter/tutorial.md
T
2026-09-05 13:39:34 +02:00

13 KiB
Raw Blame History

Tutorial: p5-wallplotter

Dieses Tutorial erklärt, wie du das Repository lädst, den Beispiel-Sketch lokal startest, den Wandplotter per USB verbindest und was Marlin mit G-code eigentlich macht.

Kurzüberblick: Der Browser zeichnet mit p5.js. Die Library WallPlotter.js wandelt Linien in G-code um und schickt ihn über Web Serial an die Steuerung. Dort läuft Marlin mit Polargraph-Kinematik: Kartesische Koordinaten (X/Y in Millimetern) werden in zwei Riemenlängen übersetzt, die die Motoren auf- und abwickeln.

Voraussetzungen:

  • Chrome oder Edge (Web Serial gibt es nicht in Firefox oder Safari)
  • Python 3
  • USB-Kabel zum Plotter
  • Plotter mit Stromversorgung (Steuerung + Motoren)

Web Serial funktioniert nicht über file://. Die Seite muss von http://localhost oder über HTTPS kommen.


1. Repository herunterladen

Das Projekt liegt hier:

https://git.collectivemedia.space/martin/p5-wallplotter

Auf der Projektseite Code → Download ZIP (oder direkt archive/main.zip). Archiv entpacken und in den Ordner p5-wallplotter wechseln.

Was im Ordner liegt

p5-wallplotter/
├── lib/
│   ├── WallPlotter.js   # p5-Library: Serial, G-code, Preview, Tasten
│   ├── README.md        # Kurzüberblick + Beispiel
│   └── doc.md           # API-Referenz
├── examples/
│   ├── zickzack/        # Einstiegsbeispiel
│   └── rechteck/        # Rechteck zeichnen
├── hardware.md          # Motoren, Board, Geometrie
├── gcode.md             # G-code in diesem Setup
└── tutorial.md          # diese Anleitung

Es gibt kein npm install. Der Sketch lädt p5.js vom CDN; der Rest sind statische Dateien.


2. Umgebung starten

Ziel: einen lokalen HTTP-Server im Projektordner, danach den Sketch in Chrome/Edge öffnen.

Linux

Im Projektordner:

cd p5-wallplotter
python3 -m http.server 8080

Browser: http://localhost:8080/examples/zickzack/

Server mit Ctrl+C beenden.

Für den USB-Port braucht dein Benutzer die Serial-Gruppe. Nach der Änderung einmal ab- und anmelden:

# Debian / Ubuntu
sudo usermod -aG dialout "$USER"

# Arch / CachyOS
sudo usermod -aG uucp "$USER"

Prüfen, ob das Board erscheint (SKR Mini E3 V3 als USB-CDC):

ls /dev/ttyACM* /dev/ttyUSB*

Windows

  1. Python von python.org installieren. Beim Setup Add python.exe to PATH aktivieren.
  2. PowerShell oder Eingabeaufforderung im Projektordner:
cd p5-wallplotter
py -m http.server 8080

Falls py unbekannt ist: python -m http.server 8080.

  1. Chrome oder Edge: http://localhost:8080/examples/zickzack/

Das Board erscheint in der Geräte-Manager-Ansicht unter Anschlüsse (COM & LPT) als virtueller COM-Port. Web Serial zeigt denselben Port im Verbindungsdialog. Extra-Treiber sind bei der SKR Mini E3 V3 meist nicht nötig; wenn der Port fehlt, USB-Kabel wechseln (manche Kabel sind nur Ladekabel) und den STM32 Virtual COM Port / WinUSB-Pfad prüfen.

macOS

Im Terminal:

cd p5-wallplotter
python3 -m http.server 8080

Chrome oder Edge öffnen (nicht Safari): http://localhost:8080/examples/zickzack/

Der Port heisst typischerweise /dev/cu.usbmodem…. macOS hält einen Serial-Port oft fest, wenn der Tab nicht sauber schliesst. Seite neu laden oder den Tab schliessen, bevor du erneut verbindest — die Library gibt den Port beim Schliessen frei.

Falls python3 fehlt: xcode-select --install oder Python über Homebrew.

Browser-Check

  • Chrome oder Edge, aktuelle Version
  • chrome://flags nicht nötig; Web Serial ist standardmässig an
  • Beim ersten Verbinden erscheint ein Port-Picker — das ist gewollt (Browser-Sicherheitsmodell)

3. Plotter anschliessen

Hardware-Reihenfolge

  1. Strom an die Steuerung (SKR Mini E3 V3, typisch 24 V). Motoren brauchen die Versorgungsspannung; USB allein reicht nicht zum Fahren.
  2. USB von der Steuerung zum Rechner (Datenkabel).
  3. Gondel hängt an beiden Riemen, Stift sitzt im Halter, Papier/Wand ist frei.
  4. Sketch im Browser öffnen (localhost, siehe oben).
  5. Connect klicken oder Taste C.
  6. Im Dialog den Serial-Port der Steuerung wählen.

Home setzen (wichtig)

Marlin kennt nach dem Einschalten keine absolute Wand-Position. Du sagst ihm, wo „jetzt“ der Ursprung ist. Die Pfeiltasten funktionieren erst nach dem ersten Home:

  1. Taste H — Home an der aktuellen Gondelposition (G92 X0 Y0).
  2. Mit den Pfeiltasten (Stift oben) zur Mitte des Blattes fahren.
  3. Nochmals H — das setzt den Ursprung auf die Blattmitte.

Ohne Home bleibt Plot gesperrt.

Not-Aus

Diese Firmware hat keinen EMERGENCY_PARSER. Ein Stopp im Browser bricht nur das weitere Senden ab; die bereits laufende G1-Fahrt läuft weiter. Für einen harten Stopp: Strom trennen.


4. Der Plotter und seine Teile

Der Wandplotter ist ein Polargraph: eine Gondel hängt an zwei Riemen, die oben links und rechts über Motoren und Umlenkrollen laufen. Es gibt keine X/Y-Schienen. Position entsteht allein aus den beiden Riemenlängen.

Baugruppen, Anschlüsse und Geometrie: hardware.md.


5. Was Marlin mit G-code macht

G-code in einem Satz

G-code ist die Kommandosprache von CNC- und 3D-Druck-Steuerungen: eine Textzeile, ein Befehl. Der Host (hier der Browser) schreibt Zeilen auf die serielle Schnittstelle. Marlin parst sie, plant Bewegung oder I/O, und antwortet mit ok, wenn der Befehl angenommen ist.

Beispiel einer Fahrt mit Stift unten:

M280 P0 S30      ; Servo 0 auf 30° → Stift aufs Papier
G1 X120 Y-40 F2500   ; Gerade zu (120, −40) mm mit 2500 mm/min
M400             ; warten, bis die Bewegung wirklich fertig ist

Der Weg einer Linie

p5 sketch
  wp.draw(x, y)          → nur in eine Warteschlange legen
  wp.runPath(false)      → nacheinander senden
        │
        ▼
  USB Serial, 115200 Baud
        │
        ▼
  Marlin auf der SKR
    1. Zeile lesen, parsen
    2. G1: Ziel in mm merken
    3. inverse Kinematik: (X, Y) → (linke Riemenlänge, rechte Riemenlänge)
    4. Planner: Beschleunigung, Segmentierung
    5. Stepper-ISR: X- und Y-Treiber takten
    6. "ok" zurück an den Browser
        │
        ▼
  WallPlotter wartet auf ok, schickt M400, erst dann den nächsten Punkt

Test (runPath(true)) bleibt im Browser: gleiche Pfadliste, nur Animation. Es geht kein G-code raus.

Inverse Kinematik (Polargraph)

Ein kartesischer Drucker fährt Schlitten auf Schienen. Der Polargraph fährt Riemenlängen. Marlin rechnet für jedes Ziel:

linke Länge  = hypot( X − linke_Rolle ,  Y − Rollenlinie )
rechte Länge = hypot( rechte_Rolle − X , Y − Rollenlinie )

In der Firmware entspricht das HYPOT in inverse_kinematics: X-Stepper = linke Länge, Y-Stepper = rechte Länge. Eine waagerechte Linie auf der Wand ist für die Motoren keine gleichmässige Rotation — beide Motoren ändern die Länge gekoppelt. Marlin zerlegt die kartesische Gerade intern in kurze Segmente (DEFAULT_SEGMENTS_PER_SECOND), damit die Kurve der Riemelängen der Geraden auf der Wand folgt.

Deshalb muss Home zur realen Geometrie passen. Falsches G92 (z. B. Ursprung zu weit unter den Rollen) erzeugt den typischen Bogen nach oben bzw. eine konische Zeichnung: Marlin glaubt, die Gondel sei woanders, als sie hängt.

Befehlsliste: gcode.md.

Was Marlin nicht ist

Marlin ist keine Zeichen-App. Es weiss nichts von p5 oder deinem Sketch. Es bekommt nur Koordinaten und Servo-Winkel. Pfadplanung, Stiftlogik und die Vorschau liegen in WallPlotter.js. Die Firmware ist der Bewegungscontroller: parsen, in Riemenlängen umrechnen, Schritte erzeugen, ok sagen.


6. Eigenen Sketch schreiben

Kopiere den Ordner examples/zickzack/ und öffne darin sketch.js. Den Rest (HTML, Buttons, Verbinden) kannst du lassen. Du änderst nur drawPlot: dort steht, was gezeichnet wird.

Koordinaten sind Millimeter, Ursprung = Home, Y nach oben.

Fertiges Rechteck: examples/rechteck/. Im Browser http://localhost:8080/examples/rechteck/ öffnen. Nach dem Speichern die Seite neu laden (F5).

Was sketch.js macht

setup() läuft einmal beim Start:

  • createCanvas — Zeichenfläche im Browser, so gross wie das Fenster
  • parent('sketch-host') — Canvas in die HTML-Seite einhängen
  • new WallPlotter({ … }) — Verbindung zum Plotter. penUpGcode / penDownGcode sind die Servo-Winkel für Stift hoch und runter
  • setSpeed(3000, 1500) — Tempo in mm/min: zuerst leer fahren (Travel), dann zeichnen (Draw)
  • enableKeyInputs() — Tastatur: C, H, Pfeile, …
  • enablePlotButtons() — Buttons Connect, Plot, Test, Abort

draw() läuft dauernd (p5-Schleife): Hintergrund und HUD (showInfos).

plot() und test() rufen dieselbe Zeichnung auf. false = G-code an den Plotter, true = nur Vorschau im Browser.

Die Zeichnung: drawPlot

async function drawPlot(testOnly) {
  const s = 200;           // halbe Seitenlänge: 200 mm → Quadrat 400 × 400 mm
  wp.startPath();          // alte Linie löschen, neue Liste beginnen
  wp.move(-s, -s);         // Stift hoch, zur unteren linken Ecke (−200, −200)
  wp.draw(s, -s);          // Stift runter, nach rechts unten (200, −200)
  wp.draw(s, s);           // nach rechts oben (200, 200)
  wp.draw(-s, s);          // nach links oben (−200, 200)
  wp.draw(-s, -s);         // zurück zur ersten Ecke, Rechteck zu
  wp.move(0, 0);           // Stift hoch, zurück zur Blattmitte
  await wp.runPath(testOnly); // Liste abarbeiten: Test oder Plot
}

move und draw fahren noch nicht. Sie merken sich nur Punkte. runPath arbeitet die Liste der Reihe nach ab.

Aufruf Stift Wohin
wp.move(x, y) oben hinfahren, keine Linie
wp.draw(x, y) unten Linie vom letzten Punkt hierhin
wp.wait(ms) — Pause
wp.startPath() — Liste leeren
wp.runPath(true) — Vorschau (Test)
wp.runPath(false) — wirklich plotten

Mehr Befehle: lib/doc.md.


7. Tasten, Buttons, HUD

Taste Aktion
C Verbinden / trennen (Port-Dialog)
H Hier ist Home (G92 X0 Y0) — zuerst an der Gondel, nach dem Joggen nochmals in der Blattmitte
T Test (Vorschau)
A Abort: Test auf Start zurück
P Stift umschalten
0 Nach (0, 0) fahren (Pen-up)
← → ↑ ↓ Joggen, Stift oben
Shift + Pfeile Joggen, Stift unten
+ / - Schrittweite 1–100 mm
S Plot stoppen / pausieren

Buttons: Connect, Plot (wird Pause / Resume), Test (wird Stop), Abort.

Das HUD (unten und als Overlay) zeigt Verbindung, Home, Position, Stift, Serial-Log. Das Log rechts unten kannst du markieren — nützlich, wenn Marlin nicht mit ok antwortet.


8. Fehlerbehebung

Symptom Was prüfen
Kein Port-Dialog, oder „Serial not supported“ Chrome oder Edge, nicht Firefox/Safari. Seite über http://localhost:…, nicht als Datei öffnen.
Port erscheint nicht Strom der Steuerung an? Daten-USB-Kabel? Linux: Gruppe dialout oder uucp, neu einloggen. ls /dev/ttyACM*. Windows: Geräte-Manager → COM-Port. macOS: Tab schliessen und neu öffnen (Port oft blockiert).
Connect, aber keine Bewegung Netzteil an der SKR einstecken (typisch 24 V). USB allein speist die Motoren nicht. Dann H drücken. Linker Motor an Buchse X, rechter an Y.
„Home not set“ Zuerst H, dann zur Blattmitte joggen, nochmals H.
Stift bleibt oben oder kratzt penUpGcode / penDownGcode an den Servo anpassen (S-Winkel). Mit P testen.
Zeichnung bogenförmig / konisch Home falsch: Gondel 80 cm unter den Rollen, dann G92 X0 Y0. Rollenabstand 1660 mm.
Motoren heiss, Schritte verloren M906 X1000 Y1000. Riemen nicht zu straff. Tempo senken.
Plot hängt bei „waiting for Marlin ok“ USB wackelt, Board reset, oder lange G1 ohne ok. Resume nach Timeout; sonst USB neu stecken und Home neu setzen.
Stop im Browser, Gondel fährt weiter Normal: laufendes G1 wird nicht abgebrochen. Strom weg für Not-Aus.
macOS verbindet nur einmal Seite komplett schliessen, Port freigeben, erneut C.
Beispiel sieht alt aus nach einem Update Browser-Cache: hart neu laden (Ctrl+Shift+R) oder ?v= an WallPlotter.js in der HTML erhöhen.

Serial-Log im HUD lesen: Marlin-Fehler stehen dort als Text, nicht als Browser-Alert.


9. Mini-Ablauf zum Merken

  1. ZIP herunterladen und entpacken.
  2. python3 -m http.server 8080 (Windows: py -m http.server 8080).
  3. Chrome/Edge: http://localhost:8080/examples/zickzack/.
  4. Plotter mit Strom und USB verbinden.
  5. C → Port wählen.
  6. H (aktuelle Position), zur Blattmitte joggen, nochmals H.
  7. Test, dann Plot.

API-Referenz: lib/doc.md. G-code: gcode.md.