Limit Switch with Stepper Motor

Hello,

I must note that I am a complete beginner in the world of Arduino, thank you in advance for your patience.

For the project I am working on we require a stepper motor to lift an object up and down, easy!

So far I have got the motor (Nema 23) wired into a Adafruit Motor shield V2, the motor performs well moving the object up and down.

However I need to make the stepper motor locate its home position on start up.

To do this I hope to fit a limit switch at the top only, when the Arduino is powered the object will rise all the way to the top slowly, hit the limit switch and then lower to the lowest point, and cycle (looped) 100 up, 100 down for example.

The reason for this is if the project loses power, especially at the highest point in the cycle, the object will crush into the motor casing.

I have found forums with similar projects but are difficult to dissect for this project, with one stepper motor and one microswitch.

I also saw a resistor included with microswitch wiring, is this required?

Ideally require guidance with the following:

  • Wiring diagram for microswitch / limit switch for motorshield v2.
  • Code required for the startup sequence.

I am using the Motor Shield test sketch code:

/*
 This is a test sketch for the Adafruit assembled Motor Shield for Arduino v2
 It won't work with v1.x motor shields! Only for the v2's with built in PWM
 control

 For use with the Adafruit Motor Shield v2
 ----> http://www.adafruit.com/products/1438
*/


#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include "utility/Adafruit_MS_PWMServoDriver.h"

// Create the motor shield object with the default I2C address
Adafruit_MotorShield AFMS = Adafruit_MotorShield();
// Or, create it with a different I2C address (say for stacking)
// Adafruit_MotorShield AFMS = Adafruit_MotorShield(0x61);

// Connect a stepper motor with 200 steps per revolution (1.8 degree)
// to motor port #2 (M3 and M4)
Adafruit_StepperMotor *myMotor = AFMS.getStepper(200, 1);

ada


void setup() {
 Serial.begin(9600);           // set up Serial library at 9600 bps
 Serial.println("Stepper test!");

 AFMS.begin();  // create with the default frequency 1.6KHz
 //AFMS.begin(1000);  // OR with a different frequency, say 1KHz

 myMotor->setSpeed(15);  // 10 rpm



}


void loop() {


 Serial.println("Double coil steps");
 myMotor->step(2000, BACKWARD, DOUBLE);
 myMotor->step(2000, FORWARD, DOUBLE);


}

Project Specs:

Motor: SY57STH76-2004A Nema 23 Stepper motor
Board: Arduino/Genuino Uno & Ada Motorshield V2

Please edit your post to use code tags. See, How to use this forum.

But it's possible. Simply connect the switch between GND and a pin (like any other switch) and use the internal pull up. (Just Google to see how this all works.)

Next, just create a function that just steps the stepper and then checks if the switch is pressed. So, don't ramp it a whole lot of steps, just take is slowly. Just make a nice function of it and call it in setup(). This can be as simple as a while loop which checks the switch as a condition. (Just Google that as well :wink: )

Now it's up to you to start writing code and test it :smiley:

I use a microswitch in my stepper motor project described in my YouTube video #38 & 39 which does exactly what you describe: detecting the start position when you switch on.

That said, if I had my time again with that project I would not use a micro-switch but rather a small magnet and a Hall effect transistor (or even a reed switch, quite frankly) - in fact anything that does not need physical contact with anything on the stepper motor. I'm pretty sure I even mention this is one of the above videos but if not you've heard it here!

URL to the videos is in the footer of this post, subscribe if you feel it's worth it, but just take a look at those two videos anyway, it may solve your problem. :slight_smile:

That said, if I had my time again with that project I would not use a micro-switch but rather a small magnet and a Hall effect transistor

or, if possible in the given environment (i.e. : a metal is "in reach" at the upper end of the travel range) an inductive sensor, which I use for my CNC as limit switches.

Firstly, a huge thank you to all responses!

I would love to investigate further with magnetic or inductive sensors in the future, however I will first start with what I have.. which is a microswitch wired, NC-->GND & C-->Pin6

Thank you Ralph for your explanation within the youtube video - I followed this to wire the switch.

However I found I could not use your code example for my project, your motors are operated using .run and mine are -->step..
I have done so much googling.. and finished with this:

#include <AccelStepper.h>
#include <MultiStepper.h>
#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include "utility/Adafruit_MS_PWMServoDriver.h"

#define sensorPin 6    // Stepper microswitch sensor

const int switchPin = 6;

// variables will change:
int switchState = 0;         // variable for reading the pushbutton status

// Create the motor shield object with the default I2C address
Adafruit_MotorShield AFMS = Adafruit_MotorShield(); 
// Or, create it with a different I2C address (say for stacking)
// Adafruit_MotorShield AFMS = Adafruit_MotorShield(0x61); 

// Connect a stepper motor with 200 steps per revolution (1.8 degree)
// to motor port #2 (M3 and M4)
Adafruit_StepperMotor *myMotor = AFMS.getStepper(200, 1);


void setup() {
 Serial.begin(9600);           // set up Serial library at 9600 bps
 Serial.println("Stepper test!");

 AFMS.begin();  // create with the default frequency 1.6KHz
 //AFMS.begin(1000);  // OR with a different frequency, say 1KHz

 // initialize the switch pin as an input:
 pinMode(switchPin, INPUT_PULLUP);
 
 myMotor->setSpeed(15);  // 10 rpm


}

void loop() { 

 // read the state of the pushbutton value:
 switchState = digitalRead(switchPin);
 
 // check if the pushbutton is pressed.
 // if it is, the buttonState is HIGH:
 if (switchState == HIGH) {
   // turn Motor off:
   Serial.println("Double coil steps");
 myMotor->step(0, FORWARD, DOUBLE); 
 myMotor->step(0, BACKWARD, DOUBLE);
 } else {
   // turn Motor: on.
    Serial.println("Double coil steps");
 myMotor->step(2000, FORWARD, DOUBLE); 
 myMotor->step(2000, BACKWARD, DOUBLE);
 }




}

I am basically just trying to get the object to stop rising when it hits the top to avoid it crushing.

Currently this will only make it stop, or run again after the whole sequence is finished. However I need the switch to interrupt the loop. (Constantly checking whether the switch has been pressed.)

If possible it would perform this on start up, hit the switch and return as I was hoping for this morning.

Im afraid my skills are not that great to 'just create a function' septillion, otherwise I may not be in this forum!

Any advice on how to do so would be HUGELY appreciated!

Ideally I would like the balloon to drop a significant amount (4000 for example) after hitting and then recommence the up and down loop.

Even more ideally, if the object was rising forward and hit the switch, it would need to reverse (return backwards x steps) and if it hit the switch rising backward it would return forwards.
(or Counter Clockwise / Clockwise)

Thank you again for your patience!

As you need the reference drive just once per starting your application, why not set this in setup and then have the remaining ups and downs in the main loop?

After having found the initial position in setup() by hitting the limit switch you can go on in the main loop and count the steps going up and down as from the initial setup position on your sketch will know the position stepwise - provided for you ensure that you don't lose steps by underpowering or other disturbing events.

The stepper motor homing sequence has been around a long time. The one I saw on the wafer tool chambers at Applied Materials following a sequence like the following:

On powerup start jogging slowly in the direction of the home sensor.
When the metal flag passes through the sensor reverse direction and cut speed by 70% and jog back out , counting steps until the flag clears the sensor going the opposite direction.
When the flag clears the sensor reverse direction and again cut speed by 70% ,
moving very (steps counted)/2 and stop. The flag is halfway into the sensor (half the distance necessary to pass out the other side)