-2

I want to create an Arduino program for a system that has three buttons and one stepper motor. If button 1 is pressed, the stepper should go for example 50 steps forward. If button 2 is pressed, the stepper should go 50 steps backward. If button 3 is pressed, the stepper should go 50 steps forward after that 50 steps backward.

I used Arduino's stepper library and wrote the following code. The functions Forward(), Backward() and Continuous() implement the actions to be performed for each button. Each function moves the motor step by step and logs the action on a serial output.

But I could not achieve my desired results: The stepper does not go backward but only goes forward. More precisely:

  • Forward() works as expected
  • Backward() produces the expected logging output (counting the steps up to 50), but the motor only moves forward instead of backward.
  • Continuous() function is not working either: after 50 step forward (moving and logging the step count), it continues moving forward logging just 1 for the counter.

I need your help. How can I make the motor going backwards in Backward()? And how to correct Continuous() to achieve move forward and backward, and producing the right backward step count?

Here my code:

#include <Stepper.h>

int forward_button = 2;
int backward_button = 3;
int cont_button = 4;

int button_cond1;
int button_cond2;
int button_cond3;

int del = 50;

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);
int stepCount = 0;         // number of steps the motor has taken
int steps;

void Forward() { // should go forward by 50 steps
  int stepCount = 0; 
  while (stepCount < 50) {
    steps = 1;
    myStepper.step(steps);
    stepCount++;
    delay(del);
    Serial.print("Forward steps :");
    Serial.println(stepCount);
  }
}

void Backward() { // should go backward by 50 steps
   int stepCount = 0;
   while (stepCount < 50) {
    steps = 1;
    myStepper.step(steps);
    stepCount++;
    delay(del);
    Serial.print("Backward steps :");
    Serial.println(stepCount);
  }
}

void Continuous() {  // should go forward by 50 steps, then backwards
  int stepCount = 0; 
  while (stepCount < 50) {
    steps = 1;
    myStepper.step(steps);
    stepCount++;
    delay(del);
    Serial.print("Continuous steps :");
    Serial.println(stepCount);
  }
  while (50 < stepCount <= 200) {
    int stepCount = 0;
    steps = 1;
    myStepper.step(steps);
    stepCount++;
    delay(del);
    Serial.print("Continuous steps :");
    Serial.println(stepCount);
  }
}

void setup() {
  // initialize the serial port:
  Serial.begin(9600);

  pinMode(forward_button, INPUT_PULLUP);
  pinMode(backward_button, INPUT_PULLUP);
  pinMode(cont_button, INPUT_PULLUP);

  //myStepper.setSpeed(60);
}

void loop() {
  // step one step:

  button_cond1 = digitalRead(forward_button);
  button_cond2 = digitalRead(backward_button);
  button_cond3 = digitalRead(cont_button);

  if ((button_cond1 == LOW) && (button_cond2 == HIGH) && (button_cond3 == HIGH))  {
    Forward();
  }
  else if ((button_cond1 == HIGH) && (button_cond2 == LOW) && (button_cond3 == HIGH))  {
    Backward();
  }
  else if ((button_cond1 == HIGH) && (button_cond2 == HIGH) && (button_cond3 == LOW))  {
    Continuous();
  } 
}
Christophe
  • 68,716
  • 7
  • 72
  • 138
  • `stepsPerRevolution` is changed in Backward() but not used. It won't change what happens with the stepper. – drescherjm Aug 22 '21 at 18:38
  • 1
    why change `stepsPerRevolution`, especially AFTER the Stepper object has been initialized ? did you try `myStepper.step(-1)` ? you define a `Forward()` and a `Backward()`function, why don't you use them inside `Continuous()` ? – Adrien Plisson Aug 22 '21 at 18:39
  • actually I forgot to delete them. I have tried just .step(1) and .step(-1) instead of them but the result is same – Meryem Çiftçi Aug 22 '21 at 18:43
  • I'm gonna edit the code in the question now – Meryem Çiftçi Aug 22 '21 at 18:53
  • 2
    `while (50 < stepCount <= 200) {` doesn't look right.. – Dmitri Aug 22 '21 at 19:06
  • there is an example code here: https://www.arduino.cc/en/Tutorial/LibraryExamples/StepperOneRevolution if your stepper does not go backward with this example code, you should chack how your stepper is connected to the board. – Adrien Plisson Aug 22 '21 at 19:18
  • @AdrienPlisson I'm making use of an example code but it is StepperOneStep, in that code .step(1) goes 1 step and I thought that if I write .step(-1) it will go backward :'((. I don't think the stepper is wrongly connected to the board – Meryem Çiftçi Aug 22 '21 at 19:19
  • Read documentation and `while (50 < stepCount <= 200)` realize that C/C++ is not python. – TomServo Aug 22 '21 at 22:26
  • This might be better split into several separate questions. If possible, pare down your code into a minimal reproducible example. – James Martherus Aug 23 '21 at 03:20
  • Hi @MeryemÇiftçi, I just updated your question to summarize the more detailed description and debugging information that you provided in our comment exchange. Not everybody is reading the comments and when such explanations is not immediately available in the question, some people tend to downvote – Christophe Aug 26 '21 at 14:48

1 Answers1

1

Issue with the direction of the stepper:

According to the documentation, myStepper.step() turns the motor:

Turns the motor a specific number of steps, at a speed determined by the most recent call to setSpeed().

And more importantly, to move in both directions, it uses a signed argument:

the number of steps to turn the motor - positive to turn one direction, negative to turn the other (int)

In your code, there is no difference between Backward() and Forward(): you provide positive values in both cases. So I suggest to change Backwards() to use a negative number:

myStepper.step(-steps); 

Issues with the logic of Continuous()

The direction needs also to be corrected in the second loop of your Continuous() function, where you want to go backwards.
But first, you need to correct this loop's condition:

while (50 < stepCount <= 200) {  //OUCH compares a boolean and an integer

C++ does not chain the comparison operators as you think. Therefore break it up in two distinct comparisons grouped with a logical and:

while (50 < stepCount && stepCount <= 200) { 

Unfortunately, at the end of the first loop stepCount is exactly 50. And 50 is not strictly smaller (<) than 50. You could use a smaller or equal (<=) instead, but since the loop does not decrement the counter, you could simplify the condition to:

while (stepCount <= 200) { // we know that it will stay 50 or above

You also need to delete the redefinition of stepCount in this loop's block, since it creates a new local variable that hides the initial definition (i.e. one name, two variables, that's very confusing).

If it still does not work

Following the long exchange of comments, here some advice (in bold the one that solved the issue):

  • Make sure the latest version of the code runs on the arduino and there's no compilation error or warning.
  • Make sure that the different buttons execute the expected function.
  • If the motor movements are not as expected, make sure that you Stepper object is configured with a number of steps per rotation that is compatible with the motor.
  • If the movements are erratic, or if there is no difference between positive and negative steps (which should according to the documentation move in opposite directions), then cross check that the Stepper's constructor gets the pin numbers in the right order: this is important, because Stepper will send a sequence of signals to the different pins in a given order to achieve the right motion.

If it still does not work there is either a hardware issue, or an incompatibility with the library (see for example here, where the authors solved the problem by providing another signal sequences, which is not the easiest way).

Christophe
  • 68,716
  • 7
  • 72
  • 138
  • Hello @Christophe. First of all, thanks for your detailed answer. I applied your suggestions to my code but now, just button 1 is working which makes the stepper go forward. buttons for backward() and continuous() functions do not work at the moment – Meryem Çiftçi Aug 22 '21 at 21:45
  • Let's go one at a time: 1) In backward, how does "not working at all" looks like: no movement at all ? A few movements ? A software error message ? And what output do you get on serial? 2) If in continuous, you'd go forwarding in the second loop, would it work, with two sequences of forwarding ? If not, how does it react precisely? – Christophe Aug 22 '21 at 22:13
  • 1) in backward() , it goes forward with determined steps. The serial port gives steps 1 to 50 which I expected. 2) in continuous(), the first while loops works from 1-50 steps however in the second while loop, the stepCount becomes just 1 in serial port and the stepper continues its forward motion. However, in the second loop, it needs to turn back and move backward – Meryem Çiftçi Aug 23 '21 at 11:37
  • Ok. So I understand that the button control seems to work? But if the motor fails to go backwards despite the negative steps, there may be an issue with the sequencing (e.g. maybe the order of the pins in the constructor should be different, e.g. the two last ones inverted?). Also check that the number of steps in the constructor matches the steps of the motor, to eliminate any issues related to differences there. Finally, the fact of step count 1 means that you did not apply the last sentence of my answer: please remove the ` int stepCount = 0;` inside the while loop. – Christophe Aug 23 '21 at 13:21
  • When you said, I removed the stepCount variable inside the while loop but it stays the same. it turns 1 1 1 1... – Meryem Çiftçi Aug 23 '21 at 20:07
  • @MeryemÇiftçi ok. two more questions: 1) what did you finally use as condition for the second while loop? 2) are you sure that your arduino executes the last version of your code ? (it’ as if none of the changes was taken into account) – Christophe Aug 23 '21 at 20:24
  • 1) I made use of what you've suggested, here it is: void Continuous() { while (stepCount < 50) { myStepper.step(steps); stepCount++; delay(del); Serial.print("Continuous steps :"); Serial.println(stepCount); } while (50 < stepCount && stepCount <= 200) { myStepper.step(-steps); stepCount++; delay(del); Serial.print("Continuous steps :"); Serial.println(stepCount); } } 2) Yes, I'm sure – Meryem Çiftçi Aug 24 '21 at 09:24
  • @MeryemÇiftçi Looking closer, when the first while ends, stepCount is 50 when you then enter the second loop, it is not executed since 50<50 is false. What happens when you try to change remove in the condition of the second while the `50 – Christophe Aug 24 '21 at 09:31
  • hey @Christophe, I applied your suggestions and I did not get any errors or warnings. However, the stepper still turns just forward, not backward whatever button I pressed on. Do you have any ideas about that :'( appreciated btw – Meryem Çiftçi Aug 25 '21 at 19:04
  • @MeryemÇiftçi The documentation says that the change of sign changes the direction. If there is no change of direction despite the change of sign, it might be a hardware issue (e,g wrong order of pins), a hardware incompatibility (on an areuino forum someone had to change the stepper code to change dime values in a long array used for the sequencing of signals) or another configuration issue – Christophe Aug 25 '21 at 19:50
  • @MeryemÇiftçi here I am at the end of the help that I can provide and I suspect that nobody here will be able to diagnose hardware issue if the hw does not react as expected by the software interface. :-/ – Christophe Aug 25 '21 at 19:55
  • 1
    hey @Christophe, I handled the problem. I just wrote Stepper myStepper(stepsPerRevolution, 8, 10, 9, 11) by changing the places. Thanks for your help, I will be more careful about writing pins – Meryem Çiftçi Aug 26 '21 at 13:26
  • @MeryemÇiftçi I'm happy that this exchange finally helped to solve the problem. I've edited my answer to incorporate the main points in our comment exchange, so that it can help also other people to solve similar problems ;-). – Christophe Aug 26 '21 at 14:19