Getting code to run after an input is recieved

Hi everyone,

I hope someone can help me out. I have a stepper motor and I have it turning as I need it to but I was trying to get it to wait until it sees pin 2 HIGH to run the code and for the motor to turn, and obviously turn off when pin 2 is LOW. I tried the if statement in various places and could not get it to work. I think I also need to debounce the switch. Maybe this is not necessary, what will switch this is a PLC output.

Is there a simple way to make the loop wait until a pin is HIGH?

I got the code from:


Motor Shield Stepper Demo by Randy Sarafan

For more information see: http://www.instructables.com/id/Arduino-Motor-Shield-Tutorial/


And I have tried a few things to get it to work but nothing happens. My latest attempt is here commented out.

//The circuit: // * pushbutton (Y0 output from Mitsubishi PLC) attached to pin 2 from +5V // * 10K resistor attached to pin 2 from ground

//const int buttonPin = 2; //int buttonState = 0; // maybe change this to LOW

void setup() {

//pinMode(2, INPUT); pinMode(12, OUTPUT); //CH A -- HIGH = forwards and LOW = backwards??? pinMode(13, OUTPUT); //CH B -- HIGH = forwards and LOW = backwards???

//establish motor brake pins pinMode(9, OUTPUT); //brake (disable) CH A pinMode(8, OUTPUT); //brake (disable) CH B

}

void loop() {

//buttonState = digitalRead(buttonPin); //if (buttonState == HIGH) {

//To make a bipolar motor spin: //Power the first coil. //Next power the second coil with reverse polarity. //Then power the first coil with reverse polarity. //Finally, power the second coil.

digitalWrite(9, LOW); //ENABLE CH A digitalWrite(8, HIGH); //DISABLE CH B

digitalWrite(12, HIGH); //Sets direction of CH A analogWrite(3, 255); //Moves CH A

delay(25);

digitalWrite(9, HIGH); //DISABLE CH A digitalWrite(8, LOW); //ENABLE CH B

digitalWrite(13, LOW); //Sets direction of CH B analogWrite(11, 255); //Moves CH B

delay(25);

digitalWrite(9, LOW); //ENABLE CH A digitalWrite(8, HIGH); //DISABLE CH B

digitalWrite(12, LOW); //Sets direction of CH A analogWrite(3, 255); //Moves CH A

delay(25);

digitalWrite(9, HIGH); //DISABLE CH A digitalWrite(8, LOW); //ENABLE CH B

digitalWrite(13, HIGH); //Sets direction of CH B analogWrite(11, 255); //Moves CH B

delay(25);

}

}

Try something like this. Note that it uses INPUT_PULLUP to ensure that the state of the input is not floating and requires the input to go LOW to activate the stepper. Feel free to change the logic to match your requirements.

const byte inputPin = 2;

void setup()
{
  pinMode(inputPin, INPUT_PULLUP);
}

void loop()
{
  byte inputState = digitalRead(inputPin);
  if (inputState == LOW)  //input has been taken LOW
  {
    //code here to run the stepper or better, call a function to do it
  }
  else  //input must be HIGH
  {
    //code here to stop the stepper or better, call a function to do it
  }
}

UKHeliBob: Try something like this. Note that it uses INPUT_PULLUP to ensure that the state of the input is not floating and requires the input to go LOW to activate the stepper. Feel free to change the logic to match your requirements.

Thanks very much for your reply, my constraints here are that I need to use an output on my PLC which when energised will close a contact and it is this contact I want to switch 5v to pin 2 with. And when the pin 2 goes low i need the motor to stop. Can I use maybe a command that runs the code only when pin 2 is high and stops when low. Sorry, I am unfamiliar with the functions you were pointing to. Would that piece of code you gave me be in the right direction for my setup?

Oh also I am only using the stepper to drive in one direction while on like a regular motor, I dont need to step it or change rotation

I need to use an output on my PLC which when energised will close a contact and it is this contact I want to switch 5v to pin 2 with.

No problem. Change INPUT_PULLUP to INPUT to stop the pin being pulled HIGH but I would suggest using a resistor on the pin to pull it LOW when the relay is not energised. Change the HIGH/LOW tests to run the appropriate code to run or stop the stepper. In the comments to my program I suggest calling functions to run or stop the stepper. Just put any code you want in the functions to make the stepper do what you want.

UKHeliBob: Try something like this. Note that it uses INPUT_PULLUP to ensure that the state of the input is not floating and requires the input to go LOW to activate the stepper. Feel free to change the logic to match your requirements.

I don't have the Arduino at hand but would this code look ok? I will just switch the ground through the PLC so when I want it to start pin 2 will be LOW and otherwise it will be HIGH. For it to stop I have changed all the digitalWrites to LOW and removed the analogWrite commands. Would this look ok or is there anything silly in there?

const byte inputPin = 2;

void setup() { pinMode(inputPin, INPUT_PULLUP);

pinMode(12, OUTPUT); //CH A -- HIGH = forwards and LOW = backwards??? pinMode(13, OUTPUT); //CH B -- HIGH = forwards and LOW = backwards???

//establish motor brake pins pinMode(9, OUTPUT); //brake (disable) CH A pinMode(8, OUTPUT); //brake (disable) CH B }

void loop() { byte inputState = digitalRead(inputPin); if (inputState == LOW) //input has been taken LOW { //code here to run the stepper or better, call a function to do it //To make a bipolar motor spin: //Power the first coil. //Next power the second coil with reverse polarity. //Then power the first coil with reverse polarity. //Finally, power the second coil.

digitalWrite(9, LOW); //ENABLE CH A digitalWrite(8, HIGH); //DISABLE CH B

digitalWrite(12, HIGH); //Sets direction of CH A analogWrite(3, 255); //Moves CH A

delay(25);

digitalWrite(9, HIGH); //DISABLE CH A digitalWrite(8, LOW); //ENABLE CH B

digitalWrite(13, LOW); //Sets direction of CH B analogWrite(11, 255); //Moves CH B

delay(25);

digitalWrite(9, LOW); //ENABLE CH A digitalWrite(8, HIGH); //DISABLE CH B

digitalWrite(12, LOW); //Sets direction of CH A analogWrite(3, 255); //Moves CH A

delay(25);

digitalWrite(9, HIGH); //DISABLE CH A digitalWrite(8, LOW); //ENABLE CH B

digitalWrite(13, HIGH); //Sets direction of CH B analogWrite(11, 255); //Moves CH B

delay(25);

} else //input must be HIGH { //code here to stop the stepper or better, call a function to do it

// Set all digitalWrites to LOW and removed the analogWrite commands. digitalWrite(9, LOW); digitalWrite(8, LOW);

digitalWrite(12, LOW);

delay(25);

digitalWrite(9, LOW); digitalWrite(8, LOW);

digitalWrite(13, LOW);

delay(25);

digitalWrite(9, LOW); digitalWrite(8, LOW);

digitalWrite(12, LOW);

delay(25);

digitalWrite(9, LOW); digitalWrite(8, LOW);

digitalWrite(13, LOW);

delay(25);

} }

UKHeliBob: No problem. Change INPUT_PULLUP to INPUT to stop the pin being pulled HIGH but I would suggest using a resistor on the pin to pull it LOW when the relay is not energised. Change the HIGH/LOW tests to run the appropriate code to run or stop the stepper. In the comments to my program I suggest calling functions to run or stop the stepper. Just put any code you want in the functions to make the stepper do what you want.

If I leave it as INPUT_PULLUP am I correct in saying I don't need to supply the pin with 5v? That is done by the INPUT_PULLUP command? And I can just switch pin 2 to ground through a 10K resistor to start the code?

If I leave it as INPUT_PULLUP am I correct in saying I don't need to supply the pin with 5v? That is done by the INPUT_PULLUP command? And I can just switch pin 2 to ground through a 10K resistor to start the code?

No need to use a resistor. INPUT_PULLUP takes the pin HIGH (5V) through a resistor.

The logic of your program looks OK but do you really need all those lines of code just to stop the stepper (I don't know) ?

Some suggestions. Use the pinMode() command to set inputPin explicitly as an input. Whilst digital pins default to being inputs it is better practice to do it explicitly. You need to do it anyway if you are going to use INPUT_PULLUP Give the pins meaningful names so that later in the code it is more obvious what you are doing Auto Format the code in the IDE (Ctrl/T) to fix the indentation Remove most of the blank lines in the code so that more is visible in the editor at a time Put the stepper control code in functions to make it easier to read and maintain. For instance

  if (inputState == LOW)  //input has been taken LOW
  {
    runStepper();
  }
  else  //input must be HIGH
  {
    stopStepper();
  }

UKHeliBob: No need to use a resistor. INPUT_PULLUP takes the pin HIGH (5V) through a resistor.

The logic of your program looks OK but do you really need all those lines of code just to stop the stepper (I don't know) ?

Some suggestions. Use the pinMode() command to set inputPin explicitly as an input. Whilst digital pins default to being inputs it is better practice to do it explicitly. You need to do it anyway if you are going to use INPUT_PULLUP Give the pins meaningful names so that later in the code it is more obvious what you are doing Auto Format the code in the IDE (Ctrl/T) to fix the indentation Remove most of the blank lines in the code so that more is visible in the editor at a time Put the stepper control code in functions to make it easier to read and maintain. For instance

  if (inputState == LOW)  //input has been taken LOW
  {
    runStepper();
  }
  else  //input must be HIGH
  {
    stopStepper();
  }

Great information. I do use the auto format in the editor but when I paste it into the forum reply it doesn't keep the format. Sorry, I know it is hard to read like that. I really don't need that many lines to stop it I would think. Is there a command that will just do nothing for example? Like to stop the stepper with the else statement, pin 2 being HIGH can I just tell the code to do nothing or wait? Rather than it needlessly scanning lines of code??

I do use the auto format in the editor but when I paste it into the forum reply it doesn't keep the format

That's because you are not using code tags. The seventh icon from the right above the smileys.

Like to stop the stepper with the else statement, pin 2 being HIGH can I just tell the code to do nothing or wait? Rather than it needlessly scanning lines of code??

You don't want the code to do nothing, you want it to keep reading the input. Don't worry if nothing changes for some time, the Arduino won't get bored, heat up or wear out. The whole point of the loop() function is that it keeps repeating code until something happens.

If you really don't want to keep executing the code to stop the stepper then set a boolean variable (perhaps named stopped) to true when you stop it and check it before running the code to stop it again. In the code to run the stepper set the stopped variable to false.

There is a simple way to tell the Arduino to do nothing for a while but I am not going to tell you what it is !

Thanks, I will be trying the code out later on it so fingers crossed I can get it going. Thank you. I will update you.

UKHeliBob: That's because you are not using code tags. The seventh icon from the right above the smileys. You don't want the code to do nothing, you want it to keep reading the input. Don't worry if nothing changes for some time, the Arduino won't get bored, heat up or wear out. The whole point of the loop() function is that it keeps repeating code until something happens.

If you really don't want to keep executing the code to stop the stepper then set a boolean variable (perhaps named stopped) to true when you stop it and check it before running the code to stop it again. In the code to run the stepper set the stopped variable to false.

There is a simple way to tell the Arduino to do nothing for a while but I am not going to tell you what it is !

Just an update, I tried your advice with the pullUp and it worked great. Motor starts when pin2 goes low. I left the code with all the lines in it for the else statement and noticed that in this state the motor gets very hot. I am going to try leave the code blank in the else statement and see what happens or just get it to do one small task.