Arduino Accelstepper with microstepper

1,544 views
Skip to first unread message

melod...@gmail.com

unread,
Jun 19, 2013, 4:30:13 PM6/19/13
to accels...@googlegroups.com
Hello,
I have a microstepper and motor that working at 4000step/rev, it is a step/dir driver with arduino.
I am trying to make a code with accelstepper to have 2850 full turns with a counter incresing with each turn and after the number of turns to stop and proceed to the rest of the code.
 
I tried move but I can't stop it and moveTo but I can get only 1 turn. Is there any one that can make a code for me, please??
 
I appreciate your help!!!

Sandy Noble

unread,
Jun 19, 2013, 4:36:42 PM6/19/13
to accels...@googlegroups.com
Maybe you could show us your code so we could try and see your error?


sn

melod...@gmail.com

unread,
Jun 19, 2013, 5:05:19 PM6/19/13
to accels...@googlegroups.com
Thank you for your reply!
I just made some tests with accelstepper library to see if I can make it work but...
So if you could make a piece of code for 2850 full turns with a counter that will stop after reaching the number of turns to go to the rest of the code to for me, please? 
I can modify this piece to fit to the rest of the code, I think.
Thank you!

Sandy Noble

unread,
Jun 19, 2013, 5:31:49 PM6/19/13
to accels...@googlegroups.com
well the basic accelstepper way to do it would be

long target = 2580L * 4000L; // evaluates to 11,400,000
stepper.moveTo(target);
stepper.runToPosition();
Serial.println("I have turned lots of times.");
...

Note the "L" suffix on the end of the numbers in the target calculation, and the long data type.  This says to use long (32 bit) integers instead of standard (16 bit) integers.  Standard int only goes up to 32,767 before it overflows and jumps back to -32768, so that might be where you were going wrong before. Long data types can go up to 2 billion odd so your 11.4 million will fit in ok.

sn

Message has been deleted

Sandy Noble

unread,
Jun 21, 2013, 6:58:08 PM6/21/13
to accels...@googlegroups.com
Getting input from buttons, debouncing, all that stuff is a whole other problem with many solutions.  There are lots of libraries and things for Arduino code to do that neatly for you.  Most of them will amount to giving to the opportunity to pull a pin low or high, depending on whether the button is pressed or not.  The code sample below expects the button input pin to be pulled HIGH if it is pressed, and LOW otherwise.
I haven't tested this, but something like it:


long target = 20L * 4000L;
int buttonPin = 9; // the pin you have your button signal appearing on

void setup() {  
  stepper.setMaxSpeed(10000);
  stepper.setAcceleration(5000);
  Serial.begin(9600);
  stepper.moveTo(target);
  pinMode(buttonPin, INPUT);
}

void loop() {
  while (stepper.distanceToGo() != 0) {
    if (digitalRead(buttonPin) == HIGH) {
      Serial.println("Button is pressed - not doing anything.");
      if ((stepper.currentPosition() % 4000) == 0) { // is the current position a multiple of of the steps per revolution?
        Serial.print("Turns: ");
        Serial.println(stepper.currentPosition() / 4000);
      }
    } else {
      stepper.run();
    }
  } // end of the "while" loop
  Serial.println("I have turned lots of times.");
}




On 20 June 2013 06:56, <melod...@gmail.com> wrote:
You have right!
This works...
Here is a basic code:
 
#include <AccelStepper.h>
AccelStepper stepper(1, 3, 4);

void setup(){ 
  stepper.setMaxSpeed(10000);
  stepper.setAcceleration(5000);
  Serial.begin(9600);
}

void loop(){
long target = 20L * 4000L;

stepper.moveTo(target);
stepper.runToPosition();
Serial.println("I have turned lots of times.");
}
 
 
The next step question is how can I print in "Serial" each time the number of the turns? I mean ex. "turns:1", "turns:2", ...,  "turns:2850" ??
Also is it possible to pause accelstepper during the "moveTo" with a button push? and with the same button to resume from the last number of "turns"??
 
Thank you for your help!!!
--
You received this message because you are subscribed to the Google Groups "accelstepper" group.
To unsubscribe from this group and stop receiving emails from it, send an email to accelstepper...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 



--
Sandy Noble

Stavros Triantafilou

unread,
Jun 24, 2013, 6:22:19 PM6/24/13
to accels...@googlegroups.com
Thank you for the corrections.
Now some more help, please. My code now is this:




#include <AccelStepper.h>

AccelStepper stepper(1, 3, 4);
AccelStepper stepper2(4, 34, 35, 36, 37);

long target = 2850L * 4000L;
int  target2 = 115;
int buttonPin = 26; // the pin you have your button signal appearing on

void setup() { 
  stepper.setMaxSpeed(20000);
  stepper.setAcceleration(10000);
  stepper2.setMaxSpeed(100);
  stepper2.setAcceleration(100);
  Serial.begin(9600);
  stepper.moveTo(target);
  stepper2.moveTo(target2);

  pinMode(buttonPin, INPUT);
}

void loop() {
  while (stepper.distanceToGo() != 0) {
    if (digitalRead(buttonPin) == HIGH) {                  //Pause of winding
       Serial.println("PAUSE - Press Start to resume");
    } else {
      if (stepper2.distanceToGo() == 0){
        target2 = -target2;
        stepper2.moveTo(target2);
      }
      stepper2.run();
      stepper.run();

      if ((stepper.currentPosition() % 4000) == 0) {
        Serial.print("Turns: ");                            //Turns print
        Serial.println(stepper.currentPosition() / 4000);
      }
    }
  }

}


It is working correctly. I added a second stepper (4pin) also but for this motor, how can I set a "default possition" so each time that the loop begin and finish to "tell" the stepper to go to the default possition so be ready for the next time the loop will be start??

Also witch is the correct way to make a tongle button that pausing the entire loop to work as permanent ON/OFF switcher? I mean with the first push to "PAUSE" the motors and with the second push to "RESUME" the loop till the end of the motors movement?

Thank you so much!!! You really solved my problem.







2013/6/22 Sandy Noble <sandy...@gmail.com>

--
You received this message because you are subscribed to a topic in the Google Groups "accelstepper" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/accelstepper/XHLh2AjIALc/unsubscribe.
To unsubscribe from this group and all its topics, send an email to accelstepper...@googlegroups.com.

Stavros Triantafilou

unread,
Jun 27, 2013, 1:43:31 AM6/27/13
to accels...@googlegroups.com
I added a second stepper (4pin) also but for this motor, how can I set a "default possition" so each time that the loop begin and finish to "tell" the stepper to go to the default possition so be ready for the next time the loop will be start??

Also witch is the correct way to make a tongle button that pausing the entire loop to work as permanent ON/OFF switcher? I mean with the first push to "PAUSE" the motors and with the second push to "RESUME" the loop till the end of the motors movement?

Thank you.


2013/6/22 Sandy Noble <sandy...@gmail.com>

--
You received this message because you are subscribed to a topic in the Google Groups "accelstepper" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/accelstepper/XHLh2AjIALc/unsubscribe.
To unsubscribe from this group and all its topics, send an email to accelstepper...@googlegroups.com.

Sandy Noble

unread,
Jun 27, 2013, 11:29:31 AM6/27/13
to accels...@googlegroups.com
Hi Stavros, show us what you've already tried and maybe we can help. (Can't do your work for you, but can help with problems.)

sn

Stavros Triantafilou

unread,
Jun 27, 2013, 4:06:04 PM6/27/13
to accels...@googlegroups.com
Thanks,
Here is the code:

#include <AccelStepper.h>

AccelStepper stepper(1, 3, 4);
AccelStepper stepper2(4, 34, 35, 36, 37);

long target = 2850L * 4000L;
int  target2 = 115;
int buttonPin = 26; // the pin you have your button signal appearing on

void setup() { 
  stepper.setMaxSpeed(20000);
  stepper.setAcceleration(10000)
;
  stepper2.setMaxSpeed(100);
  stepper2.setAcceleration(100);
  Serial.begin(9600);
  stepper.moveTo(target);
  stepper2.moveTo(target2);
  pinMode(buttonPin, INPUT);
}

void loop() {
  while (stepper.distanceToGo() != 0) {
    if (digitalRead(buttonPin) == HIGH) {                  //Pause of winding
       Serial.println("PAUSE - Press Start to resume");
    } else {
      if (stepper2.distanceToGo() == 0){
        target2 = -target2;
        stepper2.moveTo(target2);
      }
      stepper2.run();
      stepper.run();
      if ((stepper.currentPosition() % 4000) == 0) {
        Serial.print("Turns: ");                            //Turns print
        Serial.println(stepper.currentPosition() / 4000);
      }
    }
  }

}



2013/6/27 Sandy Noble <sandy...@gmail.com>
Hi Stavros, show us what you've already tried and maybe we can help. (Can't do your work for you, but can help with problems.)

sn

--

Sandy Noble

unread,
Jun 27, 2013, 4:39:50 PM6/27/13
to accels...@googlegroups.com
I'm not clear what you want the program to do.  Try writing it out in steps so it is clear which motor is turning to which position and when.  What makes it stop, what makes it start.  

The easiest way to pause or run the motors is to have a boolean variable "currentlyRunning" and the value of the variable is toggled by the button press.  And only make your calls to ".run()" if that variable is true.

boolean currentlyRunning = true;

...

if (currentlyRunning) {
   stepper.run();
   stepper2.run();
}


This page: http://danthompsonsblog.blogspot.co.uk/2011/12/arduino-push-button-onoff-example.html has a decent example of a piece of code for a toggle button.  Buttons are actually a bit more awkward than you might think, because they need debouncing.  When you press a button, it usually "bounces" when it makes contact, making and breaking the contact a few times before it finally settles in one position.  Debouncing is a way of filtering out the bounces, and getting a positive button push.  Otherwise your button will fire a few times in a row without you knowing it.

sn



--
You received this message because you are subscribed to the Google Groups "accelstepper" group.
To unsubscribe from this group and stop receiving emails from it, send an email to accelstepper...@googlegroups.com.

For more options, visit https://groups.google.com/groups/opt_out.
 
 



--
Sandy Noble

Stavros Triantafilou

unread,
Jun 27, 2013, 5:23:53 PM6/27/13
to accels...@googlegroups.com
Ok,
I got it.
Is there a way to set a "default possition" for the stepper2 so each time that the loop begin and finish to "tell" the stepper to go to the default possition so be ready for the next time the loop will be start??

Thanks!


2013/6/27 Sandy Noble <sandy...@gmail.com>

Sandy Noble

unread,
Jun 27, 2013, 5:30:20 PM6/27/13
to accels...@googlegroups.com
That's the same sentence as you've already posted - it still isn't clear to me what behaviour you want.  A position is just a number.  Use moveTo(target) with a run() loop to move a motor to a particular position.  You can also use runToNewPosition(target) which is a bit more simple to read.


sn

Stavros Triantafilou

unread,
Jun 28, 2013, 5:11:31 PM6/28/13
to accels...@googlegroups.com
Thanks for your reply!
The key for the stepper2 is to set a default starting point before make any step as it is moves radomly so I can't say how many steps it is made each time and in which possition it will stop. So each time before the loop start it must go to the default start possition.
As both steppers are moving at the same time the second stops at a radom place when the first completes the number of turns must do.

I think now it is more clear.


Thank you!


2013/6/28 Sandy Noble <sandy...@gmail.com>

Sandy Noble

unread,
Jun 28, 2013, 5:53:52 PM6/28/13
to accels...@googlegroups.com
Ok, so you want stepper2 to return to a particular position.

stepper2.runToNewPosition(0);

Does that do what you need?  I'm still not clear when you want this to happen.  The code currently runs in a loop, and only runs once.  If you wanted it to return stepper2 to zero, after the long move of stepper, then copy the line above in as a last line of the loop() function:


void loop() {

  // Wiggle stepper2 back and forth, from 115 to -115,
  // as long as stepper is moving up to its final target:
  while (stepper.distanceToGo() != 0) {
    if (digitalRead(buttonPin) == HIGH) {                  //Pause of winding
       Serial.println("PAUSE - Press Start to resume");
    } else {
      if (stepper2.distanceToGo() == 0){
        target2 = -target2;
        stepper2.moveTo(target2);
      }
      stepper2.run();
      stepper.run();

      if ((stepper.currentPosition() % 4000) == 0) { 
        Serial.print("Turns: ");                            //Turns print
        Serial.println(stepper.currentPosition() / 4000);
      }
    }
  }
  // return stepper to beginning position
  stepper2.runToNewPosition(0);
  // do any other reset stuff you might want to
}

Stavros Triantafilou

unread,
Jul 4, 2013, 8:19:13 AM7/4/13
to accels...@googlegroups.com
Thank you so much, the code works perfect now.
Is there any way with the push of a button to reset everything and make the loop restart again?? 
 
Here is the code:
 
#include <PCD8544.h>
#include <AccelStepper.h>
AccelStepper stepper(1, 3, 4);
AccelStepper stepper2(4, 34, 35, 36, 37);
static PCD8544 lcd;
 
//inputs:
int countPin = 24; // input for counter
int breakPin = 25; // input for breaker
int stbutPin = 26; //input for start button
int turnlowPin = 27; //input for turns low button
int turnhighPin = 28; // input for turns high button
int enterPin = 29; // input for enter button
int pausePin = 38;
int motorButUp = 32;
int motorButDown = 33;
 
//outputs:
int stledPin = 22; //output for start led
int rdledPin = 23; //output for ready led
 
// variables:
int stVal = LOW;
int enterVal = LOW;
int enterpreVal;
int breakVal;
float coildepth = 3.5;
int turns = 20;
 
//setup:
void setup() {
pinMode(breakPin, INPUT);    // declare breaker as input
pinMode(stbutPin, INPUT);    // declare start button as input
pinMode(turnlowPin, INPUT);  // declare resume button as input
pinMode(turnhighPin, INPUT); // declare resume button as input
pinMode(enterPin, INPUT);    // declare resume button as input
pinMode(stledPin, OUTPUT);   // initialize led pin as output
pinMode(rdledPin, OUTPUT);   // initialize led pin as output
pinMode(motorButUp, INPUT);
pinMode(motorButDown, INPUT);
pinMode(pausePin, INPUT);
stepper.setMaxSpeed(20000);
stepper.setAcceleration(10000);
stepper2.setMaxSpeed(100);
stepper2.setAcceleration(100);
lcd.begin(84, 48);    // PCD8544 display resolution
lcd.setCursor(10, 0);
lcd.print("COIL WINDER");
lcd.setCursor(25, 1);
lcd.print("  by  ");
lcd.setCursor(10, 2);
lcd.print("  Stavros  ");
lcd.setCursor(4, 3);
lcd.print("Triantafyllou");
lcd.setCursor(4, 5);
lcd.print(" v1.0   2013 ");
delay (1500);
lcd.clear();
}

//main loop:
void loop(){
stVal = digitalRead(stbutPin);
enterVal = digitalRead(enterPin);
breakVal = digitalRead(breakPin);
if (enterpreVal == LOW){
lcd.setCursor(5, 0);
lcd.print("Please select");
lcd.setCursor(0, 2);
lcd.print(" Turns: ");
lcd.setCursor(45, 2);
lcd.print(turns);
lcd.setCursor(0, 4);
lcd.print("Coil size: ");
lcd.setCursor(61, 4);
lcd.println(coildepth);
lcd.setCursor(4, 5);
lcd.print(">press ENTER<");
stepper2.runToNewPosition(0);
if (digitalRead(motorButUp) == HIGH){
  delay(100);
 coildepth = coildepth + 0.5;
}
 
if (digitalRead(motorButDown) == HIGH){
  delay(100);
 coildepth = coildepth - 0.5;
}
if (digitalRead(turnlowPin) == HIGH){
  turns++;
}
if (digitalRead(turnhighPin) == HIGH){
  turns--;
}
}
int  target2 = coildepth * 3.571;
long target = turns * 4000L;
stepper.moveTo(target);
stepper2.moveTo(target2);

if (enterVal == HIGH){
    lcd.clear();
  enterpreVal = enterVal;
}else{
  enterpreVal = enterpreVal;
}

if (enterpreVal == HIGH){
   if (stVal == HIGH && breakVal == LOW){
      lcd.setCursor(10, 0);
      lcd.print("  Winding  ");
      lcd.setCursor(5, 2);
      lcd.print("             ");
      lcd.setCursor(5, 4);
      lcd.print("counter: ");
      lcd.setCursor(0, 5);
      lcd.print("               ");
       while (stepper.distanceToGo() != 0) {
          if (digitalRead(pausePin) == HIGH) {                  //Pause of winding
              digitalWrite(stledPin, stVal);

           }
          else {
             if (stepper2.distanceToGo() == 0){
                target2 = -target2;
                stepper2.moveTo(target2);
             }
             stepper2.run();
             stepper.run();
             digitalWrite(stledPin, stVal);

        
             if ((stepper.currentPosition() % 4000) == 0) {  
                lcd.setCursor(60, 4);
                lcd.print(stepper.currentPosition() / 4000);
             }
             if (stepper.distanceToGo() == 0){
                digitalWrite (stledPin, LOW);
                digitalWrite (rdledPin, HIGH);
                lcd.setCursor(5, 0);
                lcd.print(">>> READY <<<");
                lcd.setCursor(10, 2);
                lcd.print("Press start");
                lcd.setCursor(5, 4);
                lcd.print("  to make a  ");
                lcd.setCursor(0, 5);
                lcd.print("   new coil   ");
                delay(2000);
             }
           }
         }
      }
  }
}


2013/6/29 Sandy Noble <sandy...@gmail.com>
Reply all
Reply to author
Forward
0 new messages