Go Down

Topic: stepper buttons and debounc (Read 712 times) previous topic - next topic

0joze0

Nov 22, 2018, 10:10 am Last Edit: Nov 22, 2018, 10:25 am by 0joze0
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

Robin2

#1
Nov 22, 2018, 01:02 pm Last Edit: Nov 22, 2018, 01:03 pm by Robin2
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
Two or three hours spent thinking and reading documentation solves most programming problems.

0joze0

 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.






Paul_KD7HB

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

Paul

0joze0

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 ?

0joze0

#5
Nov 22, 2018, 10:03 pm Last Edit: Nov 22, 2018, 10:04 pm by 0joze0

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



Code: [Select]

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]

Robin2

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
Two or three hours spent thinking and reading documentation solves most programming problems.

0joze0

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.



Robin2

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
Two or three hours spent thinking and reading documentation solves most programming problems.

0joze0

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

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

Robin2

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.

Quote
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
Two or three hours spent thinking and reading documentation solves most programming problems.

0joze0

Sorry for late answer.

Here is the code that I have loaded.



Code: [Select]


// 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






Robin2

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
Two or three hours spent thinking and reading documentation solves most programming problems.

0joze0

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

Robin2

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
Two or three hours spent thinking and reading documentation solves most programming problems.

Go Up