Hi I need an stepper motor to oscillate between -30deg and +30 degrees and I want it to start by the press of a button and stop at the press of the same button. I have written a code that does that below. In the set up it uses two end switches mounted each side of a arm the is attached to the motor that triggers interrupts when the motor is at -40deg and +40deg. It then center's the motor at 0deg this is seen as some type of calibrating step. After this, the user is supposed to press the start/stop button on which the arduino should start implementing the super loop. Also I want the two end switches at the beginning to be triggered on a falling edge, but when ever I change the the interrupt mode from LOW to FALLING it skips the entire calibration stage. I am using a TB6600 stepper driver to power the 4 wire stepper motor. And all three switches is end switches. Any advice?
const int stepPin = 5;
const int dirPin = 6;
const int enPin = 7;
const int pos40 = 2;
const int neg40 = 3;
const int start = 8;
volatile bool set1 = true;
bool startState = 0;
int j = 1;
int k = 1;
int x;
int counter;
const float stepper_angle = 1.8;
const int micro_step = 16;
const int gear_ratio = 30;
float angle_step;
float curr_angle;
void posFourty(){
curr_angle = 40;
j = 0;
}
void negFourty(){
curr_angle = -40;
set1 = false;
}
ISR(PCINT0_vect){
if(digitalRead(start) == LOW){
startState = !startState;
}
}
void setup() {
pinMode(stepPin,OUTPUT);
pinMode(dirPin,OUTPUT);
pinMode(enPin,OUTPUT);
pinMode(pos40,INPUT_PULLUP);
pinMode(neg40,INPUT_PULLUP);
pinMode(start, INPUT_PULLUP);
delay(50);
attachInterrupt(digitalPinToInterrupt(pos40),posFourty,LOW); //Decleration of interrupts
attachInterrupt(digitalPinToInterrupt(neg40),negFourty,LOW);
PCICR |= B00000001;
PCMSK0 |= B00000001;
digitalWrite(enPin,HIGH);
angle_step = (stepper_angle/micro_step)/gear_ratio;
curr_angle = 0.00;
Serial.begin(115200);
Serial.println("\t--- STARTING ---");
delay(500);
digitalWrite(dirPin,HIGH); // Start moving the motor clockwise
Serial.println("\t+++ Calebrating +++");
while(set1 == true){ //Start of calibration stage
if(j == 1){
digitalWrite(stepPin,LOW); //This part should run until pos40 button is pressed
delayMicroseconds(50);
digitalWrite(stepPin,HIGH);
delayMicroseconds(50);
}else {
counter ++;
digitalWrite(dirPin,LOW); //This part should run until neg40 is pressed
digitalWrite(stepPin,LOW);
delayMicroseconds(50);
digitalWrite(stepPin,HIGH);
delayMicroseconds(50);
}
}
digitalWrite(dirPin,HIGH);
int n = counter/2;
for(int x = 0; x < n; x++){
delayMicroseconds(50);
digitalWrite(stepPin,HIGH);
delayMicroseconds(50);
curr_angle = 0.00; //Motor is now in at 0deg
} //End of calibrtion stage
Serial.println("\t---Centre position---");
Serial.println("\t--- Hit start ---");
delay(1000);
}
void loop()
{
Serial.println(startState);
while(startState){
while(k == 1) {
Serial.print(startState);
for(int x = 0; x < 8000; x++){
if(startState == 0){
break;
}
Serial.print(x);
Serial.print("\t");
Serial.println(curr_angle);
digitalWrite(stepPin,LOW);
delayMicroseconds(50);
digitalWrite(stepPin,HIGH);
delayMicroseconds(50);
curr_angle += angle_step;
k = 0;
}
}
Serial.print(startState);
digitalWrite(dirPin,LOW);
for(x=0; x < 16000; x++){ //Positve rotation
if(startState == 0){
break;
}
Serial.print(x);
Serial.print("\t");
Serial.println(curr_angle);
digitalWrite(stepPin,LOW);
delayMicroseconds(50);
digitalWrite(stepPin,HIGH);
delayMicroseconds(50);
curr_angle -= angle_step;
}
Serial.print(startState);
digitalWrite(dirPin,HIGH);
for(x=0; x < 16000; x++ ){
if(startState == 0){
break;
}
Serial.print(x);
Serial.print("\t");
Serial.println(curr_angle);
digitalWrite(stepPin,LOW);
delayMicroseconds(50);
digitalWrite(stepPin,HIGH);
delayMicroseconds(50);
curr_angle += angle_step;
}
}// end of while(startState)
}// end of loop
There must be noise pick-up on the wires between the UNO and limit switches.
Try connecting a 4.7K resistor between pin 2 and 5V and also between pin 3 and 5V.
Don't use interrupts to read the state of mechanical switches/buttons. You can safely read the switch state in your calibration routine. No interrupt needed. Interruts make things complicated and produce more problems than they solve. Interrupts should only be used if a very fast reaction is needed - and fast means from the processor point of view.
Why do you need 2 limit switches when using a stepper? If you reach the first limit switch you know where the stepper is. All other positions can be computetd from there.
Thank you very much I'll give that a try but I need the two switches because the machine is mechanically set up in such a way that I am not a 100% sure at what degrees it will trigger the limit switch I only know the limit switches can be mount exactly the same distance away from 0 degrees.
I had a simillar problem where I would read false readings from the end stop buttons when the motors where running. Using isolated cables solved the problem, you could give it a try
Thanks everyone for your help, all the advice helped a lot I decided to rewrite the cod with all the new knowledge in mind and now everything works perfectly.