sensorless_homing/sensorless_homing.rs
1//! Sensorless homing example for TMC2209.
2//!
3//! This example demonstrates how to use StallGuard for sensorless homing,
4//! allowing the motor to detect when it hits a mechanical endstop without
5//! requiring physical limit switches.
6
7#![allow(unused)]
8
9use tmc2209_uart::{MicrostepResolution, Tmc2209};
10
11/// Perform sensorless homing using StallGuard.
12///
13/// # Important Notes
14///
15/// 1. StallGuard works best in SpreadCycle mode
16/// 2. The motor must be moving above the TCOOLTHRS velocity
17/// 3. Use moderate speeds for reliable detection
18/// 4. Tune SGTHRS for your specific motor and mechanics
19#[cfg(feature = "blocking")]
20fn sensorless_homing<U, E>(uart: U) -> Result<(), tmc2209_uart::Error<E>>
21where
22 U: embedded_io::Read<Error = E> + embedded_io::Write<Error = E>,
23{
24 let mut driver = Tmc2209::new(uart, 0);
25
26 // =========================================================================
27 // Step 1: Basic Configuration
28 // =========================================================================
29
30 // Set appropriate current for homing (usually lower than running current)
31 driver.set_current(12, 6, 4)?;
32
33 // Use lower microstep resolution for more reliable stall detection
34 driver.set_microsteps(MicrostepResolution::M16)?;
35
36 // =========================================================================
37 // Step 2: Configure StallGuard
38 // =========================================================================
39
40 // CRITICAL: Use SpreadCycle mode for StallGuard
41 driver.enable_spreadcycle()?;
42
43 // Configure stall detection
44 driver.configure_stall_detection(50)?;
45
46 // Set TCOOLTHRS - StallGuard is only active when TSTEP < TCOOLTHRS
47 driver.set_coolstep_threshold(0xFFFFF)?;
48
49 driver.set_enabled(true)?;
50
51 // =========================================================================
52 // Step 3: Perform Homing
53 // =========================================================================
54
55 // Move towards the endstop
56 let homing_velocity = -2000i32;
57 driver.set_velocity(homing_velocity)?;
58
59 // Poll for stall detection
60 let max_iterations = 10000u32;
61
62 for _ in 0..max_iterations {
63 if driver.is_stalled()? {
64 break;
65 }
66 // Add platform-specific delay here
67 }
68
69 // Stop the motor immediately
70 driver.stop()?;
71
72 // =========================================================================
73 // Step 4: Post-Homing Configuration
74 // =========================================================================
75
76 // Switch back to StealthChop for quiet operation
77 driver.enable_stealthchop()?;
78
79 // Restore normal running current
80 driver.set_current(20, 10, 6)?;
81
82 Ok(())
83}
84
85/// Alternative: Home in both directions to find center.
86#[cfg(feature = "blocking")]
87fn home_to_center<U, E>(uart: U) -> Result<(), tmc2209_uart::Error<E>>
88where
89 U: embedded_io::Read<Error = E> + embedded_io::Write<Error = E>,
90{
91 let mut driver = Tmc2209::new(uart, 0);
92
93 // Configure for homing
94 driver.set_current(12, 6, 4)?;
95 driver.enable_spreadcycle()?;
96 driver.configure_stall_detection(50)?;
97 driver.set_coolstep_threshold(0xFFFFF)?;
98 driver.set_enabled(true)?;
99
100 // Home to minimum position
101 driver.set_velocity(-2000)?;
102 while !driver.is_stalled()? {
103 // Wait or add timeout
104 }
105 driver.stop()?;
106 let _min_position = 0i32;
107
108 // Home to maximum position
109 driver.set_velocity(2000)?;
110 let mut step_count = 0i32;
111 while !driver.is_stalled()? {
112 step_count += 1;
113 }
114 driver.stop()?;
115 let max_position = step_count;
116
117 // Move to center
118 let _center = max_position / 2;
119 driver.set_velocity(-2000)?;
120 // Move for half the counted steps
121 driver.stop()?;
122
123 Ok(())
124}
125
126fn main() {
127 println!("TMC2209 Sensorless Homing Example");
128 println!("This example shows how to use StallGuard for sensorless homing.");
129}