|
| 1 | + |
| 2 | +# Documentation for Stepper Motor Controller with Rotational Encoder (TMC2209 + AS5600) |
| 3 | + |
| 4 | + |
| 5 | + |
| 6 | + |
| 7 | + |
| 8 | +## **Overview:** |
| 9 | +This motor controller is designed to control a stepper motor using the TMC2209 driver with optional feedback from a rotational encoder (AS5600). The Xiao microcontroller handles communication and control. |
| 10 | + |
| 11 | +## **Components:** |
| 12 | +- **TMC2209 Stepper Driver:** Manages the stepper motor's power and movement. It offers features like StallGuard for homing without limit switches. |
| 13 | +- **AS5600 Encoder:** A magnetic encoder that tracks the stepper motor’s rotational position. Connected via I2C, it provides high-precision feedback for motor positioning. |
| 14 | + |
| 15 | +## **Pin Descriptions:** |
| 16 | +- **DIR (Direction):** Controls the rotational direction of the stepper motor (Clockwise/Counter-Clockwise). Controlled via **PA02_A0_D0**. |
| 17 | +- **STEP (Step Pulse):** Sends pulses to the motor for each step. Controlled via **PA10_A2_D2**. |
| 18 | +- **UART (TX/RX):** The Xiao communicates with the TMC2209 driver for advanced functions such as StallGuard and diagnostics via UART on **PB08_A6_TX** and **PB09_D7_RX**. |
| 19 | +- **I2C (SDA/SCL):** Connects the Xiao to the AS5600 encoder for feedback. I2C pins on the Xiao are **PA8_A4_D4_SDA** and **PA9_A5_D5_SCL**. |
| 20 | + |
| 21 | +## **Power Requirements:** |
| 22 | +- **5V Input:** The Xiao uses its internal buck converter to supply 3.3V to the other components. |
| 23 | +- **12V Input:** Powers the motor and is regulated to 5V and 3.3V via a DC-DC converter for the motor driver and encoder. |
| 24 | + |
| 25 | +## **Features:** |
| 26 | +- **StallGuard Functionality:** This feature detects motor stall conditions and is useful for homing operations without mechanical limit switches. |
| 27 | +- **I2C Encoder (AS5600):** Provides high-precision feedback on motor position, allowing for closed-loop control in certain applications. |
| 28 | + |
| 29 | +## **Wiring:** |
| 30 | +1. **Motor Wiring:** |
| 31 | + - Connect the motor windings to the respective outputs on the TMC2209. |
| 32 | + - Windings A (A+, A-) and B (B+, B-) are connected to **OA1**, **OA2**, **OB1**, **OB2** pins. |
| 33 | + |
| 34 | +2. **Encoder Wiring:** |
| 35 | + - **SDA** (I2C Data) to **PA8_A4_D4_SDA** |
| 36 | + - **SCL** (I2C Clock) to **PA9_A5_D5_SCL** |
| 37 | + |
| 38 | +3. **Power:** |
| 39 | + - 12V Input to **12V Pin** (via JST). |
| 40 | + - GND to common ground. |
| 41 | + |
| 42 | + |
| 43 | + |
| 44 | +## Xiao Pin Connections for Motor Controller with Encoder (TMC2209) |
| 45 | + |
| 46 | +Based on the schematic provided for the stepper motor controller (TMC2209) with Xiao, here are the pin connections between the Xiao board and different elements such as the motor controller and encoder: |
| 47 | + |
| 48 | +## **Pinout for Xiao:** |
| 49 | +- **PA02_A0_D0** (Pin 1): **DIR** (Direction for motor control) |
| 50 | +- **PA4_A1_D1** (Pin 2): **MOT_DIR** (Motor direction) |
| 51 | +- **PA10_A2_D2** (Pin 3): **STEP** (Stepper motor step control) |
| 52 | +- **PA11_A3_D3** (Pin 4): **MOT_STEP** (Step control for motor) |
| 53 | +- **PA8_A4_D4_SDA** (Pin 5): **I2C SDA** |
| 54 | +- **PA9_A5_D5_SCL** (Pin 6): **I2C SCL** |
| 55 | +- **PB08_A6_TX** (Pin 7): **TX UART** (for TMC2209 UART communication) |
| 56 | +- **PB09_D7_RX** (Pin 8): **RX UART** (for TMC2209 UART communication) |
| 57 | +- **PA7_A8_D8_SCK** (Pin 9): **I2C SCL (Alternative)** |
| 58 | + |
| 59 | +## **Connections to Stepper Motor Controller (TMC2209):** |
| 60 | +- **DIR**: Controls the direction of the stepper motor. |
| 61 | +- **STEP**: Steps the motor in the specified direction. |
| 62 | +- **UART_PICO**: UART communication to the TMC2209 (TX from Xiao). |
| 63 | +- **UART_POCI**: UART communication from the TMC2209 (RX to Xiao). |
| 64 | +- **I2C SDA / SCL**: Communication with an external encoder (such as the AS5600 rotational encoder). |
| 65 | + |
| 66 | + |
| 67 | +## Code Example |
| 68 | + |
| 69 | +Here’s a basic ESP32S3 code to control the TMC2209 stepper motor driver and AS5600 encoder (since AS5300 is typically a typo for AS5600, which is more common) in a feedback loop for 360° rotation in both directions. The code sets up the motor driver and encoder, reads the encoder's position, and runs the motor for a full revolution in either direction based on feedback from the encoder. |
| 70 | + |
| 71 | +## Required Libraries: |
| 72 | +- **TMCStepper** for communicating with the TMC2209 driver. |
| 73 | +- **Wire** for I2C communication with the AS5600 encoder. |
| 74 | + |
| 75 | +## Wiring: |
| 76 | +- **EN** -> D10 |
| 77 | +- **DIR** (Direction) -> D8 |
| 78 | +- **STEP** (Step Pulse) -> D9 |
| 79 | +- **I2C SDA** -> PA8_A4_D4_SDA (Pin 5) |
| 80 | +- **I2C SCL** -> PA9_A5_D5_SCL (Pin 6) |
| 81 | +- **UART TX** -> PB08_A6_TX (Pin 7) |
| 82 | +- **UART RX** -> PB09_D7_RX (Pin 8) |
| 83 | + |
| 84 | +## In Action: |
| 85 | + |
| 86 | + |
| 87 | + |
| 88 | + |
| 89 | +## Code: |
| 90 | + |
| 91 | +```cpp |
| 92 | +#include <TMCStepper.h> |
| 93 | +#include <Wire.h> |
| 94 | +#include <FastAccelStepper.h> // Include the FastAccelStepper library |
| 95 | + |
| 96 | +// TMC2209 Settings |
| 97 | +#define STALL_VALUE 100 // StallGuard sensitivity [0..255] |
| 98 | +#define EN_PIN D10 // PA4_A1_D1 (Pin 2) Enable pin for motor driver |
| 99 | +#define DIR_PIN D8 // PA02_A0_D0 (Pin 1) Direction pin |
| 100 | +#define STEP_PIN D9 // PA10_A2_D2 (Pin 3) Step pin |
| 101 | +#define SW_RX D7 // PB09_D7_RX (Pin 8) UART RX pin for TMC2209 |
| 102 | +#define SW_TX A6 // PB08_A6_TX (Pin 7) UART TX pin for TMC2209 |
| 103 | +#define SERIAL_PORT Serial1 // UART Serial port for TMC2209 |
| 104 | +#define DRIVER_ADDRESS 0b00 // TMC2209 driver address |
| 105 | +#define R_SENSE 0.11f // Current sense resistor for TMC2209 |
| 106 | +#define MOT_DIAG D3 |
| 107 | + |
| 108 | +// UC2-ESP I2C Settings |
| 109 | +#define SDA_PIN_UC2 D2 |
| 110 | +#define SCL_PIN_UC2 D1 |
| 111 | +// AS5311 I2C Settings |
| 112 | +#define SDA_PIN D4 // PA8_A4_D4_SDA (Pin 5) I2C SDA |
| 113 | +#define SCL_PIN D5 // PA9_A5_D5_SCL (Pin 6) I2C SCL |
| 114 | +#define AS5311_ADDR 0x36 // I2C address for AS5311 |
| 115 | + |
| 116 | +// Encoder settings |
| 117 | +#define MAX_ENCODER_VALUE 16384 // AS5311 is a 14-bit encoder (2^14 = 16384 steps per revolution) |
| 118 | + |
| 119 | +// FastAccelStepper setup |
| 120 | +FastAccelStepperEngine engine = FastAccelStepperEngine(); // FastAccelStepper engine instance |
| 121 | +FastAccelStepper *stepper = NULL; // FastAccelStepper instance |
| 122 | + |
| 123 | +// TMC2209 instance |
| 124 | +TMC2209Stepper driver(&SERIAL_PORT, R_SENSE, DRIVER_ADDRESS); |
| 125 | + |
| 126 | +// Function to read AS5311 encoder value over I2C |
| 127 | +int readEncoder() { |
| 128 | + Wire.beginTransmission(AS5311_ADDR); |
| 129 | + Wire.write(0x0C); // Register for reading high byte of encoder position |
| 130 | + Wire.endTransmission(); |
| 131 | + Wire.requestFrom(AS5311_ADDR, 2); |
| 132 | + int high_byte = Wire.read(); |
| 133 | + int low_byte = Wire.read(); |
| 134 | + int position = (high_byte << 8) | low_byte; |
| 135 | + return position; |
| 136 | +} |
| 137 | + |
| 138 | +void setup() { |
| 139 | + Serial.begin(115200); // Init serial port and set baudrate |
| 140 | + while(!Serial); // Wait for serial port to connect |
| 141 | + Serial.println("\nStart..."); |
| 142 | + |
| 143 | + // Start Serial communication for TMC2209 |
| 144 | + SERIAL_PORT.begin(115200); |
| 145 | + |
| 146 | + // Pin setup for motor control |
| 147 | + pinMode(EN_PIN, OUTPUT); |
| 148 | + digitalWrite(EN_PIN, LOW); // Enable motor driver (LOW to enable) |
| 149 | + |
| 150 | + // Setup TMC2209 driver |
| 151 | + driver.begin(); // Initiate TMC2209 |
| 152 | + driver.toff(4); // Enable driver with off time |
| 153 | + driver.blank_time(24); // Set blank time |
| 154 | + driver.rms_current(400); // Set motor current to 400mA |
| 155 | + driver.microsteps(16); // Set microstepping to 16 |
| 156 | + driver.TCOOLTHRS(0xFFFFF); // Set threshold for switching to StealthChop |
| 157 | + driver.semin(5); // Enable StallGuard with minimum threshold |
| 158 | + driver.semax(2); // Set maximum StallGuard threshold |
| 159 | + driver.sedn(0b01); // Set StallGuard deceleration |
| 160 | + driver.SGTHRS(STALL_VALUE); // Set StallGuard sensitivity |
| 161 | + |
| 162 | + // Setup I2C for AS5311 encoder |
| 163 | + Wire.begin(SDA_PIN, SCL_PIN); // Initialize I2C with specified pins |
| 164 | + |
| 165 | + // FastAccelStepper setup |
| 166 | + engine.init(); // Initialize the FastAccelStepper engine |
| 167 | + stepper = engine.stepperConnectToPin(STEP_PIN); // Connect stepper to the STEP_PIN |
| 168 | + if (stepper) { |
| 169 | + stepper->setDirectionPin(DIR_PIN); // Set the direction pin |
| 170 | + stepper->setEnablePin(EN_PIN); // Set the enable pin |
| 171 | + stepper->enableOutputs(); // Enable motor outputs |
| 172 | + stepper->setAutoEnable(true); // Automatically enable motor when moving |
| 173 | + stepper->setSpeedInHz(10000); // Set initial speed (steps per second) |
| 174 | + stepper->setAcceleration(10000); // Set acceleration in steps/second^2 |
| 175 | + } |
| 176 | +} |
| 177 | + |
| 178 | +void loop() { |
| 179 | + static uint32_t last_time = 0; |
| 180 | + uint32_t ms = millis(); |
| 181 | + |
| 182 | + // Read encoder position and use it in feedback loop |
| 183 | + int encoderValue = readEncoder(); |
| 184 | + |
| 185 | + // Control motor movement based on encoder feedback |
| 186 | + /* |
| 187 | + if (encoderValue < MAX_ENCODER_VALUE / 2) { |
| 188 | + stepper->moveTo(1000); // Move forward by 1000 steps |
| 189 | + } else if (encoderValue >= MAX_ENCODER_VALUE / 2 && encoderValue < MAX_ENCODER_VALUE) { |
| 190 | + stepper->moveTo(-1000); // Move backward by 1000 steps |
| 191 | + }*/ |
| 192 | + |
| 193 | + // Adjust speed via serial input |
| 194 | + while(Serial.available() > 0) { |
| 195 | + int8_t read_byte = Serial.read(); |
| 196 | + if (read_byte == '0') { |
| 197 | + Serial.println("Stop"); |
| 198 | + stepper->forceStop(); // Stop the motor |
| 199 | + } |
| 200 | + else if (read_byte == '1') { |
| 201 | + Serial.println("Start"); |
| 202 | + stepper->move(10000); // Move forward by 1000 steps |
| 203 | + } |
| 204 | + /* |
| 205 | + else if (read_byte == '+') { |
| 206 | + stepper->setSpeedInHz(stepper->getSpeedInHz() + 100); // Speed up motor |
| 207 | + } |
| 208 | + else if (read_byte == '-') { |
| 209 | + stepper->setSpeedInHz(stepper->getSpeedInHz() - 100); // Slow down motor |
| 210 | + }*/ |
| 211 | + } |
| 212 | + |
| 213 | + // Print StallGuard results and motor current every 100ms |
| 214 | + if ((ms - last_time) > 100) { |
| 215 | + last_time = ms; |
| 216 | + Serial.print("SG Result: "); |
| 217 | + Serial.print(driver.SG_RESULT(), DEC); // Print StallGuard value |
| 218 | + Serial.print(" Current: "); |
| 219 | + Serial.println(driver.cs2rms(driver.cs_actual()), DEC); // Print motor current |
| 220 | + Serial.print("Encoder Value: "); |
| 221 | + Serial.println(encoderValue); |
| 222 | + |
| 223 | + } |
| 224 | +} |
| 225 | +``` |
| 226 | +
|
| 227 | +## Key Components: |
| 228 | +1. **Setup TMC2209**: The motor driver is initialized using UART communication and the current limit is set. StealthChop mode is enabled for quieter operation. |
| 229 | +2. **Encoder Setup (AS5600)**: Uses I2C to read the encoder’s current position. The encoder provides feedback with a 12-bit resolution (4096 steps per revolution). |
| 230 | +3. **MoveStepper Function**: Moves the motor in a given direction (based on step count). The direction and steps are controlled using the DIR and STEP pins. |
| 231 | +4. **Feedback Loop**: The motor moves based on encoder feedback. If the encoder position is less than 180° (half of 4096 steps), the motor moves forward; otherwise, it moves backward to maintain a 360° operation. |
0 commit comments