TMC2209 Arduino Library

repository·main·Indexed 43 days ago

https://github.com/janelia-arduino/tmc2209

An interface for controlling the Trinamic TMC2209 ultra-silent stepper motor driver. It supports high-level motion control via step/direction interfaces and low-level configuration, diagnostics, and velocity control via UART. The library provides features for bidirectional communication, multi-chip addressing, and both Voltage and Current Control modes.

Tokens
5.3K
Snippets
21
Records
29
Agent score
54%

What's inside TMC2209

  1. TMC2209 Communication Interfaces

    main

    The TMC2209 supports two distinct communication interfaces for interacting with a stepper motor controller:

    1. UART Serial Interface: Used for:

      • Tuning and control options.
      • Diagnostics.
      • Simple velocity commands (velocity control mode).
    2. Step and Direction Interface: Used for real-time motion commands, including:

      • Position.
      • Velocity.
      • Acceleration.

    Step and direction signals can be synchronized with signals sent to other stepper drivers to achieve coordinated multi-axis motion.

  2. How Voltage Control vs. Current Control modes work

    main

    The TMC2209 can operate in two modes. The library defaults to Voltage Control Mode for safety to prevent motor overheating during initial setup.

    Voltage Control Mode

    • Activation: Use disableAutomaticCurrentScaling().
    • Behavior: Operates in a feed-forward velocity-controlled mode. It does not react to changes in supply voltage or motor stalls. It provides a stable amplitude but does not regulate actual current.
    • Adjustment: You must manually adjust setPwmOffset(), setPwmGradient(), and setRunCurrent() to reach proper current levels.

    Current Control Mode

    • Activation: Use enableAutomaticCurrentScaling().
    • Behavior: The driver measures actual current through the coils and adjusts the PWM automatically to maintain target levels, even if velocity, supply voltage, or load changes. This requires an automatic tuning (calibration) routine.
    • Adjustment: Setting setRunCurrent() or setHoldCurrent() is sufficient; the driver automatically adjusts the offset and gradient during tuning.
  3. Use TMC2209 Velocity Control Mode

    main

    When using the TMC2209 without a separate stepper motor controller, you can use its simple velocity control mode. In this mode, the motor velocity is set using the moveAtVelocity(int32_t microsteps_per_period) method.

    Important Considerations:

    • No Acceleration Control: The motor may slip when attempting to jump to a new velocity.
    • Crude Position Control: Position can only be estimated by commanding a velocity for a specific duration, which is prone to error due to system delays.
    • Velocity Calculation: The actual velocity depends on the TMC2209 clock frequency ($f_{clk}$).

    Formula: microsteps_per_second = microsteps_per_period * (fclk Hz / 2^24)

    Default (Internal 12 MHz clock): microsteps_per_second = microsteps_per_period * 0.715 Hz

    // Example of setting velocity in simple mode
    // The actual speed depends on the clock frequency (fclk)
    driver.moveAtVelocity(microsteps_per_period);
  4. Configure UART Serial Communication for TMC2209

    main

    The TMC2209 uses a single-wire UART interface. You can use either unidirectional communication (microcontroller TX $\rightarrow$ TMC2209 PDN_UART) for parameter setting only, or bidirectional communication (using both TX and RX pins) for full control and diagnostics.

    Bidirectional Wiring (Coupled)

    To connect a single TMC2209 serial signal to both the microcontroller TX and RX pins, use a 1k resistor between the TX and RX pins to separate them.

    Note: Coupling TX and RX lines causes the microcontroller to receive echoes of its own TX commands. This library automatically handles the removal of these echoes. However, coupling can limit wire length due to the TMC2209's CRC mechanism.

    /* Wiring concept: 
    TX Pin ---[ 1k Resistor ]--- RX Pin
     |
     TMC2209 PDN_UART
    */
  5. Understand the TMC2209 Stepper Motor Driver and Controller Relationship

    main

    The TMC2209 is an ultra-silent motor driver IC for two-phase stepper motors. To operate a stepper motor effectively, you must understand the distinction between a Controller and a Driver:

    • Stepper Motor Controller: Responsible for commanding motor kinetics, torque, or kinematics (position, speed, and acceleration).
    • Stepper Motor Driver: Responsible for commanding the electrical current through the motor coils to meet the requirements of the controller.

    The TMC2209 can be used in two primary ways:

    1. As a standalone driver: It requires an external controller to manage complex motion. It communicates via a UART serial interface and a step and direction interface.
    2. As a combined driver and controller: It can operate independently in a limited velocity control mode. This mode lacks direct position or acceleration control and is best suited for simple applications where small position errors are acceptable.
  6. Upload the firmware

    main

    After compiling, use make or pio to upload the firmware to your hardware. Ensure your board is connected and recognized by the system.

    # Gnu/Linux
    make teensy-upload
    make mega-upload
    make uno-upload
    
    # Other platforms
    pio run -e teensy40 -t upload
    pio run -e mega -t upload
    pio run -e uno -t upload
  7. Configure udev rules for Linux users

    main

    Linux users must install PlatformIO udev rules to allow the system to recognize supported boards and devices. Follow these steps:

    1. Download the udev rules file to /etc/udev/rules.d.
    2. Restart the udev management tool.
    3. Add your user to the dialout and plugdev groups.
    4. Remove modemmanager to prevent interference.
    5. Crucial: Log out and log back in (or reboot) for group changes to take effect. Finally, physically unplug and reconnect your board.
    # 1. Download udev rules
    curl -fsSL https://raw.githubusercontent.com/platformio/platformio-core/develop/platformio/assets/system/99-platformio-udev.rules | sudo tee /etc/udev/rules.d/99-platformio-udev.rules
    
    # 2. Restart udev
    sudo service udev restart
    
    # 3. Add user to groups
    sudo usermod -a -G dialout $USER && sudo usermod -a -G plugdev $USER
    
    # 4. Remove modemmanager
    sudo apt-get purge --auto-remove modemmanager
  8. Setup Hardware Serial for TMC2209

    main

    Hardware serial ports are preferred over software serial ports for better performance and reliability. Use the setup() method of the TMC2209 instance to initialize the connection.

    Standard Hardware Serial

    Pass the hardware serial stream (e.g., Serial1) to setup().

    #include <TMC2209.h>
    
    // Instantiate TMC2209
    TMC2209 stepper_driver;
    HardwareSerial & serial_stream = Serial1;
    
    void setup()
    {
      stepper_driver.setup(serial_stream);
    }
  9. Install PlatformIO Core

    main

    To use this project with PlatformIO, you must first install the PlatformIO Core using a Python virtual environment. This ensures a clean installation and avoids conflicts with other Python packages.

    python3 -m venv .venv
    source .venv/bin/activate
    pip install platformio
    pio --version
  10. Connect Multiple TMC2209 Chips via UART

    main

    You can manage multiple TMC2209 drivers using different addressing and wiring strategies.

    1. Unidirectional: Multiple chips with identical settings

    Connect all chips to the same serial line. No addressing is required; they will all receive the same commands in parallel.

    2. Unidirectional: Multiple chips with different settings (One UART)

    Assign unique serial addresses using the hardware pins MS1 and MS2. You must specify the address during setup().

    3. Bidirectional: Multiple chips with different settings (One UART)

    When using bidirectional communication on a single UART line with multiple addresses, you must increase the reply delay to prevent non-addressed chips from detecting transmission errors during read access.

    Required Method: setReplyDelay(uint8_t delay)

    #include <TMC2209.h>
    
    TMC2209 stepper_driver_0;
    const TMC2209::SerialAddress SERIAL_ADDRESS_0 = TMC2209::SERIAL_ADDRESS_0;
    TMC2209 stepper_driver_1;
    const TMC2209::SerialAddress SERIAL_ADDRESS_1 = TMC2209::SERIAL_ADDRESS_1;
    const uint8_t REPLY_DELAY = 4;
    const long SERIAL_BAUD_RATE = 115200;
    
    void setup()
    {
      stepper_driver_0.setup(Serial1, SERIAL_BAUD_RATE, SERIAL_ADDRESS_0);
      stepper_driver_0.setReplyDelay(REPLY_DELAY);
      
      stepper_driver_1.setup(Serial1, SERIAL_BAUD_RATE, SERIAL_ADDRESS_1);
      stepper_driver_1.setReplyDelay(REPLY_DELAY);
    }
  11. Compile the firmware

    main

    You can compile the firmware using either make (on Gnu/Linux) or the pio CLI (on other platforms). Supported environments include teensy40, mega, and uno.

    # Gnu/Linux
    make teensy-firmware
    make mega-firmware
    make uno-firmware
    
    # Other platforms
    pio run -e teensy40
    pio run -e mega
    pio run -e uno