diff --git a/pico-cp/README.md b/pico-cp/README.md index 30980eb..67098eb 100644 --- a/pico-cp/README.md +++ b/pico-cp/README.md @@ -117,6 +117,9 @@ The Kit can drive a **physical metronome pendulum**: a 4-input unipolar stepper - `STEPPER_ACCEL` — ramp (half‑steps/sec²) used to reach top speed without stalling; lower it if the motor stalls/buzzes when starting. - `STEPPER_JOG_START` — jog kickoff rate from rest (keep at or below the motor's pull‑in rate). + - *Tune without recompiling:* these five are also read from **`/settings.json`** (keys `stepper_max_rate`, + `stepper_accel`, `stepper_jog_start`, `pend_swing_deg`, `stepper_steps_per_rev`) — edit in editor mode, + power‑cycle. - **Jog / test mode** (hold **A + B** at boot): the joystick sets **direction only** — **L = CCW, R = CW** — and the motor **accelerates to `STEPPER_MAX_RATE`** (reversing decelerates through zero first), with an on‑screen needle + RGB LED and a **live step counter + rate readout**. *Tuning:* raise `STEPPER_MAX_RATE` until the diff --git a/pico-cp/app.py b/pico-cp/app.py index 4410356..66a72ee 100644 --- a/pico-cp/app.py +++ b/pico-cp/app.py @@ -1054,6 +1054,7 @@ class App: # ---------- Settings persistence (/settings.json) ---------- def _load_settings(self): global LED_BRIGHTNESS, MUTE_SPEAKER, SPEAKER_AUTO_MUTE, MIDI_ENABLED, MIDI_CHANNEL, MIDI_CLOCK_OUT, MIDI_CLOCK_IN + global STEPPER_MAX_RATE, STEPPER_ACCEL, STEPPER_JOG_START, PEND_SWING_DEG, STEPPER_STEPS_PER_REV, STEPPER_ARC, PEND_THETA try: with open("/settings.json") as f: d = json.load(f) except Exception: return @@ -1065,6 +1066,14 @@ class App: MIDI_CHANNEL = max(1, min(16, int(d.get("midi_channel", MIDI_CHANNEL)))) MIDI_CLOCK_OUT = bool(d.get("clock_out", MIDI_CLOCK_OUT)) MIDI_CLOCK_IN = bool(d.get("clock_in", MIDI_CLOCK_IN)) + # Stepper/pendulum tuning (so you can dial it in by editing the file, no recompile): + STEPPER_MAX_RATE = max(50, min(4000, int(d.get("stepper_max_rate", STEPPER_MAX_RATE)))) + STEPPER_ACCEL = max(50, int(d.get("stepper_accel", STEPPER_ACCEL))) + STEPPER_JOG_START = max(1, int(d.get("stepper_jog_start", STEPPER_JOG_START))) + PEND_SWING_DEG = max(1, min(180, int(d.get("pend_swing_deg", PEND_SWING_DEG)))) + STEPPER_STEPS_PER_REV = max(1, int(d.get("stepper_steps_per_rev", STEPPER_STEPS_PER_REV))) + PEND_THETA = math.radians(PEND_SWING_DEG) / 2.0 # keep derived values in sync + STEPPER_ARC = round(STEPPER_STEPS_PER_REV * PEND_SWING_DEG / 360.0) except Exception as e: print("settings:", e) def _save_settings(self): if not self.can_write: return