pm-kit: fix jog-mode step-rate cap (loop overhead, not the motor)
The ~330 steps/s ceiling was the CircuitPython loop, not the stepper: an analog read + time.sleep(0.0005) every iteration made each pass ~3ms (1/0.003 ~ 330). Tighten the jog loop - poll the joystick at ~250Hz off the step hot-path, drop the per-iteration sleep, refresh the readout ~1/s instead of 3+/s, and raise the commanded ceiling to ~1600 steps/s - so the peak reflects the motor's real limit. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
36c7406d71
commit
5f9e9dfad7
1 changed files with 29 additions and 28 deletions
|
|
@ -1157,40 +1157,41 @@ class App:
|
||||||
show_stats(0, 0, 0)
|
show_stats(0, 0, 0)
|
||||||
self.display.refresh()
|
self.display.refresh()
|
||||||
time.sleep(0.1); center = self.jx.value
|
time.sleep(0.1); center = self.jx.value
|
||||||
last = time.monotonic(); lastdir = None
|
total = 0; win = 0; peak = 0; cw = True; dt = 1.0; lastdir = None
|
||||||
total = 0; win = 0; peak = 0; tsample = time.monotonic()
|
now = time.monotonic(); last = now; tsample = now; tjoy = now
|
||||||
while True:
|
while True: # no per-iteration sleep: tight step timing in this mode
|
||||||
now = time.monotonic()
|
now = time.monotonic()
|
||||||
dx = self.jx.value - center; mag = abs(dx)
|
if now - tjoy >= 0.004: # poll the joystick ~250x/s, OFF the step hot-path
|
||||||
if mag > JOY_DEADZONE:
|
tjoy = now
|
||||||
cw = dx > 0
|
dx = self.jx.value - center; mag = abs(dx)
|
||||||
frac = (mag - JOY_DEADZONE) / (32768 - JOY_DEADZONE)
|
if mag > JOY_DEADZONE:
|
||||||
if frac > 1.0: frac = 1.0
|
cw = dx > 0
|
||||||
dt = 0.02 + (0.001 - 0.02) * frac # full push ~1000 steps/s; just past deadzone = slow
|
frac = (mag - JOY_DEADZONE) / (32768 - JOY_DEADZONE)
|
||||||
if self.pend is not None and self.pend.ok and now - last >= dt:
|
if frac > 1.0: frac = 1.0
|
||||||
self.pend.spin(cw); last = now; total += 1; win += 1
|
dt = 0.02 + (0.0006 - 0.02) * frac # commanded up to ~1600 steps/s (find the motor's real wall)
|
||||||
if cw != lastdir: # direction changed -> update LED + needle
|
if cw != lastdir: # direction changed -> LED + needle (rare, so refresh here)
|
||||||
lastdir = cw
|
lastdir = cw
|
||||||
if cw: self.led.set(0, 150, 0)
|
if cw: self.led.set(0, 150, 0)
|
||||||
else: self.led.set(0, 0, 255)
|
else: self.led.set(0, 0, 255)
|
||||||
ang = PEND_THETA if cw else -PEND_THETA
|
ang = PEND_THETA if cw else -PEND_THETA
|
||||||
bx = PEND_PX + int(PEND_LEN * math.sin(ang)); by = PEND_PY - int(PEND_LEN * math.cos(ang))
|
bx = PEND_PX + int(PEND_LEN * math.sin(ang)); by = PEND_PY - int(PEND_LEN * math.cos(ang))
|
||||||
bob.x = bx; bob.y = by
|
bob.x = bx; bob.y = by
|
||||||
arm.points = [(PEND_PX - 4, PEND_PY), (PEND_PX + 4, PEND_PY), (bx, by)]
|
arm.points = [(PEND_PX - 4, PEND_PY), (PEND_PX + 4, PEND_PY), (bx, by)]
|
||||||
|
self.display.refresh()
|
||||||
|
elif lastdir is not None: # back to center -> stop, release, recentre needle
|
||||||
|
lastdir = None; dt = 1.0
|
||||||
|
if self.pend is not None and self.pend.ok: self.pend.release()
|
||||||
|
self.led.set(0, 0, 0)
|
||||||
|
bob.x = PEND_PX; bob.y = PEND_PY - PEND_LEN
|
||||||
|
arm.points = [(PEND_PX - 4, PEND_PY), (PEND_PX + 4, PEND_PY), (PEND_PX, PEND_PY - PEND_LEN)]
|
||||||
self.display.refresh()
|
self.display.refresh()
|
||||||
elif lastdir is not None: # back to center -> stop, release, recentre needle
|
if lastdir is not None and self.pend is not None and self.pend.ok and now - last >= dt:
|
||||||
lastdir = None
|
self.pend.spin(lastdir); last = now; total += 1; win += 1
|
||||||
if self.pend is not None and self.pend.ok: self.pend.release()
|
if now - tsample >= 1.0: # readout once/s (one tiny refresh, not 3+ hitches/s)
|
||||||
self.led.set(0, 0, 0)
|
|
||||||
bob.x = PEND_PX; bob.y = PEND_PY - PEND_LEN
|
|
||||||
arm.points = [(PEND_PX - 4, PEND_PY), (PEND_PX + 4, PEND_PY), (PEND_PX, PEND_PY - PEND_LEN)]
|
|
||||||
self.display.refresh()
|
|
||||||
if now - tsample >= 0.3: # ~3x/s: commanded-rate window -> readout (peak = motor ceiling)
|
|
||||||
rate = int(win / (now - tsample))
|
rate = int(win / (now - tsample))
|
||||||
if rate > peak: peak = rate
|
if rate > peak: peak = rate
|
||||||
show_stats(total, rate, peak); win = 0; tsample = now
|
show_stats(total, rate, peak); win = 0; tsample = now
|
||||||
self.display.refresh()
|
self.display.refresh()
|
||||||
time.sleep(0.0005)
|
|
||||||
|
|
||||||
# ---------- audio + light ----------
|
# ---------- audio + light ----------
|
||||||
def click(self, level):
|
def click(self, level):
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue