Hi guys,
Its been a long few days as I've been trying to solve the following problem. I have a setup with an arm thats rotating a total of 90 degrees in the horizontal plane around the Z axis. The rotation is achieved with a stepper motor that has an incremental encoder attached to its shaft. Also, on the left and the right side of the arm, i have limit switches to home the arm.
I found a code for reading out the encoder using interrupts, which works perfectly fine. Then I created a homing function with the limit switches. I'm encountering the following problems:
- arm moves to the first limit switch, changes direction and moves to the second limit switch, then goes all the way back to the first limit switch. This keeps repeating. After it hitting the second limit switch, i want the arm to stand still in the middle at 45 degrees, but it just keeps moving.
- I cannot put the function homing () in the void setup(). Thid would be much better because then it would home directly at startup, but if I put it in the setup, the encoder reading function doesn't work anymore. I get the error isr_2 not defined.
So, my main question is: how can I get the motor to stop rotating after homing?
See code below and thanks in advance!
//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; //microstepping incl
boolean motorMayMoveFwd = LOW;
boolean motorMayMoveFwd2 = LOW;
//limit switch 1
#define limitSwitch1 4 // limit switch 1
boolean switchState1 = LOW; // switch state
boolean prevSwitchState1 = LOW; // previous switch state
boolean leftHomingDone = false;
//limit switch 2
#define limitSwitch2 10 // limit switch 2
boolean switchState2 = LOW; // switch state
boolean prevSwitchState2 = LOW; // previous switch state
boolean rightHomingDone = true;
//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 (limitSwitch2, 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(counter);
flag = false;
}
homing();
}
//Interrupts for encoder
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
}
}
}
//homing of the arm
void homing() {
/////limit switch 1////
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 CCW
// 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);
}
switchState1 = digitalRead(limitSwitch1); //read out switch
if (switchState1 == LOW && prevSwitchState1 == HIGH) { //if switch is activated
// var_degrees = -45;
counter = 0;
Serial.print(counter);
switchState1 = prevSwitchState1;
motorMayMoveFwd = false; //motor may not move
}
if (motorMayMoveFwd == false) {
digitalWrite(dirPin, LOW);// CW
// 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);
leftHomingDone = true;
}
/////Limit switch 2/////
prevSwitchState2 != switchState2;
switchState2 = digitalRead(limitSwitch2); //read out switch
if (switchState2 == LOW && prevSwitchState2 == LOW) { //if switch is activated
//var_degrees = 45;
counter = 1024; //=90 graden in cpr
// Serial.println("pressed");
switchState2 = prevSwitchState2;
motorMayMoveFwd2 = false;
motorMayMoveFwd = true;
if (motorMayMoveFwd2 == false) {
digitalWrite(dirPin, HIGH);// CW
// 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);
rightHomingDone = true;
if (rightHomingDone == true) {
digitalWrite(dirPin, LOW);// CW
// 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);
if (counter == 512) { //tried getting it to the middle, doesn't work
digitalWrite(stepPin, LOW);
}
}
}
}
}