13426e04c9
Skipped organizing and uploading v2 of the design since it was lacklusting, feel like the v3 is closer to what i will leave the project as.
215 lines
5.8 KiB
Arduino
215 lines
5.8 KiB
Arduino
#include <AccelStepper.h>
|
|
|
|
// === Pin Definitions ===
|
|
#define M1_STEP_PIN 0 // Reel motor step
|
|
#define M1_DIR_PIN 1 // Reel motor direction
|
|
|
|
#define M2_STEP_PIN 2 // Carriage motor step
|
|
#define M2_DIR_PIN 3 // Carriage motor direction
|
|
|
|
#define HOME_SW_PIN 6 // Home limit switch
|
|
#define END_SW_PIN 5 // End limit switch
|
|
|
|
AccelStepper reelMotor(AccelStepper::DRIVER, M1_STEP_PIN, M1_DIR_PIN);
|
|
AccelStepper carriageMotor(AccelStepper::DRIVER, M2_STEP_PIN, M2_DIR_PIN);
|
|
|
|
float RAIL_LENGTH = 50; // 100mm linear rail
|
|
float CENTER_POSITION = RAIL_LENGTH / 2.0f; // Center position
|
|
|
|
// === Motor Configuration ===
|
|
const int MOTOR_STEPS = 200; // 200 steps/rev for NEMA 17
|
|
const int MICROSTEPPING = 8; // Set on driver board (MS1/MS2 jumpers)
|
|
const float SCREW_LEAD = 4.0; // mm per revolution (T8 screw)
|
|
const float CALIBRATION_FACTOR = 2.0;
|
|
const float STEPS_PER_MM = ((MOTOR_STEPS * MICROSTEPPING) / (SCREW_LEAD / CALIBRATION_FACTOR));
|
|
|
|
// === Speed Settings ===
|
|
const float REEL_RPM = 150; // Reel motor speed
|
|
const float CARRIAGE_RPM = 100; // Carriage motor speed
|
|
|
|
// State management
|
|
enum State {
|
|
IDLE,
|
|
HOMING,
|
|
FIND_END,
|
|
RUNNING
|
|
};
|
|
State currentState = HOMING;
|
|
|
|
// Manual distance tracking
|
|
long targetSteps = 0;
|
|
long stepsMoved = 0;
|
|
// Position tracking
|
|
float currentPositionMM = 0; // Tracks actual position in mm
|
|
|
|
float desiredPosition = 25;
|
|
bool bounceBool = false;
|
|
|
|
void setup() {
|
|
Serial.begin(115200);
|
|
|
|
// Configure limit switches
|
|
pinMode(HOME_SW_PIN, INPUT_PULLUP);
|
|
pinMode(END_SW_PIN, INPUT_PULLUP);
|
|
|
|
Serial.begin(115200);
|
|
Serial.println("Starting motors...");
|
|
|
|
// Configure reel motor (constant speed)
|
|
reelMotor.setMaxSpeed((REEL_RPM * MOTOR_STEPS * MICROSTEPPING) / 60.0);
|
|
reelMotor.setSpeed(-reelMotor.maxSpeed()); // Negative for reverse
|
|
reelMotor.setMinPulseWidth(50); // 50µs pulse width
|
|
|
|
// Configure carriage motor (constant speed)
|
|
carriageMotor.setMaxSpeed((CARRIAGE_RPM * MOTOR_STEPS * MICROSTEPPING) / 60.0);
|
|
carriageMotor.setSpeed(carriageMotor.maxSpeed()); // Positive direction
|
|
carriageMotor.setMinPulseWidth(50); // 50µs pulse width
|
|
}
|
|
|
|
void loop() {
|
|
// State machine for carriage
|
|
switch(currentState) {
|
|
case HOMING:
|
|
runHoming();
|
|
break;
|
|
|
|
case FIND_END:
|
|
runFindEnd();
|
|
break;
|
|
|
|
case RUNNING:
|
|
//reelMotor.runSpeed();
|
|
if(bounceBool == false){
|
|
if(runMoveToPosition(desiredPosition - 0 )){
|
|
bounceBool = true;
|
|
}
|
|
}
|
|
else {
|
|
if(runMoveToPosition(desiredPosition - 20.0)){
|
|
bounceBool = false;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
void runHoming(){
|
|
// Move carriage in positive direction
|
|
if (carriageMotor.runSpeed()) {
|
|
stepsMoved++;
|
|
}
|
|
|
|
if (digitalRead(HOME_SW_PIN) == LOW) { // Switch pressed (LOW with pullup)
|
|
carriageMotor.stop(); // Stop motor
|
|
carriageMotor.setSpeed(0); // Set speed to zero
|
|
|
|
stepsMoved = 0;
|
|
// Reset position tracking
|
|
currentPositionMM = 0;
|
|
carriageMotor.setCurrentPosition(0);
|
|
|
|
// Calculate steps needed to reach center
|
|
targetSteps = CENTER_POSITION * STEPS_PER_MM;
|
|
|
|
carriageMotor.setSpeed(-carriageMotor.maxSpeed()); // Positive direction
|
|
|
|
currentState = FIND_END;
|
|
}
|
|
}
|
|
|
|
void runFindEnd() {
|
|
// Run carriage at constant speed
|
|
if (carriageMotor.runSpeed()) {
|
|
stepsMoved++;
|
|
// Update position based on direction
|
|
currentPositionMM += (carriageMotor.speed() > 0) ?
|
|
(1.0 / STEPS_PER_MM) :
|
|
(-1.0 / STEPS_PER_MM);
|
|
|
|
// Print position every 100ms
|
|
// static unsigned long lastPrint = 0;
|
|
// if (millis() - lastPrint > 100) {
|
|
// lastPrint = millis();
|
|
// Serial.print("Position: ");
|
|
// Serial.print(currentPositionMM);
|
|
// Serial.println(" mm");
|
|
// }
|
|
}
|
|
|
|
if (digitalRead(END_SW_PIN) == LOW) { // Switch pressed (LOW with pullup)
|
|
currentState = RUNNING;
|
|
|
|
// Stop carriage motor completely
|
|
carriageMotor.stop();
|
|
carriageMotor.setSpeed(0);
|
|
|
|
// Print final position
|
|
Serial.print("Final position: ");
|
|
Serial.print(currentPositionMM);
|
|
|
|
RAIL_LENGTH = abs(currentPositionMM);
|
|
CENTER_POSITION = RAIL_LENGTH / 2.0f;
|
|
}
|
|
}
|
|
|
|
bool runMoveToPosition(float position){
|
|
|
|
float distance = abs(abs(currentPositionMM) - position);
|
|
float margin = 0.1f;
|
|
|
|
// Print position every 100ms
|
|
// static unsigned long lastPrint = 0;
|
|
// if (millis() - lastPrint > 100) {
|
|
// lastPrint = millis();
|
|
// Serial.print("Position: ");
|
|
// Serial.print(abs(currentPositionMM));
|
|
// Serial.println(" mm");
|
|
// Serial.print("Desired Position: ");
|
|
// Serial.print(position);
|
|
// Serial.println(" mm");
|
|
// Serial.println(distance);
|
|
// }
|
|
|
|
// Calculate direction
|
|
if(distance > margin){
|
|
int direction = sign(position - abs(currentPositionMM));
|
|
|
|
int previousDirection = (carriageMotor.speed() / -1.0f) / carriageMotor.maxSpeed();
|
|
if(previousDirection != direction){
|
|
carriageMotor.setSpeed(carriageMotor.maxSpeed() * direction * -1.0f);
|
|
}
|
|
}
|
|
|
|
// Run carriage at constant speed
|
|
if (carriageMotor.runSpeed()) {
|
|
stepsMoved++;
|
|
// Update position based on direction
|
|
currentPositionMM += (carriageMotor.speed() > 0) ?
|
|
(1.0 / STEPS_PER_MM) :
|
|
(-1.0 / STEPS_PER_MM);
|
|
|
|
if (distance <= margin) {
|
|
// Stop carriage motor completely
|
|
carriageMotor.setSpeed(0);
|
|
carriageMotor.stop();
|
|
return true;
|
|
}
|
|
}
|
|
|
|
if (distance <= margin) {
|
|
// Stop carriage motor completely
|
|
carriageMotor.setSpeed(0);
|
|
carriageMotor.stop();
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool withinRange(float value, float target, float margin) {
|
|
return (value >= (target - margin)) && (value <= (target + margin));
|
|
}
|
|
|
|
float sign(float value) {
|
|
return float((value>0)-(value<0));
|
|
} |