On/Off/On switch and Stepper Motor

Hello there,

I wanted to be able to control the direction in which the stepper motor moves using an On/Off/On switch.

For example, switch1 goes right, switch2 goes left, and the middle switch causes it to stop. The code works about 80% of the time, however, there are times when despite changing the direction with the switch, the stepper motor keeps moving in its previous direction (the wrong direction).
For example, going from switch1 to switch2 causes the motor to keep going right, even though it should go from right to left. Also, it does stop for a millisecond as it passes over the middle switch during the switch change. Is this a hardware issue or a coding issue? Here is the code and appreciate any help!

`#include <Stepper.h>

const int stepsPerRevolution = 200;
const float leadScrewPitch = 2.0;
const int switch1 = 6;
const int switch2 = 5;
const int limit1 = 7;
const int limit2 = 10;

#define pwmA 3
#define pwmB 11
#define brakeA 9
#define brakeB 8
#define dirA 12
#define dirB 13

Stepper myStepper = Stepper(stepsPerRevolution, dirA, dirB);

void setup() {

 pinMode(pwmA, OUTPUT);
  pinMode(pwmB, OUTPUT);
  pinMode(brakeA, OUTPUT);
  pinMode(brakeB, OUTPUT);
  pinMode(dirA, OUTPUT);
  pinMode(dirB, OUTPUT);

  pinMode(limit1, INPUT_PULLUP);
  pinMode(limit2, INPUT_PULLUP);
  pinMode(switch1, INPUT_PULLUP);
  pinMode(switch2, INPUT_PULLUP);

  Serial.begin(9600);
}

void loop() {
  int state1 = digitalRead(switch1);
  int state2 = digitalRead(switch2);
  int limitState1 = digitalRead(limit1);
  int limitState2 = digitalRead(limit2);
  int direction = 0;

  if (state1 == HIGH && state2 == LOW) {
    direction = 1;
  } else if (state1 == LOW && state2 == HIGH) {
    direction = -1;
  }

  float speed_mm_per_sec = 5.0;
  int steps_per_sec = speed_mm_per_sec * 100.0 / leadScrewPitch;

  if (direction == 1 && limitState1 == LOW) {
    analogWrite(pwmA, 255);
    analogWrite(pwmB, 255);
    digitalWrite(brakeA, LOW);
    digitalWrite(brakeB, LOW);
    myStepper.setSpeed(steps_per_sec);
    myStepper.step(direction * stepsPerRevolution);
  } else if (direction == -1 && limitState2 == LOW) {
    analogWrite(pwmA, 255);
    analogWrite(pwmB, 255);
    digitalWrite(brakeA, LOW);
    digitalWrite(brakeB, LOW);
    myStepper.setSpeed(steps_per_sec);
    myStepper.step(direction * stepsPerRevolution);
  }

  // Stop the motor if either limit switch is pressed
  if (limitState1 == HIGH || limitState2 == HIGH) {
    analogWrite(pwmA, 0);
    analogWrite(pwmB, 0);
    digitalWrite(brakeA, HIGH);
    digitalWrite(brakeB, HIGH);
  }
}`

Your other topic on the same subject deleted.

Please do not duplicate your questions as doing so wastes the time and effort of the volunteers trying to help you as they are then answering the same thing in different places.

Please create one topic only for your question and choose the forum category carefully. If you have multiple questions about the same project then please ask your questions in the one topic as the answers to one question provide useful context for the others, and also you won’t have to keep explaining your project repeatedly.

Repeated duplicate posting could result in a temporary or permanent ban from the forum.

Could you take a few moments to Learn How To Use The Forum

It will help you get the best out of the forum in the future.

Thank you.

Why are you using

analogWrite(pwmA, 255);
analogWrite(pwmB, 255);
digitalWrite(brakeA, LOW);
digitalWrite(brakeB, LOW);

if you are using the stepper library? Look at the stepper library examples in your Arduino IDE, there is no need to use analogWrite, digitalWrite as the library has built in functions, don't make things more complicated than is necessary, just use myStepper.step function, take out anything that's not needed to get it working then add more to your code once the basics work.

Also, why are you using two switches, why not use one switch to control the direction, keep it simple first then add to it once it's working?

Sure I will try that once again. Might resolve the issue.

It is one three-position switch. We want to control the direction with one switch if possible. Apologies if it was not clear.

I'd add a third clause to set direction=0 when the switch is in the center/off position. Otherwise, your direction global state variable will remember only the last end position.

I also suggest testing the three-position switch by itself at first in the serial monitor, print the button state (Serial.println in serial monitor ) when it is changed to check whether each state is acknowledged correctly by your Arduino.

1 Like

That's a good way to diagnose.

The problem as stated is

Since this is the code that keeps things moving:

... another good test would be to print out "direction" and the limit states and see if they are behaving as expected.

Do you have a single Toggle Switch (SP3T, On-Off-On) and you want it to control the stepper motor like this?
image

If so, the Toggle Library can offer these functions for your switch:

The switch functions when using 2 input pins:

isUP();
isMID();
isDN();
UPtoMID();
MIDtoDN();
DNtoMID();
MIDtoUP();

The switch has 3 positions referred to as UP, MID (center) and DN (down). The first 3 functions will continuously return true if the switch is at that position. The last 4 functions return true (once only) if the switch has just transitioned to that position.

I just tried it and unfortunately it didn't work

What didn't work?

If you've changed your code,

Did you add a line like?

Serial.print("Dir:"); Serial.println(direction);

If direction is not behaving as expected, then something unexpected must be happening where it is supposed to be set.

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