diff --git a/README.md b/README.md index 421f45c..21be2c1 100644 --- a/README.md +++ b/README.md @@ -9,13 +9,15 @@ p5-wallplotter/ ├── tutorial.md # setup + plotter + G-code ├── hardware.md # motors, board, geometry ├── gcode.md # G-code used by this setup +├── plotter.svg # devices + signal path ├── lib/ │ ├── WallPlotter.js # library │ ├── README.md # short intro + example │ └── doc.md # full API -└── examples/ - ├── zickzack/ # example sketch - └── rechteck/ # rectangle sketch +├── examples/ +│ ├── zickzack/ # example sketch +│ └── rechteck/ # rectangle sketch +└── sketches/ # your sketches ``` ## Run the example diff --git a/plotter.svg b/plotter.svg new file mode 100644 index 0000000..dfb9256 --- /dev/null +++ b/plotter.svg @@ -0,0 +1,111 @@ + + Wandplotter: Geräte und Signalweg + Medientechnische Zeichnung. Laptop mit Chrome sendet G-code per USB an die SKR Mini E3 V3. Dort läuft Marlin und steuert zwei Schrittmotoren und den Stift-Servo der Gondel. + + + + + + + + + + + Wandplotter  Geräte und Signalweg + p5.js im Browser sendet G-code. Marlin auf dem Controller bewegt die Motoren. + + + + Wand / Polargraph + + + + + + Motor X + links · Riemen links + + + + + + Motor Y + rechts · Riemen rechts + + + + Umlenkrollen · Abstand 1660 mm + + + + + + + + + + Gondel + Stift + Position aus zwei Riemenlängen + + + + + + + Laptop · Chrome + p5.js · WallPlotter.js + zeichnet Linien in Millimetern + Web Serial + + 1 Host + + + + G-code + USB + + + + Controller SKR Mini E3 V3 + + Marlin (Polargraph) + liest G1 X& Y& · inverse Kinematik + Riemenlängen ’ Schrittimpulse + Netzteil 24 V · USB nur Daten + 2 Steuerung + + + + Schritte X + + + Schritte Y + + + + Servo Stift + M280 + + + + Ablauf + 1 Chrome zeichnet den Pfad + 2 G-code geht per USB raus + 3 Marlin auf der SKR rechnet + 4 Motoren wickeln die Riemen + 5 Gondel fährt, Stift hebt / senkt + Antwort: Marlin sendet ok zurück + diff --git a/sketches/README.md b/sketches/README.md new file mode 100644 index 0000000..b68a553 --- /dev/null +++ b/sketches/README.md @@ -0,0 +1,3 @@ +# sketches + +Eigene Sketches hier ablegen, zum Beispiel *mein-sketch/*. Vorlagen kopieren aus *examples/*. diff --git a/tutorial.md b/tutorial.md index 9972ad9..0d54bee 100644 --- a/tutorial.md +++ b/tutorial.md @@ -1,121 +1,151 @@ # 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. +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. +**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) +- **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) -Web Serial funktioniert **nicht** über `file://`. Die Seite muss von `http://localhost` oder über HTTPS kommen. - ---- - -## 1. Repository herunterladen +## 1.1 Repository herunterladen Das Projekt liegt hier: [https://git.collectivemedia.space/martin/p5-wallplotter](https://git.collectivemedia.space/martin/p5-wallplotter) -Auf der Projektseite **Code → Download ZIP** (oder direkt [archive/main.zip](https://git.collectivemedia.space/martin/p5-wallplotter/archive/main.zip)). Archiv entpacken und in den Ordner `p5-wallplotter` wechseln. +Auf der Projektseite **Code → Download ZIP** (oder direkt [archive/main.zip](https://git.collectivemedia.space/martin/p5-wallplotter/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: + ``` -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: - -```bash -cd p5-wallplotter python3 -m http.server 8080 ``` -Browser: [http://localhost:8080/examples/zickzack/](http://localhost:8080/examples/zickzack/) +Windows (Python von [python.org](https://www.python.org/downloads/), beim Setup **Add python.exe to PATH**): -Server mit `Ctrl+C` beenden. - -Für den USB-Port braucht dein Benutzer die Serial-Gruppe. Nach der Änderung einmal ab- und anmelden: - -```bash -# 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): - -```bash -ls /dev/ttyACM* /dev/ttyUSB* -``` - -### Windows - -1. Python von [python.org](https://www.python.org/downloads/) installieren. Beim Setup **Add python.exe to PATH** aktivieren. -2. PowerShell oder Eingabeaufforderung im Projektordner: - -```powershell -cd p5-wallplotter py -m http.server 8080 ``` -Falls `py` unbekannt ist: `python -m http.server 8080`. +Falls *py* unbekannt ist: *python -m http.server 8080*. -3. Chrome oder Edge: [http://localhost:8080/examples/zickzack/](http://localhost:8080/examples/zickzack/) +4. Die Seite in Chrome öffnen: [http://localhost:8080/examples/zickzack/](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. +Server kann mit *Ctrl+C* im VS-Code-Terminal beendet werden. -### macOS +### USB je nach System -Im Terminal: +**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. -```bash -cd p5-wallplotter -python3 -m http.server 8080 -``` +**Linux.** Für den USB-Port braucht dein Benutzer die Serial-Gruppe. Nach der Änderung einmal ab- und anmelden. -**Chrome** oder **Edge** öffnen (nicht Safari): [http://localhost:8080/examples/zickzack/](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. +**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 oder Edge, aktuelle Version -- `chrome://flags` nicht nötig; Web Serial ist standardmässig an +- **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 -## 3. Plotter anschliessen +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/](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](https://git.collectivemedia.space/martin/p5-wallplotter/src/branch/main/lib/doc.md). + +## 3.1 Plotter anschliessen ### Hardware-Reihenfolge @@ -126,193 +156,125 @@ Falls `python3` fehlt: `xcode-select --install` oder Python über Homebrew. 5. **Connect** klicken oder Taste **C**. 6. Im Dialog den Serial-Port der Steuerung wählen. -### Home setzen (wichtig) +## 3.2 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: +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. 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. +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**. +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 -## 4. Der Plotter und seine Teile +### 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](hardware.md). +Baugruppen, Anschlüsse und Geometrie: [hardware.md](https://git.collectivemedia.space/martin/p5-wallplotter/src/branch/main/hardware.md). ---- +### Was Marlin mit G-code macht -## 5. 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](https://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 parst sie, plant Bewegung oder I/O, und antwortet mit `ok`, wenn der Befehl angenommen ist. +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: -```gcode -M280 P0 S30 ; Servo 0 auf 30° → Stift aufs Papier +``` +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 +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 -``` +*wp.draw* legt die Linie nur in eine Queue (ein Array von Punkten). Der Plotter hat noch nichts gehört. -**Test** (`runPath(true)`) bleibt im Browser: gleiche Pfadliste, nur Animation. Es geht kein G-code raus. +**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**. Marlin rechnet für jedes Ziel: +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*: ``` -linke Länge = hypot( X − linke_Rolle , Y − Rollenlinie ) -rechte Länge = hypot( rechte_Rolle − X , Y − Rollenlinie ) +L_links = sqrt( (X − X_links)^2 + (Y − Y_rollen)^2 ) +L_rechts = sqrt( (X_rechts − X)^2 + (Y − Y_rollen)^2 ) ``` -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. +Auf dieser Maschine sitzen die Rollen bei *X_links = −830*, *X_rechts = 830*, *Y_rollen = 800* (Millimeter, Ursprung Blattmitte): -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. +``` +L_links = sqrt( (X + 830)^2 + (Y − 800)^2 ) +L_rechts = sqrt( (830 − X)^2 + (Y − 800)^2 ) +``` -Befehlsliste: [gcode.md](gcode.md). +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](https://git.collectivemedia.space/martin/p5-wallplotter/src/branch/main/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. +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 -## 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/](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` - -```javascript -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](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. | +- **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 -## 9. 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/](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**. -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](lib/doc.md). G-code: [gcode.md](gcode.md). +API-Referenz: [lib/doc.md](https://git.collectivemedia.space/martin/p5-wallplotter/src/branch/main/lib/doc.md). G-code: [gcode.md](https://git.collectivemedia.space/martin/p5-wallplotter/src/branch/main/gcode.md).