Arduino AccelStepper Library: Instant speed never reaches set speed

3.5k views Asked by At

I am trying to develop a arduino code which runs a stepper motor with C# program via serial communication. I also use Accelstepper library, especially moveTo() and run() functions. I sent maxSpeed and step values as 3500 and 200.000 from C# and motor start to run immediately. I sure that it completes all steps, but after a while, I noticed that stepper motor never reaches its max Speed and it stuck at 3200-3300 range. So because of that finish time is increased. If I give steps more than 200.000, the gap between estimated finish time and real finish time is increased exponentially. If I sent speed as 1000, real speed more or less 970. I have to use acceleration function by the reason of needed torque. Then I search the problem and some people said that it occurs because of Accelstepper library which consist run() function and other stuff that I wrote in the loop section. Especially I could not ensure the reason of the problem is Arduino, AccelStepper library or code that I wrote. Can you please help me to solve problem? NOTE: Arduino Mega 2560 is used. Arduino code is below:

#include <AccelStepper.h>
#include <stdio.h>
#define STEP_PIN_C 5 //31
#define DIRECTION_PIN_C 23 //32
#define ENABLE_PIN_C 24 //33
#define SET_ACCELERATION 600.0
AccelStepper stepper(1, STEP_PIN_C, DIRECTION_PIN_C);
unsigned long oldTime=0;
unsigned long now;
float newSpeed;
float maxSpeed = 3500.0;
bool newDataBit, runAllowed = false,addingProg=false,mainProg=false;
char commandChar;
long currentPosition;
long int steps = 0, mainNewStep, addedNewStep,memMainStep;
void checkSerial();
void checkRunning();
void stopMotor();
void runMotor();
void sendInfo();
const unsigned long delayTime = 1000;
unsigned long timer;
int count = 0;
bool running = false;

void setup()
{
  Serial.begin(9600);
  pinMode(ENABLE_PIN_C, OUTPUT);
  digitalWrite(ENABLE_PIN_C, HIGH);
  stepper.setCurrentPosition(0);             //initial value
  stepper.setMaxSpeed(0.0);                  //initial value
  stepper.setAcceleration(SET_ACCELERATION); //initial value
}

void loop()
{
  sendInfo();
  checkRunning();
  checkSerial();
}
void checkRunning()
{

  if (runAllowed == true) 
  {
    if (stepper.distanceToGo() == 0)
    {
      stopMotor();
      checkSerial();
    }
    else 
    {
      runMotor();
      checkSerial();
    }
  } 
}
void checkSerial()
{
  if (Serial.available())
  {
    newDataBit = true;
    commandChar = Serial.read();
  }
  if (newDataBit == true)
  {
    ///DoStuff depends on what is received as commandChar via serial port
    mainProgram(stepper.currentPosition(),newSpeed,mainNewStep);
    newDataBit = false;
  }
}


void runMotor(){
  digitalWrite(ENABLE_PIN_C, LOW);
  stepper.run();
  running = true;
}
void stopMotor(){
  stepper.setCurrentPosition(0);
  digitalWrite(ENABLE_PIN_C, HIGH);
  stepper.stop();
  running = false;
  timer = millis() + delayTime;
}

void mainProgram(long currentPositionValue,float maxSpeedValue,long stepValue)
{ 
  mainProg = true;
  if (stepper.distanceToGo() == 0) //YOLUMU TAMAMLADIM
  {
    addingProg = false; 
    steps = stepValue;
    stepper.setCurrentPosition(currentPositionValue);
    //stepper.setSpeed(0);
    stepper.setMaxSpeed(maxSpeedValue);
    stepper.moveTo(steps);
  }
  else
  {
    steps = stepValue + steps;
    stepper.setCurrentPosition(currentPositionValue);
    //stepper.setSpeed(0);
    stepper.setMaxSpeed(newSpeed);
    stepper.moveTo(steps);
  }
}
void sendInfo(){
  now = millis();
  if(now-oldTime > 1000){ //saniyede 1
     Serial.print(stepper.currentPosition());
     Serial.print(" ");
     Serial.print(stepper.isRunning());
     Serial.print(" ");
     Serial.println(stepper.speed());
     oldTime = now;
  }
}
1

There are 1 answers

0
Piglet On

From AccelStepper documentation:

The fastest motor speed that can be reliably supported is about 4000 steps per second at a clock frequency of 16 MHz on Arduino such as Uno etc.

This is if you do nothing else but running the stepper. You check your serial interface and send multiple lines every second. Both is quite expensive.