Question about displaying speed using Accelstepper library

Hi,

General description

My project involves driving a stepper motor together with a driver DRV8825. And this is the code I use to accomplish the task.

//lib
#include<Wire.h>
#include <AccelStepper.h>

//interfacing and pins
#define dirPin 3
#define stepPin 4
#define motorInterfaceType 1
AccelStepper stepper = AccelStepper(motorInterfaceType, stepPin, dirPin);

//parameters
int dataTransfer;
int index = 0;
double previousAccel = 0;
double time;
int interval = 100; 
const int stepsPerRev = 200;
int maxSpeed = 8000;

//setup
void setup() {
  Wire.begin(); 
  stepper.setMaxSpeed(3333333);
  stepper.setSpeed(800); //initial speed in sps
}

//main
void loop() {
    while (stepper.speed() < maxSpeed) {
    time = millis();
    if (time > previousAccel + interval) {
      previousAccel = time;
      stepper.setSpeed(stepper.speed() + 4);
      //dataTransfer = stepper.speed();
      //Wire.beginTransmission(9);
      //Wire.write(dataTransfer);   
      //Wire.endTransmission(); 
      stepper.runSpeed();
    }
    stepper.runSpeed();
  }
  stepper.setSpeed(maxSpeed);
  stepper.runSpeed();
}

I found this code on this forum a long time ago and I just copied and pasted into my project. This script gradually accelerates the motor from an initial speed to a desired steps per second(SPS). Once the desired SPS is achieved, it stays at that speed and keep running.

Question

As you may notice, I commented out four lines above which basically transfers the current speed to another Arduino which is wired to a LCD to display speed. The code works perfectly with these three lines commented out. If I uncomment those lines, the motor doesn't even move at all.

I firstly tried to just use one Arduino to both control the motor and display current speed using LCD, but the motor doesn't even speed up at all. I tried to use Serial monitor to display the speed as well, but the motor doesn't accelerate as well. I wonder I might just put too much workload on one Arduino, so I ended up using two. However, it still doesn't work.

Could anyone please help me out? Many thanks in advance!

You are trying to ramp up to 3333333 steps per second? that would be a single step ever .3 usec which ain't gonna happen on an Uno, let alone leave time to do other things.

no... code does

int maxSpeed = 8000;
...
while (stepper.speed() < maxSpeed)

AccelStepper has a setAcceleration() method

have you tried it?

thanks for explaining that line of code for me!

No, I haven't. Let me try it right now and will get back to you. Many thanks!

try this

#include <AccelStepper.h>
const byte dirPin = 3;
const byte stepPin =  4;
AccelStepper stepper = AccelStepper(AccelStepper::DRIVER, stepPin, dirPin);

const float endSpeed = 8000; // the maximum speed achievable depends on your processor and clock speed

void setup() {
  stepper.setMaxSpeed(endSpeed);
  stepper.setAcceleration(40); // 40 steps per second per second
}
void loop() {
  stepper.run();
}

Dear Jackson,
I copied your code, but the motor doesn't run. Then, I changed the command in the loop from stepper.run() to stepper.runSpeed(). The motor starts to move but it doesn't accelerate at all. I changed the acceleration rate to some crazy number like 4000, and it doesn't seem to work as well

runSpeed does not implement acceleration

Oops, I forgot to give a destination ! so the motor thinks it has arrived :slight_smile:

#include <AccelStepper.h>
const byte dirPin = 3;
const byte stepPin =  4;
AccelStepper stepper = AccelStepper(AccelStepper::DRIVER, stepPin, dirPin);

const float endSpeed = 8000; // the maximum speed achievable depends on your processor and clock speed

void setup() {
  stepper.setMaxSpeed(endSpeed);
  stepper.setAcceleration(40); // 40 steps per second per second
  stepper.moveTo(2147483647); // a lot of steps ! 
}
void loop() {
  stepper.run();
}

if should do lot of steps, you could check in the loop if distanceToGo() is 0 and then give a new stepper.moveTo() (if you keep it running for more than ~74h)

I see! Many thanks!

Yeah, the acceleration works now! I just have a quick question: do you know how to read the current motor speed and display it to somewhere (LCD or Serial monitor)?

I added two lines on top of your code to display the current speed to the serial monitor. However, it seems like the motor moves super slow (generate a different sound frequency)

#include <AccelStepper.h>
const byte dirPin = 3;
const byte stepPin =  4;
AccelStepper stepper = AccelStepper(AccelStepper::DRIVER, stepPin, dirPin);

const float endSpeed = 8000; // the maximum speed achievable depends on your processor and clock speed

void setup() {
  Serial.begin(9600);
  stepper.setMaxSpeed(endSpeed);
  stepper.setAcceleration(40); // 40 steps per second per second
  stepper.moveTo(2147483647); // a lot of steps ! 
}
void loop() {
  stepper.run();
  Serial.println(stepper.speed());
}

Do you know how to overcome this?

try with

Serial.begin(2000000); // open the Serial monitor at 2 million bauds

print is probably blocking and can't go as fast as the loop needs to run

may be you should read the speed only every 5 seconds and print it (and keep a fast Serial baud rate, at least 115200)

#include <AccelStepper.h>
const byte dirPin = 3;
const byte stepPin =  4;
AccelStepper stepper = AccelStepper(AccelStepper::DRIVER, stepPin, dirPin);

const float endSpeed = 8000; // the maximum speed achievable depends on your processor and clock speed

void setup() {
  Serial.begin(115200);
  stepper.setMaxSpeed(endSpeed);
  stepper.setAcceleration(40); // 40 steps per second per second
  stepper.moveTo(2147483647); // a lot of steps ! 
}
void loop() {
  static unsigned long lastTime;
  stepper.run();
  if (millis() - lastTime >= 5000) {
    Serial.println(stepper.speed());
    lastTime = millis();
  }
}

that is also my original question. I really have a hard time displaying the current speed.

My current task is to gradually accelerate the stepper to some desired speed. During this process, the current speed needs to be displayed on a LCD. I have tried several approaches which are described in my question prompt, but nothing worked....

I proposed some code that will not saturate the print buffer, only update speed every 5s (1s should be fine too)

Man, you saved my day!! Appreciate it!!!

great to hear it's working

1 Like

Also check out my tutorial on Arduino Serial I/O for the Real World which goes Serial print blocking in detail, BUT J-M-L's solution is the the first suggestion in the tutorial.
Also check out Multi-tasking in Arduino which has a complete stepper example and details on how to give the stepper code more priority compared to other loop code (like prints)

1 Like

Many thanks! this is very helpful!

You don't, as far as I remember, the library only handles low-level calculations to determine the next step timestamp. Remember it has to handle thousands of steps a second and waste as little time as possible doing this. AccelStepper will ramp up and down with the acceleration rate you provide, and never go above the max speed you provide.

Normally with steppers you have to tune the max acceleration and speed by trial and error - so many factors affect them. Once you've experimentally determined the maximum values that work for your set-up, back off a bit with both to provide robustness.

you are right. I tried that last evening, and the acceleration works at the very beginning but the desired speed is never achieved. I just ended up using my previous code to do the acceleration.

p.s. I don't have a tachometer, so I just compare the sound the motor generates.

Accelstepper does indeed have a pretty small max speed

To display the speed you can count the number of steps which have elapsed since the last speed display. Since you know how long ago it was you can calculate an average speed over the past delta T

Hey Jackson,

As you suggested , I pretty much crank up the Serial braud rate. I just use stepper.speed() to get the current steps per sec and convert it back to RPM.

Check the section of my tutorial on Giving Important Tasks Extra Time to see how to make the stepper run faster and how to check how often you are calling stepper.run()