// Stepper Motor Control with TB6600 Driver & Arduino Mega 2560
// Moves gantry in two dimensions based on user input (position in mm).
// Pin Definitions
const int X_STEP_PIN = 5; // Step pin for X-axis stepper driver
const int X_DIR_PIN = 2; // Direction pin for X-axis stepper driver
const int X_EN_PIN = 8; // Enable pin for X-axis stepper driver
const int Y_STEP_PIN = 6; // Step pin for Y-axis stepper driver
const int Y_DIR_PIN = 3; // Direction pin for Y-axis stepper driver
const int Y_EN_PIN = 9; // Enable pin for Y-axis stepper driver
// Stepper Motor & Belt System Parameters
const int MOTOR_STEPS_PER_REV = 200; // Motor full steps per revolution
const int MICROSTEP_SETTING = 16; // Microstepping level (1, 2, 4, 8, 16, etc.)
const float BELT_PITCH = 2.0; // Belt pitch in mm (distance between two teeth)
const int PULLEY_TEETH = 20; // Pulley teeth count
// Derived Parameters
const float DIST_PER_REV = BELT_PITCH * PULLEY_TEETH; // Linear distance per full motor revolution
const int STEPS_PER_REV = MOTOR_STEPS_PER_REV * MICROSTEP_SETTING; // Steps per revolution
const float STEPS_PER_MM = STEPS_PER_REV / DIST_PER_REV; // Steps needed to move 1 mm
// Position Tracking
float currentX = 0.0; // Track current X position in mm
float currentY = 0.0; // Track current Y position in mm
// System Boundaries
const float MIN_X = 0.0, MAX_X = 200.0; // X-axis limits in mm
const float MIN_Y = 0.0, MAX_Y = 200.0; // Y-axis limits in mm
// Function Prototypes
void moveToPosition(float targetX, float targetY); // Move to target position
void moveAxis(int stepPin, int dirPin, float currentPos, float targetPos, const char* axisName); // Move axis function
void printMotorInfo(); // Print motor details
void enableMotors(); // Enable both motors
void disableMotors(); // Disable both motors
void setup() {
Serial.begin(115200); // Initialize Serial communication for debugging
// Set pin modes for both stepper motors
pinMode(X_STEP_PIN, OUTPUT);
pinMode(X_DIR_PIN, OUTPUT);
pinMode(X_EN_PIN, OUTPUT);
pinMode(Y_STEP_PIN, OUTPUT);
pinMode(Y_DIR_PIN, OUTPUT);
pinMode(Y_EN_PIN, OUTPUT);
enableMotors(); // Ensure motors are enabled at startup
Serial.println("Stepper Motors Initialized"); // Debug message
printMotorInfo(); // Print motor configuration details
}
void loop() {
// Check for user input
if (Serial.available()) {
String input = Serial.readStringUntil('\n'); // Read input line
input.trim(); // Remove any extra spaces or newlines
// Split the input into X and Y components
int commaIndex = input.indexOf(',');
if (commaIndex == -1) {
Serial.println("Invalid input! Format must be: X,Y");
return;
}
float targetX = input.substring(0, commaIndex).toFloat(); // Extract X coordinate
float targetY = input.substring(commaIndex + 1).toFloat(); // Extract Y coordinate
// Validate input
if (!isnan(targetX) && !isnan(targetY)) {
moveToPosition(targetX, targetY);
delay(2000);
} else {
Serial.println("Invalid input! Please enter valid numbers.");
}
}
}
// Function to move the stepper motor to a given position in mm
void moveToPosition(float targetPosition) {
// Check boundaries for X
if (targetX < MIN_X || targetX > MAX_X) {
Serial.println("Error: X position out of bounds!");
return;
}
if (targetY < MIN_Y || targetY > MAX_Y) {
Serial.println("Error: Y position out of bounds!");
return;
}
// Move in the X direction first
moveAxis(X_STEP_PIN, X_DIR_PIN, currentX, targetX, "X");
currentX = targetX; // Update current X position
// Then move in the Y direction
moveAxis(Y_STEP_PIN, Y_DIR_PIN, currentY, targetY, "Y");
currentY = targetY; // Update current Y position
Serial.print("Moved to position: (");
Serial.print(currentX);
Serial.print(", ");
Serial.print(currentY);
Serial.println(")");
}
// Function to move an axis to a target position
void moveAxis(int stepPin, int dirPin, float currentPos, float targetPos, const char* axisName) {
long targetSteps = targetPos * STEPS_PER_MM; // Convert target position to steps
long currentSteps = currentPos * STEPS_PER_MM; // Convert current position to steps
long stepsToMove = targetSteps - currentSteps; // Compute step difference
if (stepsToMove == 0) return; // If already at target position, do nothing
digitalWrite(dirPin, stepsToMove > 0 ? HIGH : LOW); // Set direction
Serial.print("Moving ");
Serial.print(axisName);
Serial.print(" axis to: ");
Serial.println(targetPos); // Debug message
for (long i = 0; i < abs(stepsToMove); i++) {
digitalWrite(stepPin, HIGH); // Pulse step pin HIGH
delayMicroseconds(800); // Short delay for motor driver
digitalWrite(stepPin, LOW); // Pulse step pin LOW
delayMicroseconds(800); // Short delay for motor driver
}
}
// Function to enable both motors
void enableMotors() {
digitalWrite(X_EN_PIN, LOW); // Activate motor drivers (LOW enables TB6600)
digitalWrite(Y_EN_PIN, LOW);
Serial.println("Motor Enabled"); // Debug message
}
void disableMotors() {
digitalWrite(X_EN_PIN, HIGH); // Disable motor driver
digitalWrite(Y_EN_PIN, HIGH);
Serial.println("Motor Disabled"); // Debug message
}
void printMotorInfo() {
Serial.println("Motor Configuration:");
Serial.print("Steps per Revolution: ");
Serial.println(STEPS_PER_REV); // Print total steps per revolution
Serial.print("Microstepping Setting: ");
Serial.println(MICROSTEP_SETTING); // Print microstepping value
Serial.print("Distance per Revolution (mm): ");
Serial.println(DIST_PER_REV); // Print mm per revolution
Serial.print("Steps per mm: ");
Serial.println(STEPS_PER_MM); // Print steps required for 1 mm movement
}