Files
p5-wallplotter/tutorial.md
T
2026-09-06 00:47:31 +02:00

15 KiB
Raw Blame History

Tutorial: p5-wallplotter

Dieses Tutorial erklärt, wie du das Repository lädst, den Beispiel-Sketch in VS Code 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 (Web Serial; nicht Firefox oder Safari)
  • VS Code (Editor für den Workshop)
  • Python 3
  • USB-Kabel zum Plotter
  • Plotter mit Stromversorgung (Steuerung + Motoren)

1.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. Den Ordner p5-wallplotter an einem sinnvollen Ort ablegen. Wir arbeiten innerhalb von diesem Ordner weiter.

Was im Ordner liegt

  • lib/WallPlotter.js — p5-Library: Serial, G-code, Preview, Tasten
  • lib/README.md — Kurzüberblick + Beispiel
  • lib/doc.md — API-Referenz
  • examples/zickzack/ — Einstiegsbeispiel
  • examples/rechteck/ — Rechteck zeichnen
  • hardware.md — Motoren, Board, Geometrie
  • gcode.md — G-code in diesem Setup
  • plotter.svg — Geräte und Signalweg
  • tutorial.md — diese Anleitung

1.2 Umgebung starten

Ziel: den Ordner in VS Code öffnen, dort den lokalen HTTP-Server starten, danach den Sketch in Chrome öffnen. Chrome bringt Web Serial mit — darüber redet der Browser mit dem Plotter über USB. Firefox und Safari können das nicht.

Server in VS Code

  1. VS Code: Datei → Ordner öffnen → Ordner p5-wallplotter wählen.
  2. Terminal in der IDE öffnen: Ansicht → Terminal. Das Terminal startet im Projektordner.
  3. Server im VS-Code-Terminal starten:

Linux und macOS:

python3 -m http.server 8080

Windows (Python von python.org, beim Setup Add python.exe to PATH):

py -m http.server 8080

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

  1. Die Seite in Chrome öffnen: http://localhost:8080/examples/zickzack/

Server kann mit Ctrl+C im VS-Code-Terminal beendet werden.

USB je nach System

macOS. 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.

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

Windows. Das Board erscheint im Geräte-Manager 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.

Browser-Check

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

2.1 Eigenen Sketch schreiben

Unter examples/ liegen die Vorlagen (siehe Abschnitt 1): zickzack/ und rechteck/. Lege einen Ordner sketches/ an (neben examples/). Dupliziere ein Beispiel hinein und benenne es um, zum Beispiel sketches/mein-sketch/

p5-wallplotter/
├── examples/              Vorlagen, nicht ändern
│   ├── zickzack/
│   └── rechteck/
└── sketches/              deine Sketches
    └── mein-sketch/
        ├── index.html
        └── sketch.js      hier drawPlot anpassen

Dann öffne darin sketch.js. Den Rest (HTML, Buttons, Verbinden) kannst du lassen. Ändere die Inhalte in der Funktion drawPlot: dort steht, was gezeichnet wird.

Chrome, gleicher Server: http://localhost:8080/sketches/mein-sketch/ (Ordnername in der URL anpassen). Nach dem Speichern die Seite neu laden (F5). Der Python-Server muss nicht neu starten.

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

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

Die Zeichnung: drawPlot

Koordinatensystem. In p5 liegt (0, 0) sonst oben links, und y wächst nach unten. Hier ist es anders: Ursprung ist die Blattmitte (Home, x = 0, y = 0), Werte in Millimetern. y nach oben ist positiv, x nach rechts ebenfalls.

            +y (oben)
             |
             |
    -x ------0------ +x
             |
             |
            -y (unten)
async function drawPlot(testOnly) {
  const s = 200;           // halbe Seitenlänge: 200 mm → Quadrat 400 × 400 mm
  wp.startPath();          // Queue leeren, neu 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); // Queue abarbeiten: Test oder Plot
}

move und draw fahren noch nicht. Sie hängen nur Punkte an die Queue (Array). runPath arbeitet sie der Reihe nach ab.

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

Mehr Befehle: lib/doc.md.

3.1 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.

3.2 Home setzen (wichtig)

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

  1. Einschalten oder nach neuer Verbindung
  2. Taste H — Home an der aktuellen Gondelposition.
  3. Mit den Pfeiltasten zur Mitte des Blattes fahren.
  4. 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.

3.3 Bedienung

Tasten, Buttons, HUD

Shortcuts:

  • 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 (Stift oben)
  • ← → ↑ ↓ — Joggen, Stift oben
  • Shift + Pfeile — Joggen, Stift unten
  • + / − — Schrittweite 1–100 mm
  • S — Plot stoppen / pausieren

Das HUD (unten und als Overlay) zeigt Verbindung, Home, Position, Stift, Serial-Log.

4. Polargraph und Marlin

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.

Was Marlin mit G-code macht

Marlin ist die Firmware auf dem Controller: ein Programm, das dauernd auf der Platine läuft. Der Name klingt wie Merlin der Zauberer — gemeint ist aber der Speerfisch, und die Software für 3D-Drucker (hier mit Polargraph-Kinematik): marlinfw.org. Die Platine heisst SKR (BigTreeTech SKR Mini E3 V3): die Steuerkarte am Plotter, mit USB, Motorbuchsen und 24-V-Netzteil. Marlin nimmt G-code entgegen, rechnet ihn in Motorbewegungen um und gibt ok zurück. Ohne Marlin sind USB und Motoren nur Hardware — niemand versteht die Zeichenbefehle.

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 liest 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

wp.draw legt die Linie nur in eine Queue (ein Array von Punkten). Der Plotter hat noch nichts gehört.

Plot (runPath(false)) nimmt die Queue Eintrag für Eintrag und schickt sie per USB an Marlin. Marlin liest das Ziel in Millimetern, rechnet daraus zwei Riemenlängen, bewegt die Motoren und antwortet mit ok: Befehl angekommen, nächster Eintrag bitte. Die Library wartet auf ok und auf M400 (Gondel steht wirklich still), erst dann kommt die nächste Linie. Sonst würde der Browser schon weiterreden, während die Gondel noch unterwegs ist.

Test (runPath(true)): gleiche Queue, nur Animation im Browser. Marlin bekommt keinen G-code. Gut zum Üben, bevor der Stift die Wand kennenlernt.

Inverse Kinematik (Polargraph)

Ein kartesischer Drucker fährt Schlitten auf Schienen. Der Polargraph fährt Riemenlängen. Jeder Riemen ist die Hypotenuse vom Umlenkpunkt zur Gondel — Pythagoras, in Marlin HYPOT:

L_links  = sqrt( (X − X_links)^2  + (Y − Y_rollen)^2 )
L_rechts = sqrt( (X_rechts − X)^2 + (Y − Y_rollen)^2 )

Auf dieser Maschine sitzen die Rollen bei X_links = −830, X_rechts = 830, Y_rollen = 800 (Millimeter, Ursprung Blattmitte):

L_links  = sqrt( (X + 830)^2 + (Y − 800)^2 )
L_rechts = sqrt( (830 − X)^2 + (Y − 800)^2 )

Beispiel Home (0, 0): beide Riemen sqrt(830² + 800²) ≈ 1153 mm. Weiter unten oder zur Seite wird ein Riemen länger, der andere kürzer.

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

Deshalb muss Home zur realen Geometrie passen. Falscher Ursprung (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.

5. Fehlerbehebung

  • Kein Port-Dialog, oder „Serial not supported“ — Chrome, nicht Firefox oder Safari. Seite über http://localhost:… öffnen, nicht als Datei.
  • Port erscheint nicht — Strom der Steuerung an? Daten-USB-Kabel? Linux: Gruppe dialout oder uucp, neu einloggen; im Terminal nach ttyACM oder ttyUSB schauen. 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.

6. Mini-Ablauf zum Merken

  1. ZIP herunterladen, in VS Code den Ordner p5-wallplotter öffnen.
  2. Terminal in VS Code öffnen, python3 -m http.server 8080 (Windows: py -m http.server 8080).
  3. Chrome: http://localhost:8080/examples/zickzack/.
  4. Eigenen Ordner unter sketches/ anlegen, drawPlot anpassen.
  5. Plotter mit Strom und USB verbinden.
  6. C → Port wählen.
  7. H (aktuelle Position), zur Blattmitte joggen, nochmals H.
  8. Test, dann Plot.

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