#include <Arduino.h>
#include <AccelStepper.h>
#include <EasyButton.h>
// define the pins
#define EN_PIN 7 //enable
#define STEP_PIN 8 //step
#define DIR_PIN 9 //direction
#define BTN_PIN 2 //button
#define RESET_PIN 3 //reset
#define LED_PIN 4 //led
#define SPEED_SETTING_PIN A0
#define ACCELERATION_SETTING_PIN A1
#define CALIBRATE_SPEED 1 * 20
#define MAX_SPEED 100 * 20
#define MIN_SPEED 1 * 20
#define ACCELERATION 2 * 20
#define DISTANCE_MM 100
constexpr uint32_t steps_per_mm = 20;
AccelStepper stepper(AccelStepper::DRIVER, STEP_PIN, DIR_PIN); // (Type of driver: with 2 pins, STEP, DIR)
EasyButton motorButton(BTN_PIN);
bool isOpen = false;
int distance = DISTANCE_MM * steps_per_mm;
bool isStepperRunning = false;
inline void setIsStepperRunning(bool isRunning) {
if (isStepperRunning == isRunning) return;
isStepperRunning = isRunning;
if (isStepperRunning) {
digitalWrite(LED_PIN, HIGH);
} else {
digitalWrite(LED_PIN, LOW);
}
}
void updateMaxSpeed()
{
int val = analogRead(SPEED_SETTING_PIN); // reads the value of the potentiometer (value between 0 and 1023)
val = pow(map(val, 0, 1023, 0, 50), 2) + MIN_SPEED;
stepper.setMaxSpeed(val);
}
void updateAcceleration()
{
int val = analogRead(ACCELERATION_SETTING_PIN); // reads the value of the potentiometer (value between 0 and 1023)
val = map(val, 0, 1023, 10, 500);
stepper.setAcceleration(val);
}
void open()
{
updateMaxSpeed();
updateAcceleration();
stepper.moveTo(distance);
isOpen = true;
}
void close()
{
updateMaxSpeed();
updateAcceleration();
stepper.moveTo(0);
isOpen = false;
}
void calibrate()
{
if (stepper.isRunning()) return;
stepper.setMaxSpeed(CALIBRATE_SPEED);
stepper.move(-distance);
}
void triggerMoveMotor()
{
if (stepper.isRunning()) return;
if (isOpen) {
close();
} else {
open();
}
}
void triggerPositionReset()
{
if (!stepper.isRunning()) return;
if (stepper.speed() > 0.0) return;
stepper.stop();
stepper.setCurrentPosition(0);
}
void buttonISR()
{
motorButton.read();
}
void setup()
{
pinMode(LED_PIN, OUTPUT);
pinMode(SPEED_SETTING_PIN, INPUT);
pinMode(ACCELERATION_SETTING_PIN, INPUT);
stepper.setMaxSpeed(CALIBRATE_SPEED); // 100mm/s @ 80 steps/mm
stepper.setAcceleration(ACCELERATION); // 200mm/s^2
stepper.setEnablePin(EN_PIN);
stepper.setPinsInverted(false, false, true);
stepper.enableOutputs();
attachInterrupt(digitalPinToInterrupt(RESET_PIN), triggerPositionReset, RISING);
motorButton.onSequence(4, 1000, calibrate);
motorButton.onPressedFor(3000, triggerMoveMotor);
if (motorButton.supportsInterrupt())
{
motorButton.enableInterrupt(buttonISR);
}
}
void loop()
{
setIsStepperRunning(stepper.run());
motorButton.update();
}