Stepper motor help

Hello everyone, I am new at this. I made a code for a stepper motor for a project. I need to control it x revolutions to one direction then push the button and make it go x revolutions to the oposite direction. this is because I designed a furniture that holds a tv that you can use it from both sides of the furniture, therefore the direction of rotation always must be the same, left to right then right to left, so the tv wires wont twist.

this is the code I wrote, the thing is that its unreliable, some times goes right to left, then left to right, but many times makes the rotation to the same direction twice or more times or goes totaly random.

I read somewhere to use resistors, I did trie to put a resistor into the button but it didn´t work. and it has to work with only one push button so I can take this to iot cloud and make it work from a cellphone.

somebody can help me?.

this is my code

#include <Stepper.h>
int stepsPerRevolution=2048;
int motSpeed=10;
int dt=500;
Stepper myStepper(stepsPerRevolution, 8,10,9,11);

int buttonPin=2;
int motDir=1;
int buttonValNew;
int buttonValOld=1;



void setup() {
  // put your setup code here, to run once:
Serial.begin(9600);
myStepper.setSpeed(motSpeed);
pinMode(buttonPin,INPUT);
digitalWrite(buttonPin,HIGH);
}

void loop() {  
buttonValNew=digitalRead(buttonPin);
if (buttonValOld==1 && buttonValNew==0){
  motDir=motDir*(1);
  myStepper.step(stepsPerRevolution);  
  }
delay;
buttonValNew=digitalRead(buttonPin);
if (buttonValOld==1 && buttonValNew==0){
  motDir=motDir*(-1);
  myStepper.step(-stepsPerRevolution);  
  }
delay;
  }

Please post a little schematics. Pen and paper is fine. How that button is connected raises questions.
The powering of the stepper is interesting to check.

@arqjuanmrossi - I suspect this was to be the delay time mentioned above ( @Delta_G )... try replacing delay; with delay(dt);

thanks to everyone, the button is one pin connected to pin 2 and the other to ground, I made this code based on pauls Mcwhorter schematics for a stepper then I copied the lines for the buttons. As I said I am just a begginer with this, Its been just a month since I started learning things. the delay I put it so it would stop, I don´t know if its really needed.
the thing is if someone could help me to fix it so it can go one turn and one turn back, it just needs to go one or half turn since its te rotation needed for the tv.

I made a schematics, but don´t know how to upload it to the forum, I sent it to you trought the mail that I recived from arduino forum.

thats the actual code, I put the delay thinking it would stop the stepper between the lines.

that may have been a mistake, or something else, because i started with pauls mcwhorter code for stepper where it has a delay time from right to left I guess...
what I want to do is to make the stepper go one way, then push the button and make it go back , and so on. the goal would be to be able to make this work with the iot cloud server and operate it from the phone app. so you can turn the tv arround from anywhere without getting up or pushing an actual button on the furniture.
if someone of you knows how to do that coding please help me because I know very little at this time.... I can turn on and off relays and see temperature sensors from the iot but I don´t have a clue how to make it work with the stepper...

thanks to everyone!!

I tried some of the things that everyone told me including your advise.
now I got it working but the second time I pressed the button it went crazy.

this is the code I am using now.


#include <Stepper.h>
int stepsPerRevolution=2048;
int motSpeed=10;
int dt=500;
Stepper myStepper(stepsPerRevolution, 8,10,9,11);

int buttonPin=2;
int motDir=1;
int buttonValNew;
int buttonValOld=1;

void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
myStepper.setSpeed(motSpeed);
pinMode(buttonPin, INPUT_PULLUP);
digitalWrite(buttonPin,HIGH);
}

void loop() {
buttonValNew=digitalRead(buttonPin);
if (buttonValOld==1 && buttonValNew==0){
motDir=motDir*(1);
myStepper.step(stepsPerRevolution);
}
buttonValNew=digitalRead(buttonPin);
if (buttonValOld==1 && buttonValNew==0){
motDir=motDir*(-1);
myStepper.step(-stepsPerRevolution);

delay;
}
}
````

I saw, that some times he uses delay, and I thought that that was to make some sort of diference with lines in coding; like I said I am totally newbie

Your original code was correct, but the old way, and maybe confusing to some.

pinMode(buttonPin,INPUT); // not needed, because the pin is already an INPUT at bootup
digitalWrite(buttonPin,HIGH); // enable internal pull up

// replaced with

digitalWrite(buttonPin, INPUT_PULLUP); // enable pull up on an input pin, all in one line

// this is doing things twice

pinMode(buttonPin, INPUT_PULLUP); // enable pull up
digitalWrite(buttonPin,HIGH); // enable pull up

Leo..

Don't guess about those things. There's no need to guess, there's documentation for all these functions - when you don't understand a function or a command, look it up rather than trying to guess what it means. That way you never make any progress in understanding what you're doing.

The same accounts for all other functions there.

One very likely issue you still have is button bounce - where a button when pressed makes contact, breaks it again, and after a few bounces finally comes to reset. That takes a millisecond or two, which is fast for us humans but a very long time for an Arduino. Do check out this link, even a simple button is not as simple as you probably think it is!

There are some points to consider with your code.
You are using the stepper.h library which blocks while the stepper is moving. This has pros and cons:

  • + You don't need debouncing, because after the first contact when you press the button and the motor starts, any bouncing happens while the stepper is already turning and thus is ignored.
  • + You don't need state change detection, if you don't press the button longer than the rotation lasts (and that may take a while). That means you don't need buttonValOld ( which you in fact really don't use so far)
  • - You cannot stop the movement of the stepper while it is rotating. If that is a problem for you, you should change to another library.

Your motDir is set but never used. You can use it to remember the last direction of movement, so you can alternate the direction of movement with each button press.

Consider (untested):

    buttonValNew = digitalRead(buttonPin);
    if (buttonValNew == LOW) {
        // button has been pressed, start movement
        if ( motDir == 1) { // direction of rotation?
            myStepper.step(stepsPerRevolution);
            motDir = 0;
        } else {
            myStepper.step(-stepsPerRevolution);
            motDir = 1;
        }
        delay(500);  // if you want a delay after movement
    }

thanks so much I am going to try it tonight!

thank you very much, It is true I dont need to change direction while its rotating, I need just the start and end result, I guess If I could use a slider in IOT or a potentiometer in a physical control I could make it stop in the way so yo could angle the tv as you like but I am happy just to get it working like this. Thanks so much again I will try it tonight!!

MicroBahner
thank you very much, it seems to work now, I haven´t fully tested it but it work, until now it doesn´t make random movements.
tanks a lot, now I am going to study the things you mentioned in your answer.

thanks again!!

juan

t

leo,
I made the change you told me to, and it worked like five times in a row, then it started to go random again, the change that MicroBahner suggested, seems to be stable. and as far as I know it still is stable.

I quite don´t know the difference but it works

best regard

juan

You only need the one line with INPUL_PULLUP in setup().
That internal pull up will replace the need for an external pull up resistor. But that won't fix contact bouncing, which needs extra code in loop() when the button is actually pressed.
Leo..

oh, ok I didnt understood the thing with the pull up resistor, now I understand. Thank you so much

hi everyone Its me again,
Since I got it working, now I am trying with the iot cloud.
thing is I made it work thanks to you guys with a physical button, now I am trying in the iot with a esp32 nodemcu s32. I have tried this microcontroller with relays and goes great. the thing is, I made my thing, then my variable, with a boolean, stepper, then linked it to a push button like the physical arduino. and what happens is that allways goes clockwise.
I made some adjustments but I am blind with this because there is no reference on how the button opperates.
here is the original code that works, and down I will put the iot clud sketch code,

arduino UNO code

#include <Stepper.h>
int stepsPerRevolution=2048;
int motSpeed=10;
int dt=500;
Stepper myStepper(stepsPerRevolution, 8,10,9,11);

int buttonPin=2;
int motDir=1;
int buttonValNew;
int buttonValOld=1;



void setup() {
  // put your setup code here, to run once:
Serial.begin(9600);
myStepper.setSpeed(motSpeed);
digitalWrite(buttonPin, INPUT_PULLUP);
}

void loop() {
buttonValNew = digitalRead(buttonPin);
    if (buttonValNew == LOW) {
        // button has been pressed, start movement
        if ( motDir == 1) { // direction of rotation?
            myStepper.step(stepsPerRevolution);
            motDir = 0;
        } else {
            myStepper.step(-stepsPerRevolution);
            motDir = 1;
        }
        delay(500);  // if you want a delay after movement
    }
    }

And here is the code from the IOT Sketch.

/* 
  Sketch generated by the Arduino IoT Cloud Thing "Untitled 2"
  https://create.arduino.cc/cloud/things/6be332f7-5ee9-4bb7-a7c2-751e9f71c806 

  Arduino IoT Cloud Variables description

  The following variables are automatically generated and updated when changes are made to the Thing

  bool stepper_01;

  Variables which are marked as READ/WRITE in the Cloud Thing will also have functions
  which are called when their values are changed from the Dashboard.
  These functions are generated with the Thing and added at the end of this sketch.
*/

#include "thingProperties.h"
#include <Stepper.h>
int stepsPerRevolution=2048;
int motSpeed=10;
int dt=500;
int motDir=1;
Stepper myStepper(stepsPerRevolution,16,17,5,18);


void setup() {
  // Initialize serial and wait for port to open:
  Serial.begin(9600);
  // This delay gives the chance to wait for a Serial Monitor without blocking if none is found
  delay(1500); 
  myStepper.setSpeed(motSpeed);

  // Defined in thingProperties.h
  initProperties();

  // Connect to Arduino IoT Cloud
  ArduinoCloud.begin(ArduinoIoTPreferredConnection);
  
  /*
     The following function allows you to obtain more information
     related to the state of network and IoT Cloud connection and errors
     the higher number the more granular information you’ll get.
     The default is 0 (only errors).
     Maximum is 4
 */
  setDebugMessageLevel(2);
  ArduinoCloud.printDebugInfo();
  
  
}

void loop() {
  ArduinoCloud.update();
  // Your code here 
  }
/*
  Since Stepper01 is READ_WRITE variable, onStepper01Change() is
  executed every time a new value is received from IoT Cloud.
*/
void onStepper01Change()  {
  if (stepper_01==LOW){

   if ( motDir == 1) {
  myStepper.step(stepsPerRevolution);
            motDir = 0;
  }else{
      myStepper.step(-stepsPerRevolution);
            motDir = 1;
             
  delay(500);
  }}
}

Can you tell me since I know nothing about this what I am doing wrong????

thanks to you allll

best regards!!

juan