diff --git a/BUILD.md b/BUILD.md index f87e1c9..79455c2 100644 --- a/BUILD.md +++ b/BUILD.md @@ -1,6 +1,6 @@ -# Build guide +# Gyre - build guide -This guide takes you from a pile of parts to a table drawing in sand. It follows the order that works: case first, then the electronics, the arm on the bench, the arm into the table, a test run without sand, and finally the floor, sand and glass. +This guide takes you from a pile of parts to Gyre, a sand art table, drawing in sand. It follows the order that works: case first, then the electronics, the arm on the bench, the arm into the table, a test run without sand, and finally the floor, sand and glass. ![the arm, bolted to its hub, with the counterweight](docs/arm-bolted-counterweight.png) diff --git a/README.md b/README.md index bf4797a..564fe3c 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -# sandTable +# Gyre - Sand Art Table -A 12" kinetic sand table that draws patterns in sand. A steel ball rolls under glass, pulled by a magnet on a polar arm underneath. The case is about 12.5" across and 5" tall. The parts are 3D-printed for a Bambu P1S and designed in SolidCraft. +Gyre is a 12" kinetic sand table that draws patterns in sand. A steel ball rolls under glass, pulled by a magnet on a polar arm underneath. The case is about 12.5" across and 5" tall. The parts are 3D-printed for a Bambu P1S and designed in SolidCraft. **Building one? Start with [BUILD.md](BUILD.md):** parts to buy, what to print, assembly in order, wiring, the first run and troubleshooting. diff --git a/software/README.md b/software/README.md index fe1f429..bbeb81b 100644 --- a/software/README.md +++ b/software/README.md @@ -1,4 +1,4 @@ -# Sand table software +# Gyre software A small Python program that drives the table from your computer over USB. It has a web page with a library of designs, plays `.thr` pattern files (yours or the built-in ones), and erases the sand with a spiral between patterns. diff --git a/software/previews/web-page.png b/software/previews/web-page.png index 6100082..ef0362a 100644 Binary files a/software/previews/web-page.png and b/software/previews/web-page.png differ diff --git a/software/sandtable/__init__.py b/software/sandtable/__init__.py index 868aceb..f6ad7c7 100644 --- a/software/sandtable/__init__.py +++ b/software/sandtable/__init__.py @@ -1 +1 @@ -"""Sand table pattern player: .thr files and built-in patterns -> GRBL / FluidNC over USB.""" +"""Gyre sand art table: pattern player for .thr files and built-in patterns -> GRBL / FluidNC over USB.""" diff --git a/software/sandtable/cli.py b/software/sandtable/cli.py index eb58f00..46f0256 100644 --- a/software/sandtable/cli.py +++ b/software/sandtable/cli.py @@ -52,7 +52,7 @@ def alert(title, msg): return try: import subprocess - subprocess.run(['notify-send', '-u', 'critical', '-a', 'Sand table', title, msg], + subprocess.run(['notify-send', '-u', 'critical', '-a', 'Gyre', title, msg], timeout=5, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) except Exception: pass @@ -71,15 +71,15 @@ def guarded(fn): try: return fn() except SwitchTripped as e: - alert('Sand table stopped: home switch pressed', + alert('Gyre stopped: home switch pressed', f'{e}.\nThe motors were stopped at once. Check the arm, belts and carriage, then run ' f'`play` again; it homes first.') sys.exit(1) except GrblError as e: - alert('Sand table stopped', str(e)) + alert('Gyre stopped', str(e)) sys.exit(1) except OSError as e: # pyserial's SerialException is an OSError: the USB link dropped - alert('Sand table: USB connection lost', + alert('Gyre: USB connection lost', f'{e}\nThe Uno restarts when it is plugged back in, so the table stops where it is. ' f'Run `play` again; it homes first.') sys.exit(1) diff --git a/software/sandtable/ui.py b/software/sandtable/ui.py index 5751c1f..a7ba79e 100644 --- a/software/sandtable/ui.py +++ b/software/sandtable/ui.py @@ -13,7 +13,7 @@ from .grbl import RT_HOLD, RT_JOG_CANCEL, GrblError PAGE = r""" -Sand Table Jog +Gyre - Jog
-

Sand table: jog & calibrate

+

Gyre: jog & calibrate

State-
Rho (mm)-
diff --git a/software/sandtable/web.py b/software/sandtable/web.py index bb94e5d..c257f99 100644 --- a/software/sandtable/web.py +++ b/software/sandtable/web.py @@ -251,17 +251,17 @@ class Player: self.p.homed = False self.message = f'Stopped: {e}. Check the arm, belt and carriage, then play again (it homes first).' log('ERROR ' + self.message + f' | status {c.status.state} pins={c.status.pins!r} wpos={c.status.wpos}') - self.alert('Sand table stopped: home switch pressed', self.message) + self.alert('Gyre stopped: home switch pressed', self.message) except OSError as e: # the USB cable came out: the panel reconnects self.p.lost(e) self.message = 'Stopped: the USB connection to the Uno was lost. Plug it back in; the page reconnects by itself.' log(f'ERROR USB lost: {e!r}') - self.alert('Sand table: USB connection lost', self.message) + self.alert('Gyre: USB connection lost', self.message) except GrblError as e: self.p.homed = False self.message = f'Stopped: {e}' log('ERROR ' + self.message + f' | status {c.status.state} wpos={c.status.wpos} errors={c.errors[-3:]}') - self.alert('Sand table stopped', self.message) + self.alert('Gyre stopped', self.message) except Exception as e: # a bug: stop safely and say so import traceback self.p.homed = False @@ -271,7 +271,7 @@ class Player: c.stop() except Exception: pass - self.alert('Sand table stopped', self.message) + self.alert('Gyre stopped', self.message) finally: c.guard = None c.abort = False @@ -324,7 +324,7 @@ class Player: # ---------------------------------------------------------------- page PAGE = r""" -Sand Table +Gyre - Sand Art Table
-

Sand Table

+

Gyre sand art table

connecting… @@ -511,8 +511,8 @@ def serve(ctrl, cfg, host='127.0.0.1', port=8765, open_browser=True, open_path=' lib = library or Library(cfg) player = Player(panel, cfg, lib, alert=alert) threading.Thread(target=lib.warm, daemon=True).start() - jog_page = JOG_PAGE.replace('

Sand table: jog & calibrate

', - '

← Library

Sand table: jog & calibrate

') + jog_page = JOG_PAGE.replace('

Gyre: jog & calibrate

', + '

← Library

Gyre: jog & calibrate

') def busy(): if not panel.connected: @@ -614,7 +614,7 @@ def serve(ctrl, cfg, host='127.0.0.1', port=8765, open_browser=True, open_path=' srv = ThreadingHTTPServer((host, port), H) srv.daemon_threads = True url = f'http://{"127.0.0.1" if host in ("0.0.0.0", "") else host}:{port}' - print(f'Sand table page at {url}{open_path} (Ctrl-C here to quit)', flush=True) + print(f'Gyre page at {url}{open_path} (Ctrl-C here to quit)', flush=True) if host in ('0.0.0.0', ''): print(' Also open to other devices on your network, with no password: anyone on it can drive the table.') if open_browser: diff --git a/software/tests/test_web.py b/software/tests/test_web.py index 7178345..a78a12a 100644 --- a/software/tests/test_web.py +++ b/software/tests/test_web.py @@ -249,7 +249,7 @@ class TestHttp(unittest.TestCase): return json.loads(r.read()) def test_pages_and_play(self): - self.assertIn(b'Sand Table', self.get('/')) + self.assertIn(b'Gyre', self.get('/')) self.assertIn(b'jog & calibrate', self.get('/jog')) lib = json.loads(self.get('/api/library')) self.assertEqual(len(lib), 2)