Stepper motor and limit switches

EDIT: Solved, this topic can be deleted

Hey guys,

I have an arm thats being rotated by a stepper motor for a total of 90 degrees in the horizontal plane around the Z-axis. I want to home the encoder thats on the stepper motor shaft by using two limit switches, one on 0 degrees and one on 90 degrees.

The arm should move to 0 degrees first, touch the limit switch, then reverse direction, touch the other limit switch at 90 degrees and determine the 0-90 degrees field.

So far I managed to get the motor to switch direction when it touches the limit switch at 0 degrees, but what happens is: after it lets go of the limit switch, it changes direction back again almost immediately and touches the limit switch again. This becomes an endless loop of the arm clicking on the limit switch. I haven’t been able to figure out how to adapt my code in such way that the arm only changes direction once, and then moves to the other limit switch at 90 degrees. I think I need to somehow force the value of the limit switch to stay LOW (pressed) after it touches once. However i dont know how to implement this as code.

Currently my code looks like this. I would highly appreciate if any of you guys could give me insight on how I could adapt it so that the arm goes to the limit switch at 0 degrees, then reverses direction and goes to 90 degrees.

//encoder
#define encoderPinA 2 //encoder A
#define encoderPinB 3 //encoder B
#define CPR 4096 // encoder counts/rev
volatile int counter = 0; //counter encoder steps
volatile int var_degrees = 0; // encoder output in degrees

//stepper motor
#define dirPin 8 //dir motorcontroller
#define stepPin 9 // step motorcontroller
int stepsPerRevolution = 800;
boolean motorMayMoveFwd = LOW; // motor movement allowed

//limit switch 1
#define limitSwitch1 4 // limit switch 1
boolean switchState1 = LOW; // switch state
boolean prevSwitchState1 = LOW; // previous switch state

//interrupt
volatile boolean flag; // flag for interrupts


void setup() {
  Serial.begin (115200); // baudrate serial monitor

  attachInterrupt(digitalPinToInterrupt(encoderPinA), isr_2, CHANGE); //initialize interrupt

  pinMode(stepPin, OUTPUT);
  pinMode(dirPin, OUTPUT);

  pinMode (limitSwitch1, INPUT);

  pinMode (encoderPinA, INPUT);
  pinMode (encoderPinB, INPUT);
}

void loop() {
  if (flag == true) {
    var_degrees = ((360 / 4096.00) * counter); //convert encoder steps to degrees
    Serial.println(var_degrees);
    flag = false;
  }
  homing();
}

//Interrupts

void isr_2() {
  flag = true;
  if (digitalRead(encoderPinA) == HIGH) {
    if (digitalRead(encoderPinB) == LOW) {
      counter = counter - 1; //COUNTER CLOCK WISE
    }
    else {
      counter = counter + 1; //CW
    }
  }
  else {
    if (digitalRead(encoderPinB) == LOW) {
      counter = counter + 1; //CW
    }
    else {
      counter = counter - 1 ; //CCW
    }
  }
}


void homing() {
  prevSwitchState1 = switchState1;
  switchState1 = digitalRead(limitSwitch1); //read out switch

  if (switchState1 == HIGH && prevSwitchState1 == LOW) { //if switch is not activated
    motorMayMoveFwd = true; //motor may move
  }

  if (motorMayMoveFwd == true) {
    digitalWrite(dirPin, HIGH);// Set the spinning direction clockwise:
    // Spin the stepper motor 1 revolution slowly:
    //for (int i = 0; i < stepsPerRevolution; i++) {
    // These four lines result in 1 step:
    digitalWrite(stepPin, HIGH);
    delayMicroseconds(7000);
    digitalWrite(stepPin, LOW);
    delayMicroseconds(7000);
  }

prevSwitchState1 = switchState1;
  switchState1 = digitalRead(limitSwitch1); //read out switch

  if (switchState1 == LOW && prevSwitchState1 == HIGH)
    motorMayMoveFwd = false;
    if (motorMayMoveFwd == false) {
      digitalWrite(dirPin, LOW);
      digitalWrite(stepPin, HIGH);
      delayMicroseconds(7000);
      digitalWrite(stepPin, LOW);
      delayMicroseconds(7000);

    }
  }

A state machine may be the way to go.

Hi,
Can you post your working code please.
In the spirit of the help given in this forum, your solution may help someone with a similar problem.
A copy of your working code and any hardware changes will help complete this thread.

Thanks... Tom... :slight_smile:

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