Simple direction drive possible with input device?

Hello, I have never done anything with stepper motors and thought I would be able to just connect it to power and create a simple push button thing to move forward and back. It seems I underestimated that ordeal. What I am trying to do is have a stepper motor attached to something, have it where I push a button to go forward and one for reverse. This is what I bought to practice with, yet I am failing.....

http://www.amazon.com/gp/product/B00DUSYEWY/ref=wms_ohs_product?ie=UTF8&psc=1

But overall I would like to end with using something like this...

With the ability to drive it forward and reverse by a simple input.Maybe just pushing a momentary switch or using something like this....

I thought I would be able to use it without Arduino but guess not, so the Arduino I am using is the uno R3.

My son has a medical condition that stops him from using something he really enjoys, so I thought making it so he can control it with something as simple, would allow him to get back using it.

Any help would be greatly appreciated,thank you,
Shawn

I understand your situation. Let me explain ours. In order to help you , you need to provide more information. You need to tell us what you know about connecting this stepper motor to the driver. You need to draw us a schematic of how you connected the motor to the driver and the driver to the UNO. You need to take a photo directly above the circuit (about 1 to 2 feet) , a perfect birds eye view so we can see all the wires connecting them. If you had electronics experience this wouldn't be necessary because we could just tell you. You need to post the code you are running using the "#" code tags tool button. The links you posted are helpful but are no replacement for a complete report from you detailing exactly how you connected everything. If you have to use words and make a wiring list then do that. It is better than nothing but a schematic would be preferable.

I have never done anything with stepper motors

The following questions are rhetorical. I know you know nothing about stepper motors.
The questions are asked to get you to ask yourself those questions. Why this ? Why that ?

You would not believe how difficult it is to talk a complete newbie through their first project until you've done it. We don't know if you have a handle on it or if you are completely lost and have everything hooked up backwards until you prove to us that have a handle on it by posting a SITREP (situation report) along with a wiring list or schematic and brief us on your knowledge (or lack thereof) and experience (or lack thereof) using stepper motors. To start with, do you understand what makes it turn ? Do you understand the connection between the code and the rotation ? (Why does one code make it go one way , and another make it go the other way ?
Why does one code make it take full steps and another make it take half or 1/4 steps ? What makes it go faster or slower ? What types of code are available to drive stepper motors ? Do you know what a library is ? Do you know which libraries you can use to drive your stepper motor ? And last but not least, and this is probably the most important question: are you aware that a complete newbie who has never ever HEARD of an arduino OR a stepper motor before can learn everything they need to know to do what you want to do in one 8 to 10 hour day using nothing but Google and the right keywords ?

I have been using the short code below to experiment with a stepper motor. One button makes it go one way and gues what the the other button does. The code is designed for use with a stepper motor driver that takes step and direction inputs. Changing the value of microsBetweenSteps changes the speed of the motor.

Stepper motors can be used with motor shields and with L298 H-bridges but these are a very poor alternative to a proper stepper motor driver board. I am using Pololu A4988 drivers and their web page has a huge amount of useful information.

To choose a stepper motor first you must decide how much torque you need. The next important thing is the max current drawn by the motor coils. You must choose a stepper driver board that can comfortably supply that current. Most stepper driver specs mention a coil voltage which is usually irrelevant. Stepper motors work better when driven using a high voltage (the A4988 can go up to 35v). The proper stepper driver boards have the ability to limit the max current so that the high voltage does not fry the coil windings. The small stepper "hobby" driver boards such as the A4988 can control motors requiring up to 1.5 amps or so. For motors that need larger currents the driver boards will be more expensive.

The driver boards normally allow the choice between full, half, quarter, eighth and maye 1/16th stepping. Microstepping makes the motor run more smoothly at the expense of lower torque.

The AccelStepper library is very comprehensive. But, as you can see from this code, steppers are easy to drive without a library.

// simple program that makes stepper move up or down depending on which button is pressed

unsigned int microsBetweenSteps = 2000;
byte buttonUpPin = 10;
byte buttonDownPin = 11;
byte dirPin = 5;
byte stepPin = 4;

byte buttonUp = HIGH;
byte buttonDown = HIGH;

void setup() {
  pinMode(buttonUpPin, INPUT_PULLUP);
  pinMode(buttonDownPin, INPUT_PULLUP);
  pinMode(stepPin, OUTPUT);
  pinMode(dirPin, OUTPUT);
}

void loop() {
  readButtons();
  moveMotor();
}

void readButtons() {
  buttonUp = digitalRead(buttonUpPin);
  buttonDown = digitalRead(buttonDownPin);
}

void moveMotor() {
  if (buttonUp == LOW) {
     motorStep('F');
  }
  if (buttonDown == LOW) {
     motorStep('R');
  }
}

void motorStep(char dirn) {
  if (dirn == 'F') {
     digitalWrite(dirPin, HIGH);
  }
  else {
     digitalWrite(dirPin, LOW);
  }

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

...R

Sorry for taking so long to get back, I wanted to get as much information as possible so I am able to help you, help me. Just to let you know, I do have electronics experience, just not a lot with Arduino or stepper motors. So here we go…..

Image 3 is just a simple drawing I had to give an idea of what I am trying to do overall. I just want to be able to control 2 motors with either momentary switches, a little joystick pad or a laptop/tablet if need be.

Image 1 and 2 are how I currently have it wired and working.

Now, here is how I have it wired as in pins and the info I kind of used.
http://www.4tronix.co.uk/arduino/Stepper-Motors.php

To test that I have everything connected properly so far, I ran a basic script that was in Arduino already called “stepper_onerevolution” Here is the code for it....

/* 
 Stepper Motor Control - one revolution
 
 This program drives a unipolar or bipolar stepper motor. 
 The motor is attached to digital pins 8 - 11 of the Arduino.
 
 The motor should revolve one revolution in one direction, then
 one revolution in the other direction.  
 
  
 Created 11 Mar. 2007
 Modified 30 Nov. 2009
 by Tom Igoe
 
 */

#include <Stepper.h>

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);            

void setup() {
  // set the speed at 60 rpm:
  myStepper.setSpeed(60);
  // initialize the serial port:
  Serial.begin(9600);
}

void loop() {
  // step one revolution  in one direction:
   Serial.println("clockwise");
  myStepper.step(stepsPerRevolution);
  delay(500);
  
   // step one revolution in the other direction:
  Serial.println("counterclockwise");
  myStepper.step(-stepsPerRevolution);
  delay(500); 
}

Now, I guess the part I’m not sure about, is how do I get the motor to go forwards and backwards with a push of a button/key/joystick etc.

I hope this helps some, if not, please let me know.

Thank you,
Shawn

So ? You posted a schematic and code but we still fon' t know anything about if it workz or not and if so how?
Still need a SITREP.

Areonic:
Sorry for taking so long to get back, I wanted to get as much information as possible so I am able to help you, help me.

Has any of the information you were already given here been of any relevance - just so I don't waste any more time.

...R

Why haven't you tried the sketch Robin gave you ?
That sketch works .
[EDIT]
The motor goes one direction while you hold down button-1 and the opposite if you release button-1 and hold down button-2.
That does what you asked.
You said you the example YOU posted is working ? (or not?)
What is the SITREP ?

I translated Robbins program to accomodate a driver with only four INPUT pins, (no ENABLE pins,, no STEPpin , & no DIRpin).

  /* 
 Stepper Motor Control - one revolution
 
 This program drives a unipolar or bipolar stepper motor. 
 The motor is attached to digital pins 8 - 11 of the Arduino.
 
 The motor should revolve one revolution in one direction, then
 one revolution in the other direction.  
 
  
 Created 11 Mar. 2007
 Modified 30 Nov. 2009
 by Tom Igoe
 
 */

#include <Stepper.h>
//Motor A
 int enableA = 5;
 int pinA1 = 8;
 int pinA2 = 9;
//Motor B
 int enableB = 6;
 int pinB1 = 12;
 int pinB2 = 7;
const int stepsPerRevolution = 200;  // change this to fit the number of steps per revolution
                                     // for your motor
unsigned int microsBetweenSteps = 2000;
byte buttonUpPin = 10;
byte buttonDownPin = 11;
byte dirPin = 5;
byte stepPin = 4;

byte buttonUp = HIGH;
byte buttonDown = HIGH;
// initialize the stepper library on pins 8 through 11:
Stepper myStepper(stepsPerRevolution, pinA1,pinA2,pinB1,pinB2);            

void setup() 
{
   Serial.begin(9600);
  // set the speed at 60 rpm:
  myStepper.setSpeed(60);
  // initialize the serial port:
 
 pinMode (enableA, OUTPUT);
 pinMode (pinA1, OUTPUT);
 pinMode (pinA2, OUTPUT);
 pinMode (enableB, OUTPUT);
 pinMode (pinB1, OUTPUT);
 pinMode (pinB2, OUTPUT);
 digitalWrite (enableA, HIGH);
 digitalWrite (enableB, HIGH);
}

void loop() 
{
   readButtons();
 }

void readButtons() 
{
   buttonUp = digitalRead(buttonUpPin);
   
  if (buttonUp == LOW) 
    {
   
    // step one revolution  in one direction:
    Serial.println("clockwise");
    myStepper.step(stepsPerRevolution);
    delay(200);
    digitalWrite(stepPin, HIGH);
    digitalWrite(stepPin, LOW);
    delayMicroseconds(microsBetweenSteps);
    }
  
  buttonDown = digitalRead(buttonDownPin);
    
  if (buttonDown == LOW) 
  {
   // step one revolution in the other direction:
   Serial.println("counterclockwise");
   myStepper.step(-stepsPerRevolution);
   delay(200); 
   digitalWrite(stepPin, HIGH);
   digitalWrite(stepPin, LOW);
   delayMicroseconds(microsBetweenSteps);
  }
}

see attached

Simple_Direction_Possible_V_2.ino (1.97 KB)

raschemmel:
I translated Robbins program to accomodate a driver with only four INPUT pins, (no ENABLE pins,, no STEPpin , & no DIRpin).

Assuming it is my code you are referring to (only a single 'b') I'm not sure I wish to be associated with this new mongrel. In fact I'm not sure I recognize anything of mine in it. In particular I deliberately did not use the Stepper library.

I don't understand why you have both

    myStepper.step(stepsPerRevolution);
    delay(200);

and

   digitalWrite(stepPin, HIGH);
    digitalWrite(stepPin, LOW);
    delayMicroseconds(microsBetweenSteps);

Have you tested your code?

...R

Have you tested your code?

You're joking, right ? Do you think I would post untested code ? (never)
Here is your code from Reply#2 this post:
http://forum.arduino.cc/index.php?topic=263501.new;topicseen#new

  // simple program that makes stepper move up or down depending on which button is pressed

unsigned int microsBetweenSteps = 2000;
byte buttonUpPin = 10;
byte buttonDownPin = 11;
byte dirPin = 5;
byte stepPin = 4;

byte buttonUp = HIGH;
byte buttonDown = HIGH;

void setup() {
  pinMode(buttonUpPin, INPUT_PULLUP);
  pinMode(buttonDownPin, INPUT_PULLUP);
  pinMode(stepPin, OUTPUT);
  pinMode(dirPin, OUTPUT);
}

void loop() {
  readButtons();
  moveMotor();
}

void readButtons() {
  buttonUp = digitalRead(buttonUpPin);
  buttonDown = digitalRead(buttonDownPin);
}

void moveMotor() {
  if (buttonUp == LOW) {
     motorStep('F');
  }
  if (buttonDown == LOW) {
     motorStep('R');
  }
}

void motorStep(char dirn) {
  if (dirn == 'F') {
     digitalWrite(dirPin, HIGH);
  }
  else {
     digitalWrite(dirPin, LOW);
  }

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

Here is the OP's code (by Tom Ignoe)

  /* 
 Stepper Motor Control - one revolution
 
 This program drives a unipolar or bipolar stepper motor. 
 The motor is attached to digital pins 8 - 11 of the Arduino.
 
 The motor should revolve one revolution in one direction, then
 one revolution in the other direction.  
 
  
 Created 11 Mar. 2007
 Modified 30 Nov. 2009
 by Tom Igoe
 
 */

#include <Stepper.h>

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);            

void setup() {
  // set the speed at 60 rpm:
  myStepper.setSpeed(60);
  // initialize the serial port:
  Serial.begin(9600);
}

void loop() {
  // step one revolution  in one direction:
   Serial.println("clockwise");
  myStepper.step(stepsPerRevolution);
  delay(500);
  
   // step one revolution in the other direction:
  Serial.println("counterclockwise");
  myStepper.step(-stepsPerRevolution);
  delay(500); 
}

This is the OP's code with your button read code added and all your step and dir pin code and step clock code omitted.

/* 
 Stepper Motor Control - one revolution
 
 This program drives a unipolar or bipolar stepper motor. 
 The motor is attached to digital pins 8 - 11 of the Arduino.
 
 The motor should revolve one revolution in one direction, then
 one revolution in the other direction.  
 
  
 Created 11 Mar. 2007
 Modified 30 Nov. 2009
 by Tom Igoe
 
 */

#include <Stepper.h>
//Motor A
 int enableA = 5;
 int pinA1 = 8;
 int pinA2 = 9;
//Motor B
 int enableB = 6;
 int pinB1 = 12;
 int pinB2 = 7;
const int stepsPerRevolution = 200;  // change this to fit the number of steps per revolution
                                     // for your motor
unsigned int microsBetweenSteps = 2000;
byte buttonUpPin = 10;
byte buttonDownPin = 11;
byte dirPin = 5;
byte stepPin = 4;

byte buttonUp = HIGH;
byte buttonDown = HIGH;
// initialize the stepper library on pins 8 through 11:
Stepper myStepper(stepsPerRevolution, pinA1,pinA2,pinB1,pinB2);            

void setup() 
{
   Serial.begin(9600);
  // set the speed at 60 rpm:
  myStepper.setSpeed(60);
  // initialize the serial port:
 
 pinMode (enableA, OUTPUT);
 pinMode (pinA1, OUTPUT);
 pinMode (pinA2, OUTPUT);
 pinMode (enableB, OUTPUT);
 pinMode (pinB1, OUTPUT);
 pinMode (pinB2, OUTPUT);
 digitalWrite (enableA, HIGH);
 digitalWrite (enableB, HIGH);
}

void loop() 
{
   readButtons();
 }

void readButtons() 
{
   buttonUp = digitalRead(buttonUpPin);
   
  if (buttonUp == LOW) 
    {
   
    // step one revolution  in one direction:
    Serial.println("clockwise");
    myStepper.step(stepsPerRevolution);

    }
  
  buttonDown = digitalRead(buttonDownPin);
    
  if (buttonDown == LOW) 
  {
   // step one revolution in the other direction:
   Serial.println("counterclockwise");
   myStepper.step(-stepsPerRevolution);

  }
}

I don't understand why you have both

That is an EXCELLENT question !
See , I knew as soon as you asked that question that you had found a mistake I made when modifying the code to work with the OP's cheap driver that only has IN1, IN2, IN3, & IN4 and nothing else. I'm a hardware guy and when it comes to software I'm like a bull in a china shop. I went back and looked at it and then commented out the step clock code your were referring to and it STILL worked ! Obviously that means I should have omitted the step clock code along with the other code I omitted from your example when I added your button read code to the OP's example. Thanks for pointing that out. So yes, the only code that came from your example is the button read code but is that not the only reason for this post in the first place ? I don't think the OP has enough experience to realize how specific he needs to be when describing his design criteria so we don't really know if the code you wrote for a Pololu A4988 using step and dir inputs is what the OP wanted, but that's not your fault. So asuming it is what he wanted, all I did was make the example he posted work by adding your button code. You can accept credit for it or disavow it but either way I am not going to take credit for it because I didn't write it.
And yes it works (of course) or I wouldn't have posted it. I know from past experience that every post is like chumming for sharks.
Some times you get nothing and sometimes you get a feeding frenzy so you better not post any code that is bogus or you'll attract the sharks.... XD

raschemmel:
This is the OP's code with your button read code added and all your step and dir pin code and step clock code omitted.

When I post code on the forum I am quite happy for people to take it and bend it to their own requirements.

MY button code has two lines in it. It was an important conscious decision on my part NOT to include any decision making logic in it.

YOUR button code has many lines in it.

Please feel free to take credit for your own work. :slight_smile: :slight_smile:

Seriously, the reason I am being picky about this is because it would be very difficult for me to advise the OP about code which he thinks is mine but that I didn't write and which does not follow my design principles. (There, I knew if I lived long enough I would eventually develop some principles)

@Areonic - please forgive these digressions.

...R

YOUR button code has many lines in it.

Ok, you lost me there. With the exception of the two lines of your code that I added, all of the other code in that "mongrel" as you put it, is Tom Ignoes Stepper library example . I have no idea what you mean by "many lines in it" . All of the OTHER lines are from the OP's example. I had to add the setup code for the Enable pins or I wouldn't be able to use my L293 but surely that's not what you mean.
"Design Principles " ?
Are you kidding ? Did you read the OP's original post ?

What I am trying to do is have a stepper motor attached to something, have it where I push a button to go forward and one for reverse

That's exactly what your A4988 code does and exactly what the code I just posted does. If you want to get technical, instead of being vague, this application is nothing more than add two JOG buttons to a stepper driven system , one UP_jog and one DWN_jog button.
That's all the "Design Criteria " we have so it's a bit pre-mature to be talking about "design principles", but I'm happy for you that you lived long enough to obtain them. I've been an engineering tech for 30 years and I've never heard anyone at work talking about "design principles".
They just talk about:
"does this design meet our spec ?"
and
"Is it within our allowable tolerences ? "
and
"What's our margin for error ?"

So which "design priciple(s) are you referring to ? I'm really not following your reasoning. I can understand if you want to disavow anything I posted. I'm totally cool with that, but I don't know what you mean by "many lines in it..". You lost me there.
As far as the OP is concerned, we haven't heard from him since Reply#3 and we're past #10 so I wouldn't worry about what he thinks.

but I don't know what you mean by "many lines in it..". You lost me there.

This is from MY code as quoted by you in Reply #9

void readButtons() {
  buttonUp = digitalRead(buttonUpPin);
  buttonDown = digitalRead(buttonDownPin);
}

This is from YOUR "combined" code in the same Reply

void readButtons() 
{
   buttonUp = digitalRead(buttonUpPin);
   
  if (buttonUp == LOW) 
    {
   
    // step one revolution  in one direction:
    Serial.println("clockwise");
    myStepper.step(stepsPerRevolution);

    }
  
  buttonDown = digitalRead(buttonDownPin);
    
  if (buttonDown == LOW) 
  {
   // step one revolution in the other direction:
   Serial.println("counterclockwise");
   myStepper.step(-stepsPerRevolution);

  }
}

I will leave it as an exercise for the reader to count how many lines are in YOUR code.

The difference in approach is very important to me. And I hope they way I do things is consistent across all of the demo code I post on the Forum.

My purpose in only having two lines of code is to separate the business of collecting data from the business of using that data.

My readButton() code could be parachuted into any other program without needing to be amended. Your version is specific to the project it is contained in.

My readButton() code could be placed into a very short test sketch to learn/prove how it works without tripping over other dependencies apart from the variables it uses.

I've never heard anyone at work talking about "design principles".

I think you will find that this is an important concept in computer programming literature. It's purpose is to develop methodologies that help to get working and maintainable code developed at least cost.

By the way I am not a computer professional and I don't make any claim that my design principles are more than a token gesture in the correct direction. But I am arrogant enough to believe they will make it easier for newcomers to develop complex projects.

...R

Ok. I see what you mean. I shouldn't have stuck that other code into the buttonread code because it "contaminates" it and then it is no longer pure buttonread code. I actually understand that programming concept after you explained it and agree with you that they should be separate. Thanks for the tutorial.
I'll try to fix it.
It seems like I can take my time since the OP appears to have been abducted by aliens..

@Robin2,

Here is the "purified" version.

  /*  
 Stepper Motor Control - one revolution
 
 This program drives a unipolar or bipolar stepper motor. 
 The motor is attached to digital pins 8 - 11 of the Arduino.
 
 The motor should revolve one revolution in one direction, then
 one revolution in the other direction.  
 
  
 Created 11 Mar. 2007
 Modified 30 Nov. 2009
 by Tom Igoe
 
 */

#include <Stepper.h>
//Motor A
 int enableA = 5;
 int IN1 = 8;
 int IN2 = 9;
//Motor B
 int enableB = 6;
 int IN3 = 12;
 int IN4 = 7;
const int stepsPerRevolution = 200;  // change this to fit the number of steps per revolution
                                     // for your motor
unsigned int microsBetweenSteps = 2000;
byte buttonUpPin = 10;
byte buttonDownPin = 11;
byte dirPin = 5;
byte stepPin = 4;

byte buttonUp = HIGH;
byte buttonDown = HIGH;
// initialize the stepper library on pins 8 through 11:
Stepper myStepper(stepsPerRevolution, IN1,IN2,IN3,IN4);            

void setup() 
{
   Serial.begin(9600);
  // set the speed at 60 rpm:
  myStepper.setSpeed(60);
  // initialize the serial port:
 
 pinMode (enableA, OUTPUT);
 pinMode (IN1, OUTPUT);
 pinMode (IN2, OUTPUT);
 pinMode (enableB, OUTPUT);
 pinMode (IN3, OUTPUT);
 pinMode (IN4, OUTPUT);
 digitalWrite (enableA, HIGH);
 digitalWrite (enableB, HIGH);
}

void loop() 
{
   readButtons();
   movemotor();
 }
void movemotor()
  {
    if (buttonUp == LOW) 
    {
   
    // step one revolution  in one direction:
    Serial.println("clockwise");
    myStepper.step(stepsPerRevolution);
   
    }
    if (buttonDown == LOW) 
     {
   // step one revolution in the other direction:
   Serial.println("counterclockwise");
   myStepper.step(-stepsPerRevolution);
      }
  } 
  
void readButtons() 
{
   buttonUp = digitalRead(buttonUpPin);
   buttonDown = digitalRead(buttonDownPin);
}

I think that I understand why you brought up "Design Principles " , although in my line of work it would be referred to as "Recommended Design Practice" for software engineering, and my sketch would be "rejected " at the Design Review because it does not "Comply with Recommended Design Practice". (because I violated one of them, albeit unknowingly).
I agree that it is a cleaner approach.
Thanks for the tip

raschemmel:
I think that I understand why you brought up "Design Principles " , although in my line of work it would be referred to as "Recommended Design Practice" for software engineering, and my sketch would be "rejected " at the Design Review because it does not "Comply with Recommended Design Practice". (because I violated one of them, albeit unknowingly).
I agree that it is a cleaner approach.
Thanks for the tip

You're welcome.

I freely confess that I am not certain whether design principles is the correct IT jargon.

...R

I freely confess that I am not certain whether design principles is the correct IT jargon.

Just "jargon".

We have about 6 programmers in the Software Dept. but no IT department. (we out-source that).

I am out of touch. I was just trying to distinguish it from Legal jargon and Medical jargon etc.

Maybe I should have said CompSci

Enough already!

...R

SW

Enough already!

XD