AccelStepper to the desired speed

Hi gurus,
I'm using accelstepper library to control the motor. The requirement is to make the motor to rotate 180 degree back and forth (1 cycle), complete 30 cycles in one minute.
I have written the program as below, however it takes around 1minute 24 secs to complete 30 cycles. Thank you in advance for your input.

#include <AccelStepper.h>

#define stepPin 9
#define dirPin 8
#define En 4

AccelStepper stepper(AccelStepper::DRIVER, stepPin, dirPin);

int stepsPerRevolution = 1600; // steps per revolution
int stepsPerHalfRevolution = stepsPerRevolution / 2; // steps for 180 degrees
const int totalCycles = 30; // total cycles
const int totalTimeSeconds = 60; // total time in seconds
const int timePerCycle = totalTimeSeconds / totalCycles; // time per cycle in seconds
const int timePerHalfMove = timePerCycle / 2; // time for 180-degree move (1 second)
float stepsPerSecond = float(stepsPerHalfRevolution) / timePerHalfMove; // steps per second 
float stepsPerSecond_S = stepsPerSecond * 2;

void setup() {
  pinMode(En, OUTPUT);
  Serial.begin(9600);
  stepper.setMaxSpeed(stepsPerSecond); // Set speed to achieve 180 degrees in 1 second
  stepper.setAcceleration(stepsPerSecond_S); // Set acceleration
}

void loop() {

  if (Serial.available()) {
    String data_from_display = "";
    delay(10);
    while (Serial.available()) {
      data_from_display += char(Serial.read());
    }
    sendData(data_from_display);
  }
}

void Start() {
  Serial.println("START invert");
  for (int x = 0; x < totalCycles; x++) {

    // Move 180 degrees clockwise
    stepper.moveTo(stepper.currentPosition() + stepsPerHalfRevolution);
    while (stepper.distanceToGo() != 0) {
      stepper.run();
    }

    // Move 180 degrees counterclockwise
    stepper.moveTo(stepper.currentPosition() - stepsPerHalfRevolution);
    while (stepper.distanceToGo() != 0) {
      stepper.run();
    }

    if (Serial.available()) {
      String data_from_display = "";
      //delay(30);
      while (Serial.available()) {
        data_from_display += char(Serial.read());
      }
      if (data_from_display == "S")
        stepper.stop();
      break;
    }
  }
  delay(2000);
  digitalWrite(En, LOW);  //disable motor drive to make it free rotate
  Serial.println("DISABLE");
}


void sendData(String data_from_display) {
  if (data_from_display == "START") {
    Start();
  }
  
  if (data_from_display == "disEn") {
    digitalWrite(En, LOW);
    Serial.println("DISABLE");
  }
  if (data_from_display == "En") {
    digitalWrite(En, HIGH);
    Serial.println("EN");
  }
  if (data_from_display == "200") {
    stepsPerRevolution =200;
    Serial.println("200");
  }
  if (data_from_display == "400") {
    stepsPerRevolution =400;
    Serial.println("400");
  }
  if (data_from_display == "800") {
    stepsPerRevolution =800;
    Serial.println("800");
  }
}

so you set the max speed at 800 steps / seconds and the acceleration at 1600.00 steps / seconds / seconds

if your max speed is 800 steps / seconds and you want to perform 800 steps in one second, you would need to instantly accelerate to 800 steps / seconds at the first step ➜ you need an infinite acceleration... You would have to calculate a max speed that is > 800 steps/s and an acceleration/deceleration that is suitable to deliver those 800 steps at the end of the first second. Not easy ➜ accelStepper might not be the best library for your need as it's driven in position rather than pure speed or acceleration.

may be consider constant speed ? or MobaTools or other libraries ?

1 Like

Interpolate ten revolutions.

  If (10_rev_time > 10) increase_speed((10_rev_time - 10) / 2);
  If (10_rev_time < 10) decrease_speed((10 - 10_rev_time) / 2);

Yes and I think this will work.
You can drive stepper-motors with a constant speed as long as the speed is not too high.
This is called start-stop-speed.
Within the limits of start-stop-speed you can rotate as many or as less steps CW or CCW as you like. The stepper-motor is able start and stop at this speed without acceleration.

So 180 degrees clockwise and back counter-clockwise is 1600 steps.

I assume it is a standard stepper-motor which has 200 fullsteps per rotation.
Which means stepper-motor-driver is configured to 1/8 microstepping.
With microstepping the speed will be more or less the same as in fullsteps.

In fullsteps it is 200 steps per cycle.
Each cycle takes 2 seconds 60 second per minute / 30 cycles per minute = 2 seconds per rotation.

So the stepper-motor is rotating at 0.5 rotations per minute.
Should be very doable with constant speed.

Should be doable with acceleration too
but you will have to set the maximum-speed higher than 800 steps/second as a part of the way is done at less than 800 steps per second.