// Including Required Libraries
#include <AccelStepper.h> // You need to install this library from Library manager. Writer "AccelStepper" in search
#include <Encoder.h> // You need to install this library from Library manager. Writer "Encoder" in search
// Pins for Inputs
const int encoderPinA = 3; // Rotary Encoder Pin A
const int encoderPinB = 4; // Rotary Encoder Pin B
const int potPin = A0; // Potentiometer (Analog Input)
const int estopPin = 2; // Emergency Stop Button
const int limitSwitchPin = 6; // Limit Switch (NPN Proximity)
const int resetPin = 7; // Reset Button
// Create a Rotary Encoder Object
Encoder rotaryEncoder(encoderPinA, encoderPinB);
// Pins for stepper Driver
const int stepPin = 8; // Step pin for stepper driver
const int dirPin = 9; // Direction pin for stepper driver
const int enPin = 10; // Enable pin for stepper driver
// Stepper Motor Object (Using AccelStepper for smoother control)
AccelStepper stepper(AccelStepper::DRIVER, stepPin, dirPin);
// Pins for Outputs
const int relay1Pin = 11; // Relay 1
const int relay2Pin = 12; // Relay 2
bool relayLogic = LOW; // Relay working Logic to operate Relay (Set it as HIGH/LOW based on your relay)
volatile bool emergencyStop = false; // flag to be set on emergency button press
// Constants
const int forwardDistance = 1000; // Pulses to move forward (adjust for your setup)
const int backwardDistance = -1000; // Pulses to move back
// Global Variables
long encoderPosition = 0;
int encoderStep = 20; // Number of encoder pulses to trigger movement
float speedModifier = 1.0;
bool forwardCut = false;
void emergencyBtnPressed() {
emergencyStop = true; // set emergency flag true
}
void setup() {
// Initialize pins
pinMode(estopPin, INPUT_PULLUP);
pinMode(limitSwitchPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(estopPin), emergencyBtnPressed, FALLING);
pinMode(resetPin, INPUT_PULLUP);
pinMode(relay1Pin, OUTPUT);
pinMode(relay2Pin, OUTPUT);
pinMode(enPin, OUTPUT);
// Set up stepper motor parameters
stepper.setMaxSpeed(1000);
stepper.setAcceleration(500);
stopAll(); // Initiall stop everything
// Homing routine on startup
homeStepper();
// Initialize encoder position
encoderPosition = rotaryEncoder.read();
}
void loop() {
// Check for emergency stop
if (emergencyStop) {
// Stop everything and reset homing
stopAll();
// Reset button functionality
while (digitalRead(resetPin) != LOW) {
;
}
homeStepper();
emergencyStop = false; // Reset emergency stop flag
}
if(digitalRead(resetPin) == LOW){
// Check if user has pressed Reset button take stepper back to home
homeStepper();
}
// Read the potentiometer for adjusting the speed modifier
speedModifier = analogRead(potPin) / 1023.0; // Scale from 0 to 1
// Read the rotary encoder position
long newPosition = rotaryEncoder.read();
// Check if the encoder has reached the set threshold for movement
if (abs(newPosition - encoderPosition) >= encoderStep) {
if (forwardCut == false) { // Check if motor has made a backward cut previously then make forward cut now
// Move the stepper motor forward
moveStepper(forwardDistance);
forwardCut = true; // Set the forward cut flag
} else {
// Move the stepper motor back
moveStepper(backwardDistance);
forwardCut = false; // Reset forward cut flag
}
// Update encoder position
encoderPosition = newPosition;
}
}
void turnOnRelay1() {
digitalWrite(relay1Pin, relayLogic); // Turn on relay 1
}
void turnOffRelay1() {
digitalWrite(relay1Pin, !relayLogic); // Turn off relay 1
}
void turnOnRelay2() {
digitalWrite(relay2Pin, relayLogic); // Turn on relay 2
}
void turnOffRelay2() {
digitalWrite(relay2Pin, !relayLogic); // Turn off relay 2
}
// Function to move the stepper motor
void moveStepper(int distance) {
digitalWrite(enPin, LOW); // Enable stepper driver
stepper.setSpeed(1000 * speedModifier);
stepper.move(distance);
while (stepper.distanceToGo() != 0) {
if (emergencyStop) { // if emergency button is pressed get out of loop
return;
}
stepper.run();
}
digitalWrite(enPin, HIGH); // Disable stepper driver
}
// Function to home the stepper motor
void homeStepper() {
// Move the stepper motor backward slowly until the limit switch is triggered
digitalWrite(enPin, LOW); // Enable stepper driver
stepper.setSpeed(-200); // Slow speed for homing
while (digitalRead(limitSwitchPin) != LOW) {
if (emergencyStop) { // if emergency button is pressed get out of loop
return;
}
stepper.runSpeed();
}
// Stop the motor and set position to 0
stepper.setCurrentPosition(0);
digitalWrite(enPin, HIGH); // Disable stepper driver
forwardCut = false; // Reset forward cut flag
}
// Function to stop all actions (emergency stop)
void stopAll() {
stepper.stop();
digitalWrite(enPin, HIGH); // Disable stepper driver
digitalWrite(relay1Pin, !relayLogic); // Turf off relay
digitalWrite(relay2Pin, !relayLogic); // Turn off relay
}