Skip to content

fix(filter-wheel): reset W/W2 range to full after home (rotary axis) — fixes intermittent post-home CMD_EXECUTION_ERROR#560

Open
Alpaca233 wants to merge 1 commit into
masterfrom
fix/filter-wheel-home-latch-edge
Open

fix(filter-wheel): reset W/W2 range to full after home (rotary axis) — fixes intermittent post-home CMD_EXECUTION_ERROR#560
Alpaca233 wants to merge 1 commit into
masterfrom
fix/filter-wheel-home-latch-edge

Conversation

@Alpaca233

@Alpaca233 Alpaca233 commented Jun 17, 2026

Copy link
Copy Markdown
Collaborator

Problem

Intermittently, a filter-wheel home succeeds but the immediate post-home offset move (MOVETO_W, an absolute +102 ustep target) is rejected with CMD_EXECUTION_ERROR, crashing startup. Observed across runs; ~1 in N power-ups.

Root cause

The home anchors its coordinate frame from the limit-switch PRESS latch (X_LATCH_RD) but declares "home found" on the switch RELEASE, leaving final xmin = L − C (L = press-latch position, C = release position). tmc4361A_moveTo is the sole rejection gate (x_pos < xmin || x_pos > xmax; no transient path; enable_filterwheel == false ruled out post-INITFILTERWHEEL). So the abort is exactly xmin > 102, which happens whenever a home reaches release without a fresh, correctly-ordered in-cycle press (stale/mis-ordered latch). It's intermittent because L − C depends on the wheel's resting/switch state at power-up.

(Confirmed by a multi-agent adversarial root-cause analysis: xmin = L − C, absolute +102 target, sole gate — all verified against source.)

Fix

The [xmin,xmax] range check is linear-stage infrastructure (physical end-stops, SET_LIM, moveToExtreme). The filter wheel is rotary — no travel end-stop; the home switch is a reference mark. So finalize_homing_w/_w2 now reset the wheel's range to full int32 after anchoring home, and a latch-derived xmin can never reject a valid rotary move — on every home entry path.

Safe: W/W2 xmin/xmax are written only in check_homing_w/w2 and consumed only by the moveTo range gate; check_limits acts on X/Y/Z only and never touches W/W2; SET_LIM targets the stage.

FIRMWARE_VERSION 1.3 → 1.4 so logs (Detected firmware version) confirm the flashed build.

Changes

  • firmware/controller/src/operations.cppfinalize_homing_w/_w2 reset xmin/xmax to full range
  • firmware/controller/src/constants.h — version 1.4 + changelog

Note

An earlier iteration tried a "back-off, then re-approach" homing phase to force a fresh press-latch. Hardware testing showed it only fixed the pressed-at-entry subcase — a released-at-entry home still failed — so it was dropped in favor of this version-independent, root-cause fix.

Testing

  • pio run -e teensy41 builds clean.
  • Hardware validation pending: reflash, confirm Detected firmware version: (1, 4), then power-cycle ~10+ times (varying the wheel's resting position) and confirm every home completes with no CMD_EXECUTION_ERROR.

🤖 Generated with Claude Code

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the Teensy filter-wheel (W/W2) homing state machine to guarantee a fresh hardware latch capture on every home cycle, addressing an intermittent post-home MOVETO_W rejection (CMD_EXECUTION_ERROR) caused by a stale X_LATCH_RD when homing begins with the switch already pressed.

Changes:

  • Add is_backing_off_W / is_backing_off_W2 global state to represent a new “back off first” homing phase.
  • Implement back_off_homing_w() / back_off_homing_w2() and invoke them each loop before the existing prepare_homing_* phase.
  • Update HOME command entry for W/W2 to start in back-off when the switch is pressed, and clear the new flags on RESET; add accompanying design/spec documentation.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
software/docs/superpowers/specs/2026-06-16-filter-wheel-home-latch-edge-design.md Adds approved design writeup describing the latch-edge mismatch and the back-off-first approach.
software/docs/superpowers/plans/2026-06-16-filter-wheel-home-latch-edge.md Adds implementation plan and validation steps for the firmware change.
firmware/controller/src/globals.cpp Defines new global homing-state flags for W/W2 back-off.
firmware/controller/src/globals.h Exposes new back-off flags via extern declarations.
firmware/controller/src/operations.h Declares new back-off phase functions.
firmware/controller/src/operations.cpp Implements back_off_homing_w/w2() to transition from pressed-start to normal prepare homing.
firmware/controller/main_controller_teensy41.ino Runs back-off phase functions each loop prior to prepare_homing_*.
firmware/controller/src/commands/stage_commands.cpp Switches pressed-start HOME entry to set back-off state (and resets flag at entry).
firmware/controller/src/commands/commands.cpp Clears new back-off flags on RESET alongside existing homing flags.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread firmware/controller/src/commands/stage_commands.cpp Outdated
Comment thread firmware/controller/src/commands/stage_commands.cpp Outdated
@Alpaca233 Alpaca233 force-pushed the fix/filter-wheel-home-latch-edge branch 3 times, most recently from 8a26f64 to a12dff6 Compare June 18, 2026 13:14
@Alpaca233 Alpaca233 requested a review from Copilot June 18, 2026 14:32

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

Comment thread firmware/controller/src/operations.cpp Outdated
Comment on lines +384 to +385
// range-rejected. Safe: W xmin/xmax are written only in check_homing_w and
// consumed only by the moveTo range check (check_limits clamps X/Y/Z only).

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Claude Code] Fixed in 0475d2f — reworded to: "check_limits acts on X/Y/Z only, stopping them on a limit-switch event, and never touches W/W2". You're right: it doesn't clamp positions, it stops X/Y/Z motion on a limit-switch event and ignores W/W2.

Comment on lines +15 to +17
// Version 1.4 = filter-wheel (W/W2) home resets xmin/xmax to full range (rotary
// axis has no travel end-stop); fixes intermittent post-home
// MOVETO_W CMD_EXECUTION_ERROR (home left xmin = L - C > offset)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Claude Code] Updated the PR title + description to match the code. The back-off state machine (is_backing_off_, back_off_homing_) was intentionally removed: hardware testing showed it only fixed the pressed-at-entry subcase — a released-at-entry home still failed (firmware v1.4 back-off build) — so it was dropped in favor of this version-independent root-cause fix (reset the rotary wheel's xmin/xmax to full range after home). The implemented diff is exactly that + the version bump; no missing code.

… v1.4

Intermittent: the filter-wheel home reports success but the post-home offset
move (absolute +102 usteps) is rejected with CMD_EXECUTION_ERROR.

Root cause: the home anchors its coordinate frame from the limit-switch PRESS
latch (X_LATCH_RD) but detects "home found" on the switch RELEASE, leaving
xmin = L - C (L = press-latch position, C = release position). tmc4361A_moveTo
is the sole reject gate (x_pos < xmin), so the abort means xmin > 102, which
happens whenever a home reaches release without a fresh, correctly-ordered
in-cycle press (stale/mis-ordered latch). Depends on the wheel's resting state,
hence intermittent.

Fix at the right altitude: the [xmin,xmax] range check is linear-stage
infrastructure (physical end-stops, SET_LIM, moveToExtreme). The filter wheel is
rotary with no travel end-stop. finalize_homing_w/_w2 now reset xmin/xmax to full
int32 range after anchoring home, so a latch-derived xmin can never reject a
valid rotary move -- every entry path. Safe: W/W2 xmin/xmax are written only in
check_homing_w/w2 and consumed only by the moveTo gate (check_limits clamps
X/Y/Z only; SET_LIM targets the stage). FIRMWARE_VERSION 1.3 -> 1.4.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@Alpaca233 Alpaca233 force-pushed the fix/filter-wheel-home-latch-edge branch from a12dff6 to 0475d2f Compare June 18, 2026 15:11
@Alpaca233 Alpaca233 changed the title fix(filter-wheel): fresh press-latch every home (fixes intermittent post-home CMD_EXECUTION_ERROR) fix(filter-wheel): reset W/W2 range to full after home (rotary axis) — fixes intermittent post-home CMD_EXECUTION_ERROR Jun 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants