Stepper Motor + Easydriver tuning.

Hi all,
i developed a sketch, where the stepper motor, driven by the easydriver board will turn, but constantly read some buttons, in order to start turning or stop, when the button is hit. It works, but the motor shakes while running. To constantly be able to check button state, the stepper function is called and turns 26 microsteps.

The code (part), is as follow:

void loop() {
  check_mode();
  switch (operation_mode) {
    case 'A':
      Automatic_Mode();
      break;
    case 'C':
      Manual_Close();
      break;
    case 'O':
      Manual_Open();
      break; 
    case 'P':
      break;   
  }  
 
}

void check_mode() {
  automatic.listen(); manual_close.listen(); manual_open.listen();
  if (automatic.onPress()) {
    if (operation_mode == 'A') {
      operation_mode = 'P';
    } else {
     operation_mode = 'A';    
    } 
  } 
  if (manual_close.onPress()) {
    if (operation_mode == 'C') {
      operation_mode = 'P';
    } else {
     operation_mode = 'C';    
    }
  }
  if (manual_open.onPress()) {
    if (operation_mode == 'O') {
      operation_mode = 'P';
    } else {
     operation_mode = 'O';
    } 
  }
}

void Manual_Close() {
  delay(500);
  while(digitalRead(stop_close) == LOW && operation_mode == 'C') {
    direction = 'C';
    EasyDriverEnable();
    BlindMotor();
    check_mode();
  }
     EasyDriverDisable();
}

void BlindMotor() {
  if (direction == 'O')
      digitalWrite(MotorDir, HIGH);
  if (direction == 'C')
      digitalWrite(MotorDir, LOW);
  int dist = 0;
  // the motor makes a full turn with 1600 microsteps. So, this move makes the motor turns 1/64th of a full turn = 25 microsteps.
  while (dist < 26) {
    digitalWrite(MotorStep, HIGH);
    delayMicroseconds(280);
    digitalWrite(MotorStep, LOW);
    delayMicroseconds(280);
    dist = dist + 1;
  }
}

Question: is there a way to tune the BlindMotor function so it moves smoother? I did try, but with not luck. I need the motor to run slow (not too slow).
Could anyone with better skills than me help?

Thanks in advance,

Paulo

No ideas?

I suspect you need to get rid of the delay()s and replace them with the type of code in "blink without delay"

...R

pw44:
Hi all,
i developed a sketch, where the stepper motor, driven by the easydriver board will turn, but constantly read some buttons, in order to start turning or stop, when the button is hit. It works, but the motor shakes while running. To constantly be able to check button state, the stepper function is called and turns 26 microsteps.

The code (part), is as follow:

void loop() {

check_mode();
  switch (operation_mode) {
    case ‘A’:
      Automatic_Mode();
      break;
    case ‘C’:
      Manual_Close();
      break;
    case ‘O’:
      Manual_Open();
      break;
    case ‘P’:
      break;   
  }

}

void check_mode() {
  automatic.listen(); manual_close.listen(); manual_open.listen();
  if (automatic.onPress()) {
    if (operation_mode == ‘A’) {
      operation_mode = ‘P’;
    } else {
     operation_mode = ‘A’;   
    }
  }
  if (manual_close.onPress()) {
    if (operation_mode == ‘C’) {
      operation_mode = ‘P’;
    } else {
     operation_mode = ‘C’;   
    }
  }
  if (manual_open.onPress()) {
    if (operation_mode == ‘O’) {
      operation_mode = ‘P’;
    } else {
     operation_mode = ‘O’;
    }
  }
}

void Manual_Close() {
  delay(500);
  while(digitalRead(stop_close) == LOW && operation_mode == ‘C’) {
    direction = ‘C’;
    EasyDriverEnable();
    BlindMotor();
    check_mode();
  }
     EasyDriverDisable();
}

void BlindMotor() {
  if (direction == ‘O’)
      digitalWrite(MotorDir, HIGH);
  if (direction == ‘C’)
      digitalWrite(MotorDir, LOW);
  int dist = 0;
  // the motor makes a full turn with 1600 microsteps. So, this move makes the motor turns 1/64th of a full turn = 25 microsteps.
  while (dist < 26) {
    digitalWrite(MotorStep, HIGH);
    delayMicroseconds(280);
    digitalWrite(MotorStep, LOW);
    delayMicroseconds(280);
    dist = dist + 1;
  }
}




Question: is there a way to tune the BlindMotor function so it moves smoother? I did try, but with not luck. I need the motor to run slow (not too slow).
Could anyone with better skills than me help?

Thanks in advance, 

Paulo

Get rid of the delay statements and use the millis function to achieve what you want

Basically Delay stops everything else happening.

if you want an easy way to use millis - then look at the SimpleTimer library

Craig

craigcurtin:
Get rid of the delay statements and use the millis function to achieve what you want

Basically Delay stops everything else happening.

if you want an easy way to use millis - then look at the SimpleTimer library

Craig

Thx for the answer. I did read the millis(), but did not understand how to replace delay by millis. Could you please show me how?
You said delay stops everything. Why would millis not do the same?
Thx in advance,

"delay()" is a piece of Arduino code that goes round in a circle until the time expires.

If you want to use millis() you must realize that the loop() function also goes round in a circle pretty quickly (as long as you have no "delay()" in it). So to use millis() all you need to do is save the value of millis() and then start something (such as switching on an led) and in every iteration of loop you compare the latest value of millis() and when the difference exceeds whatever time you are interested in it's time to stop the thing (i.e. switch off the led).

...R

delayMicroseconds() works quite well when dealing with stepper motors, if no other operations are required during the delay.

negativ3:
delayMicroseconds() works quite well when dealing with stepper motors, if no other operations are required during the delay.

Exactly the point.
The stepper shall turn 26 microsteps, and then end.
Problem: it shakes a lot, with 280 microseconds. With 150, 180 microseconds, it's smoother, but it turns faster.
The main point is how to make it turn slow, without or at least with less shaking as possible.
TIA

I'm only learning about stepper motors and I'm rather hazy about how microstepping works. However I wonder if it's only possible to get the motor to stop at a "proper" or full step. I would try testing with a number of microsteps that equals a full step and see what happens.

As far as I know (and I would be glad to be corrected) microstepping is to give smooth movement rather than extra stopping points.

...R

pw44:

negativ3:
delayMicroseconds() works quite well when dealing with stepper motors, if no other operations are required during the delay.

Exactly the point.
The stepper shall turn 26 microsteps, and then end.
Problem: it shakes a lot, with 280 microseconds. With 150, 180 microseconds, it's smoother, but it turns faster.
The main point is how to make it turn slow, without or at least with less shaking as possible.
TIA

So... do you have any of the MS lines of the Easydriver connected? According to the Easydriver website, it defaults to 8-step microstepping mode which corresponds to your 1600 steps/rev.

Can you provide the motor number?
What voltage are you supplying accross GND and +M on the Easydriver?

Another thing that may be worth doing is only running the "check" function periodically. e.g.

unsigned short n=0; //Counter to implement the periodic checking
unsigned short nCycles=3000; //Checking every "nCycles" passses through the loop. 
void loop() {
  if (++n == nCycles){
    RUNCHECK();  
    n=0;
    }

  //Do motor stuff

} //End loop()

I have a similar situation as you, and I've set my nCycles variable such that the checking function is called about 30 times a second. That's plenty good enough and frees up the main loop to do other stuff. This can become important if your "checking function" becomes large and slow to execute.

pw44:

craigcurtin:
Get rid of the delay statements and use the millis function to achieve what you want

Basically Delay stops everything else happening.

if you want an easy way to use millis - then look at the SimpleTimer library

Craig

Thx for the answer. I did read the millis(), but did not understand how to replace delay by millis. Could you please show me how?
You said delay stops everything. Why would millis not do the same?
Thx in advance,

Millis is essentially a clock that is built into the arduino and that you can access to track elapsed time for a function. so if you wanted to do something once a second you could put

delay (1000) into a loop at the end of your function which makes the processor stop and do nothing at all for 1 second, or you could put a if statement that would check how many millis had passed and if it was greater than 1000 then do your next round of motor turns - whilst it is waiting for the second to pass it can be doing other things.

It is easier when you are starting out to use one of the prebuilt libraries and then later own do your own manipulation if you outgrow the library

have a look at

http://playground.arduino.cc/Code/SimpleTimer

Download the sample and run it and look at the serial monitor and you will understand what it does.

Then have a look at the blinkwithdelay example in the IDE and you can see how they both achieve the same thing

Craig

@craigcurtin, thx for the explanation and answer. The millis is not suitable for this, but the micros is, because the need for making the stepper turn is in microseconds, not milliseconds. But i really did like the tip. I will rewrite the whole sketch to use micros, so it will perform faster, without delays.

@raacampbell, thx for the answer, but the problem is not the delay, but making the stepper run smoother, without gasping, which is being the case with the 280uS delay between step high, step low.

@negativ3, thx, the easydriver is not using any of the MS pins, so the default is 1/8 th, and so, 1600 microteps to perform a full turn. Rotation is not the problem, but the low speed, which makes the stepper gasp.... The motor is a RB step motor 17hd0004-6, with a 12V power supply.

pw44:
@craigcurtin, thx for the explanation and answer. The millis is not suitable for this, but the micros is, because the need for making the stepper turn is in microseconds, not milliseconds. But i really did like the tip. I will rewrite the whole sketch to use micros, so it will perform faster, without delays.

@raacampbell, thx for the answer, but the problem is not the delay, but making the stepper run smoother, without gasping, which is being the case with the 280uS delay between step high, step low.

@negativ3, thx, the easydriver is not using any of the MS pins, so the default is 1/8 th, and so, 1600 microteps to perform a full turn. Rotation is not the problem, but the low speed, which makes the stepper gasp.... The motor is a RB step motor 17hd0004-6, with a 12V power supply.

OK good to know you are on the case

It might be worthwhile looking at some of the custom easydriver libraries that have been written - could simplify what you are trying to achieve.

The point about using millis is that you can do other things whilst the stepper is turning and then come back and service it - so your loop() function can test if 100 (or 50 or whatever) number of millis has passed and then go back and toggle the stepper pins.

Craig