Could use some guidance with limit switches and a prox switch arduino mega

Hello,

First, I will explain what I am using to interface with my Arduino Mega 2560. I am using at the time, two NEMA 23 bipolar stepper motors, a spark fun quadstepper motor controller, two DFROBOT crash sensors, as well as one DFROBOT mag sensor (proximity switch). I am currently powering my quadstepper with a 12V DC power supply. The first link below, is what I purchased as my first attempt. It is basically a CNC router setup. I had it working, but needed a PC to control it and Mach3 CNC software. What I am looking for is a standalone device. This led me in the direction of the Arduino. I am still currently using the same power supply and the same NEMA 23 stepper motors.

http://www.ebay.com/itm/US-Ship-Free-Ship-US-4Axis-Nema-23-Stepper-Motor-290oz-in-Driver-CNC-Kit-/280912796022?pt=LH_DefaultDomain_0&hash=item4167b51976

http://www.dfrobot.com/wiki/index.php/Crash_Sensor_(SKU:_SEN0138)
http://www.dfrobot.com/wiki/index.php/Digital_magnetic_sensor_(SKU:_DFR0033)

I will try to explain in detail what it is I am trying to accomplish. I want my Arduino from the moment it awakes (from reset or powers down and powers up) to turn my stepper motor 1 CCW until it triggers my limit switch left (crash sensor). From that point I want motor 2 to rotate CCW until it sees my mag sensor (I call it a prox switch). It will do this continuously about 20 times. Every time it reads my prox switch, I would like it to delay for 5 minutes (just an example). Once it reaches the 20th I/O device for my prox switch. I want motor 1 to rotate CCW and perform the same action all in one loop. So, to wrap up, I want the first action with the limit switch to act at power up only (1 time). Then I want to bounce back and forth, 20 times each way, with a constant loop stopping in intervals. Basically the two limit switches are in place, only if my prox switch fails. When and If the Program doesn't see the prox switch as being open or closed, then motors (1 or 2) will rotate until they trigger the limits and stop indefinitely. I hope I have added enough info to further help.
Thank You,
U_R

Sorry,
I didn't post any code. I have been tinkering around with this code some. I can reset my Arduino and it rotates until I press limit switch (sensor left). When I release the switch it spins again, in the same direction. I am Uncertain what to do from here. I have tried while loop, if/else statements. I haven't tried switch case. It doesn't seem relevant to me. I do apologize, in my last post I mentioned motors 1 & 2. Here my code reads motors 2 & 4. Sorry for any confusion.
Thank You,
U_R

// include the motor library
#include <quadstep.h>

// create an instance of the class motor
quadstep motor2;
quadstep motor4;

// These constants won't change:
  const int switchPin1 = 3;       // pin that the limit switch is attached to for motor 2
  const int switchPin2 = 12;       // pin that the limit switch is attached to for motor 4
  const int magPin = 8;       // pin that the mag sensor is attached to for positioning 
  const int enablePin = 7;       // pin that motor2 is attached to
  
  // These variables will change:
  int sensorLeft = 1;      // left sensor value
  int sensorRight = 1;     // right sensor value
  int sensorMag = 1;        // mag sensor value
  int sensorValue = 0;         // the sensor value

void setup() {
  
  // assign the pin connections for my motors
  
  motor2.set_enable_pin(7);
  motor2.set_direction_pin(6);
  motor2.set_step_pin(5);
  motor2.set_microstep_select_pins(A0,A1,A2);
    
  motor4.set_enable_pin(4);
  motor4.set_direction_pin(27);
  motor4.set_step_pin(11);
  motor4.set_microstep_select_pins(A0,A1,A2);
    
 // set the mag pin and the switch pins as inputs:
  
    pinMode (switchPin1, INPUT);
    pinMode (switchPin3, INPUT);
    pinMode (magPin2, INPUT);
    pinMode (enablePin, OUTPUT);
    
  
 }
 
 void loop()
 {
  if (digitalRead(switchPin1) == LOW) {     
  digitalWrite(enablePin, LOW);            
  }
  // step motor 2 for -2000 increments CCW
  
   else if (digitalRead(switchPin1) == HIGH) {    // check if the input is HIGH
    motor2.go(FULL,-2000,10);                     // turn motor2 CCW
   }  
    else {
    digitalWrite(magPin, HIGH);             // check if magPin is ON
    motor4.go(FULL,-2000,10);            // turn motor 4 CCW
    motor4.stall();                   //Stop motor 4           
    delay(1500);                    //delay(1500)
  }
 }

Unhinged_Reprisal:
I want my Arduino from the moment it awakes (from reset or powers down and powers up) to turn my stepper motor 1 CCW until it triggers my limit switch left (crash sensor). From that point I want motor 2 to rotate CCW until it sees my mag sensor (I call it a prox switch). It will do this continuously about 20 times. Every time it reads my prox switch, I would like it to delay for 5 minutes (just an example). Once it reaches the 20th I/O device for my prox switch. I want motor 1 to rotate CCW and perform the same action all in one loop. So, to wrap up, I want the first action with the limit switch to act at power up only (1 time). Then I want to bounce back and forth, 20 times each way, with a constant loop stopping in intervals. Basically the two limit switches are in place, only if my prox switch fails. When and If the Program doesn't see the prox switch as being open or closed, then motors (1 or 2) will rotate until they trigger the limits and stop indefinitely. I hope I have added enough info to further help.

Can you clarify the bit in red? I'm not sure whether this is trying to recap what you wrote previously, or describing some additional actions you want to follow.

Once it reaches the 20th I/O device for my prox switch. I want motor 1 to rotate CCW and perform the same action all in one loop.

I'm sorry, I do see your point. After motor 2, rotates CCW and reads the proximity switch 20 times, I want Motor 1 to rotate CCW and read the proximity switch 19 to 20 times. I do see where it seems I have 20 I/O devices. Sorry

Hello,
I will try to make my post more simple than before. I hope I am posting in the correct place. If not Please let me know...

(Run Once) from power off to power on state
1)Rotate motor 2 CCW continuously until
2)Trigger switch left (crash sensor)
3)Delay 3 sec

(Run Loop)
4)Rotate motor 4 CCW until
5)Trigger prox switch (magnetic sensor)
6)Delay 5 minutes
7)Repeat 4),5),& 6) 20 times
8)Rotate motor 2 CCW until
9)Trigger prox switch (magnetic sensor)
10)Delay 5 minutes
11)Repeat 8),9),& 10) 20 times

(Fail Safety)
If either motor 2 or motor 4 is rotating when the prox switch (mag sensor) fails,
I would want motor 2 to rotate to switch left (crash sensor1) and delay indefinitely
I would want motor 4 to rotate to switch right (crash sensor2) and delay indefinably

Thank You,
U_R

Here is some code I have been unsuccessful with.....
I am also going to leave a link to the quadstep.h library I am using from GitHub

#include <quadstep.h>

// create an instance of the class motor
quadstep motor2;
quadstep motor4;

// These constants won't change:
  const int switchPin1 = 3;       // pin that the limit switch is attached to for motor 2
  const int switchPin2 = 12;       // pin that the limit switch is attached to for motor 4
  const int magPin = 8;       // pin that the mag sensor is attached to for positioning 
  const int enablePin = 7;       // pin that motor2 is attached to
    
  
  // These variables will change:
  int sensorLeft = 1;      // left sensor value
  int sensorRight = 1;     // right sensor value
  int sensorMag = 1;        // mag sensor value
  int sensorValue = 0;         // the sensor value
  int i = 90000;
  int j = 0;

void setup() {
  
  // assign the pin connections for my motors
  
  motor2.set_enable_pin(7);
  motor2.set_direction_pin(6);
  motor2.set_step_pin(5);
  motor2.set_microstep_select_pins(A0,A1,A2);
    
  motor4.set_enable_pin(4);
  motor4.set_direction_pin(27);
  motor4.set_step_pin(11);
  motor4.set_microstep_select_pins(A0,A1,A2);
    
 // set the mag pin and the switch pins as inputs:
  
    pinMode (switchPin1, INPUT);
    pinMode (switchPin2, INPUT);
    pinMode (magPin, INPUT);
    pinMode (enablePin, OUTPUT);
    
  // create at start up command procedure to run once
  // i was thinking I could run this from void set up to run once
   
   for (int i = 90000; i > 0; i--);                    // Amount of maximum space i can travel 
   motor2.go(FULL, -i, 10);                        // Rotate motor 2 CCW from anywhere power is lost   
   if (digitalRead (switchPin1) == LOW); {     // When I trigger switch left it should read low
   delay (3000);                                      // Delay for 3 sec
   }                                                     // Here it will not exit void setup into void loop
  }   
  
 void loop() {

//at this point switch left will read low and mag pin will be high
//so it should skip the while statement and loop back to it when the statement is true at the end of code 
//also I am testing only motor 2 in this sketch for simplicity at this time
 
 for (int x = 0; x < 20; x++);                         //repeat 20 times 
 while (digitalRead (magPin) == LOW){           //read prox switch low when interrupted
 motor2.stall ();                                        //stop motor
 delay (300000);                                       //delay 5 min
 {
 for (int j = 0; j < 90000; j--);                     //amount of maximum space i can travel
 }
 for (int x = 20; x > 0; x--);                         //repeat 20 times 
 if (digitalRead (magPin) == HIGH){               //prox switch pin is high until triggered
 motor2.go(FULL, -j, 10);                         //rotate motor CCW until prox switch is triggered
 }
 else {
 sensorValue = digitalRead (magPin);          //read current value of prox switch should be low 
 delay (300000);                                    //delay for 5 minutes
   }
  }
 }

11)Repeat smiley-cool,9),& 10) 20 times

Should read
11)Repeat 8),9), & 10) 20 times.....
I don't know where the cool dude smiley came from
OOPS!

11)Repeat 8,9,&10!!!!!!!!!

  int i = 90000;

Yeah, right. Reading up on the range of values that can be stored in different types of variables would be a first step.

  motor2.set_microstep_select_pins(A0,A1,A2);
  motor4.set_microstep_select_pins(A0,A1,A2);

How can both motors use the same set of pins?

   for (int i = 90000; i > 0; i--);                    // Amount of maximum space i can travel

See comment above.

   if (digitalRead (switchPin1) == LOW); {     // When I trigger switch left it should read low

The ; at the end forms the body of the if statement. It's a noop (no operation/do nothing) statement. So, if the switch is pressed, do nothing. If the switch is not pressed, do nothing. What's the purpose of reading the switch state?

 delay (300000);                                       //delay 5 min

Literal constants are treated as ints. 300000 is not a valid value for an int. You need UL on the end of the constant, to tell the compiler to treat the value as an unsigned long, instead.

I'm sure that there are other issues. This was as far as I read.

Paul,
I wish I had 1/16 of the knowledge you obtain. How about this for test purposes?

(edits)

  1. I am only really using A1 & A2 for motors 2 & 4
  2. I changed 300000 to 3000
  3. i changed rotation from 90000 900

I don't mind criticism. Please read on, I really want to know what I am doing wrong.
My father once said told me. "If you don't learn something new every day, then you are wasting your time"
Thank You,
U_R

As well sir, could you elaborate a little to what you mean here

What's the purpose of reading the switch state?

int i = 900;
int j = 0;

void setup() {
  
  // assign the pin connections for my motors
  
  motor2.set_microstep_select_pins(A1);
    
  motor4.set_microstep_select_pins(A2);
    
 // set the mag pin and the switch pins as inputs:
  
    pinMode (switchPin1, INPUT);
    pinMode (switchPin2, INPUT);
    pinMode (magPin, INPUT);
    pinMode (enablePin, OUTPUT);
    
  // create at start up command procedure to run once
  // i was thinking I could run this from void set up to run once
   
   for (int i = 900; i > 0; i--);                    // Amount of maximum space i can travel changed from 90000 
   motor2.go(FULL, -i, 10);                        // Rotate motor 2 CCW from anywhere power is lost   
   if (digitalRead (switchPin1) == LOW) {  // When I trigger switch left it should read low removed semicolon
   delay (3000);                                      // Delay for 3 sec
   }                                                     // Here it will not exit void setup into void loop
  }   
  
 void loop() {

//at this point switch left will read low and mag pin will be high
//so it should skip the while statement and loop back to it when the statement is true at the end of code 
//also I am testing only motor 2 in this sketch for simplicity at this time
 
 for (int x = 0; x < 20; x++);                         //repeat 20 times 
 while (digitalRead (magPin) == LOW){           //read prox switch low when interrupted
 motor2.stall ();                                        //stop motor
 delay (3000);                                       //delay 5 min
 {
 for (int j = 0; j < 900; j--);                     //amount of maximum space i can travel
 }
 for (int x = 20; x > 0; x--);                         //repeat 20 times 
 if (digitalRead (magPin) == HIGH){               //prox switch pin is high until triggered
 motor2.go(FULL, -j, 10);                         //rotate motor CCW until prox switch is triggered
 }
 else {
 sensorValue = digitalRead (magPin);          //read current value of prox switch should be low 
 delay (3000);                                    //delay for 3 sec changed from 5 min
   }
  }
 }
 for (int x = 0; x < 20; x++);

Maybe that semicolon could go to the semicolon retirement home.

 for (int x = 0; x < 20; x++);                         //repeat 20 times

Same problem as with the if statement. The ; forms the body of the for loop. Do nothing twenty times. That certainly won't take long. :slight_smile:

 for (int j = 0; j < 900; j--);                     //amount of maximum space i can travel
  for (int x = 20; x > 0; x--);                         //repeat 20 times

Ditto.

 {
 for (int j = 0; j < 900; j--);                     //amount of maximum space i can travel
 }

What are the curly braces for?

Thanks Awol and Paul,
It is like a bad case of colon cancer!

It is like a bad case of colon cancer!

More like semicolon cancer.

Unhinged_Reprisal:
(Run Loop)

4)Rotate motor 4 CCW until

5)Trigger prox switch (magnetic sensor)
6)Delay 5 minutes
7)Repeat 4),5),& 6) 20 times

Is something else supposed to happen between 7 and 4? I thought you had previously stopped motor4 at the point where the proximity switch triggered; isn't motor4 still in the same position, hence the proximity switch still triggered?

More like semicolon cancer.

Good one Paul!

Is something else supposed to happen between 7 and 4? I thought you had previously stopped motor4 at the point where the proximity switch triggered; isn't motor4 still in the same position, hence the proximity switch still triggered?

Peter,
Yes, motor 4 will take it there to the prox switch. From that point motor 2 will take over and move the opposite direction. In fact, if motor 4 moves to the prox switch the first time then repeats 20 times. That would be 21 delays. When motor 2 takes over and moves it would actually be 1 move that repeats 19 delays, because motor 2 starts where motor 4 left off. If this is what you meant with the question, then you are correct....
Thank You
U_R

Hello Folks,
I am having this problem with my subroutine command not wanting to work in void loop. Could somebody further advise me to what I'm doing wrong. I can get it to work in set up, but of course it will not loop. If I take motorRight & motorLeft out of setup and place them into loop, my program does not exit setup into loop. Also, I can't get my 2nd subroutine to function at all. I must be missing something miniscule or mind is majorly malfunctioned..... Maybe a little bit of both!
Thank You,
U_R

void setup() {
  
  // assign the pin connections for my motors
  
  motor2.set_enable_pin(7);
  motor2.set_direction_pin(6);
  motor2.set_step_pin(5);
  motor2.set_microstep_select_pins(A1);
    
  motor4.set_enable_pin(4);
  motor4.set_direction_pin(27);
  motor4.set_step_pin(11);
  motor4.set_microstep_select_pins(A2);
    
 // set the mag pin and the switch pins as inputs:
  
    pinMode (swP1, INPUT);
    pinMode (swP2, INPUT);
    pinMode (mP, INPUT);
    pinMode (enablePin, OUTPUT);

   while(digitalRead(swP1)== HIGH) {
   motor2.go(FULL,-900,10);
   if(digitalRead(swP1)==LOW) { 
   goto finish;
    }  
   }
   finish:
   motor2.stall();
   delay(3000);
  motorRight();    //try code from if else program
  motorLeft();
} 
 void loop() {} 
 
 void motorRight ()
 {
    for(i=0; i<4; i++) {
    while (digitalRead(mP) == HIGH) {
    motor2.go(FULL, 2000, 10);
      
    if (digitalRead(mP) == LOW) {  
    motor2.stall();
    delay (3000);
   }  
  }
 }  
}
 void motorLeft ()
 {
    for(i=0; i>3; i--) {
    while (digitalRead(mP) == LOW) {
    motor2.go(FULL, -2000, 10);
      
    if (digitalRead(mP) == HIGH) {  
    motor2.stall();
    delay (3000);
   }
  }  
 }
}

Also, I can't get my 2nd subroutine to function at all. I must be missing something miniscule or mind is majorly malfunctioned.....

I'm voting for the latter. I've been writing code in C and C++ for almost 30 years now (it's how I make my living). !00s of thousands of lines of code, and not a single goto.

Yours is not needed, either. If the switch is low, go to a label. If it isn't, drop through to the same place. The goto is absolutely useless.

It would greatly improve the readability of your program if you put each { on a new line, and used the Tools + Auto Format menu item.

Meaningful names are important. One can't even begin to guess what mP means. Comments are important, too. We can see what the code is doing, but we have no idea what you expect it to be doing. If you have a comment like

// Run the left motor for 10 seconds

and code like

   while(millis() - then > 5000)
   {
       motorRight.go();
   }

Then we can see that there is (or is not) a discrepancy between what the comment says and what the code does.

It also helps to tell us what actually happens, along with what you expect. "It doesn't work" gives us nothing to go on.

Yes Sir,
I do apologize for my incomprehensive programming skills. I am having trouble interrupting my motor with my limit switch. The program wants to complete the revolutions before stopping the motor. Programming micro controllers is a bit different than programming CNC machinery. So please, beat me up as much as it takes to get it through my thick skull.....
Thank You,
U_R

  pinMode (swP1, INPUT);  //limit switch left over travel motor #2  
  pinMode (swP2, INPUT);  //limit switch right over travel motor #4
  pinMode (mP, INPUT);     //mag sensor (proximity) switch between motors 2 & 4
  pinMode (enablePin, OUTPUT); 

  while (digitalRead (swP1)==LOW)  //while limit switch 1 is OFF 
{
    motor2.stall();                       //motor stop
    delay(3000);                         //3 sex
    motor2.go(FULL, -900, 10);    // motor 2 rotate CCW 4-1/2 rev's 
                                              //THE MOTOR WANTS TO TURN FULL 4-1/2 REV'S BEFORE THE SWITCH STOPS IT   
    if (digitalRead (swP1)==HIGH)   //if limit switch 1 is ON
{                                              
    }
    else {
      break;
    }
  }
}
void loop()
{
  if (digitalRead(swP1) == HIGH)       //if limit switch 1 is ON
      if (digitalRead(swP1) == LOW)    //if limit switch 1 is OFF 
{       
      digitalWrite(enablePin, HIGH);          // turn motor enable pin ON
      motor2.go(FULL, 2000, 10);            //THE MOTOR WANTS TO TURN FULL 10 REV'S BEFORE THE SWITCH STOPS IT
      delay (5000);                                //5 sec's   
    }  
  if (digitalRead(swP1) == HIGH)        // check if the input is HIGH 
{    
    motor2.go(FULL, -2000, 10);       // step motor 2 CCW 10 rev's
                                                   //THE MOTOR WANTS TO TURN FULL 10 REV'S BEFORE THE SWITCH STOPS IT  
    digitalWrite(enablePin, HIGH);      // turn motor enable pin ON
    motor2.stall();                          //stop motor
    delay(3000);                             //3 sex
  }
}

Your incomplete code makes it very difficult to help.

Once this command is executed is there any way of stopping the motor before it has done 4.5 revs ?

    motor2.go(FULL, -900, 10);    // motor 2 rotate CCW 4-1/2 rev's

What do the parameters of the motor2.go function mean ? You need to move the motor a little, check the switch, stop if at the limit else move the motor a little bit more and so on until the limit is reached or you have moved the complete distance.

Another question for you. What should happen when swP1 is HIGH ?

    if (digitalRead (swP1)==HIGH)   //if limit switch 1 is ON
{                                              
    }

At the moment your code does everything between { and } above. Is that right ?