Code for optical switch and stepper motor

I'm trying to integrated the code for stepper motor and optical switch. Now the problem is that the motor only loops around the limitswitch1 where it goes forth and back.

I want to make the motor go forward when it reaches limitswitch1 and go backward when it reaches limitswitch2.

The current code uploaded but it only loops around limitswitch1:

#include <Stepper.h>                                          //Arduino Stepper Library

const int stepsPerRevolution = 200;                           //Number of steps per revolution for your motor; 1.8 degree = 200 step per revolution

Stepper sm(stepsPerRevolution, 8, 9, 10, 11);                // initialize the stepper library on pins 8 through 11 (4 wire bipolar motor)

int stepCount = 0;                                          // number of steps the motor has taken

int limitswitch1 = 48;                                      //input switch1; pin 48
int limitswitch2 = 30;                                     //input switch2; pin 30
int LEDPin = 13;                                            // output,indicator; pin 13


void setup() 
{          
  Serial1.begin (9600);                                     // initialise serial port at 9600 baud rate
  Serial2.begin (9600);     
  pinMode(LEDPin, OUTPUT);                                  //output indicator for limitswitches
  pinMode(limitswitch1, INPUT);                             //input sense for limitswitch1
  pinMode(limitswitch2, INPUT);                             //input sense for limitswitch2
         
}


void loop() 
{
  int speedKnob = analogRead(A15);                           //potentiometer; pin A15
  int motorSpeed = map(speedKnob, 0, 1023, 50, 150);         

  if (motorSpeed > 0)                                       
  {
    sm.setSpeed(motorSpeed);
    sm.step(1);                                             // step one step
  }

  if (digitalRead(limitswitch1) == LOW)                     //limitswitch1 read 0V; blocked
  {
    digitalWrite(LEDPin, HIGH);                             //Turn ON LED
    Serial1.println("Stepper Motor:Anti-Clockwise");        // step one revolution in anti-clockwise
    sm.step(-stepsPerRevolution);                           //turn anti-clockwise
  }      
  else if (digitalRead(limitswitch2) == LOW)                 //limitswitch1 read 0V
  {
     digitalWrite(LEDPin, HIGH);                           //Turn ON LED
     Serial2.println("Stepper Motor:Clockwise");           // step one revolution in clockwise
     sm.step(stepsPerRevolution);                          //turn clockwise

  }  
  return;
}

I think you need a variable to record the required direction and when the limit switch is triggered it changes that variable. Call it stepDirection and give it a value 1 or -1 as appropriate

Then just use only the lines at the top of the code to do the movement

 if (motorSpeed > 0)                                       
  {
    sm.setSpeed(motorSpeed);
    sm.step(stepDirection);           // step one step
  }

And replace

sm.step(-stepsPerRevolution);                           //turn anti-clockwise

with

stepDirection = -stepDirection;

etc.

...R

Hi, thanks for your reply. The variable stepDirection needs to be declared at int stepDirection???

I have done some adjustments and I've got it running. So now when it reaches limitswitch1 it will rotate forwards and then backward when limitswitch2 is reached.

But I would like to the motion to remain until the switches are reached. For now, the moment the switch is not blocked, the motor stops moving.

Is there any function that hold until the next condition is met? Would appreciate for any help. Thank You.

#include <Stepper.h>                                          //Arduino Stepper Library

const int stepsPerRevolution = 200;                           //Number of steps per revolution for your motor; 1.8 degree = 200 step per revolution

Stepper sm(stepsPerRevolution, 8, 9, 10, 11);                // initialize the stepper library on pins 8 through 11 (4 wire bipolar motor)

int stepCount = 0;                                          // number of steps the motor has taken
int stepDirection;

int limitswitch1 = 48;                                      //input switch1; pin 48
int limitswitch2 = 30;                                     //input switch2; pin 30
int LEDPin = 13;                                            // output,indicator; pin 1


void setup() 
{              
  pinMode(LEDPin, OUTPUT);                                  //output indicator for limitswitches
  pinMode(limitswitch1, INPUT);                             //input sense for limitswitch1
  pinMode(limitswitch2, INPUT);                             //input sense for limitswitch2
         
}


void loop() 
{
  int speedKnob = analogRead(A15);                           //potentiometer; pin A15
  int motorSpeed = map(speedKnob, 0, 1023, 50, 200);         

  if (motorSpeed > 0)                                       
  {
    sm.setSpeed(motorSpeed);
    sm.step(stepDirection);                                  // step one step
  }

  if (digitalRead(limitswitch1) == LOW)                     //limitswitch1 read 0V; blocked
  {
    digitalWrite(LEDPin, HIGH);                             //Turn ON LED
    sm.step(-stepsPerRevolution);                         //turn anti-clockwise
  }      
  else if (digitalRead(limitswitch2) == LOW)                 //limitswitch1 read 0V
  {
     digitalWrite(LEDPin, HIGH);                           //Turn ON LED
     sm.step(stepsPerRevolution);                          //turn clockwise

  }  
}

I think you are making it more complicated than it needs to be. This is the sort of thing I have in mind

void loop() {
  if (digitalRead(limitswitch1) == LOW)                     //limitswitch1 read 0V; blocked
  {
     stepDirection = - stepDirection;                         //change direction
  }     
  if (digitalRead(limitswitch2) == LOW)                 //limitswitch1 read 0V
  {
     stepDirection = - stepDirection;                       //change direction
  }
  sm.step(stepDirection); 
}

Note how the sm.step() is not inside any IF statement so it gets called at every iteration of loop().

It assumes that at the top of the program you define

int stepDirection = 1;

...R

Hi R, thanks for your help. But I would like to know the meaning of putting the stepDirection and placing it at the end of if loop. Why do you place "stepDirection = -stepDirection" in both if loops???

Right now it is moving the way it is expected. But it stops when the limitswitches are blocked. How do I code it in a way that when it blocks then the motor changes its direction???

Really appreciate your help, thanks alot.

#include <Stepper.h>                                            //Arduino Stepper Library

const int stepsPerRevolution = 200;                             //Number of steps per revolution for your motor; 1.8 degree = 200 step per revolution

Stepper sm(stepsPerRevolution, 8, 9, 10, 11);                   // initialize the stepper library on pins 8 through 11 (4 wire bipolar motor)

int stepCount = 0;                                              // number of steps the motor has taken
int stepDirection = 1;

int limitswitch1 = 48;                                          //input switch1; pin 48
int limitswitch2 = 30;                                          //input switch2; pin 30
int LEDPin = 13;                                                // output,indicator; pin 1


void setup() 
{              
  pinMode(LEDPin, OUTPUT);                                      //output indicator for limitswitches
  pinMode(limitswitch1, INPUT);                                 //input sense for limitswitch1
  pinMode(limitswitch2, INPUT);                                 //input sense for limitswitch2
         
}


void loop() 
{
  int speedKnob = analogRead(A15);                              //potentiometer; pin A15
  int motorSpeed = map(speedKnob, 0, 1023, 50, 150);         

  if (motorSpeed > 0)                                       
  {
    sm.setSpeed(motorSpeed);
  }
 
  if (digitalRead(limitswitch1) == LOW)                     //limitswitch1 read 0V; blocked
  {
     stepDirection = - stepDirection;                         //change direction
  }     
  if (digitalRead(limitswitch2) == LOW)                 //limitswitch1 read 0V
  {
     stepDirection = - stepDirection;                       //change direction
  }
  sm.step(stepDirection); 
}

solo96:
Hi R, thanks for your help. But I would like to know the meaning of putting the stepDirection and placing it at the end of if loop. Why do you place "stepDirection = -stepDirection" in both if loops???

To make it change direction. You could have a combined IF test.

Right now it is moving the way it is expected. But it stops when the limitswitches are blocked. How do I code it in a way that when it blocks then the motor changes its direction

I can't reconcile your first sentence in this piece with the other two.

What do you mean by the parts in bold.

...R

Hi R, do you mean something like this?

if (digitalRead(limitswitch1) == LOW && digitalRead(limitswitch2) == LOW)                     //limitswitch1 read 0V; blocked
  {
     stepDirection = - stepDirection;                                                         //change direction
  }     
  sm.step(stepDirection); 
}

What I'm trying to do the code to meet this function:

limitswitch1 is blocked; motor turn clockwise(forward)
limitswitch2 is blocked; motor turn anti-clockwise(backward)

Currently with R, your code:

limitswitch1 is blocked; motor stop turning; motor turn clockwise when not blocked.
limitswitch2 is blocked; motor stop turning; motor turn anti-clockwise when not blocked.

So I would like know if there is any code that needs to be added in it, or maybe another loop??? Sorry for the trouble caused.

If one step in the reverse direction does not clear the limit switch, the stepper will oscillate +/- one step at the limit switch.

If this is what is happening, you could determine how may steps it takes to clear the switch and make the first move after the switch is tripped multiple steps. When you clear the switch you can go back to the single steps.

Maybe something like this

void loop() 
{
  
 
  if (digitalRead(limitswitch1) == LOW)                     //limitswitch1 read 0V; blocked
  {
     stepDirection = - stepDirection;                         //change direction
     sm.step(stepDirection*5);                                 //use a number which clears the switch

}     
  if (digitalRead(limitswitch2) == LOW)                 //limitswitch1 read 0V
  {
     stepDirection = - stepDirection;                       //change direction
      sm.step(stepDirection*5); 
}
  

sm.step(stepDirection); 

}

solo96:
Hi R, do you mean something like this?

You are not reading carefully. You have put the

sm.step(stepDirection);

inside the IF block when I told you not to in Reply #4.

What I'm trying to do the code to meet this function:

limitswitch1 is blocked; motor turn clockwise(forward)
limitswitch2 is blocked; motor turn anti-clockwise(backward)

Currently with R, your code:

limitswitch1 is blocked; motor stop turning; motor turn clockwise when not blocked.
limitswitch2 is blocked; motor stop turning; motor turn anti-clockwise when not blocked.

I had assumed that the limit switch is just a trigger to cause the motor to change direction and move away from the switch and keep going until it reaches the other limit switch.

You seem to want the situation where the motor only moves if the switch is pressed. Is that correct? It is perfectly possible, but it is not what one would normally describe as a limit switch.

If you only want the motor to move when the switch is pressed please tell us what presses the switch.

...R

Thanks R & C for your help. A reply to R's question, there's no switch to be pressed. The optical switch is a just trigger to change the direction.

OMG, it works for this code.

void loop() 
{
 
  int speedKnob = analogRead(A15);                              //potentiometer; pin A15
  int motorSpeed = map(speedKnob, 0, 1023, 50, 150);         

  if (motorSpeed > 0)                                       
  {
    sm.setSpeed(motorSpeed);
  }
 
  if (digitalRead(limitswitch1) == LOW)                     //limitswitch1 read 0V; blocked
  {
     stepDirection = - stepDirection;                         //change direction
     delay(10000);
  }     
  if (digitalRead(limitswitch2) == LOW)                 //limitswitch1 read 0V
  {
     stepDirection = - stepDirection;                       //change direction
     delay(10000);
  }
  
  sm.step(stepDirection); 
}

Just that, there is always a long pause when it reaches the limitswitch. Is it because it is trying to read the loop??? Would it be better if I add in a delay();

solo96:
OMG, it works for this code.

That's what I expected.

Ahhh - I think my stepDirection = - stepDirection; is a little too clever. It assumes that the next step will take the motor clear away from the switch, but that is probably not true and the direction just changes over and over to no use. This is the problem of giving advice without being able to test the code.

It would be better if it was like this - then you would not need the delay()

 if (digitalRead(limitswitch1) == LOW)                     //limitswitch1 read 0V; blocked
  {
     stepDirection = 1;                         //change direction
  }     
  if (digitalRead(limitswitch2) == LOW)                 //limitswitch1 read 0V
  {
     stepDirection = -1;                       //change direction
  }

I may have the 1 and the -1 in the wrong places.

Just that, there is always a long pause when it reaches the limitswitch. Is it because it is trying to read the loop??? Would it be better if I add in a delay();

In my universe adding delay()s makes pauses longer - but maybe your universe is different.

...R

void loop()
{

int speedKnob = analogRead(A15); //potentiometer; pin A15
int motorSpeed = map(speedKnob, 0, 1023, 50, 150);

if (motorSpeed > 0)
{
sm.setSpeed(motorSpeed);
}

if (digitalRead(limitswitch1) == LOW) //limitswitch1 read 0V; blocked
{
stepDirection = - stepDirection; //change direction
delay(10000);
}
if (digitalRead(limitswitch2) == LOW) //limitswitch1 read 0V
{
stepDirection = - stepDirection; //change direction
delay(10000);
}

sm.step(stepDirection);
}

I guess this code works perfectly fine. It fulfills the function I've been wanting to achieve.

However, it sometimes is not able to read anything and thus, the limit switch will stay blocked.

Why does this happens?? Or maybe I should understand how arduino code is looping???

solo96:
I guess this code works perfectly fine. It fulfills the function I've been wanting to achieve.

Why have you stopped using code tags ?

Did you read Reply #12 ?

...R