-Newbie /where to add a limit switch code to my existing sketch up

Hi
everyone

I’m using:

  • Power source 12V 5A
    -NEMA 23 stepper motor 200 steps/1.8°
    -TB5860 Motor Driver
    -Arduino UNO R3

The following code lets me, by pressing a button, to move my motor CW. I have another button that when i press it lets me move my motor CCW, and it will automatically move 300 steps. ( 540°)

I also have connected a limit switch, but that still requires to be programmed in order for it to work.

I found this tutorial online with its code that shows that when a limit switch is pressed, the motor will stop.
I want to replicate that and put it on my code.

The thing is I do not know what to copy and modify exactly from that code and where to put it.

[This is the code im using ][/// defines pins numbers
const int dirPin = 3;
const int stepPin = 2;
const int enPin = 6;
const int limitPin = 7;

const int switchOne = 8;
const int switchTwo = 9;

int p1buttonState = 0; // current state of the button
int lastp1buttonState = 0; // previous state of the button

int p2buttonState = 0; // current state of the button
int lastp2buttonState = 0; // previous state of the button
bool bPress = false;

bool isForward = false;
bool isBackward = false;

void setup() {

Serial.begin(9600);
pinMode( switchOne, INPUT_PULLUP);
pinMode( switchTwo, INPUT_PULLUP);

pinMode(limitPin,INPUT);
// Sets the two pins as Outputs
pinMode(stepPin,OUTPUT);
pinMode(dirPin,OUTPUT);

pinMode(enPin,OUTPUT);
digitalWrite(enPin,LOW);

}
void loop() {

isForward = false;
isBackward = false;

p1buttonState = digitalRead(switchOne);
p2buttonState = digitalRead(switchTwo);

if (p1ButtonPress()) {

digitalWrite(dirPin,HIGH);

delay(5);
}

if (p2ButtonPress()) {

digitalWrite(dirPin,LOW);

delay(5);
}

if( isForward || isBackward ){

for(int x = 0; x < 300; x++) {
digitalWrite(stepPin,HIGH);
delayMicroseconds(1200);
digitalWrite(stepPin,LOW);
delayMicroseconds(1200);
}
}

}

bool p1ButtonPress()
{
bool isPress = false;
// compare the p1buttonState to its previous state
if (p1buttonState != lastp1buttonState) {
// if the state has changed, increment the counter
if (p1buttonState == LOW) {
// if the current state is HIGH then the button went from off to on:
bPress = true;
isPress = true;
Serial.println(“Plaer One score”);

} else {
// if the current state is LOW then the button went from on to off:
Serial.println(“off”);
isForward = true;
}
// Delay a little bit to avoid bouncing
delay(50);
}
// save the current state as the last state, for next time through the loop
lastp1buttonState = p1buttonState;
return isPress;
}

bool p2ButtonPress()
{
bool isPress = false;
// compare the p1buttonState to its previous state
if (p2buttonState != lastp2buttonState) {
// if the state has changed, increment the counter
if (p2buttonState == LOW) {
// if the current state is HIGH then the button went from off to on:
bPress = true;
isPress = true;
Serial.println(“Plaer Two score”);

} else {
// if the current state is LOW then the button went from on to off:
Serial.println(“off”);
isBackward = true;
}
// Delay a little bit to avoid bouncing
delay(50);
}
// save the current state as the last state, for next time through the loop
lastp2buttonState = p2buttonState;
return isPress;
}]

Regarding the limit switch, the red wire is connected to the arduino 5V
the black wire is connected to Arduino GND
The green/blue, which is the signal, is connected to pin7.

I tried copying

if( digitalRead(limitPin) == HIGH){
digitalWrite(stepPin,HIGH);
delayMicroseconds(500);
digitalWrite(stepPin,LOW);
delayMicroseconds(500);

and to put it in several places of my own code but i get an error message (img attached).
What’s highlighted in yellow is what I copied from the other code. I do not know if it is correctly placed or not… or if I have to modify something on it… ( im still very new to all this arduino mambo jambo)

Could anybody please provide me some help/guidance?

Thank you

How could you possibly expect help if you don't show the problematic code and don't show the error message? It might be something simple but who can tell?

Looks like you might be missing a right curly bracket but who knows?

Sigh,

If this is the complete code, than the compile message should have been a big clue as to why it will not compile. It would be helpful to see this error when posting.

In any event, p1ButtonPress and p2ButtonPress are not defined.

Not sure what there are to be used for.

vaj4088:
How could you possibly expect help if you don't show the problematic code and don't show the error message? It might be something simple but who can tell?

Looks like you might be missing a right curly bracket but who knows?

I just added as an attached file on the first post the problem itself.

"p1ButtonPress1 was not declared in this scope"

( i honestly don't know what to write there)

Romonaga:
Sigh,

If this is the complete code, than the compile message should have been a big clue as to why it will not compile. It would be helpful to see this error when posting.

In any event, p1ButtonPress and p2ButtonPress are not defined.

Not sure what there are to be used for.

Hi
you’re right. sorry about that
Please have a look at the image I attached on the first post.
Whenever I copy and paste the lines highlihgted in yellow, I get the error. If not, the code works fine ( but without the limit switch, of course)

The compiler is screaming the issue. I have told you what is wrong.

The 2 variables are not defined.

Romonaga:
...

In any event, p1ButtonPress and p2ButtonPress are not defined.

...

p1ButtonPress() and p2ButtonPress() are functions. Unfortunately, they are defined AFTER the place where they are used, and C/C++ requires that they be defined BEFORE they are used. Typically, a .h file is included with function declarations so that this does not happen.

If you do not know how to make and include a .h file, just move the definitions of these functions to a place ahead of the loop() function, say, between the setup() function and the loop() function.

Of course, the Arduino IDE does some preprocessing to try to deal with this issue, but it can be fooled (although I am not seeing the problem with this code) or you could have an issue if you use some IDE other than the Arduino IDE.

vaj4088:
Of course, the Arduino IDE does some preprocessing to try to deal with this issue, but it can be fooled (although I am not seeing the problem with this code) or you could have an issue if you use some IDE other than the Arduino IDE.

vaj4088:
p1ButtonPress() and p2ButtonPress() are functions. Unfortunately, they are defined AFTER the place where they are used, and C/C++ requires that they be defined BEFORE they are used. Typically, a .h file is included with function declarations so that this does not happen.

If you do not know how to make and include a .h file, just move the definitions of these functions to a place ahead of the loop() function, say, between the setup() function and the loop() function.

If I put this code :

if( digitalRead(limitPin) == HIGH){
digitalWrite(stepPin,HIGH);
delayMicroseconds(500);
digitalWrite(stepPin,LOW);
delayMicroseconds(500);

between the setup() function and the loop() function the code works, but not as intented.
Only by clicking the limit switch, and pressing a button, the motor will spin.

I really don't know how to keep going with this...

Any more advices/tips/suggestions are more than welcome

Tinback123,

I would suggest to you, stop poking at a solution... you need to step away from the code and sit down and make a UML of your program. You might only need an Activity diagram to help you understand why your code isn't progressing as you wish.

You might think that this isn't very helpful, but it is extremely important that you clearly understand why a problem may occur throughout your coding now and in the future. After you finish writing these diagram/s you will be more prepared to expand your program. I usually use names in my diagrams that are used in the development of the program.

I'll just add one thing to this post. As it was suggested in post#6 including spinets of code already written will make your programming experience much easier and generally more readable to you & others that might be involved with your projects.

if your code run OK and you only need to add limit switch. don’t let the piece of code that turn the motor execute:

 if( (isForward || isBackward ) && digitalRead(limitPin) == HIGH){ // limit not pressed

      for(int x = 0; x < 300; x++) {
        digitalWrite(stepPin,HIGH);
        delayMicroseconds(1200);
        digitalWrite(stepPin,LOW);
        delayMicroseconds(1200);
      }

or do it as you wish.

Wrong,

Only add a process, if previous data is invalid.

Do you need to start you car twice? You might need to see your mechanic.

You don't replace the engine, do you?

im re doing this from sratch

and there are some things i do not know how to write them.
Here’s my code with its coments and with my doubts:

// define the numer of pins
const int dirPin = 3; //Direction Pin
const int stepPin = 2; // Steps Pin
const int enPin = 6; //Enable Pin

const int limitPin1 =7; //LimitPin 1
const int limitPin2 =8; //LimitPin2
const int botonuno = 8; //Buttono 1
const int botondos = 5; //Button 2

void setup() {

Serial.begin(9600);
pinMode( botonuno, INPUT); //
pinMode( botondos, INPUT); //
pinMode (limitPin1,INPUT); // I dont know if it should be INPUT or INPUT_PULLOUT? ( I can’t understand what Pullout actually means in this code ( I’ve already seen examples of it)
pinMode (limitPin2,INPUT); // same here

// Output pins
pinMode(stepPin,OUTPUT);
pinMode(dirPin,OUTPUT);

pinMode(enPin,OUTPUT);
digitalWrite(enPin,LOW);

}

void loop() {

Here’s when I get confused

if I press button 1 or button 2( once, not holding it pressed), it should do 300 steps.

The code should be something like this(or not…?):

for(int x = 0; x < 300; x++) {
digitalWrite(stepPin,HIGH);
delayMicroseconds(500);
digitalWrite(stepPin,LOW);
delayMicroseconds(500);

now… if button 1 is pressed and the motor is rotating to CW, and it hits the limit switch, the motor should stop, it should not let it move CW again, and it should allow button2 to be pressed and the motor to rotate CCW.

Same thing the other way around. So I have something like this:

if (boton1 ==HIGH) { //If I press button1
if (!digitalRead(limitPin1)) {} //check if LimitPin1 was pressed (is this right?)
else { // if limit switch wasnt activated, allow the motor to rotate
}

digitalWrite(dirPin,LOW);

delay(5);

Now, if this is correct, what’s the order it should be put in the code?
if those coding lines are not correct, what do I need to change/add/ remove?

You asked "INPUT or INPUT_PULLOUT?" Never INPUT_PULLOUT. Perhaps you intended INPUT_PULLUP. It is hard to go wrong with INPUT_PULLUP no matter what your wiring. However, if you really want to choose between INPUT and INPUT_PULLUP, you need to share your wiring diagram or equivalent. I cannot see your wiring and my crystal ball is in the shop! :grinning:

This

  if (!digitalRead(limitPin1)) {} //check if LimitPin1 was pressed  (is this right?)

will probably work correctly, but according to the documentation at
https://www.arduino.cc/reference/en/language/functions/digital-io/digitalread/
it should be

  if (digitalRead(limitPin1) == LOW) {} //check if LimitPin1 was pressed.

although possibly LOW should be HIGH depending upon how the limit switches work and how they are wired.

Hi!
I’m attaching my wiring diagram
I did not include on it any power supply, but in case you have any doubts.
The driver is connected to a 12V 5 A power supply ( the motor is a nema 23 stepper motor up to 3A)
and the arduino is connected via USB.

so inputs for the limit switch should be pins 4 and 7

I did a boo-boo before so my code should actually be this at start:

// define the numer of pins
const int dirPin = 3; //Direction Pin
const int stepPin = 2; // Steps Pin
const int enPin = 6; //Enable Pin

const int limitPin1 =7; //LimitPin 1
const int limitPin2 =4; //LimitPin2
const int botonuno = 8; //Button 1
const int botondos = 9; //Button 2

I hope this was helpfull for you

vaj4088:
You asked “INPUT or INPUT_PULLOUT?” Never INPUT_PULLOUT. Perhaps you intended INPUT_PULLUP. It is hard to go wrong with INPUT_PULLUP no matter what your wiring. However, if you really want to choose between INPUT and INPUT_PULLUP, you need to share your wiring diagram or equivalent. I cannot see your wiring and my crystal ball is in the shop! :grinning:

This

  if (!digitalRead(limitPin1)) {} //check if LimitPin1 was pressed  (is this right?)

will probably work correctly, but according to the documentation at
digitalRead() - Arduino Reference
it should be

  if (digitalRead(limitPin1) == LOW) {} //check if LimitPin1 was pressed.

although possibly LOW should be HIGH depending upon how the limit switches work and how they are wired.

Hi!
I’m attaching my wiring diagram
I did not include on it any power supply, but in case you have any doubts.
The driver is connected to a 12V 5 A power supply ( the motor is a nema 23 stepper motor up to 3A)
and the arduino is connected via USB.

so inputs for the limit switch should be pins 4 and 7

I did a boo-boo before so my code should actually be this at start:

// define the numer of pins
const int dirPin = 3; //Direction Pin
const int stepPin = 2; // Steps Pin
const int enPin = 6; //Enable Pin

const int limitPin1 =7; //LimitPin 1
const int limitPin2 =4; //LimitPin2
const int botonuno = 8; //Button 1
const int botondos = 9; //Button 2

I hope this was helpfull for you

Your limit switches (pin 4 and pin 7) do not need INPUT_PULLUP because they have both ground and power available. A pin mode of INPUT is sufficient but INPUT_PULLUP will also work with a very tiny increase in current.

Your push buttons require INPUT_PULLUP and a press is LOW because only ground is available and (I assume) the push button switches are normally open.

Hi
So according to what you say this is my code so far:

#include <Stepper.h>

// DEFINE PIN NUMBERS
const int dirPin  = 3; //Direction pin
const int stepPin = 2;  // Stepper pin
const int enPin   = 6;  //Enable pin

const int limitPin1  =7; //LimitPin1
const int limitPin2 =4; //LimitPin2

const int button1     = 8; //Button1
const int button2     = 9; //Button2

int p1buttonState = 0;         // current state of the button
int lastp1buttonState = 0;     // previous state of the button

int p2buttonState = 0;         // current state of the button
int lastp2buttonState = 0;     // previous state of the button
bool bPress = false;

bool isForward = false;
bool isBackward = false;


const int stepsPerRevolution = 200;  // change this to fit the number of steps per revolution
// for your motor


// initialize the stepper library on pins 8 through 11:
Stepper myStepper(stepsPerRevolution, 8, 9, 10, 11);  //CAMBIAR ESTOS PINES

void setup() {
   // set the speed at 60 rpm:
  myStepper.setSpeed(60);
   Serial.begin(9600);
  pinMode( button1, INPUT_PULLUP); //Botton1 as an input signal
  pinMode( button2, INPUT_PULLUP); //Button2 as an input signal
  pinMode (limitPin1,INPUT); // Limitpin1  as input signal
  pinMode (limitPin2,INPUT); // Limitpin2 as input signal

  // Defino los pines como salidas
  pinMode(stepPin,OUTPUT);
  pinMode(dirPin,OUTPUT);

  pinMode(enPin,OUTPUT);
  digitalWrite(enPin,LOW);

}
void loop() {

   isForward=false;
   isBackward=false;
   
   p1buttonState = digitalRead(button1);
   p2buttonState = digitalRead(button2);
 // HASTA ACA TODO OK

if (button1 == LOW ) {
  digitalWrite(dirPin,HIGH);

  delay(5);
                      }

if (button2 ==LOW ) {
  digitalWrite(dirPin,HIGH);

  delay(5);
                     }
            }


if (isForward || isBackward) {

              for (int x=0; x<300; x++) {
                digitalWrite(stepPin,HIGH);
                delayMicroseconds(1200);
                digitalWrite(stepPin,LOW);
                delayMicroseconds(1200);
              }
  }

Im getting the following message… ( please see file attached). and I do not know what to do about it…

up until the " if (isForward || isBackward) { " am I in the correct path?

Good hing that I was on my laptop which can read JPEG files and not my mobile device which sometimes can't.

If you used Tools | auto format you might see that your "if" statement and its following code are NOT in the loop() function. ALL executable code (aside from some exceptions) must be inside a function and this code is not.

You need to move the code (or move a squiggly bracket, depending upon what is easy for you and what your intent is).

Great, now I’m not getting that error anymore

So this is my code so far:

#include <Stepper.h>

// DEFINE PIN NUMBERS
const int dirPin  = 3; //Direction pin
const int stepPin = 2;  // Stepper pin
const int enPin   = 6;  //Enable pin

const int limitPin1  =7; //LimitPin1
const int limitPin2 =4; //LimitPin2

const int button1     = 8; //Button1
const int button2     = 9; //Button2

int p1buttonState = 0;         // current state of the button
int lastp1buttonState = 0;     // previous state of the button

int p2buttonState = 0;         // current state of the button
int lastp2buttonState = 0;     // previous state of the button
bool bPress = false;

bool isForward = false;
bool isBackward = false;


const int stepsPerRevolution = 200;  // change this to fit the number of steps per revolution
// for your motor


// initialize the stepper library on pins 8 through 11:
Stepper myStepper(stepsPerRevolution, 8, 9, 10, 11);  //I need to change this pins, forget about this

void setup() {
   // set the speed at 60 rpm:
  myStepper.setSpeed(60);
  
   Serial.begin(9600);
  pinMode( button1, INPUT_PULLUP); //Botton1 as an input signal
  pinMode( button2, INPUT_PULLUP); //Button2 as an input signal
  pinMode (limitPin1,INPUT); // Limitpin1  as input signal
  pinMode (limitPin2,INPUT); // Limitpin2 as input signal

  // Sets the two pins as outputs
  pinMode(stepPin,OUTPUT);
  pinMode(dirPin,OUTPUT);

  pinMode(enPin,OUTPUT);
  digitalWrite(enPin,LOW);

}
void loop() {

   isForward=false;
   isBackward=false;
   
   p1buttonState = digitalRead(button1);
   p2buttonState = digitalRead(button2);

 // Up to here everything works OK

if (button1 == HIGH ) {
  digitalWrite(dirPin,HIGH);

  delay(5);
                      }

if (button2 ==HIGH ) {
  digitalWrite(dirPin,HIGH);

  delay(5);
                     }
            


if (isForward || isBackward) {

              for (int x=0; x<300; x++) {
                digitalWrite(stepPin,HIGH);
                delayMicroseconds(1200);
                digitalWrite(stepPin,LOW);
                delayMicroseconds(1200);
              }
}
}

Now, what I have to do is to program something that would do the following:

If button1 is pressed, the motor will move 300 steps CW. If button2 is pressed, the motor will move 300 steps CCW.

But, if button1 is pressed AND limitPin1 is pressed, the motor will stop (not necessarily simultaneous)
and, if button2 is pressed and limitPin2 is pressed, the motor will also stop. (not necessarily simultaneous)

Any thoughts/suggestions and/or modifications about this? ( I don’t know for sure if this is OK…)

{
if (digitalRead(button1) == HIGH) ; //if buton1 is pressed
if (digitalRead(limitPin1) == LOW {}//if limitPin1 is pressed
else { // if it is not, then limitpin1 is not activated, rotate the motor CW

  digitalWrite(dirPin,HIGH);
  digitalWrite(stepPin,HIGH);

 if (digitalRead(button2) == HIGH) ; //if button2 is pressed
if (digitalRead(limitPin2) == LOW {} //if limitPin2 is not pressed
else { // if it is not, then limitpin2 is not activated, rotate the motor CW

  digitalWrite(dirPin,HIGH);
  digitalWrite(stepPin,HIGH);
  
}

I don’t know if that’s a code that will actually work

or if I could actually put the following, which is from a code that I found online:

bool p1ButtonPress() 
{
  bool isPress=false;
  //comparar p1ButtonState to its previous state.
  if (p1buttonState != lastp1buttonState) {
    //if the state has changed, increment the counter
    if (p1buttonState ==LOW ) {
      //if the current state is HIGH then the button went from off to on:
      bPress  = true;
      isPress = true;

    } else {
      //if the current state is LOW then the button went from on to off:
      isForward = true;
    }

    //Delay a little bit
    delay(50);
  }
  //save the current state as the last state, for next time through the loop 
  lastp1buttonState = p1buttonSate;
  return isPress;
}

bool p2ButtonPress()
{
  bool isPress = false;
  //compare the p1buttonState to its previous state
  if (p2buttonState != lastp2buttonState) {
    //if the state has changed, increment the counter
    if (p2buttonState == LOW) {
      // if the current state is HIGH then the button went from off to on:
      bPress = true;
      isPress = true;

    }else{
      //if the current state is LOW then the button went from on to off:
      isBackward = true;
    }
    //Delay a little bit to avoid bouncing
    delay(50);
  }
  //save the current state as the lat state, for next time through the loop
  lastp2buttonState=p2buttonState;
  return isPress;
}
    }
  }
}

That piece of code came actually from the code below, which works as I want to, but has no limitswitches what so ever…

// defines pins numbers
const int dirPin  = 3;
const int stepPin = 2;
const int enPin   = 6;
const int limitPin = 7;

const int switchOne     = 8;
const int switchTwo     = 9;

int p1buttonState = 0;         // current state of the button
int lastp1buttonState = 0;     // previous state of the button

int p2buttonState = 0;         // current state of the button
int lastp2buttonState = 0;     // previous state of the button
bool bPress = false;

bool isForward = false;
bool isBackward = false;

void setup() {

  Serial.begin(9600);
  pinMode( switchOne, INPUT_PULLUP);
  pinMode( switchTwo, INPUT_PULLUP);
  pinMode(limitPin,INPUT);
  
  // Sets the two pins as Outputs
  pinMode(stepPin,OUTPUT);
  pinMode(dirPin,OUTPUT);

  pinMode(enPin,OUTPUT);
  digitalWrite(enPin,LOW);

}

 
void loop() {
      
   
   isForward = false;
   isBackward = false;

   p1buttonState = digitalRead(switchOne);
   p2buttonState = digitalRead(switchTwo);

  if (p1ButtonPress()) {

    digitalWrite(dirPin,HIGH);

    delay(5);
  }

    if (p2ButtonPress()) {

      digitalWrite(dirPin,LOW);

      delay(5);
    }

    if( isForward || isBackward ){

      for(int x = 0; x < 300; x++) {
        digitalWrite(stepPin,HIGH);
        delayMicroseconds(1200);
        digitalWrite(stepPin,LOW);
        delayMicroseconds(1200);
      }
    }
    
}

bool p1ButtonPress()
{
   bool isPress = false;
   // compare the p1buttonState to its previous state
  if (p1buttonState != lastp1buttonState) {
    // if the state has changed, increment the counter
    if (p1buttonState == LOW) {
      // if the current state is HIGH then the button went from off to on:
      bPress = true;
      isPress = true;
      Serial.println("Plaer One score");
    
    } else {
      // if the current state is LOW then the button went from on to off:
      Serial.println("off");
      isForward = true;
    }
    // Delay a little bit to avoid bouncing
    delay(50);
  }
  // save the current state as the last state, for next time through the loop
  lastp1buttonState = p1buttonState;
  return isPress;
}

bool p2ButtonPress()
{
   bool isPress = false;
   // compare the p1buttonState to its previous state
  if (p2buttonState != lastp2buttonState) {
    // if the state has changed, increment the counter
    if (p2buttonState == LOW) {
      // if the current state is HIGH then the button went from off to on:
      bPress = true;
      isPress = true;
      Serial.println("Plaer Two score");
    
    } else {
      // if the current state is LOW then the button went from on to off:
      Serial.println("off");
      isBackward = true;
    }
    // Delay a little bit to avoid bouncing
    delay(50);
  }
  // save the current state as the last state, for next time through the loop
  lastp2buttonState = p2buttonState;
  return isPress;
}

What do you think Vaj?