Stepper Motor Acceleration

Hello people of the internet,

I'm working on a project that involves a large (1600mm dia) turntable capable of carrying a maximum load of 300kg. So as it stands i have made the turntable and a chain driven gearbox (49:1) I'm using 150 transfer bearing to take the load and i have a Nema 34 with a MSD752 Microstepping Drive. Up until now I've been running it with a simple code writing pin high, delay, low. But ideally i'd like to have acceleration. So after a few weeks of googling I've now come to the conclusion that i have no clue what i'm doing when it comes to Arduino code.

This is roughly how i'd like the system to work. It would have a momentary start button that accelerates the motor to a given speed, it would hold that speed until a reed switch on the turntable was triggered then it would decelerate to a stop ready for the start button to be pushed again. From what I've read it's possible to negate the reed switch and have the Arduino count the number of steps and then stop accordingly. However with the gear reduction most likely adding complexity i'm more than happy to add a reed switch just to make things simpler.

So there is my project, i would greatly appreciate any input to help me with this task and if you have any questions please don't hesitate to ask.

Kind Regards

Aaran Boulton

It would seem to me that if you do "high, delay, low" that the way to Speed it up would to be reduce the delay in between.

There are also stepper libraries that handle acceleration/deceleration for you.

If you need acceleration the simplest thing is probably to look at the AccelStepper library

If that is not suitable then you will need to create your own acceleration code by varying the interval between steps as @JaBa has suggested. Either of the examples in this Simple Stepper Code could be adapted to do that.

...R
Stepper Motor Basics

Hello

Thank you both for you feedback, its much appreciated. I've been messing around with the AccelStepper library the last few days but to no avail. I have pull together some code I've found online and it does the acceleration and deceleration which is great but i'm struggling to integrate a start button. I figure out i can change the total amount of time the motor is on with this code so that mitigates the need the stop (reed) switch, which is great.

So the start button, I've tried a few methods that people have recommended but all result in me having to either constantly press the momentary button to run the motor or it just runs all of the time on its own. This is the current iteration of the code, apologise if its got some random lines that don't make sense.

/*
=============================================================
=       Project: S curve
=      Language: Arduiino r12
=          Date: January 2008
=        Author: C. Eckert
=============================================================
*/
#include <Button.h> 

// Givens
long ta = 3e6;     // acceleration time (microsec)
long td = 3e6;     // decelleration time (microsec)
long Vm = 3200;    // steady state velocity (pulse/sec)
long Pt = 12800;    // total number of pulses for move (1600 steps per rev)

// Other variables
long dly;           // stepper pulse delay (microsec)
long t = td/9;      // current time (microsec)  -  You need to seed the initial time with something > 0
                   //                             so you don't calculate to long of a delay
long t12;           // time during constant velocity (microsec)

int count = 0;      // count the number of pulses
int Perr = 0;       // error in position
//Button button = Button(12,PULLUP);
boolean state = false;
int buttonPin = 2;

// Arduino pins
#define dirPin 3
#define stepPin 8

void setup() {
 Serial.begin(9600);
 pinMode(dirPin, OUTPUT);
 pinMode(stepPin, OUTPUT);
 pinMode(buttonPin, INPUT);
 
 // Calculate the time at constant velocity 
 t12 = (Pt/(Vm/1e6))-0.5*(ta+td);
 Serial.println(); Serial.println();

 Serial.println("Setup Done");
}

void loop()
{
  //check button pressed, if so enter program condition (inside if statement)
  //if(button.uniquePress()){ //functions based off of button pulling input pin LO
    if (digitalRead(buttonPin) == HIGH){
      state = true;
     
    
    if (state == true);
    { 
      //put code you want to run on button press here.
     //if will run once and then when it's done it will exit the if statement and return to the top of the loop 
     //function and continually checking to see if the button has been pressed, if it hasn't it will keep 
     //checking, if it has it will run the program again and then once done continue to check after
 digitalWrite(dirPin, LOW);  // Set the stepper direction

 // Decide which part of the velocity curve your at
 if (t<ta) {                                       // Acceleration
   //Serial.println ("Acceleration Curve");
   dly = (ta)/(2*(Vm/1e6)*t);
 } 
 else if (t>=ta && t<(ta+t12)){                    // Constant velocity
   //Serial.println ("Constant Velocity");
   dly = 1/(2*(Vm/1e6));
 }
 else if (t>=(ta+t12) && t<(ta+t12+td)){          // Deceleration
   //Serial.println ("Deceleration Curve");
   dly = 1/(2*((Vm/1e6)-(Vm/(1e6*td))*(t-ta-t12)));
 }
 
 t = t+2*dly; // update the current time
 //Serial.print("dly: "); Serial.print (dly); Serial.println(" microsec");
 //Serial.print ("Current time: "); Serial.print(t); Serial.println(" microsec");
 
 // Move stepper one pulse using delay just calculated
 digitalWrite(stepPin, HIGH);
 delayMicroseconds(dly);
 digitalWrite(stepPin, LOW);
 delayMicroseconds(dly);
 count ++;
   
 // The move is finished
 if (t>(ta+t12+td)){
   Serial.println ("Move Complete");
   Serial.print ("Total steps indexed: "); Serial.println (count);
   
   // Correct for any position error due to rounding
   Perr = Pt-count;
   if (Perr < 0) {
     digitalWrite(dirPin, 1^digitalRead(dirPin));  // reverse the stepper direction
     delay(50);
     Perr = -1*Perr;
   }
   for (;Perr>0;){
     digitalWrite(stepPin, HIGH);
     delayMicroseconds(dly);
     digitalWrite(stepPin, LOW);
     delayMicroseconds(dly);
     Perr--;
   }
   
   count=0;
   t=td/9;
   
   Serial.print ("Flat Line");
   delay (1000);
   state = false;
   
 }
    }
  }
  }

I can't make sense of that due to your use of cryptic variable names. Code is much easier for you as well as us if you use meaningful names for variables - for example totalTime rather the t (assuming that's what t means - I may be wrong)

Have you checked that this does what you want without errors

dly = (ta)/(2*(Vm/1e6)*t);

all your variables are longs so there is likely to be a lot of unexpected rounding. Integer maths on an Arduino is not the same as the maths on a calculator.

Apart from all that you need to give us a better description of what you want your program to do. For example, what do you want to happen before the start button is pressed and what should happen after it. Will the button only be pressed once?

And if your program has some useless lines in it please take the trouble to remove them before posting your program. Help us to help you.

If you are timing things have a look at how millis() is used to manage timing without blocking in Several things at a time.

...R

tappu1996:
i need your help sir

This Thread has been dead for over a year.

Start your own Thread with a title that summarises your problem and then provide a good description of the project you want to create and the problem you are having.

See How to use the Forum

...R