Start and Stop Stepper Using AccelStepper

4,866 views
Skip to first unread message

Tom Jenkins

unread,
Oct 23, 2012, 9:18:40 PM10/23/12
to accels...@googlegroups.com
I am working on a class project that is a rotating wheel like a Ferris wheel, instead of chairs it has dixie cups. There are a total of 12 positions. Here are the logical steps.

1. Rotate wheel 30 degrees and stop.
2. Turn on Solid State Relay ,which is attached to a small pump, the pump stays on for 2 seconds adds some water.
3. Wait 5 seconds for drips to stop.
4. Rotate to next position and repeat above.
5. Do this for all 12 positions.

After all cups have water.

1. Rotate wheel 360 for X number of times.
2. Start fill sequence again.

I am new to the Arduino platform and have been running into some issues with the stepper motor being able to start and stop. I am using the AccelStepper with the following hardware.

Arduino Uno
Spark Fun Solid State Relay Kit (KIT-10684)
Spark Fun Stepper Motor - 125 oz.in (200 steps/rev) (ROB-10847)
Big Easy Driver (ROB-10735)

I have everything together and working. I can't seem to figure out the code to get the pause to happen for 5 seconds between when the pump turns off and the motor indexes to next position or how to get the second phase to integrated. I have provided the code I am using below. Can one of you pro's take a look and make some suggestions? It seems pretty straight forward.

Thanks in advance for any help or suggestions.

[code]

#include <AccelStepper.h>

#define relayPin 2                         //Output Pin for the SSR
#define dirPin 9                            //Direction Output on pin 8
#define stepPin 8                          //Step Output on pin 9
#define relayOn 8000                     //Amount of time the SSR stays on
#define relayOff 4000                    //Amount of time the SSR stays off
#define maxSpeed 4000
#define shaftSpeed 4000

const int steps = 200;                             
AccelStepper stepper(1, dirPin, stepPin);

int Distance;
unsigned long ms;                           //time from millis()
unsigned long msLast;                     //last time the relay changed state
boolean relayState;                         //current state of relay on or off

void setup()
{
    Serial.begin(9600);
    stepper.setMaxSpeed(maxSpeed);
    stepper.setSpeed(shaftSpeed);
    relayState = 0;
}

void loop()
{
   ms = millis();
   changeRelayState();
   
    if (relayState == 0)
  {
    stepper.runSpeed();
  }
    else
  {
    digitalWrite(dirPin, LOW);       
    digitalWrite(stepPin, LOW);
   
  }   
}

void changeRelayState()
{
    if (ms - msLast > (relayState ? relayOn : relayOff))
    {
      digitalWrite(relayPin, relayState = !relayState);
      msLast = ms;
    }
}

[/code]

Tom Jenkins

unread,
Oct 24, 2012, 10:20:45 PM10/24/12
to accels...@googlegroups.com
I can't believe not one reply? Is this the AccelStepper group?

Mike McCauley

unread,
Oct 24, 2012, 10:38:13 PM10/24/12
to accels...@googlegroups.com, Tom Jenkins
Sorry for not helping you quickly enough :-(

If it were me, for simplicity sake I would structure the code differently, in
a strictly linear sequence based on your description

Pseudocode:

setup()
{
something like you have currently
}

loop()
{
fill();
rotate();
}

fill()
{
for (i = 0; i < 12; i++)
{
set stepper target to current position + n (for 30 degrees)
runToPosition();
pumpOn();
delay(2000);
pumpOff();
delay(5000);
}
}

rotate()
{
set stepper target to current position + m (enough for x rotations)
runToPosition();
}


Perhaps you will be able to contribute back to the community by posting your
code when you are finished?

Cheers.
--
Mike McCauley mi...@open.com.au
Open System Consultants Pty. Ltd
9 Bulbul Place Currumbin Waters QLD 4223 Australia http://www.open.com.au
Phone +61 7 5598-7474 Fax +61 7 5598-7070

Radiator: the most portable, flexible and configurable RADIUS server
anywhere. SQL, proxy, DBM, files, LDAP, NIS+, password, NT, Emerald,
Platypus, Freeside, TACACS+, PAM, external, Active Directory, EAP, TLS,
TTLS, PEAP, TNC, WiMAX, RSA, Vasco, Yubikey, MOTP, HOTP, TOTP,
DIAMETER etc. Full source on Unix, Windows, MacOSX, Solaris, VMS, NetWare etc.

Sandy Noble

unread,
Oct 25, 2012, 3:17:34 AM10/25/12
to accels...@googlegroups.com
Tom, sorry for not replying - I must look to see if the SLA we have is
still realistic. The reason I didn't is that this has nothing to do
with accelstepper - it seems like "just" an arduino programming
problem. Your specification is very good. But since this is the
accelstepper group I assumed I must be missing something since I could
not see the accelstepper issue in it - I assumed the problem was more
sophisticated than I could see, and the program flow was a little
obfuscated for my tired old eyes so I didn't feel qualified to comment
without breaking out the compiler and testing it for real.

Looking at Mike's reply and solution, it does exactly what I would
have suggested (but more neatly) because it rewrites your entire
program, and that opens up a whole new conversation about style and
expression and approach to program flow - Which also doesn't have
anything specific to do with accelstepper. Perhaps the sparkfun
arduino forums would have been a better place to look for generic help
- after all you have already paid sparkfun for support by buying their
products, but Mike does all this for free.

cheers!
sn

Tom Jenkins

unread,
Oct 25, 2012, 8:41:36 AM10/25/12
to accels...@googlegroups.com
Hi Sandy and Mike, thanks for the reply and positive feedback. I am pretty new to Arduino, Stepper Motors, programming and forums for that matter. I have been going through every tutorial putting the necessary layers of learning into my brain. I have grabbed lots of snippets and put them together to form my code, I know its not the best way but either way I am learning from it. My comments about no one replying was not is anger but in if I had posted correctly and in the right place. And I would love to contribute monetarily for anyone's time because I know it's valuable. Just let me know how. I look forward to learning from you guys further.

PS - I will try to implement the new code and when I get it working to my spec's I will post for the community to use or beat up. LOL.

Tom

Tom Jenkins

unread,
Oct 25, 2012, 10:07:47 AM10/25/12
to accels...@googlegroups.com
Mike,

Your approach to the sequence is exactly what I was trying to do I just didn't know how to start. I took your code and modified it below. When void fillcycle() is called why does it not return to void loop() to do it all over again? It runs the pumpOn(), pumpOff() and rotate() moves the stepper. I know that is a C programming question but not sure how or what to call it in order to look it up. It doesn't return to void loop() after rotate(). Is this by design of AccelStepper?


[code]

#include <AccelStepper.h>

#define relayPin 2                         //Output Pin for the SSR

#define dirPin 9                           //Direction Output on pin 8
#define stepPin 8                          //Step Output on pin 9

#define maxSpeed 4000
#define shaftSpeed 4000

const int steps = 200;                            
AccelStepper stepper(1, dirPin, stepPin);


void setup()
{
    Serial.begin(9600);
    pinMode(relayPin, OUTPUT);
    pinMode(dirPin, OUTPUT);
    pinMode(stepPin, OUTPUT);
    stepper.setMaxSpeed(maxSpeed);
    stepper.setSpeed(shaftSpeed);
}

void loop()
{
    fillcycle();
}

void fillcycle()
{
   for (int i = 0; i < 12; i++)
  {
  pumpOn();
  pumpOff();
  rotate();
  }
}

void rotate()
{
  stepper.moveTo(1000);
  stepper.setSpeed(shaftSpeed);
  long lastPosition = 0;
  while (stepper.distanceToGo())
 {
   stepper.runSpeed();
   long thisPosition = stepper.currentPosition(); //grab current position
   if (thisPosition != lastPosition)
   {
     Serial.println(thisPosition); //print position
     lastPosition = thisPosition;
   }
  }
  while(1); // done
}

void pumpOn()
{
  digitalWrite(relayPin, HIGH);
  delay(2000);
}

void pumpOff()
{
  digitalWrite(relayPin, LOW);
  delay(5000);
}

[/code]


geoff probert

unread,
Oct 25, 2012, 10:27:11 AM10/25/12
to accels...@googlegroups.com
Tom, "Why doesn't it return to void loop() ?  Easy:  You've put it "on hold" with your  while(1); // done at the end of rotate()

Geoff

Tom Jenkins

unread,
Oct 25, 2012, 10:05:59 PM10/25/12
to accels...@googlegroups.com
Hi Geoff,

Thanks for the reply. Can you give a little more about "why" its on hold? Also when I comment out that while(1) line the pumpOn() and pumpOff() seem to repeat but the rotate() does not get repeated. Can you provide insight as to why this behavior is happening?

Thanks.

Tom

Aljoša kopina

unread,
Oct 26, 2012, 12:23:04 AM10/26/12
to accels...@googlegroups.com
Hey Tom,

It's "on hold" because you put this line there: while(1); // done
this is the same as saying:
while(1)
{
//do nothing
}

and when you put this line into comment everything that you have in your loop (pumpon, pumpOff and rotate) is executed everytime, the problem (at least i think that could be it) is that you are using moveTo (which sets the absolute destination)

stepper.moveTo(1000);

what it does it sets the destiation to 1000 (and when the motor reaches that destination it will stop moving). the first time arround it's ok since the motor is at 0 and it moves to 1000. then next time in the loop when rotate is called the motor is already at 1000 and therefore at it's destination. you could either use
stepper.moveTo(1000*i); (and then the destination would always be 1000 more than the last one) OR you could use stepper.move(1000); (it's move() instead of moveTo() that takes relative destination as an argument)

hope that helped and if not tell me what part was unclear and i'll try again.

good luck,
Aljoša

translated into english... always (because the exit contition is always true -> 1 = true) do nothing...


Dne petek, 26. oktober 2012 04:06:00 UTC+2 je oseba Tom Jenkins napisala:
Reply all
Reply to author
Forward
0 new messages