I am trying to have a stepper motor rotate in one direction continously once a button is pressed and released and stop when a limit switch is activated.
The problem is that if both conditions are "IF" statements, the stepper stops rotating after the button is released.
If both conditions are "WHILE" statments, the stepper will not stop when the limit switch is activated.
If the "IF" condition is nested within the "WHILE" (or vice versa), the "WHILE" always seems to have precedent and the orginal intent is still not accomplished.
Here is a version of the the code with both conditions as "IF" statements.
const int limitSwitchPin = 3;
const int buttonPin = 8;
int limitSwitchState = 0;
int buttonState = 0;
void setup() {
pinMode(limitSwitchPin, INPUT);
pinMode(buttonPin, INPUT);
pinMode(9, OUTPUT); //Dir
pinMode(10, OUTPUT);//Pul
}
void loop() {
limitSwitchState = digitalRead(limitSwitchPin);
buttonState = digitalRead(buttonPin);
if((buttonState == HIGH)&&(limitSwitchState == LOW)){
rotateForward();
}
}
void rotateForward(){
digitalWrite(9, HIGH);
digitalWrite(10, HIGH);
delayMicroseconds(100);
digitalWrite(10, LOW);
}
Any help would be much appreciated.
You need another variable to read the button and then store the result in buttonState.
Define buttonRead in the setup and insert:
buttonRead = digitalRead(buttonPin);
if (buttonRead == HIGH)
{
buttonState = HIGH;
}
After that you can make your if condition
if((buttonState == HIGH)&&(limitSwitchState == LOW)){
Then save it when the button became pressed and reset that when the limit is reached. Only rotate while the flag is set.
Btw, did you connect a pull down resistor to the switch? Also, keep in mind the delay() in the rotate function will block the reading of the switches while it's waiting. Maybe go for a library?
const int limitSwitchPin = 3;
const int buttonPin = 8;
void setup() {
pinMode(limitSwitchPin, INPUT);
pinMode(buttonPin, INPUT);
pinMode(9, OUTPUT); //Direction
pinMode(10, OUTPUT);// Step
}
void loop() {
static boolean running = false;
int limitSwitchState = digitalRead(limitSwitchPin);
int buttonState = digitalRead(buttonPin);
if (buttonState == HIGH)
running = true;
if (running && (limitSwitchState == LOW))
rotateForward();
else
running = false;
}
void rotateForward() {
digitalWrite(9, HIGH);
digitalWrite(10, HIGH);
delayMicroseconds(100);
digitalWrite(10, LOW);
}
I have now tried for hours to have the motor rotate in the other direction once the limit switch is activated with no success.
Similar to the first issue, it only rotates back when the limit switch is coninually held high. I would like the motor to rotate back with an initial activation similar to when it rotates forward with a push of button.
My current code reads something as follows:
const int limitSwitchPin = 3;
const int buttonPin = 8;
void setup() {
pinMode(limitSwitchPin, INPUT);
pinMode(buttonPin, INPUT);
pinMode(9, OUTPUT); //Direction
pinMode(10, OUTPUT);// Step
}
void loop() {
static boolean running = false;
int limitSwitchState = digitalRead(limitSwitchPin);
int buttonState = digitalRead(buttonPin);
if (buttonState == HIGH)
running = true;
if (running && (limitSwitchState == LOW))
rotateForward();
if (limitSwitchState == HIGH){
rotateBackward();}
/* else
running = false;*/
}
void rotateForward() {
digitalWrite(9, HIGH);
digitalWrite(10, HIGH);
delayMicroseconds(100);
digitalWrite(10, LOW);
}
void rotateBackward(){
digitalWrite(9, LOW);
digitalWrite(10, LOW);
delayMicroseconds(100);
digitalWrite(10, HIGH);
}
Help in correcting would be greatly appreciated.
if (running && (limitSwitchState == LOW))
rotateForward();
That's not what you want... Why include the limit switch it you want to rotate even when it's not pressed?
So WHEN do you want to turn the other way?
Because you wanted to go to the first limit switch after you pressed the button. When does it need to go the other way?
And you only use one limit switch? For both ends?
And start making it a habbit to give every pin you use a name. You might know now that pin 9 and 10 are for the stepper. But we don't and future you in a year might not as well.
When the limit switch == HIGH, I would like for the stepper to rotate in the opposite direction.
I do have another limit switch (limitSwitch2) that will stop the entire process once activated.
Your initial requirement only had two states: Idle and Forward. Your new requirement added at least one new state: Backward. You can keep track of the state with a variable like the 'running' variable but with more than two states. The 'enum' (enumeration) type is good for keeping track of states and the switch/case statement is a good way to associate a bit of code with each state.
const int limitSwitchPin = 3;
const int buttonPin = 8;
const int StepperStepPin = 10;
const int StepperDirectionPin = 9;
enum {IdleState, ForwardState, BackwardState} State;
void setup() {
pinMode(limitSwitchPin, INPUT);
pinMode(buttonPin, INPUT);
pinMode(StepperDirectionPin, OUTPUT); //Direction
pinMode(StepperStepPin, OUTPUT); // Step
State = IdleState;
}
void loop() {
switch (State) {
case IdleState:
if (digitalRead(buttonPin) == HIGH)
State = ForwardState;
break;
case ForwardState:
rotateForward();
if (digitalRead(limitSwitchPin) == HIGH)
State = BackwardState;
break;
case BackwardState:
rotateBackward();
// NOTE: This backward motion will never stop
break;
} // end switch
}
void rotateForward() {
digitalWrite(StepperDirectionPin, HIGH);
digitalWrite(StepperStepPin, HIGH);
delayMicroseconds(100);
digitalWrite(StepperStepPin, LOW);
}
void rotateBackward() {
digitalWrite(StepperDirectionPin, LOW);
digitalWrite(StepperStepPin, LOW);
delayMicroseconds(100);
digitalWrite(StepperStepPin, HIGH);
}
Still vague..
So, to recap, you want to start moving in direction A when the button is pressed?
Go in direction when limitSwitch 1 is reached?
Stop all together when limit switch 2 is reached?
Then have a look at state machines
Then t will look like:
const int LimitSwitchPins[] = {3, 4};
const int ButtonPin = 8;
enum run_states_t {R_STOP, R_FORWARD, R_BACKWARD};
void setup() {
for(byte i = 0; i < sizeof(LimitSwitchPins); i++){
pinMode(LimitSwitchPins[i], INPUT);
}
pinMode(ButtonPin, INPUT);
pinMode(9, OUTPUT); //Direction
pinMode(10, OUTPUT);// Step
}
void loop() {
static byte runState = R_STOP;
if(runState == R_FORWARD){
rotateForward();
//if limit switch is reached, go backwards
if(!LimitSwitchPins[0]){
runState = R_BACKWARD;
}
}
else if(runState == R_BACKWARD){
rotateBackward();
//if limit switch is reached, stop
if(!LimitSwitchPins[1]){
runState = R_STOP;
}
}
else{
//We need to stop, just check the button
//If the button is pressed, go forwards
if(digitalRead(ButtonPin)){
runState = R_FORWARD;
}
}
}
void rotateForward() {
digitalWrite(9, HIGH);
digitalWrite(10, HIGH);
delayMicroseconds(100);
digitalWrite(10, LOW);
}
void rotateBackward(){
digitalWrite(9, LOW);
digitalWrite(10, LOW);
delayMicroseconds(100);
digitalWrite(10, HIGH);
}
John was first, almost looks the same 