CNC shield - using end stops question

My pinball table with a moveable scoreboard (moves closer for landscape mame gaming) is finally nearing completion but I’m now stuck with programming the arduino

basically pressing as button moves the screen up and down perfectly as required. It reaches the endstop and stops as expected. However, with the switch engaged, it wont move when pressing the button again unless the endstop switch is disengaged. So how do engage the switch to stop and then continue in the code if it wont do anything unless I manually move the screen to open the switch???

components used :

Cnc shield
https://www.aliexpress.com/item/New...32730411128.html?spm=a2g0s.9042311.0.0.3D1pA0

Endstop

https://www.aliexpress.com/item/3D-...32697274474.html?spm=a2g0s.9042311.0.0.3D1pA0

Code :

#include <EdgeDebounceLite.h> //Use EdgeDebounceLite to debounce the pin

EdgeDebounceLite debounce; //Name it debounce

enum MoveMachineStates {WAIT, MOVE_UP, MOVE_DOWN}; //The 3 possible states of the Vending state machine

MoveMachineStates vmState = WAIT; //Start state is WAIT

enum SwitchStates {IS_OPEN, IS_RISING, IS_CLOSED, IS_FALLING}; //The four possible states of the Switch state machine

SwitchStates switchState[2] = {IS_OPEN, IS_OPEN}; //Both switch’s states are IS_OPEN

byte switchPin[2] = {10, 11}; //Switches are on pins 10 and 11

enum SwitchModes {PULLUP, PULLDOWN}; //The two possible modes for the switches

SwitchModes switchMode[2] = {PULLUP, PULLUP}; //Both switches are in PULLUP mode

byte ledPin[2] = {2, 3}; //LEDs are on pins 3 and 2

void movingScreen() { //The moving screen state machine

switch (vmState) { //Depending on the state

case WAIT: { if (upPressed()) vmState = MOVE_UP;

if (downPressed()) vmState = MOVE_DOWN; break; }

case MOVE_UP: { movingUp(); vmState = WAIT; break; }

case MOVE_DOWN: { movingDown(); vmState = WAIT; break; }

}

}

void switchMachine(byte i) { //The Switch state machine

byte pinIs = debounce.pin(switchPin); //<<<<<Replace digitalRead() with debounce.pin()

if (switchMode == PULLUP) pinIs = !pinIs; //Reverse the value read if the switch is in PULLUP mode

switch (switchState) { //Depending of the state

case IS_OPEN: { //State is IS_OPEN

if(pinIs == HIGH) //If the pin is HIGH

switchState = IS_RISING; //We just changed form LOW to HIGH: State is now IS_RISING

break; //Get out of switch

}

case IS_RISING: { //State is IS_RISING

switchState = IS_CLOSED; //It is not rising anymore, State is now IS_CLOSED

break; //Get out of switch

}

case IS_CLOSED: { //State is IS_CLOSED

if(pinIs == LOW) //If the pin is LOW

switchState = IS_FALLING; //We just changed form HIGH to LOW: State is now IS_FALLING

break; //Get out of switch

}

case IS_FALLING: { //State is IS_FALLING

switchState = IS_OPEN; //It is not falling anymore, State is now IS_OPEN

break; //Get out of switch

}

}

}

bool upPressed() { //Find out if up button has been pressed

switchMachine(0); //Read switch 0

if (switchState[0] == IS_FALLING) //If it is in the state IS_FALLING

return true; //Up has been pressed, return true

else //If not

return false; //return false

}

bool downPressed() { //Find out if down button has been pressed

switchMachine(1); //Read switch 1

if (switchState[1] == IS_FALLING) //If it is in the state IS_FALLING

return true; //Down has been pressed, return true

else //If not

return false; //return false

}

void blinkLed(byte i) { //A function to blink an LED with ID i

digitalWrite(ledPin, HIGH); //Bring pin of LED i HIGH

delay(50); //Wait there for 50 milliseconds so we can see it blink

digitalWrite(ledPin, LOW); //Bring pin of LED i LOW

}

void movingUp() { //Simulate moving up

blinkLed(0); //Blink the first LED

}

void movingDown() { //Simulate moving down

blinkLed(1); //Blink second LED

}

void setup() {

for (int i = 0 ; i < 2 ; i++) //For each switch

pinMode(switchPin, INPUT_PULLUP); //Their modes are INPUT_PULLUP

for (int i = 0 ; i < 2 ; i++) { //For aech LED

pinMode(ledPin, OUTPUT); //Their mode is OUTPUT

digitalWrite(ledPin, LOW); //They start LOW as we said on line 18

}

}

void loop() {

movingScreen();

}

As part if the program that moves the display, when you move to the end stop and sense the switch closure, move back just enough to disengage the switch so that it is no longer closed. That is called pull back or pull off and is common in CNC machines.

Your improperly posted code is hard to read without indents and all of the unnecessary white space so I won't even try. Pleas read the "how to use this forum-please read" stickies to see how to post code properly.

You can easily auto indent your code with CTRL-T (Win) or Tools, Auto Format.

Another way to avoid being a prisoner of the pressed switch is just to respond to the switch when it changes from not-pressed to pressed.

...R

A third way to not get stuck is to only check the limit switch you are moving TOWARD. That allows you to move AWAY from a limit switch that is triggered.

Thanks all for the suggestions, but for some reason the end stops are behaving like an E-stop and totally over riding the code? I dont even have checks in the code - it just stops due to the switch. Is there a command to override the end stop and then move it back 1/2 a turn once the switch is triggered?

#include <EdgeDebounceLite.h>    //Use EdgeDebounceLite to debounce the pin
EdgeDebounceLite debounce;         //Name it debounce

enum MoveMachineStates {WAIT, MOVE_UP, MOVE_DOWN};   //3 possible states of the state machine
MoveMachineStates vmState = WAIT;                                     //Start state is WAIT

enum SwitchStates {IS_OPEN, IS_RISING, IS_CLOSED, IS_FALLING};  //4 - Switch state machine
SwitchStates switchState[2] = {IS_OPEN, IS_OPEN};               //Both switch's states are IS_OPEN
byte switchPin[2] = {12, 13};                                                 //Switches are on pins 10 and 11
enum SwitchModes {PULLUP, PULLDOWN};                              //2 possible modes for the switches
SwitchModes switchMode[2] = {PULLUP, PULLUP};                   //Both switches are in PULLUP mode
// byte ledPin[2] = {2, 3};                                                     //LEDs are on pins 3 and 2

#define EN        8  

//Direction pin
#define X_DIR     5 
#define Y_DIR     6
#define Z_DIR     7

//Step pin
#define X_STP     2
#define Y_STP     3 
#define Z_STP     4 


//DRV8825
int delayTime=500;                                                          //Delay between each pause (uS)
int stps=3000;                                                                 // Steps to move

int X_STOP = 9;                                                               //used at the top and bottom

void step(boolean dir, byte dirPin, byte stepperPin, int steps)
{
  digitalWrite(dirPin, dir);
  delay(1);
  for (int i = 0; i < steps; i++) {
    digitalWrite(stepperPin, HIGH);
    delayMicroseconds(delayTime); 
    digitalWrite(stepperPin, LOW);
    delayMicroseconds(delayTime);
    int buttonState = digitalRead(X_STOP);
    //Serial.println (buttonState, DEC);
    if (buttonState == 0) break;
    
  }
}

void movingUp() {                                        //Simulate moving up
//  blinkLed(0);                                             //Blink the first LED
 step(false, X_DIR, X_STP, stps);                    //X, Clockwise
  }

void movingDown() {                                     //Simulate moving down
//  blinkLed(1);                                              //Blink second LED
  step(true, X_DIR, X_STP, stps);                    //X, Counterclockwise
 }
 
void movingScreen() {           
  switch (vmState) {             
    case WAIT:  {      if (upPressed())           vmState = MOVE_UP;
                       if (downPressed())              vmState = MOVE_DOWN;  break;    }           
    case MOVE_UP: { movingUp();               vmState = WAIT;              break;    }
    case MOVE_DOWN: { movingDown();     vmState = WAIT;              break;    }
    }
  }

void switchMachine(byte i) {                             //The Switch state machine
  byte pinIs = debounce.pin(switchPin[i]);          //<<<<<Replace digitalRead() with debounce.pin()
  if (switchMode[i] == PULLUP) pinIs = !pinIs;    //Reverse the value read if the switch is in PULLUP mode
  switch (switchState[i]) {                                 //Depending of the state
    case IS_OPEN:    {                                       //State is IS_OPEN
      if(pinIs == HIGH)                                       //If the pin is HIGH
        switchState[i] = IS_RISING;                      //We just changed form LOW to HIGH: State is now IS_RISING 
      break;                                                       //Get out of switch
    }
    case IS_RISING:  {                                       //State is IS_RISING
      switchState[i] = IS_CLOSED;                       //It is not rising anymore, State is now IS_CLOSED
      break;                                                        //Get out of switch
    }
    case IS_CLOSED:  {                                       //State is IS_CLOSED
      if(pinIs == LOW)                                         //If the pin is LOW
        switchState[i] = IS_FALLING;                     //We just changed form HIGH to LOW: State is now IS_FALLING 
      break;                                                        //Get out of switch 
    }
    case IS_FALLING: {                                      //State is IS_FALLING
      switchState[i] = IS_OPEN;                          //It is not falling anymore, State is now IS_OPEN    
      break;                                                       //Get out of switch
    }
  }
}

bool upPressed() {                      
  switchMachine(0);                           
  if (switchState[0] == IS_FALLING)          
    return true;                                
  else                                        
    return false;                              
}

bool downPressed() {                     
  switchMachine(1);                          
  if (switchState[1] == IS_FALLING)           
    return true;                               
  else                                        
    return false;                               
}

void blinkLed(byte i) {                         //A function to blink an LED with ID i
//  digitalWrite(ledPin[i], HIGH);           //Bring pin of LED i HIGH
  delay(50);                                        //Wait there for 50 milliseconds so we can see it blink
//  digitalWrite(ledPin[i], LOW);            //Bring pin of LED i LOW
  
}

void setup() {
  for (int i = 0 ; i < 2 ; i++)                          //For each switch
    pinMode(switchPin[i], INPUT_PULLUP);      //Their modes are INPUT_PULLUP
//  for (int i = 0 ; i < 2 ; i++) {                     //For aech LED
//    pinMode(ledPin[i],    OUTPUT);                //Their mode is OUTPUT
//    digitalWrite(ledPin[i], LOW);                    //They start LOW
Serial.begin(9600);
pinMode (X_STOP, INPUT_PULLUP);


pinMode(X_DIR, OUTPUT); pinMode(X_STP, OUTPUT);
// pinMode(Y_DIR, OUTPUT); pinMode(Y_STP, OUTPUT);
// pinMode(Z_DIR, OUTPUT); pinMode(Z_STP, OUTPUT);
  pinMode(EN, OUTPUT);
  digitalWrite(EN, LOW);
  }

void loop() {
    movingScreen();
}

whatthecrappin:
Thanks all for the suggestions, but for some reason the end stops are behaving like an E-stop and totally over riding the code? I dont even have checks in the code - it just stops due to the switch. Is there a command to override the end stop and then move it back 1/2 a turn once the switch is triggered?

Not if the switch is over-riding the software.

Why not integrate the end stops into the code?

...R

I'd like to use code, but trying to work out how to not let the switches overwrite it

I've currently got the switches wired into the pins highlighted in yellow. Does that mean I should be using the hold instead? I've got 4 end stop switches at the moment (2 motors with stops at each end)

Is the only way to hardwire 4 pairs into the hold pin? I'm assuming I wont have the problem that a closed switch on this pin wont override the code

I can't view the picture because FireFox tells me that the connection is not secure. To post the picture on the forum follow this guide.

whatthecrappin:
I'd like to use code, but trying to work out how to not let the switches overwrite it

I've currently got the switches wired into the pins highlighted in yellow. Does that mean I should be using the hold instead? I've got 4 end stop switches at the moment (2 motors with stops at each end)

Is the only way to hardwire 4 pairs into the hold pin? I'm assuming I wont have the problem that a closed switch on this pin wont override the code

You are assuming we know a whole lot of stuff - but we don't.

What pin is highlighted in yellow?
What is a "hold" pin?
Are these pins on an Arduino board?

If you want to post an image see this Simple Image Guide

...R

board is the cnc shield

pins which I'm using are marked in yellow. I assumed endstop would behave differently from estop....

I would suggest that you separate the reading of the limit switch from the step function. And instead of running a for loop that you break out of, do one step, check the switch, step, check, step, check and keep doing that till the limit switch is activated. Then pull off the switch. That is how Grbl or other firmware does "homing".

:frowning: I was way off track.....did the code months ago (you can see my lights code which I used to simulate the movement). unfortunately the lights would always light and theres me thinking thats fine

you're right though - its immedialtely breaking out of the loop due to the switch

I'll try and salvage the code and put some logic into calling a reversing routine, (I'm stubborn like that!), but yeah, I can see how it would be easier to just move and check on each step. only thing I'm worried about there is I'm moving a 20kg plasma on a plasma and any changes to the stepping may mean further adjustments to timing and counter weights etc

thanks for the help though!

And done - thanks GroundFungus - you got me out of a rut!

#include <EdgeDebounceLite.h>                             //Use EdgeDebounceLite to debounce the pin
EdgeDebounceLite debounce;                                //Name it debounce

enum MoveMachineStates {WAIT, MOVE_UP, MOVE_DOWN};        //The 3 possible states of the state machine
MoveMachineStates vmState = WAIT;                         //Start state is WAIT
enum SwitchStates {IS_OPEN, IS_RISING, IS_CLOSED, IS_FALLING};  //The four possible states of the Switch state machine
SwitchStates switchState[2] = {IS_OPEN, IS_OPEN};         //Both switch's states are IS_OPEN
byte switchPin[2] = {12, 13};                             //Switches are on pins 10 and 11
enum SwitchModes {PULLUP, PULLDOWN};                      //The two possible modes for the switches
SwitchModes switchMode[2] = {PULLUP, PULLUP};             //Both switches are in PULLUP mode
// byte ledPin[2] = {2, 3};                               //LEDs are on pins 3 and 2

#define EN        8  

//Direction pin
#define X_DIR     5 
#define Y_DIR     6
#define Z_DIR     7

//Step pin
#define X_STP     2
#define Y_STP     3 
#define Z_STP     4 


//DRV8825
int delayTime=500;                                        //Delay between each pause (uS)
int stps=20000;                                           // Steps to move
int stpsback=200;                                         // Steps to back off
int X_STOP = 9;                                           //used at the top and bottom
                                                          //10 and 11 can also be used  use z for the slow down????

void step(boolean dir, byte dirPin, byte stepperPin, int steps)
{
  digitalWrite(dirPin, dir);
  delay(1);
  for (int i = 0; i < steps; i++) {
    digitalWrite(stepperPin, HIGH);
    delayMicroseconds(delayTime); 
    digitalWrite(stepperPin, LOW);
    delayMicroseconds(delayTime);
    int buttonState = digitalRead(X_STOP);
    //Serial.println (buttonState, DEC);
    if (buttonState == 0) break;
    }
}

void stepback(boolean dir, byte dirPin, byte stepperPin, int steps)
{
  digitalWrite(dirPin, dir);
  delay(1);
  for (int i = 0; i < steps; i++) {
    digitalWrite(stepperPin, HIGH);
    delayMicroseconds(delayTime); 
    digitalWrite(stepperPin, LOW);
    delayMicroseconds(delayTime);
    }
}

void movingUp() {          //Simulate moving up
//  blinkLed(0);           //Blink the first LED
  step(false, X_DIR, X_STP, stps); //X, Clockwise
  delay(1000);
  stepback(true, X_DIR, X_STP, stpsback);
}

void movingDown() {       //Simulate moving down
//  blinkLed(1);          //Blink second LED
  step(true, X_DIR, X_STP, stps); //X, Counterclockwise
  delay(1000);
  stepback(false, X_DIR, X_STP, stpsback);
 }
 
void movingScreen(){           
  switch (vmState) {             
    case WAIT:  {      if (upPressed())           vmState = MOVE_UP;
                       if (downPressed())         vmState = MOVE_DOWN;  break;    }           
    case MOVE_UP: { movingUp();                   vmState = WAIT;       break;    }
    case MOVE_DOWN: { movingDown();               vmState = WAIT;       break;    }
    }
  }

void switchMachine(byte i) {                        //The Switch state machine
  byte pinIs = debounce.pin(switchPin[i]);          //<<<<<Replace digitalRead() with debounce.pin()
  if (switchMode[i] == PULLUP) pinIs = !pinIs;      //Reverse the value read if the switch is in PULLUP mode
  switch (switchState[i]) {                         //Depending of the state
    case IS_OPEN:    {                              //State is IS_OPEN
      if(pinIs == HIGH)                             //If the pin is HIGH
        switchState[i] = IS_RISING;                 //We just changed form LOW to HIGH: State is now IS_RISING 
      break;                                        //Get out of switch
    }
    case IS_RISING:  {                              //State is IS_RISING
      switchState[i] = IS_CLOSED;                   //It is not rising anymore, State is now IS_CLOSED
      break;                                        //Get out of switch
    }
    case IS_CLOSED:  {                              //State is IS_CLOSED
      if(pinIs == LOW)                              //If the pin is LOW
        switchState[i] = IS_FALLING;                //We just changed form HIGH to LOW: State is now IS_FALLING 
      break;                                        //Get out of switch 
    }
    case IS_FALLING: {                              //State is IS_FALLING
      switchState[i] = IS_OPEN;                     //It is not falling anymore, State is now IS_OPEN    
      break;                                        //Get out of switch
    }
  }
}

bool upPressed() {                      
  switchMachine(0);                           
  if (switchState[0] == IS_FALLING)          
    return true;                                
  else                                        
    return false;                              
}

bool downPressed() {                     
  switchMachine(1);                          
  if (switchState[1] == IS_FALLING)           
    return true;                               
  else                                        
    return false;                               
}

void blinkLed(byte i) {                         //A function to blink an LED with ID i
//  digitalWrite(ledPin[i], HIGH);              //Bring pin of LED i HIGH
  delay(50);                                    //Wait there for 50 milliseconds so we can see it blink
//  digitalWrite(ledPin[i], LOW);               //Bring pin of LED i LOW
  
}

void setup() {
  for (int i = 0 ; i < 2 ; i++)               //For each switch
    pinMode(switchPin[i], INPUT_PULLUP);      //Their modes are INPUT_PULLUP
//  for (int i = 0 ; i < 2 ; i++) {           //For each LED
//    pinMode(ledPin[i],    OUTPUT);          //Their mode is OUTPUT
//    digitalWrite(ledPin[i], LOW);           //They start LOW
Serial.begin(9600);
pinMode (X_STOP, INPUT_PULLUP);


pinMode(X_DIR, OUTPUT); pinMode(X_STP, OUTPUT);
// pinMode(Y_DIR, OUTPUT); pinMode(Y_STP, OUTPUT);
// pinMode(Z_DIR, OUTPUT); pinMode(Z_STP, OUTPUT);
  pinMode(EN, OUTPUT);
  digitalWrite(EN, LOW);
  }

void loop() {
    movingScreen();
}

You are welcome. Not exactly what I meant, but if it does what you want then all is well.