Go Down

Topic: driving stepper motors a4988 (Read 171 times) previous topic - next topic

doodlebob

I will go ahead and share what i am trying to accomplish to make it easier. I am building a autonomous tool to help me wrap a speaker voice coil for a project. I already have a simplified version that just uses a gear motor but i want to use 2 stepper motors for more precision and to be autonomous. I am using a uno and 2 a4988 drivers with 2 stepper motors. One will be turning the shaft and the other will be guiding a wire guide piece on a screw and linear rails. Ultimately i want to be able to position the motors and wire and hit a button and have the motors do all the work because making them by hand is just no fun. So i need to be able to have the main motor turn at a set speed and x amount of full rotations then switch directions and go x amount back and stop, but while the main motor is spinning, i need the screw guide motor to turn x amount of rotations for every rotation of main motor and switch directions with main motor and go back to were it started. The screw motor will need to turn slower than the main motor but i need to figure out through trial and error how much slower it needs to be, it should be the pitch of the threads and width of the wire i am using. I have wrote some simple code that turns the motor 5 rotations one way then 5 the other at the press of a button. But trying to make this code run 2 motors at different speeds is impossible because i am using a delay to set the speed of the steppers so no matter what both steppers will turn at the same speed determined by the sum of the delays. So how could i set the speed of the motors and then the delta of the screw to main motor in rotations or steps?

const int stepPin1 = 3;
const int dirPin1 = 4;
const int stepPin2 = 5;
const int dirPin2 = 6;
int button = 7;

void setup() {
  pinMode(stepPin1,OUTPUT);
  pinMode(dirPin1,OUTPUT);
  pinMode(button,INPUT);
  pinMode(stepPin2,OUTPUT);
  pinMode(dirPin2,OUTPUT);

}

void loop() {
  if(digitalRead(button) == HIGH) {
  digitalWrite(dirPin1,HIGH);
  for(int x = 0; x < 5; x++) {
  for(int x = 0; x < 3200; x++) {
    digitalWrite(stepPin1,HIGH);
    delayMicroseconds(100);
    digitalWrite(stepPin1,LOW);}}
   
   delay(10);
   digitalWrite(dirPin1,LOW);
  for(int x = 0; x < 5; x++){
  for(int x = 0; x < 3200; x++) {
    digitalWrite(stepPin1,HIGH);
    delayMicroseconds(100);
    digitalWrite(stepPin1,LOW);}}}}

Robin2

Have a look at the second example in this Simple Stepper Code. It uses millis() and micros() for non-blocking timing.

...R
Stepper Motor Basics

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

doodlebob

I have started a new code using the mills approach but i am stuck. When i press the button the motor just makes  a noise instead of turning. I do not fully understand the curmills=mills(); in the other code. I know the timer needs a starting point for reference but i do not know how to integrate it into this code.

byte stepPin_1 = 3;
byte dirPin_1 = 4;
byte stepPin_2 = 5;
byte dirPin_2 = 6;
int button = 7;
unsigned long curmills_1;
unsigned long curmills_2;
unsigned long prevstepmills_1 = 0;
unsigned long prevstepmills_2 = 0;
unsigned long millsBetweenSteps_1 = .150;
unsigned long millsBetweenSteps_2 = .250;

void setup() {
  pinMode(stepPin_1, OUTPUT);
  pinMode(dirPin_1, OUTPUT);
  pinMode(button, INPUT_PULLUP);
  pinMode(stepPin_2, OUTPUT);
  pinMode(dirPin_2, OUTPUT);
}

void loop() {
  if (digitalRead(button) == LOW) {
    digitalWrite(dirPin_1, HIGH);
    digitalWrite(dirPin_2, LOW);
    for (int x = 0; x < 1600; x++) {
      singleStep_1();
      singleStep_2();
    }
    digitalWrite(dirPin_1, LOW);
    digitalWrite(dirPin_2, HIGH);
    for (int x = 1600; x == 0; x--) {
      singleStep_1();
      singleStep_2();
    }
  }

}

void singleStep_1() {
  if (curmills_1 - prevstepmills_1 >= millsBetweenSteps_1) {
    prevstepmills_1 += millsBetweenSteps_1;
    prevstepmills_1 = curmills_1;
    digitalWrite(stepPin_1, HIGH);
    digitalWrite(stepPin_1, LOW);
  }
}

void singleStep_2() {
  if (curmills_2 - prevstepmills_2 >= millsBetweenSteps_2) {
    prevstepmills_2 += millsBetweenSteps_2;
    prevstepmills_2 = curmills_2;
    digitalWrite(stepPin_2, HIGH);
    digitalWrite(stepPin_2, LOW);
  }
}

Delta_G

You never give our curmillis_1 variable a value.  So it is stuck at 0. 

This line:

Code: [Select]
if (curmills_1 - prevstepmills_1 >= millsBetweenSteps_1)

Is literally saying, if the time nowminus the time it was last time you did this (so the difference in time or the elapsed time if you will) is greater than some given amount then do the thing again. 

But you aren't going to let it know what the current time is.  That's what this line:

Code: [Select]
curmills=mills();

does.  That is getting the current time from millis and storing it in that curmillis variable. 


It really isn't very hard of a concept.  If I told you at 2:00 to meet me at the pub in 20 minutes would you be able to do that?  If it is 2:15 now then is it time to meet me?  What if it is 2:21?  How did you do that?  See how easy it is?
|| | ||| | || | ||  ~Woodstock

Please do not PM with technical questions or comments.  Keep Arduino stuff out on the boards where it belongs.

doodlebob

it makes since why it is used now. I am getting a error because mills() was not declared. Does mills() need to be in global and then defined in setup. I have tried adding just curmills=mills() but there is error.

Delta_G

#5
Jan 24, 2019, 12:43 am Last Edit: Jan 24, 2019, 12:43 am by Delta_G
It's millis() not mills().   Spelling matters.

When you have errors, post the actual error message and the actual code that caused it.  Surely you can understand why.  Just saying that there was an error is a completely useless statement unless all you want is sympathy
|| | ||| | || | ||  ~Woodstock

Please do not PM with technical questions or comments.  Keep Arduino stuff out on the boards where it belongs.

Go Up