Go Down

Topic: Button control stepper motor forward and backward (Read 154 times) previous topic - next topic

laoadam

Used two buttons to control the stepper motor forward and backward by the sketch attached, it was OK. I tried to stop the motor by changed the  myStepper.setSpeed(motorSpeed); into myStepper.setSpeed(0); and used  BTStop button, the motor can't restart again even pressed the Forward button after BTStop pressed. why? how to use button control the running stepper motor?

Thanks


Code: [Select]


//20200528 test GOOD!

const int BTSMForward  = A2; 
const int BTSMBackward = A3;

int BTSMForwardState = 0;
int BTSMBackwardState = 0;

const int BTStop = A4;

int BTStopState = 0;

#include <Stepper.h>

const int stepsPerRevolution = 200;  /

Stepper myStepper(stepsPerRevolution, 8, 9, 10, 11);

int stepCount = 0;  // number of steps the motor has taken

void setup() {

  Serial.begin(9600);

  pinMode(BTSMForward, INPUT_PULLUP);
  pinMode(BTStop, INPUT_PULLUP);

} // close setup

void loop() {

  button();

}

void button() {

  BTStopState = digitalRead(BTStop);

  if (!BTStopState) {

    Stop();
  }

  BTSMForwardState = digitalRead(BTSMForward);
  if (BTSMForwardState) {

    ForwardSM();
  }

  BTSMBackwardState = digitalRead(BTSMBackward);
  if (BTSMBackwardState) {

    BackwardSM();
  }
}
// close void loop

void ForwardSM() {

  // read the sensor value:
  int sensorReading = analogRead(A0);
  // map it to a range from 0 to 100:
  int motorSpeed = map(sensorReading, 0, 1023, 0, 100);
  // set the motor speed:
  if (motorSpeed > 0) {
    myStepper.setSpeed(motorSpeed);
    // step 1/100 of a revolution:
    myStepper.step(stepsPerRevolution / 100);
  }
}

void BackwardSM() {
  // read the sensor value:
  int sensorReading = analogRead(A0);
  // map it to a range from 0 to 100:
  int motorSpeed = map(sensorReading, 0, 1023, 0, 100);
  // set the motor speed:
  if (motorSpeed > 0) {
    ///  myStepper.setSpeed(motorSpeed);

    myStepper.setSpeed(0);

    myStepper.setSpeed(motorSpeed);

    // step 1/100 of a revolution:
    myStepper.step(-stepsPerRevolution / 100);
  }
}

void Stop() {

  // read the sensor value:
  int sensorReading = analogRead(A0);
  // map it to a range from 0 to 100:
  int motorSpeed = map(sensorReading, 0, 1023, 0, 100);
  // set the motor speed:
  if (motorSpeed > 0) {
    myStepper.setSpeed(0);
    // step 1/100 of a revolution:
    myStepper.step(-stepsPerRevolution / 100);
  }
  Serial.print("stop");
  //  Serial.print();
}


JCA34F

#1
May 29, 2020, 02:06 am Last Edit: May 29, 2020, 02:07 am by JCA34F
Code: [Select]
myStepper.setSpeed(0);
    // step 1/100 of a revolution:
    myStepper.step(-stepsPerRevolution / 100); // this can't happen with speed set to 0,
                                                // your code probably hangs here

Robin2

#2
May 29, 2020, 11:24 am Last Edit: May 29, 2020, 11:25 am by Robin2
This is not the right way to go about it
Code: [Select]
void button() {

  BTStopState = digitalRead(BTStop);

  if (!BTStopState) {

    Stop();
  }

  BTSMForwardState = digitalRead(BTSMForward);
  if (BTSMForwardState) {

    ForwardSM();
  }

  BTSMBackwardState = digitalRead(BTSMBackward);
  if (BTSMBackwardState) {

    BackwardSM();
  }
}


You have three separate variables but logically the motor can only do one thing so you should have a single variable let's call it motorState and depending on which button is pressed it should have the values 'S' for stop, 'F' for forward and 'B' for backward.

And then the code in the action functions can just check that variable to decide if they should work - for example

Code: [Select]
void ForwardSM() {
    if (motorState != 'F') {
         return)
    }
    // the rest of the code
}


and the functions ForwardSM()  etc should be called from loop() like this
Code: [Select]
void loop() {
  button();
  ForwardSM();
  // etc
}


...R
Two or three hours spent thinking and reading documentation solves most programming problems.

gcjr

- don't you need a pinMode for BTSMBackward?

- your Forward(), Backward() and Stop() are very similar.  why not have just one function that uses global variables for speed or direction and recognize that speed == 0 implies stop

- in button, why not set parameters for speed: 0, + or -, instead of calling unique functions

- do you need to capture a button press so the motor function is only called once.



greg - somerset, nj
seeing well written code is the best way to learn to write well written code.

laoadam

This is not the right way to go about it
Code: [Select]
void button() {

  BTStopState = digitalRead(BTStop);

  if (!BTStopState) {

    Stop();
  }

  BTSMForwardState = digitalRead(BTSMForward);
  if (BTSMForwardState) {

    ForwardSM();
  }

  BTSMBackwardState = digitalRead(BTSMBackward);
  if (BTSMBackwardState) {

    BackwardSM();
  }
}


You have three separate variables but logically the motor can only do one thing so you should have a single variable let's call it motorState and depending on which button is pressed it should have the values 'S' for stop, 'F' for forward and 'B' for backward.

And then the code in the action functions can just check that variable to decide if they should work - for example

Code: [Select]
void ForwardSM() {
    if (motorState != 'F') {
         return)
    }
    // the rest of the code
}


and the functions ForwardSM()  etc should be called from loop() like this
Code: [Select]
void loop() {
  button();
  ForwardSM();
  // etc
}


...R
Thanks, you are right, I was planning to use three buttons like you mentioned, F for forward, B-backward, S-stop, in the third Subroutine I coded:  myStepper.setSpeed(0) works , the stepper motor stop when I pressed the S button.
The problem is the motor can never restart again, even pressed F  or B.
Best

laoadam

Code: [Select]
myStepper.setSpeed(0);
    // step 1/100 of a revolution:
    myStepper.step(-stepsPerRevolution / 100); // this can't happen with speed set to 0,
                                                // your code probably hangs here

Thanks

 myStepper.step(-stepsPerRevolution / 100);  this make the motor reverse only;
 myStepper.setSpeed(0); this make the motor stop.
Best

laoadam

- don't you need a pinMode for BTSMBackward?

- your Forward(), Backward() and Stop() are very similar.  why not have just one function that uses global variables for speed or direction and recognize that speed == 0 implies stop

- in button, why not set parameters for speed: 0, + or -, instead of calling unique functions

- do you need to capture a button press so the motor function is only called once.


Thanks, you are right, I need  a pinMode for BTSMBackward? but the code work well on Arduino UNO, and the F/B buttons work well. problem came as long as I added S button.

Yes, I'll learn to config the button and try to use just one.
Best



Go Up