Stepper Motor with 2 Momentary Switches and 2 Limit Switches, limit switch code?

Hi everyone,

Summary:
I have a stepper motor with 2 momentary switches, and 2 limit switches.

I’m try to accomplish:
Stepper Motor rotate in one direct when a momentary switch is pressed, go indefinitely.
Hit a limit switch and stop (possibly backup enough to disengage the switch if necessary).

That’s it. One button and one limit switch for each direction.

The setup is turning a lead screw and traveling about 8 feet (if it matters).

The Hardware:
NEMA 24 Stepper (8-wire, setup for Bipolar Parallel)
Stepperonline Digital Driver - DM556T
Stepperonline S-400-36 AC/DC Power Unit

Arduino UNO V3

My Problem:
I’m totally new to programming and am have a hard time wrapping my head around the limit switch conditional logic.
Do I need a do( ) While( ) variable or if ( ) else ( )?
Boolean?
Should I utilize the enable pin on the motor driver for the limit switches?

Currently I have both momentary switches working correctly, but no love on the limit switches.

I’ve had everything working independently, but when it comes together it breaks :(
Any push in the right direction would be great.
Also, not opposed to using a library. AccelStepper? ezButton for debouncing?

Paul

#define stp 9 //Stepper Motor Pulse Pin 9
#define dir 8 //Stepper Motor Direction Pin 8
#define MS4 4 //Momentary Button Pin 4
#define MS5 5 //Momentary Button Pin 5
#define MS6 6 //Limit Switch Top 6
#define MS7 7 //Limit Switch Bottom 7

const int button4Pin = 4; //unchanging pin assignment
const int button5Pin = 5; //unchanging pin assignment
const int button6Pin = 6; //unchanging pin assignment
const int button7Pin = 7; //unchanging pin assignment

int button4State = 0; //initial pin state assignment
int button5State = 0; //initial pin state assignment
int button6State = 0; //initial pin state assignment
int button7State = 0; //initial pin state assignment

char user_input;
int x; //motor variable values
int state;

void setup() {
pinMode(button4Pin, INPUT); //assign pin 4 as an input pin
pinMode(button5Pin, INPUT); //assign pin 5 as an input pin

pinMode(stp, OUTPUT); //assign stepper pin 9 pul as output
pinMode(dir, OUTPUT); //assign stepper pin 8 dir as output
pinMode(MS4, OUTPUT); //assign stepper pin 4 momentary switch as output
pinMode(MS5, OUTPUT); //assign stepper pin 5 momentary switch as output
pinMode(MS6, OUTPUT); //assign stepper pin 6 limit switch as output
pinMode(MS7, OUTPUT); //assign stepper pin 9 limit switch as output
resetEDPins(); //resets pin states back to initial 0 state
}

void loop() {
button4State = digitalRead(button4Pin); //reads variable state of button 4
button5State = digitalRead(button5Pin); //reads variable state of button 5
button6State = digitalRead(button6Pin); //reads variable state of button 6
button7State = digitalRead(button7Pin); //reads variable state of button 7

if (button4State == HIGH) { //conditional value of button 4
StepForward();
resetEDPins();
delay(1000);
}
if (button5State == HIGH) { //conditional value of button 5
StepBack();
resetEDPins();
delay(1000);
}
if (button6State == LOW){ //conditional value of button 6
resetEDPins();
delay(1000);
}
if (button7State == LOW){ //conditional value of button 7
resetEDPins();
delay(1000);
}
else {
}
}

void resetEDPins() //resets pin to initial 0 state
{
digitalWrite(stp, LOW); //reads variable state of button 9
digitalWrite(dir, LOW); //reads variable state of button 8
digitalWrite(MS4, LOW); //reads variable state of button 4
digitalWrite(MS5, LOW); //reads variable state of button 5
digitalWrite(MS6, LOW); //reads variable state of button 6
digitalWrite(MS7, LOW); //reads variable state of button 7

}

void StepForward()
{
digitalWrite(dir, LOW); //pin 8, CW

for(x= 1; x<10000; x++) //motor rev variables
{
digitalWrite(stp,HIGH); //pin 9, HIGH
delayMicroseconds(200); //pulse time, delay
digitalWrite(stp,LOW); //pin 8, False
delayMicroseconds(200); //pulse time, delay
}
}

void StepBack()
{
digitalWrite(dir, HIGH); //pin 8, CCW
for(x= 1; x<10000; x++) //motor rev variables
{
digitalWrite(stp,HIGH); //pin 9, True
delayMicroseconds(200); //pulse time, delay
digitalWrite(stp,LOW); //pin 8, False
delayMicroseconds(200); //pulse time, delay
}

}

You’re doing some real strange stuff with your pin assignments.

At the top you define a constant and give it the name MS4 and assign it the value of 4 which matches up a momentary button pin. Then you create variable called button4Pin and also assign it to pin 4. Then you set pin 4 as a input immediately followed by setting it to an output. Do yourself a favour and assign sensible names to all of the pins e.g. switchLimitTop instead of MS7. It makes the code much easier for us and you to understand. Also why are you setting limit switches as outputs when switches are inputs?

As for adding the limit switch code, I’d go with a WHILE loop. It will allow the motor to run up until the limit switch closes, then stop. Having it automatically back off the limit switch usually isn’t a good idea because the motor will jitter backwards and forwards as long as the user holds the up button. You can’t use the enable pin because that would prevent the motor moving at all as soon as the limit switch activates.

void StepForward()
{
  while (MS6 != LOW)     //stop moving the motor when the limit switch goes low
  {
	  digitalWrite(dir, LOW); //pin 8, CW
  
		for(x= 1; x<10000; x++)         //motor rev variables 
		{
					digitalWrite(stp,HIGH);         //pin 9, HIGH
					delayMicroseconds(200);     //pulse time, delay
					digitalWrite(stp,LOW);          //pin 8, False
					delayMicroseconds(200);     //pulse time, delay
			}
	}
}

Also bear in mind the code you’ve got there tells the motor to move one step then wait for 200+200 microseconds, and do that 10,000 times before checking to see if the button is still pressed. It would be more sensible to have it move only a few steps then check the button again before moving again.

my understanding is you have two buttons that can be pressed to move a motor in each direction and a limit switch intended to prevent moving in each direction.

the simple logic for each case (i.e. direction) is to prevent further movement if the limit switch is active. for example (where LOW is active)

if (LOW == butCw && HIGH == limitCw)

i don't understand why you configure the limit switches as OUTPUTs. And it's common to configure a switch input with a pull-up (INPUT_PULLUP) and wire the switch between ground and the input so that it pulls the input LOW when pressed. the same can be true for the limit switch.

looks like you have two definitions for buttons 4-7: MS4-MS7 and button4Pin - button7Pin. you first configure button4/5Pin as INPUT and then MS4/5 as OUTPUT

i don't understand the purpose of resetEDPins()

also a step rate of 1 every 400 usec may be much too fast

consider

#if 0       // my hardware
enum { ON = LOW, OFF = HIGH };

# define Stp    10
# define Dir    11

# define MSF    A1
# define MSR    A2
# define LSF    A3
# define LSR    2

#else
enum { OFF = LOW, ON = HIGH };

# define Stp 9 //Stepper Motor Pulse Pin 9
# define Dir 8 //Stepper Motor Direction Pin 8

# define MSF 4 //Momentary Button Pin 4
# define MSR 5 //Momentary Button Pin 5
# define LSF 6 //Limit Switch Top 6
# define LSR 7 //Limit Switch Bottom 7
#endif

// -----------------------------------------------------------------------------
void setup () {
    digitalWrite (Stp, OFF);
    digitalWrite (Dir, OFF);

    pinMode (Stp, OUTPUT);
    pinMode (Dir, OUTPUT);

    pinMode (MSF, INPUT_PULLUP);
    pinMode (MSR, INPUT_PULLUP);

    pinMode (LSF, INPUT_PULLUP);     // limit switch
    pinMode (LSR, INPUT_PULLUP);     // limit switch
}

// -----------------------------------------------------------------------------
enum { DIR_FORWARD = LOW, DIR_REVERSE = HIGH };

#define PULSE_PERIOD    500

void step (
    int   dir)
{
    digitalWrite (Dir, dir);

    digitalWrite (Stp, HIGH);
    delay        (PULSE_PERIOD/2);
    digitalWrite (Stp, LOW);
    delay        (PULSE_PERIOD/2);
}

void loop () {
    if (LOW == digitalRead (MSF) && HIGH == digitalRead (LSF))
        step (DIR_FORWARD);

    if (LOW == digitalRead (MSR) && HIGH == digitalRead (LSR))
        step (DIR_FORWARD);
}

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.