Jump to content

Banner.jpg.b83b14cd4142fe10848741bb2a14c66b.jpg

Accel Stepper Program for Arduino


SonnyE

Recommended Posts

I've been whiling away my shipping wait for my hardware by watching and reading about Arduino and Stepper Motor control (Specifically). I was watching one rather informative video where the author hit on another library for the Arduino, AccelStepper.

It appears to be a bit simpler than regular Arduino coding, which was attractive to me. But what really brought me running was that it can accelerate and decelerate on either end of the command. Think of it being a Soft Start for a stepper motor running your focuser, or a Filter Wheel. Soft Start? :wacko:

Yes, a Soft Start, and also a Soft Stop. Making your stepper motor gently begin to move, traveling to your selected point, then slowing the travel so it coasts in to what you requested. Soft Start is becoming quite common for a lot of motor driven devices.

So my thoughts on it were to program my upcoming Arduino projects with my own Soft Start and Soft Stop to bring the focuser to Step XXX and when trying to toy in a best focus, the automatic Soft Start could aid in getting gentler adjustments.

I bounced this idea off of my friend and he said that ramping speed was more for CNC machines and the like. And that tweaking in a focuser was more like around 70 steps to get the human eye to see the difference. I don't know (yet), but it seemed to me making any command gentler on the overall equipment might be a better idea.

Arduino (I've been led to believe) doesn't have this Soft Start - Soft Stop in their library yet. If you would like, Here are the links to this idea:

The Maker Show by Bret Stateham. If you scroll down on this page, there are quick links to the different parts he covers, including the AccelStepper part.

Quick Link to the AccellStepper Part.  Or a bit before, where he refers to the Library, and where this software will be if you choose to download it for your Arduino Programming. I did, so it is there when I get my hardware here and actually begin my developing. (I prefer to have things in front of me as I prototype. I'm a hands on kinda guy.)

I searched to see if this had been posted here, but found nothing. So I thought I'd offer it up to anyone who might be interested. OK, back to hammering on my brain. (Think: A BB in a Boxcar.) :hello:

 

Link to comment
Share on other sites

Hi SonnyE,

AccelStepper is a really useful tool for control of steppers - I have made a lot of use of it for the software for my observatory automation. There are a couple of gotchas - be careful not to use the blocking commands in the library - unless you are sure about what you want to do and also the maximum pulse (step) rate is limmited to about 4000 pps with a standard 16 MHz Arduino. If you need higher pulse rates, you need a faster processor. I have attached a bit of the code I use for opening my observatory shutter. Because I use a stepper with a built-in 50:1 reduction gear box and a Gecko driver with fixed x10 microstepping to get reasonable open and close times I have used a 96 MHz Teensy 3.2.

Code is below - enjoy!!

Regards, Hugh

//*******************************************************START OF FULLY OPEN*****************************************************
            case ORDER_OPEN_FULLY: //Shutter Full Open from any position
                SendLogEntry("AB6:LA4 moveOrder 1, ORDER_OPEN_FULLY from ",myMotor.currentPosition());
                //Enable movement   
                isActive = true; 
                digitalWrite(pnMotorEnable,HIGH);
                myMotor.moveTo(fastOpenTarget); //A bit short of fully open 
                shutterState = MOVE_OPENING;
                SendShutterState();
                if (BENCH_TEST)
                    {
                        isFullyClosed = false;
                        isFullyOpen = false;
                        validPosn = false;
                    }
                //isAutoActive is set TRUE if the Open Fully command is from the ASCOM automation system.
                //So, check for a time out failure - needn't do this for manual operation.
                if (isAutoActive)
                    {
                        elapsedMillis timeOut; //Creates timeOut and sets value to zero. timeOut increments in the 'while'loop
                        while (myMotor.distanceToGo() && !isNudging && !isFullyOpen && timeOut < 100000) myMotor.run();    
                        if (timeOut > 100000)
                            {
                                bitSet(shutterSafety, SAF_TIMEOUT); //Set the move timeout bit flag
                                timeOut = 0; //Stop the elapsedMIllis timer
                                break;
                            }
                        else bitClear(shutterSafety, SAF_TIMEOUT);    
                        timeOut = 0;
                    }
                else
                    {
                        while (myMotor.distanceToGo() && !isNudging && !isFullyOpen) myMotor.run();                        
                    }
                    
                //The Fast Movement motor operation uses Semi-Blocking code. That is, the motor will only stop when
                //when (1) the target is reached OR (2) an interrupt occurs and sets isNudging - (a button
                //has been pressed) or isFullyOpen - (limit switch has triggered).
                //For the AUTO operation only, the motor also stops if the elapsed time is more than 100 seconds.

                //Fast Movement has now ENDED
                //If we got here because we triggered the Fully Open limit switch we need to gracefully exit
                if (isFullyOpen)
                  {
                      SmoothStop(); //Allows a 1 mm stopping distance. Calls myMotor.stop()
                      shutterState = FindShutterState();                        
                      moveOrder = 0; //Reset moveOrder 
                      SendLogEntry("AB6:LA4 OPEN FULLY, isFullyOpen TRUE at ",myMotor.currentPosition());
                      digitalWrite(pnMotorEnable,LOW);
                      isActive = false;
                      break;
                  }

                //If we got here because we pushed a Nudge Button we need to gracefully exit
                if (isNudging)
                  {
                      SmoothStop(); //Allows a 1 mm stopping distance. Calls myMotor.stop()
                      shutterState = FindShutterState();                        
                      moveOrder = 0; //Reset moveOrder 
                      SendLogEntry("AB6:LA4 OPEN FULLY, isNudging TRUE at ",myMotor.currentPosition());
                      digitalWrite(pnMotorEnable,LOW);
                      isActive = false;
                      break;
                  }
                
                //If we got here because we reached the fastOpenTarget, we need to complete the move
                if (myMotor.distanceToGo() == 0) //stopped due to reaching 1st target position
                //so go ahead with slow speed move to final endpoint.
                    {
                        SendLogEntry("AB6:LA4 OPEN_FULLY 1st Posn",myMotor.currentPosition());
                        //Enable final nudge part of move
                        isActive = true;
                        //Change maxSpeed to a lower value
                        myMotor.setMaxSpeed(nudgeSpeed); 
                        //Note: Acceleration unchanged from the value used with runSpeed. But as nudgeSpeed 
                        //is only 7% of runSpeed, the acceleration happens over a much shorter time.             
                        digitalWrite(pnMotorEnable,HIGH);
                        myMotor.moveTo(maxTravel);
                        myMotor.setSpeed(nudgeSpeed);
                        
                    if (isAutoActive)
                        {
                            elapsedMillis timeOut; //Creates timeOut and sets value to zero. timeOut increments in the 'while'loop
                            while (myMotor.distanceToGo() && !isFullyOpen && timeOut < 20000) myMotor.run();    
                            if (timeOut > 20000)
                                {
                                    bitSet(shutterSafety, SAF_TIMEOUT); //Set the move timeout bit flag
                                    timeOut = 0;
                                    break;
                                }    
                        else bitClear(shutterSafety, SAF_TIMEOUT);                                    
                            timeOut = 0;
                        }
                    else
                        {
                            while (myMotor.distanceToGo() && !isFullyOpen) myMotor.run();                        
                        }                        
                            //Blocking code - sort of. Still responds to interrupt when limit switch activates
                            //and to timeOut event for AUTO OPEN order.
                            //Slow movement has now ENDED
                        isActive = false;
                        myMotor.stop();
                        //Reset maxSpeed
                        myMotor.setMaxSpeed(runSpeed);            
                        digitalWrite(pnMotorEnable,LOW);
                        if (BENCH_TEST)
                            {
                                isFullyOpen = true;
                                validPosn = true;
                            }
                        shutterState = FindShutterState();                        
                        moveOrder = 0; //Reset moveOrder  
     
                        if (isFullyOpen)
                            {
                                SendLogEntry("AB6:LA4 isFullyOpen TRUE at ",myMotor.currentPosition());  
                            }
                        else
                            {
                                SendLogEntry("AB6:LA4 isFullyOpen FALSE at ",myMotor.currentPosition());
                            }
                    }    
            break;
//*************************************************************END OF FULLY OPEN********************************************************
 

Link to comment
Share on other sites

Thank You very much for sharing that. As a fledgling Arduino user, I'm just beginning to get a grasp on the coding.

I downloaded the code you posted, but I'm doing something wrong I'd imagine. I copy and pasted it in its entirety. When I run the "verify" I get error messages, and it stumps me.

Arduino: 1.8.1 (Windows 10), Board: "Arduino Nano, ATmega328"

DomeControl:2: error: expected unqualified-id before 'case'

             case ORDER_OPEN_FULLY: //Shutter Full Open from any position

             ^

DomeControl:5: error: 'isActive' does not name a type

                 isActive = true;

                 ^

DomeControl:6: error: expected constructor, destructor, or type conversion before '(' token

                 digitalWrite(pnMotorEnable,HIGH);

                             ^

DomeControl:7: error: 'myMotor' does not name a type

                 myMotor.moveTo(fastOpenTarget); //A bit short of fully open

                 ^

DomeControl:8: error: 'shutterState' does not name a type

                 shutterState = MOVE_OPENING;

                 ^

DomeControl:9: error: expected constructor, destructor, or type conversion before ';' token

                 SendShutterState();

                                   ^

DomeControl:10: error: expected unqualified-id before 'if'

                 if (BENCH_TEST)

                 ^

DomeControl:18: error: expected unqualified-id before 'if'

                 if (isAutoActive)

                 ^

exit status 1
expected unqualified-id before 'case'

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.


 I don't have a dome, unless my inverted, manually operated, plastic trash bin somehow qualifies (doubtful). But I hope to save your generously shared code in my Arduino code library. (Hope? I have saved it.)

Might you have, or might you know, where I could acquire code for a motorized filter wheel? I'm currently dabbling with a Nano (clone) to drive a ULN2003 and a 28byj 48 stepper motor. I have high hopes of being able to run my equipment outside from inside, including filter wheel and focusing.

One of these days I will likely blow up my laptop with all these demands I want it to do.... :lol:

Thank You, Hugh, for sharing! Clear Skies!

Link to comment
Share on other sites

On 1/25/2017 at 12:21, NickK said:

One of the INDI stepper drivers use it.

Thank You, Nick!

I didn't know what INDI was, so I went looking. And it looks very good. http://www.indilib.org/

I'll be off looking over the site. Thank You!

Is INDI more of a LINUX based system? Because I'm Windows 10 here. Are the INDI compatible with my Arduino and Windows 10 base?

Oh, sorry I just checked and answered my own question. No Windows portal yet. :tongue:

Link to comment
Share on other sites

Hi Sonny,

I think I have confused you a bit - the code I put in my post was just a fragment of the program and, as you have found, it won't work on its own. It was just meant to illustrate the use of the Accelstepper library.

I don't have any code for running a filter wheel - I don't have a filter wheel, so no need.

I suggest you have a look at this project. Rob Brown has done some excellent Arduino astronomy projects that are very well documented and easy for a beginner to follow. He is also very helpful if you run into any snags.

https://sourceforge.net/projects/myfilterwheel-ascom-diy/

Sorry if I misled you. If you do want the whole of my Dome Shutter code I would be happy to send it to you. Send me a PM with your email address and I will send you a copy of the whole program. 

Regards, Hugh

Link to comment
Share on other sites

2 hours ago, hughgilhespie said:

Hi Sonny,

I think I have confused you a bit - the code I put in my post was just a fragment of the program and, as you have found, it won't work on its own. It was just meant to illustrate the use of the Accelstepper library.

I don't have any code for running a filter wheel - I don't have a filter wheel, so no need.

I suggest you have a look at this project. Rob Brown has done some excellent Arduino astronomy projects that are very well documented and easy for a beginner to follow. He is also very helpful if you run into any snags.

https://sourceforge.net/projects/myfilterwheel-ascom-diy/

Sorry if I misled you. If you do want the whole of my Dome Shutter code I would be happy to send it to you. Send me a PM with your email address and I will send you a copy of the whole program. 

Regards, Hugh

Thank You for the link to Rob's. I had already been there and that project is on hold. Apparently indefinitely. So I'll continue my quest for shared codes. I have found and bookmarked one example that is very close to my needs, up to the actual attempt to verify it.

I don't have a dome, and most likely won't, as I live in a more desert like climate zone. But thank you for sharing your Accel Stepper code example.

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. By using this site, you agree to our Terms of Use.