Tmc2209

Struct Tmc2209 

Source
pub struct Tmc2209<U> { /* private fields */ }
Expand description

TMC2209 driver over UART.

This struct provides methods for reading and writing TMC2209 registers via a UART interface. Both blocking and async versions are available depending on enabled features.

§Type Parameters

  • U - UART peripheral type implementing embedded_io::Read + embedded_io::Write or embedded_io_async::Read + embedded_io_async::Write

§Example (blocking)

use tmc2209::{Tmc2209, registers::IholdIrun};

let mut driver = Tmc2209::new(uart, 0);

// Read a register
let status = driver.read_register::<DrvStatus>()?;

// Write a register
let mut irun = IholdIrun::new();
irun.set_irun(16).set_ihold(8);
driver.write_register(&irun)?;

Implementations§

Source§

impl<U> Tmc2209<U>

Source

pub fn new(uart: U, slave_addr: u8) -> Self

Create a new TMC2209 driver.

§Arguments
  • uart - UART peripheral for communication
  • slave_addr - Slave address (0-3)
§Panics

Panics if slave_addr is greater than 3.

Examples found in repository?
examples/basic.rs (line 25)
20fn basic_motor_control<U, E>(uart: U) -> Result<(), tmc2209_uart::Error<E>>
21where
22    U: embedded_io::Read<Error = E> + embedded_io::Write<Error = E>,
23{
24    // Create driver with slave address 0
25    let mut driver = Tmc2209::new(uart, 0);
26
27    // Check if the driver is responding
28    if !driver.is_connected() {
29        // Handle connection error
30        return Err(tmc2209_uart::Error::NoResponse);
31    }
32
33    // Clear any previous errors
34    driver.clear_gstat()?;
35
36    // Configure motor current
37    // IRUN=20 (run current), IHOLD=10 (hold current), IHOLDDELAY=6
38    driver.set_current(20, 10, 6)?;
39
40    // Set microstep resolution to 16 with interpolation to 256
41    driver.set_microsteps(MicrostepResolution::M16)?;
42    driver.set_interpolation(true)?;
43
44    // Enable StealthChop for quiet operation
45    driver.enable_stealthchop()?;
46
47    // Enable the driver
48    driver.set_enabled(true)?;
49
50    // Start moving the motor forward
51    driver.set_velocity(5000)?;
52
53    // Check status
54    let status = driver.drv_status()?;
55
56    if status.ot() {
57        // Overtemperature shutdown - stop immediately!
58        driver.stop()?;
59        driver.set_enabled(false)?;
60    }
61
62    if status.otpw() {
63        // Overtemperature warning - reduce current or add cooling
64        println!("Warning: Motor temperature is high");
65    }
66
67    // Reverse direction
68    driver.set_velocity(-5000)?;
69
70    // Stop the motor
71    driver.stop()?;
72
73    Ok(())
74}
More examples
Hide additional examples
examples/sensorless_homing.rs (line 24)
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}
examples/stealthchop.rs (line 16)
12fn configure_stealthchop<U, E>(uart: U) -> Result<(), tmc2209_uart::Error<E>>
13where
14    U: embedded_io::Read<Error = E> + embedded_io::Write<Error = E>,
15{
16    let mut driver = Tmc2209::new(uart, 0);
17
18    // Basic setup
19    driver.set_current(16, 8, 4)?;
20    driver.set_microsteps(MicrostepResolution::M256)?;
21
22    // =========================================================================
23    // StealthChop Configuration
24    // =========================================================================
25
26    // Enable StealthChop mode (this is the default)
27    driver.enable_stealthchop()?;
28
29    // Configure StealthChop PWM parameters
30    // - pwm_ofs: Base PWM amplitude (0-255)
31    // - pwm_grad: PWM amplitude gradient (0-255)
32    // - autoscale: Enable automatic current scaling
33    // - autograd: Enable automatic gradient adaptation
34    driver.configure_stealthchop(
35        36,   // pwm_ofs (default)
36        14,   // pwm_grad (default)
37        true, // autoscale enabled (recommended)
38        true, // autograd enabled (recommended)
39    )?;
40
41    // =========================================================================
42    // Velocity-Based Mode Switching
43    // =========================================================================
44
45    // Set StealthChop/SpreadCycle velocity threshold (TPWMTHRS)
46    // Below this TSTEP value, StealthChop is used
47    // Above this velocity (lower TSTEP), SpreadCycle is used
48    driver.set_stealthchop_threshold(500)?;
49
50    // =========================================================================
51    // Chopper Configuration
52    // =========================================================================
53
54    // Fine-tune chopper parameters for your motor
55    driver.configure_chopper(
56        3, // toff
57        4, // hstrt
58        1, // hend
59        2, // tbl
60    )?;
61
62    // =========================================================================
63    // Current Sense Configuration
64    // =========================================================================
65
66    // For high-current motors, use low sensitivity VSENSE
67    driver.set_vsense(false)?;
68
69    // Enable the driver
70    driver.set_enabled(true)?;
71
72    // =========================================================================
73    // Monitor StealthChop Status
74    // =========================================================================
75
76    // Start moving
77    driver.set_velocity(1000)?;
78
79    // Check if StealthChop or SpreadCycle is active
80    let _is_stealth = driver.is_stealthchop_active()?;
81
82    // Check actual current being used
83    let _actual_cs = driver.actual_current_scale()?;
84
85    Ok(())
86}
Source

pub fn slave_addr(&self) -> u8

Get the slave address.

Source

pub fn set_slave_addr(&mut self, addr: u8)

Set the slave address.

§Panics

Panics if addr is greater than 3.

Source

pub fn uart(&self) -> &U

Get a reference to the UART peripheral.

Source

pub fn uart_mut(&mut self) -> &mut U

Get a mutable reference to the UART peripheral.

Source

pub fn release(self) -> U

Release the UART peripheral.

Source§

impl<U, E> Tmc2209<U>
where U: Read<Error = E> + Write<Error = E>,

Source

pub fn read_register<R: ReadableRegister>(&mut self) -> Result<R, Error<E>>

Read a register (blocking).

Sends a read request and waits for the response.

§Type Parameters
  • R - Register type to read (must implement ReadableRegister)
§Returns

The register value, or an error if communication fails.

Source

pub fn write_register<R: WritableRegister>( &mut self, reg: &R, ) -> Result<(), Error<E>>

Write a register (blocking).

Sends a write request to update a register value.

§Arguments
  • reg - Register value to write
§Returns

Ok(()) on success, or an error if communication fails.

Source

pub fn read_raw(&mut self, reg_addr: u8) -> Result<u32, Error<E>>

Read a register by raw address (blocking).

Use this when you need to read a register by its raw address value.

Source

pub fn write_raw(&mut self, reg_addr: u8, data: u32) -> Result<(), Error<E>>

Write a register by raw address (blocking).

Use this when you need to write a register by its raw address value.

Source

pub fn is_connected(&mut self) -> bool

Check if the driver is communicating properly.

Reads IFCNT and verifies we get a valid response.

Examples found in repository?
examples/basic.rs (line 28)
20fn basic_motor_control<U, E>(uart: U) -> Result<(), tmc2209_uart::Error<E>>
21where
22    U: embedded_io::Read<Error = E> + embedded_io::Write<Error = E>,
23{
24    // Create driver with slave address 0
25    let mut driver = Tmc2209::new(uart, 0);
26
27    // Check if the driver is responding
28    if !driver.is_connected() {
29        // Handle connection error
30        return Err(tmc2209_uart::Error::NoResponse);
31    }
32
33    // Clear any previous errors
34    driver.clear_gstat()?;
35
36    // Configure motor current
37    // IRUN=20 (run current), IHOLD=10 (hold current), IHOLDDELAY=6
38    driver.set_current(20, 10, 6)?;
39
40    // Set microstep resolution to 16 with interpolation to 256
41    driver.set_microsteps(MicrostepResolution::M16)?;
42    driver.set_interpolation(true)?;
43
44    // Enable StealthChop for quiet operation
45    driver.enable_stealthchop()?;
46
47    // Enable the driver
48    driver.set_enabled(true)?;
49
50    // Start moving the motor forward
51    driver.set_velocity(5000)?;
52
53    // Check status
54    let status = driver.drv_status()?;
55
56    if status.ot() {
57        // Overtemperature shutdown - stop immediately!
58        driver.stop()?;
59        driver.set_enabled(false)?;
60    }
61
62    if status.otpw() {
63        // Overtemperature warning - reduce current or add cooling
64        println!("Warning: Motor temperature is high");
65    }
66
67    // Reverse direction
68    driver.set_velocity(-5000)?;
69
70    // Stop the motor
71    driver.stop()?;
72
73    Ok(())
74}
Source

pub fn ifcnt(&mut self) -> Result<u8, Error<E>>

Get the interface transmission counter.

This counter increments on each successful UART write. Useful for verifying communication.

Source

pub fn gstat(&mut self) -> Result<Gstat, Error<E>>

Get the global status flags.

Source

pub fn clear_gstat(&mut self) -> Result<(), Error<E>>

Clear the global status flags (write to clear).

Examples found in repository?
examples/basic.rs (line 34)
20fn basic_motor_control<U, E>(uart: U) -> Result<(), tmc2209_uart::Error<E>>
21where
22    U: embedded_io::Read<Error = E> + embedded_io::Write<Error = E>,
23{
24    // Create driver with slave address 0
25    let mut driver = Tmc2209::new(uart, 0);
26
27    // Check if the driver is responding
28    if !driver.is_connected() {
29        // Handle connection error
30        return Err(tmc2209_uart::Error::NoResponse);
31    }
32
33    // Clear any previous errors
34    driver.clear_gstat()?;
35
36    // Configure motor current
37    // IRUN=20 (run current), IHOLD=10 (hold current), IHOLDDELAY=6
38    driver.set_current(20, 10, 6)?;
39
40    // Set microstep resolution to 16 with interpolation to 256
41    driver.set_microsteps(MicrostepResolution::M16)?;
42    driver.set_interpolation(true)?;
43
44    // Enable StealthChop for quiet operation
45    driver.enable_stealthchop()?;
46
47    // Enable the driver
48    driver.set_enabled(true)?;
49
50    // Start moving the motor forward
51    driver.set_velocity(5000)?;
52
53    // Check status
54    let status = driver.drv_status()?;
55
56    if status.ot() {
57        // Overtemperature shutdown - stop immediately!
58        driver.stop()?;
59        driver.set_enabled(false)?;
60    }
61
62    if status.otpw() {
63        // Overtemperature warning - reduce current or add cooling
64        println!("Warning: Motor temperature is high");
65    }
66
67    // Reverse direction
68    driver.set_velocity(-5000)?;
69
70    // Stop the motor
71    driver.stop()?;
72
73    Ok(())
74}
Source

pub fn ioin(&mut self) -> Result<Ioin, Error<E>>

Get the input pin states.

Source

pub fn drv_status(&mut self) -> Result<DrvStatus, Error<E>>

Get the driver status.

Examples found in repository?
examples/basic.rs (line 54)
20fn basic_motor_control<U, E>(uart: U) -> Result<(), tmc2209_uart::Error<E>>
21where
22    U: embedded_io::Read<Error = E> + embedded_io::Write<Error = E>,
23{
24    // Create driver with slave address 0
25    let mut driver = Tmc2209::new(uart, 0);
26
27    // Check if the driver is responding
28    if !driver.is_connected() {
29        // Handle connection error
30        return Err(tmc2209_uart::Error::NoResponse);
31    }
32
33    // Clear any previous errors
34    driver.clear_gstat()?;
35
36    // Configure motor current
37    // IRUN=20 (run current), IHOLD=10 (hold current), IHOLDDELAY=6
38    driver.set_current(20, 10, 6)?;
39
40    // Set microstep resolution to 16 with interpolation to 256
41    driver.set_microsteps(MicrostepResolution::M16)?;
42    driver.set_interpolation(true)?;
43
44    // Enable StealthChop for quiet operation
45    driver.enable_stealthchop()?;
46
47    // Enable the driver
48    driver.set_enabled(true)?;
49
50    // Start moving the motor forward
51    driver.set_velocity(5000)?;
52
53    // Check status
54    let status = driver.drv_status()?;
55
56    if status.ot() {
57        // Overtemperature shutdown - stop immediately!
58        driver.stop()?;
59        driver.set_enabled(false)?;
60    }
61
62    if status.otpw() {
63        // Overtemperature warning - reduce current or add cooling
64        println!("Warning: Motor temperature is high");
65    }
66
67    // Reverse direction
68    driver.set_velocity(-5000)?;
69
70    // Stop the motor
71    driver.stop()?;
72
73    Ok(())
74}
Source

pub fn tstep(&mut self) -> Result<u32, Error<E>>

Get the current step time (inverse of velocity).

Source

pub fn sg_result(&mut self) -> Result<u16, Error<E>>

Get the StallGuard result.

Source

pub fn mscnt(&mut self) -> Result<u16, Error<E>>

Get the microstep counter position (0-1023).

Source

pub fn set_current( &mut self, run_current: u8, hold_current: u8, hold_delay: u8, ) -> Result<(), Error<E>>

Set the motor currents.

§Arguments
  • run_current - Run current (0-31)
  • hold_current - Hold current (0-31)
  • hold_delay - Delay before reducing to hold current (0-15)
Examples found in repository?
examples/basic.rs (line 38)
20fn basic_motor_control<U, E>(uart: U) -> Result<(), tmc2209_uart::Error<E>>
21where
22    U: embedded_io::Read<Error = E> + embedded_io::Write<Error = E>,
23{
24    // Create driver with slave address 0
25    let mut driver = Tmc2209::new(uart, 0);
26
27    // Check if the driver is responding
28    if !driver.is_connected() {
29        // Handle connection error
30        return Err(tmc2209_uart::Error::NoResponse);
31    }
32
33    // Clear any previous errors
34    driver.clear_gstat()?;
35
36    // Configure motor current
37    // IRUN=20 (run current), IHOLD=10 (hold current), IHOLDDELAY=6
38    driver.set_current(20, 10, 6)?;
39
40    // Set microstep resolution to 16 with interpolation to 256
41    driver.set_microsteps(MicrostepResolution::M16)?;
42    driver.set_interpolation(true)?;
43
44    // Enable StealthChop for quiet operation
45    driver.enable_stealthchop()?;
46
47    // Enable the driver
48    driver.set_enabled(true)?;
49
50    // Start moving the motor forward
51    driver.set_velocity(5000)?;
52
53    // Check status
54    let status = driver.drv_status()?;
55
56    if status.ot() {
57        // Overtemperature shutdown - stop immediately!
58        driver.stop()?;
59        driver.set_enabled(false)?;
60    }
61
62    if status.otpw() {
63        // Overtemperature warning - reduce current or add cooling
64        println!("Warning: Motor temperature is high");
65    }
66
67    // Reverse direction
68    driver.set_velocity(-5000)?;
69
70    // Stop the motor
71    driver.stop()?;
72
73    Ok(())
74}
More examples
Hide additional examples
examples/sensorless_homing.rs (line 31)
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}
examples/stealthchop.rs (line 19)
12fn configure_stealthchop<U, E>(uart: U) -> Result<(), tmc2209_uart::Error<E>>
13where
14    U: embedded_io::Read<Error = E> + embedded_io::Write<Error = E>,
15{
16    let mut driver = Tmc2209::new(uart, 0);
17
18    // Basic setup
19    driver.set_current(16, 8, 4)?;
20    driver.set_microsteps(MicrostepResolution::M256)?;
21
22    // =========================================================================
23    // StealthChop Configuration
24    // =========================================================================
25
26    // Enable StealthChop mode (this is the default)
27    driver.enable_stealthchop()?;
28
29    // Configure StealthChop PWM parameters
30    // - pwm_ofs: Base PWM amplitude (0-255)
31    // - pwm_grad: PWM amplitude gradient (0-255)
32    // - autoscale: Enable automatic current scaling
33    // - autograd: Enable automatic gradient adaptation
34    driver.configure_stealthchop(
35        36,   // pwm_ofs (default)
36        14,   // pwm_grad (default)
37        true, // autoscale enabled (recommended)
38        true, // autograd enabled (recommended)
39    )?;
40
41    // =========================================================================
42    // Velocity-Based Mode Switching
43    // =========================================================================
44
45    // Set StealthChop/SpreadCycle velocity threshold (TPWMTHRS)
46    // Below this TSTEP value, StealthChop is used
47    // Above this velocity (lower TSTEP), SpreadCycle is used
48    driver.set_stealthchop_threshold(500)?;
49
50    // =========================================================================
51    // Chopper Configuration
52    // =========================================================================
53
54    // Fine-tune chopper parameters for your motor
55    driver.configure_chopper(
56        3, // toff
57        4, // hstrt
58        1, // hend
59        2, // tbl
60    )?;
61
62    // =========================================================================
63    // Current Sense Configuration
64    // =========================================================================
65
66    // For high-current motors, use low sensitivity VSENSE
67    driver.set_vsense(false)?;
68
69    // Enable the driver
70    driver.set_enabled(true)?;
71
72    // =========================================================================
73    // Monitor StealthChop Status
74    // =========================================================================
75
76    // Start moving
77    driver.set_velocity(1000)?;
78
79    // Check if StealthChop or SpreadCycle is active
80    let _is_stealth = driver.is_stealthchop_active()?;
81
82    // Check actual current being used
83    let _actual_cs = driver.actual_current_scale()?;
84
85    Ok(())
86}
Source

pub fn set_microsteps( &mut self, resolution: MicrostepResolution, ) -> Result<(), Error<E>>

Set the microstep resolution.

Examples found in repository?
examples/basic.rs (line 41)
20fn basic_motor_control<U, E>(uart: U) -> Result<(), tmc2209_uart::Error<E>>
21where
22    U: embedded_io::Read<Error = E> + embedded_io::Write<Error = E>,
23{
24    // Create driver with slave address 0
25    let mut driver = Tmc2209::new(uart, 0);
26
27    // Check if the driver is responding
28    if !driver.is_connected() {
29        // Handle connection error
30        return Err(tmc2209_uart::Error::NoResponse);
31    }
32
33    // Clear any previous errors
34    driver.clear_gstat()?;
35
36    // Configure motor current
37    // IRUN=20 (run current), IHOLD=10 (hold current), IHOLDDELAY=6
38    driver.set_current(20, 10, 6)?;
39
40    // Set microstep resolution to 16 with interpolation to 256
41    driver.set_microsteps(MicrostepResolution::M16)?;
42    driver.set_interpolation(true)?;
43
44    // Enable StealthChop for quiet operation
45    driver.enable_stealthchop()?;
46
47    // Enable the driver
48    driver.set_enabled(true)?;
49
50    // Start moving the motor forward
51    driver.set_velocity(5000)?;
52
53    // Check status
54    let status = driver.drv_status()?;
55
56    if status.ot() {
57        // Overtemperature shutdown - stop immediately!
58        driver.stop()?;
59        driver.set_enabled(false)?;
60    }
61
62    if status.otpw() {
63        // Overtemperature warning - reduce current or add cooling
64        println!("Warning: Motor temperature is high");
65    }
66
67    // Reverse direction
68    driver.set_velocity(-5000)?;
69
70    // Stop the motor
71    driver.stop()?;
72
73    Ok(())
74}
More examples
Hide additional examples
examples/sensorless_homing.rs (line 34)
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}
examples/stealthchop.rs (line 20)
12fn configure_stealthchop<U, E>(uart: U) -> Result<(), tmc2209_uart::Error<E>>
13where
14    U: embedded_io::Read<Error = E> + embedded_io::Write<Error = E>,
15{
16    let mut driver = Tmc2209::new(uart, 0);
17
18    // Basic setup
19    driver.set_current(16, 8, 4)?;
20    driver.set_microsteps(MicrostepResolution::M256)?;
21
22    // =========================================================================
23    // StealthChop Configuration
24    // =========================================================================
25
26    // Enable StealthChop mode (this is the default)
27    driver.enable_stealthchop()?;
28
29    // Configure StealthChop PWM parameters
30    // - pwm_ofs: Base PWM amplitude (0-255)
31    // - pwm_grad: PWM amplitude gradient (0-255)
32    // - autoscale: Enable automatic current scaling
33    // - autograd: Enable automatic gradient adaptation
34    driver.configure_stealthchop(
35        36,   // pwm_ofs (default)
36        14,   // pwm_grad (default)
37        true, // autoscale enabled (recommended)
38        true, // autograd enabled (recommended)
39    )?;
40
41    // =========================================================================
42    // Velocity-Based Mode Switching
43    // =========================================================================
44
45    // Set StealthChop/SpreadCycle velocity threshold (TPWMTHRS)
46    // Below this TSTEP value, StealthChop is used
47    // Above this velocity (lower TSTEP), SpreadCycle is used
48    driver.set_stealthchop_threshold(500)?;
49
50    // =========================================================================
51    // Chopper Configuration
52    // =========================================================================
53
54    // Fine-tune chopper parameters for your motor
55    driver.configure_chopper(
56        3, // toff
57        4, // hstrt
58        1, // hend
59        2, // tbl
60    )?;
61
62    // =========================================================================
63    // Current Sense Configuration
64    // =========================================================================
65
66    // For high-current motors, use low sensitivity VSENSE
67    driver.set_vsense(false)?;
68
69    // Enable the driver
70    driver.set_enabled(true)?;
71
72    // =========================================================================
73    // Monitor StealthChop Status
74    // =========================================================================
75
76    // Start moving
77    driver.set_velocity(1000)?;
78
79    // Check if StealthChop or SpreadCycle is active
80    let _is_stealth = driver.is_stealthchop_active()?;
81
82    // Check actual current being used
83    let _actual_cs = driver.actual_current_scale()?;
84
85    Ok(())
86}
Source

pub fn set_enabled(&mut self, enabled: bool) -> Result<(), Error<E>>

Enable or disable the driver.

When TOFF=0, the driver is disabled.

Examples found in repository?
examples/basic.rs (line 48)
20fn basic_motor_control<U, E>(uart: U) -> Result<(), tmc2209_uart::Error<E>>
21where
22    U: embedded_io::Read<Error = E> + embedded_io::Write<Error = E>,
23{
24    // Create driver with slave address 0
25    let mut driver = Tmc2209::new(uart, 0);
26
27    // Check if the driver is responding
28    if !driver.is_connected() {
29        // Handle connection error
30        return Err(tmc2209_uart::Error::NoResponse);
31    }
32
33    // Clear any previous errors
34    driver.clear_gstat()?;
35
36    // Configure motor current
37    // IRUN=20 (run current), IHOLD=10 (hold current), IHOLDDELAY=6
38    driver.set_current(20, 10, 6)?;
39
40    // Set microstep resolution to 16 with interpolation to 256
41    driver.set_microsteps(MicrostepResolution::M16)?;
42    driver.set_interpolation(true)?;
43
44    // Enable StealthChop for quiet operation
45    driver.enable_stealthchop()?;
46
47    // Enable the driver
48    driver.set_enabled(true)?;
49
50    // Start moving the motor forward
51    driver.set_velocity(5000)?;
52
53    // Check status
54    let status = driver.drv_status()?;
55
56    if status.ot() {
57        // Overtemperature shutdown - stop immediately!
58        driver.stop()?;
59        driver.set_enabled(false)?;
60    }
61
62    if status.otpw() {
63        // Overtemperature warning - reduce current or add cooling
64        println!("Warning: Motor temperature is high");
65    }
66
67    // Reverse direction
68    driver.set_velocity(-5000)?;
69
70    // Stop the motor
71    driver.stop()?;
72
73    Ok(())
74}
More examples
Hide additional examples
examples/sensorless_homing.rs (line 49)
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}
examples/stealthchop.rs (line 70)
12fn configure_stealthchop<U, E>(uart: U) -> Result<(), tmc2209_uart::Error<E>>
13where
14    U: embedded_io::Read<Error = E> + embedded_io::Write<Error = E>,
15{
16    let mut driver = Tmc2209::new(uart, 0);
17
18    // Basic setup
19    driver.set_current(16, 8, 4)?;
20    driver.set_microsteps(MicrostepResolution::M256)?;
21
22    // =========================================================================
23    // StealthChop Configuration
24    // =========================================================================
25
26    // Enable StealthChop mode (this is the default)
27    driver.enable_stealthchop()?;
28
29    // Configure StealthChop PWM parameters
30    // - pwm_ofs: Base PWM amplitude (0-255)
31    // - pwm_grad: PWM amplitude gradient (0-255)
32    // - autoscale: Enable automatic current scaling
33    // - autograd: Enable automatic gradient adaptation
34    driver.configure_stealthchop(
35        36,   // pwm_ofs (default)
36        14,   // pwm_grad (default)
37        true, // autoscale enabled (recommended)
38        true, // autograd enabled (recommended)
39    )?;
40
41    // =========================================================================
42    // Velocity-Based Mode Switching
43    // =========================================================================
44
45    // Set StealthChop/SpreadCycle velocity threshold (TPWMTHRS)
46    // Below this TSTEP value, StealthChop is used
47    // Above this velocity (lower TSTEP), SpreadCycle is used
48    driver.set_stealthchop_threshold(500)?;
49
50    // =========================================================================
51    // Chopper Configuration
52    // =========================================================================
53
54    // Fine-tune chopper parameters for your motor
55    driver.configure_chopper(
56        3, // toff
57        4, // hstrt
58        1, // hend
59        2, // tbl
60    )?;
61
62    // =========================================================================
63    // Current Sense Configuration
64    // =========================================================================
65
66    // For high-current motors, use low sensitivity VSENSE
67    driver.set_vsense(false)?;
68
69    // Enable the driver
70    driver.set_enabled(true)?;
71
72    // =========================================================================
73    // Monitor StealthChop Status
74    // =========================================================================
75
76    // Start moving
77    driver.set_velocity(1000)?;
78
79    // Check if StealthChop or SpreadCycle is active
80    let _is_stealth = driver.is_stealthchop_active()?;
81
82    // Check actual current being used
83    let _actual_cs = driver.actual_current_scale()?;
84
85    Ok(())
86}
Source

pub fn set_velocity(&mut self, velocity: i32) -> Result<(), Error<E>>

Set velocity for internal motion controller (VACTUAL).

§Arguments
  • velocity - Velocity value (signed, 23-bit range)
    • Positive: Forward motion
    • Negative: Reverse motion
    • 0: Stop
Examples found in repository?
examples/basic.rs (line 51)
20fn basic_motor_control<U, E>(uart: U) -> Result<(), tmc2209_uart::Error<E>>
21where
22    U: embedded_io::Read<Error = E> + embedded_io::Write<Error = E>,
23{
24    // Create driver with slave address 0
25    let mut driver = Tmc2209::new(uart, 0);
26
27    // Check if the driver is responding
28    if !driver.is_connected() {
29        // Handle connection error
30        return Err(tmc2209_uart::Error::NoResponse);
31    }
32
33    // Clear any previous errors
34    driver.clear_gstat()?;
35
36    // Configure motor current
37    // IRUN=20 (run current), IHOLD=10 (hold current), IHOLDDELAY=6
38    driver.set_current(20, 10, 6)?;
39
40    // Set microstep resolution to 16 with interpolation to 256
41    driver.set_microsteps(MicrostepResolution::M16)?;
42    driver.set_interpolation(true)?;
43
44    // Enable StealthChop for quiet operation
45    driver.enable_stealthchop()?;
46
47    // Enable the driver
48    driver.set_enabled(true)?;
49
50    // Start moving the motor forward
51    driver.set_velocity(5000)?;
52
53    // Check status
54    let status = driver.drv_status()?;
55
56    if status.ot() {
57        // Overtemperature shutdown - stop immediately!
58        driver.stop()?;
59        driver.set_enabled(false)?;
60    }
61
62    if status.otpw() {
63        // Overtemperature warning - reduce current or add cooling
64        println!("Warning: Motor temperature is high");
65    }
66
67    // Reverse direction
68    driver.set_velocity(-5000)?;
69
70    // Stop the motor
71    driver.stop()?;
72
73    Ok(())
74}
More examples
Hide additional examples
examples/sensorless_homing.rs (line 57)
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}
examples/stealthchop.rs (line 77)
12fn configure_stealthchop<U, E>(uart: U) -> Result<(), tmc2209_uart::Error<E>>
13where
14    U: embedded_io::Read<Error = E> + embedded_io::Write<Error = E>,
15{
16    let mut driver = Tmc2209::new(uart, 0);
17
18    // Basic setup
19    driver.set_current(16, 8, 4)?;
20    driver.set_microsteps(MicrostepResolution::M256)?;
21
22    // =========================================================================
23    // StealthChop Configuration
24    // =========================================================================
25
26    // Enable StealthChop mode (this is the default)
27    driver.enable_stealthchop()?;
28
29    // Configure StealthChop PWM parameters
30    // - pwm_ofs: Base PWM amplitude (0-255)
31    // - pwm_grad: PWM amplitude gradient (0-255)
32    // - autoscale: Enable automatic current scaling
33    // - autograd: Enable automatic gradient adaptation
34    driver.configure_stealthchop(
35        36,   // pwm_ofs (default)
36        14,   // pwm_grad (default)
37        true, // autoscale enabled (recommended)
38        true, // autograd enabled (recommended)
39    )?;
40
41    // =========================================================================
42    // Velocity-Based Mode Switching
43    // =========================================================================
44
45    // Set StealthChop/SpreadCycle velocity threshold (TPWMTHRS)
46    // Below this TSTEP value, StealthChop is used
47    // Above this velocity (lower TSTEP), SpreadCycle is used
48    driver.set_stealthchop_threshold(500)?;
49
50    // =========================================================================
51    // Chopper Configuration
52    // =========================================================================
53
54    // Fine-tune chopper parameters for your motor
55    driver.configure_chopper(
56        3, // toff
57        4, // hstrt
58        1, // hend
59        2, // tbl
60    )?;
61
62    // =========================================================================
63    // Current Sense Configuration
64    // =========================================================================
65
66    // For high-current motors, use low sensitivity VSENSE
67    driver.set_vsense(false)?;
68
69    // Enable the driver
70    driver.set_enabled(true)?;
71
72    // =========================================================================
73    // Monitor StealthChop Status
74    // =========================================================================
75
76    // Start moving
77    driver.set_velocity(1000)?;
78
79    // Check if StealthChop or SpreadCycle is active
80    let _is_stealth = driver.is_stealthchop_active()?;
81
82    // Check actual current being used
83    let _actual_cs = driver.actual_current_scale()?;
84
85    Ok(())
86}
Source

pub fn stop(&mut self) -> Result<(), Error<E>>

Stop the motor (set VACTUAL to 0).

Examples found in repository?
examples/basic.rs (line 58)
20fn basic_motor_control<U, E>(uart: U) -> Result<(), tmc2209_uart::Error<E>>
21where
22    U: embedded_io::Read<Error = E> + embedded_io::Write<Error = E>,
23{
24    // Create driver with slave address 0
25    let mut driver = Tmc2209::new(uart, 0);
26
27    // Check if the driver is responding
28    if !driver.is_connected() {
29        // Handle connection error
30        return Err(tmc2209_uart::Error::NoResponse);
31    }
32
33    // Clear any previous errors
34    driver.clear_gstat()?;
35
36    // Configure motor current
37    // IRUN=20 (run current), IHOLD=10 (hold current), IHOLDDELAY=6
38    driver.set_current(20, 10, 6)?;
39
40    // Set microstep resolution to 16 with interpolation to 256
41    driver.set_microsteps(MicrostepResolution::M16)?;
42    driver.set_interpolation(true)?;
43
44    // Enable StealthChop for quiet operation
45    driver.enable_stealthchop()?;
46
47    // Enable the driver
48    driver.set_enabled(true)?;
49
50    // Start moving the motor forward
51    driver.set_velocity(5000)?;
52
53    // Check status
54    let status = driver.drv_status()?;
55
56    if status.ot() {
57        // Overtemperature shutdown - stop immediately!
58        driver.stop()?;
59        driver.set_enabled(false)?;
60    }
61
62    if status.otpw() {
63        // Overtemperature warning - reduce current or add cooling
64        println!("Warning: Motor temperature is high");
65    }
66
67    // Reverse direction
68    driver.set_velocity(-5000)?;
69
70    // Stop the motor
71    driver.stop()?;
72
73    Ok(())
74}
More examples
Hide additional examples
examples/sensorless_homing.rs (line 70)
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}
Source

pub fn set_stall_threshold(&mut self, threshold: u8) -> Result<(), Error<E>>

Set the StallGuard threshold.

Higher values make stall detection more sensitive.

Source

pub fn enable_stealthchop(&mut self) -> Result<(), Error<E>>

Enable StealthChop mode.

Examples found in repository?
examples/basic.rs (line 45)
20fn basic_motor_control<U, E>(uart: U) -> Result<(), tmc2209_uart::Error<E>>
21where
22    U: embedded_io::Read<Error = E> + embedded_io::Write<Error = E>,
23{
24    // Create driver with slave address 0
25    let mut driver = Tmc2209::new(uart, 0);
26
27    // Check if the driver is responding
28    if !driver.is_connected() {
29        // Handle connection error
30        return Err(tmc2209_uart::Error::NoResponse);
31    }
32
33    // Clear any previous errors
34    driver.clear_gstat()?;
35
36    // Configure motor current
37    // IRUN=20 (run current), IHOLD=10 (hold current), IHOLDDELAY=6
38    driver.set_current(20, 10, 6)?;
39
40    // Set microstep resolution to 16 with interpolation to 256
41    driver.set_microsteps(MicrostepResolution::M16)?;
42    driver.set_interpolation(true)?;
43
44    // Enable StealthChop for quiet operation
45    driver.enable_stealthchop()?;
46
47    // Enable the driver
48    driver.set_enabled(true)?;
49
50    // Start moving the motor forward
51    driver.set_velocity(5000)?;
52
53    // Check status
54    let status = driver.drv_status()?;
55
56    if status.ot() {
57        // Overtemperature shutdown - stop immediately!
58        driver.stop()?;
59        driver.set_enabled(false)?;
60    }
61
62    if status.otpw() {
63        // Overtemperature warning - reduce current or add cooling
64        println!("Warning: Motor temperature is high");
65    }
66
67    // Reverse direction
68    driver.set_velocity(-5000)?;
69
70    // Stop the motor
71    driver.stop()?;
72
73    Ok(())
74}
More examples
Hide additional examples
examples/sensorless_homing.rs (line 77)
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}
examples/stealthchop.rs (line 27)
12fn configure_stealthchop<U, E>(uart: U) -> Result<(), tmc2209_uart::Error<E>>
13where
14    U: embedded_io::Read<Error = E> + embedded_io::Write<Error = E>,
15{
16    let mut driver = Tmc2209::new(uart, 0);
17
18    // Basic setup
19    driver.set_current(16, 8, 4)?;
20    driver.set_microsteps(MicrostepResolution::M256)?;
21
22    // =========================================================================
23    // StealthChop Configuration
24    // =========================================================================
25
26    // Enable StealthChop mode (this is the default)
27    driver.enable_stealthchop()?;
28
29    // Configure StealthChop PWM parameters
30    // - pwm_ofs: Base PWM amplitude (0-255)
31    // - pwm_grad: PWM amplitude gradient (0-255)
32    // - autoscale: Enable automatic current scaling
33    // - autograd: Enable automatic gradient adaptation
34    driver.configure_stealthchop(
35        36,   // pwm_ofs (default)
36        14,   // pwm_grad (default)
37        true, // autoscale enabled (recommended)
38        true, // autograd enabled (recommended)
39    )?;
40
41    // =========================================================================
42    // Velocity-Based Mode Switching
43    // =========================================================================
44
45    // Set StealthChop/SpreadCycle velocity threshold (TPWMTHRS)
46    // Below this TSTEP value, StealthChop is used
47    // Above this velocity (lower TSTEP), SpreadCycle is used
48    driver.set_stealthchop_threshold(500)?;
49
50    // =========================================================================
51    // Chopper Configuration
52    // =========================================================================
53
54    // Fine-tune chopper parameters for your motor
55    driver.configure_chopper(
56        3, // toff
57        4, // hstrt
58        1, // hend
59        2, // tbl
60    )?;
61
62    // =========================================================================
63    // Current Sense Configuration
64    // =========================================================================
65
66    // For high-current motors, use low sensitivity VSENSE
67    driver.set_vsense(false)?;
68
69    // Enable the driver
70    driver.set_enabled(true)?;
71
72    // =========================================================================
73    // Monitor StealthChop Status
74    // =========================================================================
75
76    // Start moving
77    driver.set_velocity(1000)?;
78
79    // Check if StealthChop or SpreadCycle is active
80    let _is_stealth = driver.is_stealthchop_active()?;
81
82    // Check actual current being used
83    let _actual_cs = driver.actual_current_scale()?;
84
85    Ok(())
86}
Source

pub fn enable_spreadcycle(&mut self) -> Result<(), Error<E>>

Enable SpreadCycle mode.

Examples found in repository?
examples/sensorless_homing.rs (line 41)
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}
Source

pub fn is_standstill(&mut self) -> Result<bool, Error<E>>

Check if motor is in standstill.

Source

pub fn is_overtemperature_warning(&mut self) -> Result<bool, Error<E>>

Check if overtemperature warning is active.

Source

pub fn is_overtemperature_shutdown(&mut self) -> Result<bool, Error<E>>

Check if overtemperature shutdown is active.

Source

pub fn enable_coolstep(&mut self, semin: u8, semax: u8) -> Result<(), Error<E>>

Enable CoolStep adaptive current control.

CoolStep automatically reduces motor current when load is low, saving power and reducing heat.

§Arguments
  • semin - Minimum StallGuard value for current increase (1-15, 0 disables)
  • semax - Hysteresis for current decrease (0-15)
§Example
// Enable CoolStep with moderate sensitivity
driver.enable_coolstep(4, 2)?;
Source

pub fn disable_coolstep(&mut self) -> Result<(), Error<E>>

Disable CoolStep.

Source

pub fn set_coolstep_threshold(&mut self, threshold: u32) -> Result<(), Error<E>>

Set the CoolStep velocity threshold (TCOOLTHRS).

CoolStep and StallGuard are only active when TSTEP < TCOOLTHRS. Below this velocity, CoolStep and stall detection are disabled.

§Arguments
  • threshold - TSTEP threshold value (0 = disabled, 0xFFFFF = always active)
Examples found in repository?
examples/sensorless_homing.rs (line 47)
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}
Source

pub fn set_stealthchop_threshold( &mut self, threshold: u32, ) -> Result<(), Error<E>>

Set the StealthChop velocity threshold (TPWMTHRS).

Above this velocity, the driver switches from StealthChop to SpreadCycle.

§Arguments
  • threshold - TSTEP threshold value (0 = only SpreadCycle, 0xFFFFF = only StealthChop)
Examples found in repository?
examples/stealthchop.rs (line 48)
12fn configure_stealthchop<U, E>(uart: U) -> Result<(), tmc2209_uart::Error<E>>
13where
14    U: embedded_io::Read<Error = E> + embedded_io::Write<Error = E>,
15{
16    let mut driver = Tmc2209::new(uart, 0);
17
18    // Basic setup
19    driver.set_current(16, 8, 4)?;
20    driver.set_microsteps(MicrostepResolution::M256)?;
21
22    // =========================================================================
23    // StealthChop Configuration
24    // =========================================================================
25
26    // Enable StealthChop mode (this is the default)
27    driver.enable_stealthchop()?;
28
29    // Configure StealthChop PWM parameters
30    // - pwm_ofs: Base PWM amplitude (0-255)
31    // - pwm_grad: PWM amplitude gradient (0-255)
32    // - autoscale: Enable automatic current scaling
33    // - autograd: Enable automatic gradient adaptation
34    driver.configure_stealthchop(
35        36,   // pwm_ofs (default)
36        14,   // pwm_grad (default)
37        true, // autoscale enabled (recommended)
38        true, // autograd enabled (recommended)
39    )?;
40
41    // =========================================================================
42    // Velocity-Based Mode Switching
43    // =========================================================================
44
45    // Set StealthChop/SpreadCycle velocity threshold (TPWMTHRS)
46    // Below this TSTEP value, StealthChop is used
47    // Above this velocity (lower TSTEP), SpreadCycle is used
48    driver.set_stealthchop_threshold(500)?;
49
50    // =========================================================================
51    // Chopper Configuration
52    // =========================================================================
53
54    // Fine-tune chopper parameters for your motor
55    driver.configure_chopper(
56        3, // toff
57        4, // hstrt
58        1, // hend
59        2, // tbl
60    )?;
61
62    // =========================================================================
63    // Current Sense Configuration
64    // =========================================================================
65
66    // For high-current motors, use low sensitivity VSENSE
67    driver.set_vsense(false)?;
68
69    // Enable the driver
70    driver.set_enabled(true)?;
71
72    // =========================================================================
73    // Monitor StealthChop Status
74    // =========================================================================
75
76    // Start moving
77    driver.set_velocity(1000)?;
78
79    // Check if StealthChop or SpreadCycle is active
80    let _is_stealth = driver.is_stealthchop_active()?;
81
82    // Check actual current being used
83    let _actual_cs = driver.actual_current_scale()?;
84
85    Ok(())
86}
Source

pub fn configure_stall_detection( &mut self, threshold: u8, ) -> Result<(), Error<E>>

Configure stall detection for sensorless homing.

This sets up the StallGuard feature to detect when the motor hits an endstop or obstacle.

§Arguments
  • threshold - StallGuard threshold (0-255, higher = more sensitive)
§Note

For sensorless homing to work properly:

  • Use SpreadCycle mode (not StealthChop)
  • Set appropriate TCOOLTHRS (stall detection only works above this velocity)
  • Move at a consistent, moderate speed
§Example
// Configure for sensorless homing
driver.configure_stall_detection(50)?;
driver.enable_spreadcycle()?;
driver.set_coolstep_threshold(0)?; // Enable at all velocities

// Move towards endstop
driver.set_velocity(-1000)?;

// Poll for stall
loop {
    if driver.is_stalled()? {
        driver.stop()?;
        break;
    }
}
Examples found in repository?
examples/sensorless_homing.rs (line 44)
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}
Source

pub fn is_stalled(&mut self) -> Result<bool, Error<E>>

Check if the motor is currently stalled.

Returns true if the StallGuard result is below the threshold. Only valid when motor is moving and TSTEP < TCOOLTHRS.

Examples found in repository?
examples/sensorless_homing.rs (line 63)
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}
Source

pub fn load_indicator(&mut self) -> Result<u16, Error<E>>

Get the current load indicator from StallGuard.

Returns a value from 0 (high load/stall) to 510 (no load). Useful for load monitoring and stall detection tuning.

Source

pub fn configure_stealthchop( &mut self, pwm_ofs: u8, pwm_grad: u8, autoscale: bool, autograd: bool, ) -> Result<(), Error<E>>

Configure StealthChop PWM settings.

§Arguments
  • pwm_ofs - PWM amplitude offset (0-255)
  • pwm_grad - PWM amplitude gradient (0-255)
  • autoscale - Enable automatic current scaling
  • autograd - Enable automatic gradient adaptation
Examples found in repository?
examples/stealthchop.rs (lines 34-39)
12fn configure_stealthchop<U, E>(uart: U) -> Result<(), tmc2209_uart::Error<E>>
13where
14    U: embedded_io::Read<Error = E> + embedded_io::Write<Error = E>,
15{
16    let mut driver = Tmc2209::new(uart, 0);
17
18    // Basic setup
19    driver.set_current(16, 8, 4)?;
20    driver.set_microsteps(MicrostepResolution::M256)?;
21
22    // =========================================================================
23    // StealthChop Configuration
24    // =========================================================================
25
26    // Enable StealthChop mode (this is the default)
27    driver.enable_stealthchop()?;
28
29    // Configure StealthChop PWM parameters
30    // - pwm_ofs: Base PWM amplitude (0-255)
31    // - pwm_grad: PWM amplitude gradient (0-255)
32    // - autoscale: Enable automatic current scaling
33    // - autograd: Enable automatic gradient adaptation
34    driver.configure_stealthchop(
35        36,   // pwm_ofs (default)
36        14,   // pwm_grad (default)
37        true, // autoscale enabled (recommended)
38        true, // autograd enabled (recommended)
39    )?;
40
41    // =========================================================================
42    // Velocity-Based Mode Switching
43    // =========================================================================
44
45    // Set StealthChop/SpreadCycle velocity threshold (TPWMTHRS)
46    // Below this TSTEP value, StealthChop is used
47    // Above this velocity (lower TSTEP), SpreadCycle is used
48    driver.set_stealthchop_threshold(500)?;
49
50    // =========================================================================
51    // Chopper Configuration
52    // =========================================================================
53
54    // Fine-tune chopper parameters for your motor
55    driver.configure_chopper(
56        3, // toff
57        4, // hstrt
58        1, // hend
59        2, // tbl
60    )?;
61
62    // =========================================================================
63    // Current Sense Configuration
64    // =========================================================================
65
66    // For high-current motors, use low sensitivity VSENSE
67    driver.set_vsense(false)?;
68
69    // Enable the driver
70    driver.set_enabled(true)?;
71
72    // =========================================================================
73    // Monitor StealthChop Status
74    // =========================================================================
75
76    // Start moving
77    driver.set_velocity(1000)?;
78
79    // Check if StealthChop or SpreadCycle is active
80    let _is_stealth = driver.is_stealthchop_active()?;
81
82    // Check actual current being used
83    let _actual_cs = driver.actual_current_scale()?;
84
85    Ok(())
86}
Source

pub fn set_vsense(&mut self, high_sensitivity: bool) -> Result<(), Error<E>>

Set VSENSE for current sense resistor scaling.

§Arguments
  • high_sensitivity - true for high sensitivity (low current range), false for low sensitivity (high current range)
Examples found in repository?
examples/stealthchop.rs (line 67)
12fn configure_stealthchop<U, E>(uart: U) -> Result<(), tmc2209_uart::Error<E>>
13where
14    U: embedded_io::Read<Error = E> + embedded_io::Write<Error = E>,
15{
16    let mut driver = Tmc2209::new(uart, 0);
17
18    // Basic setup
19    driver.set_current(16, 8, 4)?;
20    driver.set_microsteps(MicrostepResolution::M256)?;
21
22    // =========================================================================
23    // StealthChop Configuration
24    // =========================================================================
25
26    // Enable StealthChop mode (this is the default)
27    driver.enable_stealthchop()?;
28
29    // Configure StealthChop PWM parameters
30    // - pwm_ofs: Base PWM amplitude (0-255)
31    // - pwm_grad: PWM amplitude gradient (0-255)
32    // - autoscale: Enable automatic current scaling
33    // - autograd: Enable automatic gradient adaptation
34    driver.configure_stealthchop(
35        36,   // pwm_ofs (default)
36        14,   // pwm_grad (default)
37        true, // autoscale enabled (recommended)
38        true, // autograd enabled (recommended)
39    )?;
40
41    // =========================================================================
42    // Velocity-Based Mode Switching
43    // =========================================================================
44
45    // Set StealthChop/SpreadCycle velocity threshold (TPWMTHRS)
46    // Below this TSTEP value, StealthChop is used
47    // Above this velocity (lower TSTEP), SpreadCycle is used
48    driver.set_stealthchop_threshold(500)?;
49
50    // =========================================================================
51    // Chopper Configuration
52    // =========================================================================
53
54    // Fine-tune chopper parameters for your motor
55    driver.configure_chopper(
56        3, // toff
57        4, // hstrt
58        1, // hend
59        2, // tbl
60    )?;
61
62    // =========================================================================
63    // Current Sense Configuration
64    // =========================================================================
65
66    // For high-current motors, use low sensitivity VSENSE
67    driver.set_vsense(false)?;
68
69    // Enable the driver
70    driver.set_enabled(true)?;
71
72    // =========================================================================
73    // Monitor StealthChop Status
74    // =========================================================================
75
76    // Start moving
77    driver.set_velocity(1000)?;
78
79    // Check if StealthChop or SpreadCycle is active
80    let _is_stealth = driver.is_stealthchop_active()?;
81
82    // Check actual current being used
83    let _actual_cs = driver.actual_current_scale()?;
84
85    Ok(())
86}
Source

pub fn configure_chopper( &mut self, toff: u8, hstrt: u8, hend: u8, tbl: u8, ) -> Result<(), Error<E>>

Configure chopper settings for optimal performance.

§Arguments
  • toff - Off-time (1-15, 0 disables driver)
  • hstrt - Hysteresis start (0-7)
  • hend - Hysteresis end (0-15)
  • tbl - Comparator blank time (0-3)
Examples found in repository?
examples/stealthchop.rs (lines 55-60)
12fn configure_stealthchop<U, E>(uart: U) -> Result<(), tmc2209_uart::Error<E>>
13where
14    U: embedded_io::Read<Error = E> + embedded_io::Write<Error = E>,
15{
16    let mut driver = Tmc2209::new(uart, 0);
17
18    // Basic setup
19    driver.set_current(16, 8, 4)?;
20    driver.set_microsteps(MicrostepResolution::M256)?;
21
22    // =========================================================================
23    // StealthChop Configuration
24    // =========================================================================
25
26    // Enable StealthChop mode (this is the default)
27    driver.enable_stealthchop()?;
28
29    // Configure StealthChop PWM parameters
30    // - pwm_ofs: Base PWM amplitude (0-255)
31    // - pwm_grad: PWM amplitude gradient (0-255)
32    // - autoscale: Enable automatic current scaling
33    // - autograd: Enable automatic gradient adaptation
34    driver.configure_stealthchop(
35        36,   // pwm_ofs (default)
36        14,   // pwm_grad (default)
37        true, // autoscale enabled (recommended)
38        true, // autograd enabled (recommended)
39    )?;
40
41    // =========================================================================
42    // Velocity-Based Mode Switching
43    // =========================================================================
44
45    // Set StealthChop/SpreadCycle velocity threshold (TPWMTHRS)
46    // Below this TSTEP value, StealthChop is used
47    // Above this velocity (lower TSTEP), SpreadCycle is used
48    driver.set_stealthchop_threshold(500)?;
49
50    // =========================================================================
51    // Chopper Configuration
52    // =========================================================================
53
54    // Fine-tune chopper parameters for your motor
55    driver.configure_chopper(
56        3, // toff
57        4, // hstrt
58        1, // hend
59        2, // tbl
60    )?;
61
62    // =========================================================================
63    // Current Sense Configuration
64    // =========================================================================
65
66    // For high-current motors, use low sensitivity VSENSE
67    driver.set_vsense(false)?;
68
69    // Enable the driver
70    driver.set_enabled(true)?;
71
72    // =========================================================================
73    // Monitor StealthChop Status
74    // =========================================================================
75
76    // Start moving
77    driver.set_velocity(1000)?;
78
79    // Check if StealthChop or SpreadCycle is active
80    let _is_stealth = driver.is_stealthchop_active()?;
81
82    // Check actual current being used
83    let _actual_cs = driver.actual_current_scale()?;
84
85    Ok(())
86}
Source

pub fn set_interpolation(&mut self, enabled: bool) -> Result<(), Error<E>>

Enable interpolation to 256 microsteps.

When enabled, the driver interpolates between microsteps for smoother motion, even at lower microstep settings.

Examples found in repository?
examples/basic.rs (line 42)
20fn basic_motor_control<U, E>(uart: U) -> Result<(), tmc2209_uart::Error<E>>
21where
22    U: embedded_io::Read<Error = E> + embedded_io::Write<Error = E>,
23{
24    // Create driver with slave address 0
25    let mut driver = Tmc2209::new(uart, 0);
26
27    // Check if the driver is responding
28    if !driver.is_connected() {
29        // Handle connection error
30        return Err(tmc2209_uart::Error::NoResponse);
31    }
32
33    // Clear any previous errors
34    driver.clear_gstat()?;
35
36    // Configure motor current
37    // IRUN=20 (run current), IHOLD=10 (hold current), IHOLDDELAY=6
38    driver.set_current(20, 10, 6)?;
39
40    // Set microstep resolution to 16 with interpolation to 256
41    driver.set_microsteps(MicrostepResolution::M16)?;
42    driver.set_interpolation(true)?;
43
44    // Enable StealthChop for quiet operation
45    driver.enable_stealthchop()?;
46
47    // Enable the driver
48    driver.set_enabled(true)?;
49
50    // Start moving the motor forward
51    driver.set_velocity(5000)?;
52
53    // Check status
54    let status = driver.drv_status()?;
55
56    if status.ot() {
57        // Overtemperature shutdown - stop immediately!
58        driver.stop()?;
59        driver.set_enabled(false)?;
60    }
61
62    if status.otpw() {
63        // Overtemperature warning - reduce current or add cooling
64        println!("Warning: Motor temperature is high");
65    }
66
67    // Reverse direction
68    driver.set_velocity(-5000)?;
69
70    // Stop the motor
71    driver.stop()?;
72
73    Ok(())
74}
Source

pub fn actual_current_scale(&mut self) -> Result<u8, Error<E>>

Read the actual motor current scale being used.

This reflects CoolStep adjustments if enabled. Returns a value from 0-31.

Examples found in repository?
examples/stealthchop.rs (line 83)
12fn configure_stealthchop<U, E>(uart: U) -> Result<(), tmc2209_uart::Error<E>>
13where
14    U: embedded_io::Read<Error = E> + embedded_io::Write<Error = E>,
15{
16    let mut driver = Tmc2209::new(uart, 0);
17
18    // Basic setup
19    driver.set_current(16, 8, 4)?;
20    driver.set_microsteps(MicrostepResolution::M256)?;
21
22    // =========================================================================
23    // StealthChop Configuration
24    // =========================================================================
25
26    // Enable StealthChop mode (this is the default)
27    driver.enable_stealthchop()?;
28
29    // Configure StealthChop PWM parameters
30    // - pwm_ofs: Base PWM amplitude (0-255)
31    // - pwm_grad: PWM amplitude gradient (0-255)
32    // - autoscale: Enable automatic current scaling
33    // - autograd: Enable automatic gradient adaptation
34    driver.configure_stealthchop(
35        36,   // pwm_ofs (default)
36        14,   // pwm_grad (default)
37        true, // autoscale enabled (recommended)
38        true, // autograd enabled (recommended)
39    )?;
40
41    // =========================================================================
42    // Velocity-Based Mode Switching
43    // =========================================================================
44
45    // Set StealthChop/SpreadCycle velocity threshold (TPWMTHRS)
46    // Below this TSTEP value, StealthChop is used
47    // Above this velocity (lower TSTEP), SpreadCycle is used
48    driver.set_stealthchop_threshold(500)?;
49
50    // =========================================================================
51    // Chopper Configuration
52    // =========================================================================
53
54    // Fine-tune chopper parameters for your motor
55    driver.configure_chopper(
56        3, // toff
57        4, // hstrt
58        1, // hend
59        2, // tbl
60    )?;
61
62    // =========================================================================
63    // Current Sense Configuration
64    // =========================================================================
65
66    // For high-current motors, use low sensitivity VSENSE
67    driver.set_vsense(false)?;
68
69    // Enable the driver
70    driver.set_enabled(true)?;
71
72    // =========================================================================
73    // Monitor StealthChop Status
74    // =========================================================================
75
76    // Start moving
77    driver.set_velocity(1000)?;
78
79    // Check if StealthChop or SpreadCycle is active
80    let _is_stealth = driver.is_stealthchop_active()?;
81
82    // Check actual current being used
83    let _actual_cs = driver.actual_current_scale()?;
84
85    Ok(())
86}
Source

pub fn is_stealthchop_active(&mut self) -> Result<bool, Error<E>>

Check if the driver is currently in StealthChop mode.

Examples found in repository?
examples/stealthchop.rs (line 80)
12fn configure_stealthchop<U, E>(uart: U) -> Result<(), tmc2209_uart::Error<E>>
13where
14    U: embedded_io::Read<Error = E> + embedded_io::Write<Error = E>,
15{
16    let mut driver = Tmc2209::new(uart, 0);
17
18    // Basic setup
19    driver.set_current(16, 8, 4)?;
20    driver.set_microsteps(MicrostepResolution::M256)?;
21
22    // =========================================================================
23    // StealthChop Configuration
24    // =========================================================================
25
26    // Enable StealthChop mode (this is the default)
27    driver.enable_stealthchop()?;
28
29    // Configure StealthChop PWM parameters
30    // - pwm_ofs: Base PWM amplitude (0-255)
31    // - pwm_grad: PWM amplitude gradient (0-255)
32    // - autoscale: Enable automatic current scaling
33    // - autograd: Enable automatic gradient adaptation
34    driver.configure_stealthchop(
35        36,   // pwm_ofs (default)
36        14,   // pwm_grad (default)
37        true, // autoscale enabled (recommended)
38        true, // autograd enabled (recommended)
39    )?;
40
41    // =========================================================================
42    // Velocity-Based Mode Switching
43    // =========================================================================
44
45    // Set StealthChop/SpreadCycle velocity threshold (TPWMTHRS)
46    // Below this TSTEP value, StealthChop is used
47    // Above this velocity (lower TSTEP), SpreadCycle is used
48    driver.set_stealthchop_threshold(500)?;
49
50    // =========================================================================
51    // Chopper Configuration
52    // =========================================================================
53
54    // Fine-tune chopper parameters for your motor
55    driver.configure_chopper(
56        3, // toff
57        4, // hstrt
58        1, // hend
59        2, // tbl
60    )?;
61
62    // =========================================================================
63    // Current Sense Configuration
64    // =========================================================================
65
66    // For high-current motors, use low sensitivity VSENSE
67    driver.set_vsense(false)?;
68
69    // Enable the driver
70    driver.set_enabled(true)?;
71
72    // =========================================================================
73    // Monitor StealthChop Status
74    // =========================================================================
75
76    // Start moving
77    driver.set_velocity(1000)?;
78
79    // Check if StealthChop or SpreadCycle is active
80    let _is_stealth = driver.is_stealthchop_active()?;
81
82    // Check actual current being used
83    let _actual_cs = driver.actual_current_scale()?;
84
85    Ok(())
86}
Source

pub fn status_summary(&mut self) -> Result<(bool, bool, bool), Error<E>>

Get a comprehensive status summary.

Returns a tuple of (errors_present, warnings_present, is_running).

Source§

impl<U, E> Tmc2209<U>
where U: Read<Error = E> + Write<Error = E>,

Source

pub async fn read_register_async<R: ReadableRegister>( &mut self, ) -> Result<R, Error<E>>

Read a register (async).

Sends a read request and waits for the response.

Source

pub async fn write_register_async<R: WritableRegister>( &mut self, reg: &R, ) -> Result<(), Error<E>>

Write a register (async).

Sends a write request to update a register value.

Source

pub async fn read_raw_async(&mut self, reg_addr: u8) -> Result<u32, Error<E>>

Read a register by raw address (async).

Source

pub async fn write_raw_async( &mut self, reg_addr: u8, data: u32, ) -> Result<(), Error<E>>

Write a register by raw address (async).

Source

pub async fn is_connected_async(&mut self) -> bool

Check if the driver is communicating properly (async).

Source

pub async fn ifcnt_async(&mut self) -> Result<u8, Error<E>>

Get the interface transmission counter (async).

Source

pub async fn drv_status_async(&mut self) -> Result<DrvStatus, Error<E>>

Get the driver status (async).

Source

pub async fn set_current_async( &mut self, run_current: u8, hold_current: u8, hold_delay: u8, ) -> Result<(), Error<E>>

Set the motor currents (async).

Source

pub async fn set_microsteps_async( &mut self, resolution: MicrostepResolution, ) -> Result<(), Error<E>>

Set the microstep resolution (async).

Source

pub async fn set_velocity_async( &mut self, velocity: i32, ) -> Result<(), Error<E>>

Set velocity for internal motion controller (async).

Source

pub async fn stop_async(&mut self) -> Result<(), Error<E>>

Stop the motor (async).

Source

pub async fn enable_coolstep_async( &mut self, semin: u8, semax: u8, ) -> Result<(), Error<E>>

Enable CoolStep adaptive current control (async).

Source

pub async fn disable_coolstep_async(&mut self) -> Result<(), Error<E>>

Disable CoolStep (async).

Source

pub async fn set_coolstep_threshold_async( &mut self, threshold: u32, ) -> Result<(), Error<E>>

Set the CoolStep velocity threshold (async).

Source

pub async fn set_stealthchop_threshold_async( &mut self, threshold: u32, ) -> Result<(), Error<E>>

Set the StealthChop velocity threshold (async).

Source

pub async fn configure_stall_detection_async( &mut self, threshold: u8, ) -> Result<(), Error<E>>

Configure stall detection for sensorless homing (async).

Source

pub async fn is_stalled_async(&mut self) -> Result<bool, Error<E>>

Check if the motor is currently stalled (async).

Source

pub async fn load_indicator_async(&mut self) -> Result<u16, Error<E>>

Get the current load indicator from StallGuard (async).

Source

pub async fn enable_stealthchop_async(&mut self) -> Result<(), Error<E>>

Enable StealthChop mode (async).

Source

pub async fn enable_spreadcycle_async(&mut self) -> Result<(), Error<E>>

Enable SpreadCycle mode (async).

Source

pub async fn set_enabled_async(&mut self, enabled: bool) -> Result<(), Error<E>>

Enable or disable the driver (async).

Source

pub async fn is_standstill_async(&mut self) -> Result<bool, Error<E>>

Check if motor is in standstill (async).

Auto Trait Implementations§

§

impl<U> Freeze for Tmc2209<U>
where U: Freeze,

§

impl<U> RefUnwindSafe for Tmc2209<U>
where U: RefUnwindSafe,

§

impl<U> Send for Tmc2209<U>
where U: Send,

§

impl<U> Sync for Tmc2209<U>
where U: Sync,

§

impl<U> Unpin for Tmc2209<U>
where U: Unpin,

§

impl<U> UnwindSafe for Tmc2209<U>
where U: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.