Controlling a stepper motor with accelstepper and if statements

Hi,

I am working on a hobby project and I am trying to control a steppermotor. The goal is to be able to move the stepper motor into 5 different positions by pressing different buttons. Right now my code looks like this:

// Include the AccelStepper library:
#include <AccelStepper.h>

// Define number of steps per revolution:
const int stepsPerRevolution = 200;

// Give the motor control pins names:
#define pwmA 3
#define pwmB 11
#define brakeA 9
#define brakeB 8
#define dirA 12
#define dirB 13
#define HOMING A0

// Define the AccelStepper interface type:
#define MotorInterfaceType 2

// Create a new instance of the AccelStepper class:
AccelStepper stepper = AccelStepper(MotorInterfaceType, dirA, dirB);

void setup() {
 // Set the PWM and brake pins so that the direction pins can be used to control the motor:
 pinMode(pwmA, OUTPUT);
 pinMode(pwmB, OUTPUT);
 pinMode(brakeA, OUTPUT);
 pinMode(brakeB, OUTPUT);
 pinMode(HOMING, INPUT);

 digitalWrite(pwmA, HIGH);
 digitalWrite(pwmB, HIGH);
 digitalWrite(brakeA, LOW);
 digitalWrite(brakeB, LOW);

 // Set the maximum steps per second:
 stepper.setMaxSpeed(600);
}

void loop() {

 
 stepper.setCurrentPosition(0); // Set the current position to 0:
 
 if (digitalRead(HOMING), HIGH); // Homing function of motor setup
 
   while (stepper.currentPosition() != 200) // Run the motor forward at 400 steps/second until the motor reaches 200 steps (1 revolution):
   {
     stepper.setSpeed(100);
     stepper.runSpeed();
   }

 delay(1000);

}

The result of this code is that the motor will spin regardless whether or not A0 is being used. (I am using the REV3 motor shield so I will have to use the analog inputs as digital inputs as I need to register 5 inputs and I dont have the digital input pins for this. right? :sweat_smile: )

Setup:
1 stepper motor
5 switches
Arduino UNO
Arduino REV3 motor shield

I'd gladly take your advice on what is wrong with my code so that I will be able to activate the motor so it takes an x amount of steps when A0 is active. If A0 is not in use the motor should not rotate.

Please help :cry: ,

Hi,
Welcome to the forum.

Please read the post at the start of any forum , entitled "How to use this Forum".
OR
http://forum.arduino.cc/index.php/topic,148850.0.html.
Then look down to item #7 about how to post your code.
It will be formatted in a scrolling window that makes it easier to read.

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?

Thanks .. Tom... :slight_smile:

Hi TomGeorge,

Thanks I updated the code into the correct manner. My circuit is pretty basic as I am trying to figure out how to move the motor to a position by means of a switch. Once I understand this I will be able to build on to it.

As for right now, this is the current situation (see attachment)

The motor should not rotate if the switch is not actived. Once the switch is activated it should rotate an x amount of steps.

Currently it is also fed via the USBport but later I would like to be able to power both the arduino and shield separatly. However I am not sure this is possible, as google searches pointed me to cutting a connection but I am worried this will break my board.

Hi,
Thanks for the diagram.
If your homing input is just a switch, you need to have a 10k pulldown resistor between A0 and gnd, this will pull A0 to ground when the 5V is switched off.
Ops diag.

I think you will find it easier to draw a circuit by hand on paper and send a picture of it.
Although your diagram shows the basics, it needs to show pins labels and the motor shield.

Can you post a link to the motor shield you are using please?

Tom.... :slight_smile:

This is wrong

 if (digitalRead(HOMING), HIGH);

An IF statement should be like this

 if (digitalRead(HOMING) == HIGH) {
     // code to execute when the test is true
 }

Note that your semi-colon ensures that the IF statement does nothing.

This is also inappropriate

   while (stepper.currentPosition() != 200)

as the Accelstepper library will automatically stop when the target position is reached and you have not specified a target position. You need a line like stepper.move(200);

Perhaps the whole thing should be something like this

void loop() {
    buttonState = digitalRead(buttonPin);
    if (buttonState == HIGH and motorMoving == false) {
        stepper.move(200);
        motorMoving = true;
    }
    if (stepper.distanceToGo() == 0) {
        motorMoving = false;
    }
    stepper.runSpeed();
}

...R

Thanks Robin,

I changed the arduino uno to mega in hopes of using its inputs. I succeeded with part of your code I managed to get it to run. However something really weird happens. I ask of the arduino to turn the motor when input 50 gets high. However I only have to put a wire in there not even connected to anything and the motor will spin. The motor will also spin contentiously and not stop at the 200 steps like programmed

// Include the AccelStepper library:
#include <AccelStepper.h>

// Define number of steps per revolution:
const int stepsPerRevolution = 200;

// Give the motor control pins names:
#define pwmA 3
#define pwmB 11
#define brakeA 9
#define brakeB 8
#define dirA 12
#define dirB 13
#define HOMING 50

// Define the AccelStepper interface type:
#define MotorInterfaceType 2

// Create a new instance of the AccelStepper class:
AccelStepper stepper = AccelStepper(MotorInterfaceType, dirA, dirB);

void setup() {
  // Set the PWM and brake pins so that the direction pins can be used to control the motor:
  pinMode(pwmA, OUTPUT);
  pinMode(pwmB, OUTPUT);
  pinMode(brakeA, OUTPUT);
  pinMode(brakeB, OUTPUT);
  pinMode(HOMING, INPUT);

  digitalWrite(pwmA, HIGH);
  digitalWrite(pwmB, HIGH);
  digitalWrite(brakeA, LOW);
  digitalWrite(brakeB, LOW);

  // Set the maximum steps per second:
  stepper.setMaxSpeed(200);
  
}

void loop() 
{  
  int Homing = 0;
  Homing = digitalRead(HOMING);
  
    if (Homing == HIGH) 
    {
       stepper.setSpeed(200); // 200/second = 1 rps
       stepper.move(200);
    }
    if (Homing == LOW)
    {
      stepper.setSpeed(0);
    }
    stepper.runSpeed();
}

This is what I managed so far. Also the code you had posted did not seem to work as the motor did nothing when the required input got powered

cptblueberry:
I ask of the arduino to turn the motor when input 50 gets high. However I only have to put a wire in there not even connected to anything and the motor will spin.

Because nothing is connected to the pin when the button is not pressed the pin is floating and its value is unstable.

The usual way to deal with that is to use

pinMode(HOMING, INPUT_PULLUP);

and wire the switch so that pressing it connects the pin the GND. The internal pullup resistor holds the pin HIGH when the switch is not pressed.

Then your logic needs to change to

if (Homing == LOW)

...R

Hey,

So I have an arduino ATmega 2560 in combination with the arduino motor shield REV 3. when putting in my code to make a stepper motor run. I use pin 40 as input for a switch. If pin 40 is not triggered the motor should and will not run and if it gets triggered it should and will run. HOWEVER it will also run if I put something in pin 40 for example a wire with no connection to anything.

This problem does not only occur with pin 40 but also with others. does anyone perhaps know what the problem could be?

void setup() {
  // Set the PWM and brake pins so that the direction pins can be used to control the motor:
  pinMode(pwmA, OUTPUT);
  pinMode(pwmB, OUTPUT);
  pinMode(brakeA, OUTPUT);
  pinMode(brakeB, OUTPUT);
  pinMode(HOMING, INPUT);

  digitalWrite(pwmA, HIGH);
  digitalWrite(pwmB, HIGH);
  digitalWrite(brakeA, LOW);
  digitalWrite(brakeB, LOW);

  // Set the maximum steps per second:
  stepper.setMaxSpeed(100);
 
}

void loop()
{ 
  int Homing = 0;
  Homing = digitalRead(HOMING);
 
    if (Homing == HIGH)

Is something wrong with my code?
Is my board broken?
Is motor shield REV 3 not supposed to work with arduino mega?
Am I not supposed to use inputs when using motor shield REV 3?

Pin 40 is floating?

Hard to tell from your snippet.

Woops sorry, Here is the full code

// Include the AccelStepper library:
#include <AccelStepper.h>

// Define number of steps per revolution:
const int stepsPerRevolution = 200;

// Give the motor control pins names:
#define pwmA 3
#define pwmB 11
#define brakeA 9
#define brakeB 8
#define dirA 12
#define dirB 13
#define HOMING 40

// Define the AccelStepper interface type:
#define MotorInterfaceType 2

// Create a new instance of the AccelStepper class:
AccelStepper stepper = AccelStepper(MotorInterfaceType, dirA, dirB);

void setup() {
 // Set the PWM and brake pins so that the direction pins can be used to control the motor:
 pinMode(pwmA, OUTPUT);
 pinMode(pwmB, OUTPUT);
 pinMode(brakeA, OUTPUT);
 pinMode(brakeB, OUTPUT);
 pinMode(HOMING, INPUT);

 digitalWrite(pwmA, HIGH);
 digitalWrite(pwmB, HIGH);
 digitalWrite(brakeA, LOW);
 digitalWrite(brakeB, LOW);

 // Set the maximum steps per second:
 stepper.setMaxSpeed(100);

}

void loop()
{ 
 int Homing = 0;
 Homing = digitalRead(HOMING);

   if (Homing == HIGH)
   {
      stepper.move(200); // 200/second = 1 rps
      stepper.setAcceleration(100.0);
      stepper.runToPosition();
   }
   if (Homing == LOW)
   {
     stepper.setSpeed(0);
   }
   stepper.runSpeed();
}

cptblueberry:
However I only have to put a wire in there not even connected to anything and the motor will spin. The motor will also spin contentiously and not stop at the 200 steps like programmed

See second sentence in post #3.

I just tested with a high resistance (600k, 800k, 2.5M) and it still behaves the same way

Just connect the pin to Vcc or GND and test.

If you want to solve the problem, use a 10K resistor from pin 40 to GND. Or use pinMode(HOMING, INPUT_PULLUP) and reverse the logic (a pressed button will read LOW).

600K is relative high resistance so there is still a chance that you pick up noise from the environment.

@cptblueberry, please do not double post - it just wastes time with people giiving duplicate answers.

I am suggesting to the Moderator to merge your Threads.

...R

@cptblueberry

TOPIC MERGED.

Could you take a few moments to Learn How To Use The Forum.
Other general help and troubleshooting advice can be found here.
It will help you get the best out of the forum.

int Homing = 0;
 Homing = digitalRead(HOMING);

Waste of time.

Simply

int Homing = digitalRead(HOMING);

Also, if digitalRead didn't return HIGH, you can be sure it returned LOW; there's no need to test again, a simple "else" will suffice.

Hi,

 // Set the PWM and brake pins so that the direction pins can be used to control the motor:
 pinMode(pwmAPin, OUTPUT);
 pinMode(pwmBPin, OUTPUT);
 pinMode(brakeAPin, OUTPUT);
 pinMode(brakeBPin, OUTPUT);
 pinMode(HOMINGPin, INPUT);

Renaming your pins like this will help with variable identification.

int Homing = 0;
 Homing = digitalRead(HOMING);

Homing and HOMING, although they are different in C++, as you read the code the human eye can confuse them.

Tom... :slight_smile:

Thank you guys it worked!

Sorry for double posting, I didn't intend on doing it as I thought I had both a software and hardware problem I.E. unrelated problems. Either way I will make sure it wont happen again in the future

Hi,
Can you post the final code and circuit that you have working please, this will help any other people looking for a solution to similar situations.

Thanks.. Tom... :slight_smile: