Go Down

Topic: Ramping stepper by manual code or library (Read 174 times) previous topic - next topic

jingleby

I am trying to ramp up a stepper to 4000 pulses per second (10 RPS), maintain that speed as long as desired, then accel/decel to a new determined speed.

I have tried AccelStepper, but believe it is intended to reach a position and not a constant speed. I have also tried manually ramping the speed (see bottom of code), but not really sure the appropriate method.

With AccelStepper code, the motor constantly spins (slowly) but doesn't ramp up to goal. Is there a way to constantly offset it's "moveTo" & setSpeed so that it abides by its Acceleration Rate, but changes to a new speed? I have attempted this below.

With my manual code approach, the motor ramps up and achieves what appears to be a decently fast speed but I'm not sure how fast it is running at and am not sure how I would ramp to a new speed after X time.

I don't have a lot of experience coding so am open to any suggestions & help.
Thanks



Code: [Select]
/*
 * Notes re RPS Speed.
 * 10 RPS * 400 Steps/rev = 4000 pulses for 10 RPS
 */

#include <AccelStepper.h>
#define directionPin 3
#define stepPin 2
#define MS1 4
#define MS2 5
#define MS3 6
#define EN  7

unsigned long curMicros;
unsigned long prevMicros = 0;
unsigned long minPulseSpeed = 500; //shortest micros duration to send a pulse
int currSpeed = 400; //current speed in pulses per second
int goalSpeed = 4000; //goal 10 RPS
unsigned long targetPos = 100000; //perpetually increased position to always move

//OTHER Variables for ALT Loop at end without Library
int goalRPS = 10; //IE 10 RPS = 250 microseconds per pulse
int stepsPerRev = 400;
int targetMicros = (1000000/(goalRPS*stepsPerRev));// how long for each revolution based on desiredRPS
unsigned long prevStepMicros = 0;
unsigned long microsBetweenSteps = 10000; //  1000 micros in milli

AccelStepper stepper; // Defaults to AccelStepper::FULL4WIRE

void setup()

  pinMode(MS1, OUTPUT);
  pinMode(MS2, OUTPUT);
  pinMode(MS3, OUTPUT);
  pinMode(EN, OUTPUT);
  digitalWrite(MS1, LOW); //Micro. 000 = full 100 = 1/2, 010 = 1/4, 110 = 1/8
  digitalWrite(MS2, LOW);
  digitalWrite(MS3, LOW);
  digitalWrite(directionPin, LOW);
 
  stepper.setMaxSpeed(5000); //slightly lower than goalSpeed
  stepper.setSpeed(0);
  stepper.setAcceleration(500);
  stepper.moveTo(targetPos);
  delay(1000);
}

void loop()
{
 curMicros = micros();
 singleStep();
// singleStepALT(); //Ramp attempt without Library.
}

void singleStep() {
  if (currSpeed <= goalSpeed) {
    if (curMicros - prevMicros >= minPulseSpeed) {
      curMicros = prevMicros;
      currSpeed *= 1.1; //increase speed slightly
      stepper.setSpeed(currSpeed); //update motor speed
    }
  }
  else if (currSpeed >= goalSpeed){
    stepper.move(targetPos + 1000);
    stepper.setSpeed(goalSpeed);
  }
  stepper.run();
}

//RAMP ATTEMPT WITHOUT LIBRARY. Works but not sure Pulse speed
//void singleStepALT() {
// if (curMicros - prevStepMicros >= microsBetweenSteps) {
//  prevStepMicros += microsBetweenSteps;
//  if (microsBetweenSteps > targetMicros) {
//    microsBetweenSteps *= .999;
//  }
//    digitalWrite(stepPin, HIGH);
//    digitalWrite(stepPin, LOW);
// }
//}

Robin2

I posted a short program here that illustrates a simple method of acceleration.

The speed of a stepper motor is determined by the interval between steps so should always be easy to determine.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

MarkT

#2
Nov 13, 2018, 02:12 pm Last Edit: Nov 13, 2018, 02:13 pm by MarkT
I am trying to ramp up a stepper to 4000 pulses per second (10 RPS), maintain that speed as long as desired, then accel/decel to a new determined speed.

I have tried AccelStepper, but believe it is intended to reach a position and not a constant speed. I have also tried manually ramping the speed (see bottom of code), but not really sure the appropriate method.

With AccelStepper code, the motor constantly spins (slowly) but doesn't ramp up to goal. Is there a way to constantly offset it's "moveTo" & setSpeed so that it abides by its Acceleration Rate, but changes to a new speed? I have attempted this below.
You just have to use the run() method and keep updating the target position so it doesn't stop
(setting the target to a very large number is probably good enough).

Code: [Select]

  stepper.setSpeed (whatever) ;
  stepper.moveTo (1000000000L) ;
[ I will NOT respond to personal messages, I WILL delete them, use the forum please ]

jingleby

I posted a short program here that illustrates a simple method of acceleration.
Wow, thanks @robin2! I've spent hours reading posts and hadn't come across this. Very helpful.
It should be pinned to the top of the motors category.

Thanks MarkT, I thought it was more complicated than this. I'll have to test this later, but does simply changing "setSpeed" every 20 seconds automatically accel/decel to the desired speed and keep going? Or does the moveTo need to be updated as well?

MarkT

You've got the library, why not look at the code like I do?
[ I will NOT respond to personal messages, I WILL delete them, use the forum please ]

Go Up