Claude/buffer deferred motor drive p mp bi#13
Closed
adebuyss wants to merge 22 commits intoFly3DTeam:mainfrom
Closed
Claude/buffer deferred motor drive p mp bi#13adebuyss wants to merge 22 commits intoFly3DTeam:mainfrom
adebuyss wants to merge 22 commits intoFly3DTeam:mainfrom
Conversation
Replaces macro-based buffer control with a Klipper host plugin that runs in the reactor loop. Uses TMC2209 VACTUAL for velocity control and buttons callbacks for sensor monitoring, independent of the gcode queue. Matches extruder velocity with sensor-based correction. https://claude.ai/code/session_01CATwsdMwumQvPKVz4AjkFt
When buffer hits the full sensor, instead of immediately retracting: 1. Slow feed to extruder_velocity * slowdown_factor (default 0.5) 2. Only retract after full_zone_timeout seconds (default 3.0s) This lets the buffer naturally drain before forcing a retract. https://claude.ai/code/session_01CATwsdMwumQvPKVz4AjkFt
The buffer uses a TMC2225 which is a TMC2208 variant, not TMC2209. https://claude.ai/code/session_01CATwsdMwumQvPKVz4AjkFt
…nfigurable threshold - Configurable min_extrusion_velocity (default 0.05 mm/s) replaces hard-coded 0.5 - Sensor callbacks now update extruder velocity before evaluating - Cache GCONF register to eliminate UART read on direction change - Detect extruder retraction (negative delta) and immediately stop motor - Full zone timeout only counts active feeding time, not stopped time - Burst feed: when empty while stopped, wait burst_delay then feed for burst_feed_time https://claude.ai/code/session_01CATwsdMwumQvPKVz4AjkFt
- Add burst cycle counter (max 5) to prevent infinite feeding when buffer is stuck in empty zone (jammed motor, sensor failure) - Full zone feed time now tracks actual elapsed time instead of adding a fixed control_interval increment, preventing double-counting when sensor callbacks trigger extra evaluations https://claude.ai/code/session_01CATwsdMwumQvPKVz4AjkFt
buttons.register_buttons() expects pin description strings and does its own parsing via ppins.lookup_pin(). We were pre-parsing into dicts which caused 'dict has no attribute strip' on startup. https://claude.ai/code/session_01CATwsdMwumQvPKVz4AjkFt
Raw GCONF bit manipulation was not changing direction - both BUFFER_FEED and BUFFER_RETRACT spun the same way. Switch to mcu_tmc.fields.set_field() which uses Klipper's own register field definitions for correct bit layout. Also removes the GCONF cache since the field helper maintains its own state. https://claude.ai/code/session_01CATwsdMwumQvPKVz4AjkFt
When the material switch detects filament insertion (absent → present), the buffer auto-enables and immediately evaluates sensor state to start feeding. The existing control loop handles the rest — feeds forward until the middle sensor triggers, then stops. Matches the original mellow-plus.cfg insert_gcode behavior. https://claude.ai/code/session_01CATwsdMwumQvPKVz4AjkFt
extruder.last_position returns [x, y, z, e] list, not a float. Index [3] extracts the E axis position for velocity calculation. https://claude.ai/code/session_01CATwsdMwumQvPKVz4AjkFt
Skip shaft and vactual register writes when the values haven't changed. Pressing the feed button while auto-control was running caused multiple rapid UART writes that overwhelmed the STM32F072 MCU. https://claude.ai/code/session_01CATwsdMwumQvPKVz4AjkFt
With ^! pins, the buttons module reports state=0 when the sensor is blocked (carriage present). Invert in the callback so sensor_states reads True when the carriage is at that position. https://claude.ai/code/session_01CATwsdMwumQvPKVz4AjkFt
- Add debug config option (default False). When True, logs all three hall sensor states to console whenever any sensor changes. - Fix sensor callback to use not bool(state) — with ^! pins, state=0 means sensor is triggered (carriage present). https://claude.ai/code/session_01CATwsdMwumQvPKVz4AjkFt
Debug output shows middle+full sensors trigger simultaneously in the transition zone between those positions. Split the full branch: - full only (deep full): existing slowdown + timeout + retract - full+middle (overlap): slow down but no timeout/retract accumulation - empty+middle overlap handled by empty branch (aggressive feed) - all-false (between empty and middle) handled by between-sensors branch https://claude.ai/code/session_01CATwsdMwumQvPKVz4AjkFt
manual_stepper.do_enable() triggers Klipper's TMC module to re-send all configuration registers (~30 UART writes), which overwhelms the STM32F072 MCU. Instead, enable the motor once at startup in handle_ready and use VACTUAL=0 for stop. TMC2208 at VACTUAL=0 draws negligible power with the motor holding at zero velocity. https://claude.ai/code/session_01CATwsdMwumQvPKVz4AjkFt
extruder.last_position[3] wasn't updating during printing. toolhead.get_position() returns the live gcode position [x,y,z,e] which tracks E axis movement in real time. https://claude.ai/code/session_01CATwsdMwumQvPKVz4AjkFt
When print_stats.state != "printing", the buffer follows extruder movement in both directions: - Forward E movement: buffer feeds (same as before) - Backward E movement: buffer retracts to follow During active printing, short retractions (firmware retraction) still just stop the buffer motor as before. New config: follow_retract (default True) New status fields: is_printing, extruder_retracting This means SIMPLE_UNLOAD_FILAMENT and SIMPLE_LOAD_FILAMENT work automatically with no macro changes needed. https://claude.ai/code/session_01CATwsdMwumQvPKVz4AjkFt
Claude/klipper buffer plugin u cmqu
) * Switch from polling to event-driven E tracking via G0/G1/G2/G3 hooks Replace the 100ms polling loop (toolhead.get_position()[3]) with direct interception of G0/G1/G2/G3 gcode commands. The wrapper reads gcode_move.last_position before/after the original handler to get exact E deltas, accounting for M82/M83/G92/M221 automatically. E velocity is computed from the commanded path speed (F parameter): - Mixed XYZ+E moves: e_vel = speed * |de| / xyz_distance - Pure E moves: e_vel = speed (feedrate applies to E directly) - Fallback: delta/time between commands The control timer is demoted to a watchdog (default 500ms): - Forward timeout checking - Velocity decay (move-time-aware, won't cut mid-move) - Burst feed and full-zone timeout timing Sensor callbacks remain unchanged (immediate via buttons module). G10/G11 firmware retraction is caught automatically since it internally generates G1 commands via run_script_from_command. https://claude.ai/code/session_01CATwsdMwumQvPKVz4AjkFt * Add pytest test framework for buffer plugin (99 tests) Pure-mock test infrastructure inspired by Kalico's PrinterShim pattern. Mocks all Klipper interfaces (reactor, gcode, TMC driver, buttons, gcode_move, print_stats) with controllable time for deterministic testing of burst cycles, full zone timeouts, and velocity decay. Covers: BufferMotor register writes/caching, state machine transitions, burst feed cycles, full zone timeout/retract, E velocity tracking, retraction following, error conditions, manual button control, all BUFFER_* gcode commands, and material insertion/removal. Also fixes latent bug: _update_extruder_velocity() was called but never defined (would raise AttributeError on sensor callbacks). https://claude.ai/code/session_0142Jm124CYMHMjo13dCNgwp * Add __pycache__ and .pytest_cache to gitignore https://claude.ai/code/session_0142Jm124CYMHMjo13dCNgwp --------- Co-authored-by: Claude <noreply@anthropic.com>
Klipper's register_command rejects duplicate registrations. Must pass None first to unregister the existing handler. https://claude.ai/code/session_01CATwsdMwumQvPKVz4AjkFt Co-authored-by: Claude <noreply@anthropic.com>
Separate velocity state updates (fast, arithmetic-only) from TMC2208 UART register writes (slow, blocking) in the G-code move path. The _on_e_movement hook now updates state variables immediately, then schedules a rate-limited reactor callback for the actual motor write. Key changes: - Add _request_drive_update/_deferred_drive for coalesced UART writes - Rate-limit motor writes to ~10/s via _min_drive_interval (100ms) - Tighten control_interval default from 0.5s to 0.25s for faster catch-up of rate-limited updates - Expose drive_interval as configurable (default 0.1s, range 0.02-1.0) - Add register_callback/flush_callbacks to MockReactor for testing - Add test_deferred_drive.py with 11 tests for the new behavior This eliminates per-move UART latency on dense G-code streams, reducing risk of "Timer too close" MCU errors and print stutter. https://claude.ai/code/session_01YEx9rspTQ2wVUJkrAqLphm
Avatarsia
pushed a commit
to Avatarsia/BufferPLUS-klipper
that referenced
this pull request
Apr 22, 2026
12 Verbesserungen aus der parallelen LLL_Plus-Variante integriert. Unser Refactor (Helpers, Parametrisierung, Raw-State) bleibt. Kategorie A - Sensor- und Event-Filterung: ss1gohan13#1 Sensor disable waehrend Erstbefuellung, reaktivieren in _initial_follow_end, STOP_BUFFER_FILL, BUFFER_AUTO_ON ss1gohan13#2 runout_gcode ignoriert Events wenn manual_operation==1 Fly3DTeam#3 HALL2/HALL3 Guards erweitert um manual_operation-Check Fly3DTeam#4 HALL1 selektiv: nur _MANUAL_FEED stoppen, LOAD/UNLOAD weiterlaufen lassen. action_respond_info() statt M118 mit Emoji. Guard zusaetzlich. Kategorie B - Toggle-Features: Fly3DTeam#6 variable_feed_burst_enabled (default 0): Triple-Feed-Burst nur aktiv wenn =1. Default = sicher (Dauerlauf-Neustart). Fly3DTeam#8 variable_auto_load_after_follow (default 0): nach Follow-Phase automatisch LOAD_FILAMENT wenn Hotend warm, nur wenn =1. Kategorie C - UNLOAD-Praezision: Fly3DTeam#9 Phase 3a Distanz = load_fast_distance + Follow-Strecke (initial_follow_speed * initial_follow_duration). Fly3DTeam#10 sync_locked=0 und sync_state=0 explizit am UNLOAD-Ende. Kategorie D - Diagnose: Fly3DTeam#11 _STATE_DUMP zeigt sync_locked und sync_state. Fly3DTeam#12 _boot_autostart ueberspringt BUFFER_AUTO_ON wenn initial_lockout==1 (Stromausfall-Edge-Case). Fly3DTeam#13 ENABLE/DISABLE_RUNOUT_SENSOR description nennt runout_pause=1-Abhaengigkeit explizit. Punkt Fly3DTeam#5 (M118 -> action_respond_info flaechig) bewusst uebersprungen - nur HALL1 bekommt das, Rest bleibt M118. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.