#include <AccelStepper.h>
#include <PinChangeInterrupt.h>
// Define pins and mottor type.
#define dirPin 5
#define stepPin 6
#define motorInterfaceType 1
#define buttonPin 4 // Define the pin connected to the button
#define encoderClkPin 2
#define encoderDTPin 3
// Variables to manage the stepper and the encoder state:
volatile bool motorEnabled = false; // Motor state flag
volatile unsigned long buttonLastDebounceTime = 0;
unsigned long buttonDebounceDelay = 50;
volatile unsigned long encoderLastDebounceTime = 0;
unsigned long encoderDebounceDelay = 50;
volatile long encoderCount = 0;
long prevEncoderCount = 0;
// Variables for direction of rotation for manual adjustments
int DIRECTION_CW = 1;
int DIRECTION_CCW = -1;
volatile int direction = DIRECTION_CW;
// Create a new instance of the AccelStepper class:
AccelStepper stepper = AccelStepper(motorInterfaceType, stepPin, dirPin);
void setup() {
stepper.setMaxSpeed(1000);
pinMode(buttonPin, INPUT_PULLUP);
attachPinChangeInterrupt(digitalPinToPinChangeInterrupt(buttonPin), toggleMotor, FALLING);
pinMode(encoderClkPin, INPUT_PULLUP);
pinMode(encoderDTPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(encoderClkPin), readEncoder, RISING);
}
void toggleMotor() {
if ((millis() - buttonLastDebounceTime) < buttonDebounceDelay) {
return;
}
motorEnabled = !motorEnabled;
}
void readEncoder() {
if ((millis() - encoderLastDebounceTime) < encoderDebounceDelay) {
return;
}
if (digitalRead(encoderDTPin) == HIGH) {
encoderCount--;
direction = DIRECTION_CCW;
} else {
encoderCount++;
direction = DIRECTION_CW;
}
encoderLastDebounceTime = millis();
}
void loop() {
if (motorEnabled) {
// Do the automatic rotation step
stepper.setSpeed(100);
stepper.runSpeed();
} else {
// Do the manual rotation step only if encoder was touched
if (prevEncoderCount == encoderCount ) {
return;
}
stepper.setSpeed(direction * 100);
stepper.runSpeed();
prevEncoderCount = encoderCount;
}
}