stepper buttons and debounc

I am using code from Robin2 ( Simple stepper program -without delay), to run stepper with 2 pushbuttons.

https://forum.arduino.cc/index.php?topic=277692.0

Somethimes it happen that when I push CCW button, motor make 1 step CW and then run correct CCW direction. The same is for CW button.

Maybe the reason is button debouncing, but why motor turns first 1 step wrong direction...

How can I implement debounce library code in that simple stepper program. As you can see, I am the beginner in arduino programming.

thx for help

0joze0: How can I implement debounce library code in that simple stepper program.

You can introduce a short interval (maybe 50 millisecs) between successive reads of the buttons. See how that is done in Several Things at a Time

Post a link to the datasheet for your stepper motor and tell us what driver you are using.

...R

I am using A4988 driver and didnt test yet with DRV8825.

I tested with 2 different motors from old printers , so dont have much datasheet..only steps 7.5 degree and coil resistance, that I was able to manage the current limit on driver board.

If I upload some test code only to run motors without button control, that works nice.

Are you using the enable/disable pin to stop the motor and controller?

Paul

Now I tied it to GND...enable , but it is the same

Should I try to add in the code, to switch it off/on every time button pressed ?

I added 6 delays and that works OK now. But need to be on all 6 lines I am using nano board

void readButtons() {

 buttonCCWpressed = false;
 buttonCWpressed = false;

 if (digitalRead(buttonCWpin) == HIGH) {
 delay(1);
   buttonCWpressed = true;

 }
 if (digitalRead(buttonCCWpin) == HIGH) {
 delay(1);
  buttonCCWpressed = true;

 }
}

void actOnButtons() {
 if (buttonCWpressed == true) {
 delay(1);
 digitalWrite(directionPin, LOW);
 delay(1);
 singleStep();
 }


 if (buttonCCWpressed == true) {
   delay(1);
 digitalWrite(directionPin, HIGH);
 delay(1);
 singleStep();
 }
}[code]

0joze0:
I added 6 delays and that works OK now.

If you study the example I gave you a link to you will see how to do it without using delay()

…R

Later I notice strange behaviour of motors after left buttons untached for a few minutes .

I found solution that now works OK without any delays added in the code.

In the function

void SingleStep()

I replaced line

prevStepMillis += millisBetweenSteps;

with

prevStepMillis = curMillis;

For button debouncing I am using RC circuit with Schmitt inverter.

Robin2, maybe you can also wire this setup and test and then correct the code for others, that also might have problems with this code.

0joze0:
I replaced line

prevStepMillis += millisBetweenSteps;

with

prevStepMillis = curMillis;

For button debouncing I am using RC circuit with Schmitt inverter.

Robin2, maybe you can also wire this setup and test and then correct the code for others, that also might have problems with this code.

The first way is generally the better way to do it as it avoids accumulating small timing errors.

If you need to do it the second way it suggests that some other part of the program you have not posted is getting in the way.

I certainly do not consider that my code needs “correcting”.

…R

I dont know why , I am realy beginer in programing.

I just copy paste your code for driving motor with buttons without delays.

0joze0: I dont know why , I am realy beginer in programing.

Based on that I don't know what you don't know so I can't help.

I just copy paste your code for driving motor with buttons without delays.

Post the exact program that YOU have uploaded to your Arduino and tell us in detail what it does and what you want it to do that is different.

...R

Sorry for late answer.

Here is the code that I have loaded.

// testing a stepper motor with a Pololu A4988 driver board or equivalent

// this version uses millis() to manage timing rather than delay()
// and the movement is determined by a pair of momentary push switches
// press one and it turns CW, press the other and it turns CCW

byte directionPin = 6;
byte stepPin = 7;

byte buttonCWpin = 4;
byte buttonCCWpin = 5;

boolean buttonCWpressed = false;
boolean buttonCCWpressed = false;

byte ledPin = 13;

unsigned long curMillis;
unsigned long prevStepMillis = 0;
unsigned long millisBetweenSteps = 300; // milliseconds

void setup() { 

  Serial.begin(9600);
  Serial.println("Starting Stepper Demo with millis()");

  pinMode(directionPin, OUTPUT);
  pinMode(stepPin, OUTPUT);
  pinMode(ledPin, OUTPUT);
  
  pinMode(buttonCWpin, INPUT);
  pinMode(buttonCCWpin, INPUT);
  
}

void loop() { 

 curMillis = millis();
 readButtons();
 actOnButtons();

}

void readButtons() {

 buttonCCWpressed = true;
 buttonCWpressed = true;

 if (digitalRead(buttonCWpin) == HIGH) {
 buttonCWpressed = false;
 }
 if (digitalRead(buttonCCWpin) == HIGH) {
 buttonCCWpressed = false;
 }
}

void actOnButtons() {
 if (buttonCWpressed == false) {
 digitalWrite(directionPin, LOW);
 singleStep();
 }
 if (buttonCCWpressed == false) {
 digitalWrite(directionPin, HIGH);
 singleStep();
 }
}

void singleStep() {
 if (curMillis - prevStepMillis >= millisBetweenSteps) {
// prevStepMillis += millisBetweenSteps;
prevStepMillis = curMillis;

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

Difference is at the end , your code have line prevStepMillis += millisBetweenSteps; which I changed to prevStepMillis = curMillis; and now motor runs smotely.

Before that ...

Somethimes it happen that when I push CCW button, motor make 1 step CW and then run correct CCW direction. The same is for CW button. Also jumps few steps ahead...which doesnt happen with changed line.

I am using RC debounce circuit with Schmitt triger.

Look at the video Stepper 1 is with your code, stepper 2 is with corrected code

stepper 1

stepper 2

I understand. I have just been having a similar problem myself.

The problem is that if you don't update the value of prevStepMillis it will have a very old value (maybe from some minutes ago) and the result of that is that there will be a huge number of very fast steps (probably too fast for the motor) while the time catches up.

Your solution is perfectly practical.

What I have done in my own program is the equivalent of setting prevStepMillis = currentMillis when a button is first pressed. That brings the value up to date without interfering with the slightly greater precision of using prevStepMillis += millisBetweenSteps; for the rest of the time that the button is held. But my program is not using button and I doubt if the small loss of accuracy will matter when using buttons.

I will consider whether I should change the demo code.

Many thanks for picking this up.

...R

Thanks for the explanation. It is realy nice feeling when things works as we plan. I am working on some kind of cutting machine and this was first step ... moving the motors :)

regards

0joze0: moving the motors

If you plan on moving two or more stepper motors in sync (like on a CNC machine) then I suspect precise step timing will be important and I would not rely on prevStepMillis = currentMillis other than for setting the initial value for a movement.

...R

It will be hobby machine and for now I dont need to spin motors in sync.

Maybe for some other project in future... I didnt try with any libraries yet

regards