pm-kit: stepper/pendulum tuning via settings.json (no recompile)
_load_settings now also reads stepper_max_rate / stepper_accel / stepper_jog_start / pend_swing_deg / stepper_steps_per_rev and recomputes the derived PEND_THETA + STEPPER_ARC, so the motor speed/accel/swing can be dialed in by editing the file on the drive instead of rebuilding the firmware. README documents the keys. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
19d646a873
commit
a7e8061a9b
2 changed files with 12 additions and 0 deletions
|
|
@ -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
|
- `STEPPER_ACCEL` — ramp (half‑steps/sec²) used to reach top speed without stalling; lower it if the motor
|
||||||
stalls/buzzes when starting.
|
stalls/buzzes when starting.
|
||||||
- `STEPPER_JOG_START` — jog kickoff rate from rest (keep at or below the motor's pull‑in rate).
|
- `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
|
- **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
|
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
|
needle + RGB LED and a **live step counter + rate readout**. *Tuning:* raise `STEPPER_MAX_RATE` until the
|
||||||
|
|
|
||||||
|
|
@ -1054,6 +1054,7 @@ class App:
|
||||||
# ---------- Settings persistence (/settings.json) ----------
|
# ---------- Settings persistence (/settings.json) ----------
|
||||||
def _load_settings(self):
|
def _load_settings(self):
|
||||||
global LED_BRIGHTNESS, MUTE_SPEAKER, SPEAKER_AUTO_MUTE, MIDI_ENABLED, MIDI_CHANNEL, MIDI_CLOCK_OUT, MIDI_CLOCK_IN
|
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:
|
try:
|
||||||
with open("/settings.json") as f: d = json.load(f)
|
with open("/settings.json") as f: d = json.load(f)
|
||||||
except Exception: return
|
except Exception: return
|
||||||
|
|
@ -1065,6 +1066,14 @@ class App:
|
||||||
MIDI_CHANNEL = max(1, min(16, int(d.get("midi_channel", MIDI_CHANNEL))))
|
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_OUT = bool(d.get("clock_out", MIDI_CLOCK_OUT))
|
||||||
MIDI_CLOCK_IN = bool(d.get("clock_in", MIDI_CLOCK_IN))
|
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)
|
except Exception as e: print("settings:", e)
|
||||||
def _save_settings(self):
|
def _save_settings(self):
|
||||||
if not self.can_write: return
|
if not self.can_write: return
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue