steppermotor only few steps

Hi all,

I'm currently trying to program something with an a4988 stepper motor driver shield.

I've uploaded the sample code, everything works without problems.

But, I can't figured it out how to get this done.

What I want:

  • On startup of the program nothing may move (no rotation of the steppermotor)
  • If I pres the button (pin13) the stepper motor (Nema17) must turn 1 turn to the right
  • If I release the button the stepper motor must turn one turn back to the left.
  • Everything may rest untill the button is pressed again.

I've tried to manage this by the following code, but my stepper motor keeps turning because of the else signal.

const int stepPin = 3; 
const int dirPin = 4; 
int relpin = 13;
int relpinstate = 0;
 
void setup() {
  // Sets the two pins as Outputs
  pinMode(stepPin,OUTPUT); 
  pinMode(dirPin,OUTPUT);
  pinMode(relpin, INPUT);
  Serial.begin(9600);
}

void loop() {
  int relpinstate = digitalRead (relpin);

  if (relpinstate == 1)
  {
    Serial.println(relpinstate);
    delay (1);
      digitalWrite(dirPin,HIGH); // Enables the motor to move in a particular direction

         for(int x = 0; x < 200; x++) 
            {
            digitalWrite(stepPin,HIGH); 
             delayMicroseconds(500); 
             digitalWrite(stepPin,LOW); 
             delayMicroseconds(500); 
            }
  }

  else

  {
  digitalWrite(dirPin,LOW); //Changes the rotations direction
  // Makes 400 pulses for making two full cycle rotation
  for(int x = 0; x < 400; x++) {
    digitalWrite(stepPin,HIGH);
    delayMicroseconds(500);
    digitalWrite(stepPin,LOW);
    delayMicroseconds(500);
  }
}
}

Can someone give me an helping hand? Many thanks!

Start by detecting when the button becomes pressed rather than when it is pressed. See the StateChangeDetection example in the IDE. Change the state of a variable ( a boolean is convenient) every time the button becomes pressed.

1 turn to the right

I assume that you mean 360 degrees. How many steps are needed to turn the motor 360 degrees ?

Based on the value of the boolean variable move the motor the required number of steps in one direction or the other when the button becomes pressed.

Hi Bob,

thanks for your answer, 200 steps are needed to complete 1 turn.

I'm unfamiliar with the boolean's....

Thanks!

boolean = true or false

Pseudo code

if (button becomes pressed)
  change state of boolean variable
  if boolean variable is true
    move 200 steps in one direction
  end if
  else
    move 200 steps in opposite direction
  end else
end if

It would be convenient to write a function to move 200 steps and for it to take a parameter that indicates which direction in which to move.

Hi thanks allready for all the tips and hints.

This is what I've got, but there is something wrong in the code because it won't work.

const int stepPin = 3; 
const int dirPin = 4; 
int relpin = 12;
const int stepsPerRevolution = 200;

boolean running = false;
 
void setup() {

  pinMode(stepPin,OUTPUT); 
  pinMode(dirPin,OUTPUT);
  pinMode(relpin, INPUT);
  digitalWrite (relpin, LOW);
  Serial.begin(9600);
}

void loop() 
{
  if (digitalRead(relpin)==HIGH)
  running = !running;
    if (running == !running)
    {
      digitalWrite(dirPin,HIGH); 
      for(int x = 0; x < 200; x++) 
            {
            digitalWrite(stepPin,HIGH); 
            delayMicroseconds(500); 
            digitalWrite(stepPin,LOW); 
            delayMicroseconds(500); 
            }
    }


  else
      digitalWrite(dirPin,LOW); 
      for(int x = 0; x < 200; x++) 
            {
            digitalWrite(stepPin,HIGH); 
            delayMicroseconds(500); 
            digitalWrite(stepPin,LOW); 
            delayMicroseconds(500); 
            }
}

Can someone give me another help?

  if (running == !running)Think about this, How can running ever equal not running ?

Just test the value of running and act on it

void loop() 
{
  if (digitalRead(relpin)==HIGH)
  running = true;
    if (running == true)
    {

I've changed the !running to true, but still nothing.

Is the rest of my code ok?

Thanks!

Is the rest of my code ok?

Please post the whole program as it is now

hi Bob,

off course you can't check the program as it isn't in the reply, here it is:

const int stepPin = 3; 
const int dirPin = 4; 
int relpin = 12;
const int stepsPerRevolution = 200;

boolean running = false;
 
void setup() {

  pinMode(stepPin,OUTPUT); 
  pinMode(dirPin,OUTPUT);
  pinMode(relpin, INPUT);
  digitalWrite (relpin, LOW);
  Serial.begin(9600);
}

void loop() 
{
  if (digitalRead(relpin)==HIGH)
  running = true;
    if (running == true)
    {
      digitalWrite(dirPin,HIGH); 
      for(int x = 0; x < 200; x++) 
            {
            digitalWrite(stepPin,HIGH); 
            delayMicroseconds(500); 
            digitalWrite(stepPin,LOW); 
            delayMicroseconds(500); 
            }
    }


  else
      digitalWrite(dirPin,LOW); 
      for(int x = 0; x < 200; x++) 
            {
            digitalWrite(stepPin,HIGH); 
            delayMicroseconds(500); 
            digitalWrite(stepPin,LOW); 
            delayMicroseconds(500); 
            }
}

Try this simplified program

const int stepPin = 3;
const int dirPin = 4;
int relpin = 12;
const int stepsPerRevolution = 200;

void setup()
{
  pinMode(stepPin, OUTPUT);
  pinMode(dirPin, OUTPUT);
  pinMode(relpin, INPUT);
  digitalWrite (relpin, LOW);
  Serial.begin(9600);
}

void loop()
{
  if (digitalRead(relpin) == HIGH)
  {
    runMotor(LOW);
  }
  else
  {
    runMotor(HIGH);
  }
}

void runMotor(byte direction)
{
  digitalWrite(dirPin, direction);
  for (int x = 0; x < stepsPerRevolution; x++)
  {
    digitalWrite(stepPin, HIGH);
    delayMicroseconds(500);
    digitalWrite(stepPin, LOW);
    delayMicroseconds(500);
  }
}

NOTE : it does not do what you want but it will allow you to test reading your input pin and running the motor and can then be added to.

Note the use of a function that moves the motor 200 steps in a direction set by the value passed to it.

Try the program and report back what happens. If it does what I think then you can move on to do exactly what you want but that will involve adding more logic but the moveMotor() function can still be used.

How is the input wired ?

Hi,

the program works as followed:

  • Motor is turning left, unlimited
  • Button pressed than the motor is turning right unlimited.

hope someone can give me some more hints

It sounds like the hardware is working OK

Now to add more control.

Instead of detecting when the button is pressed change the program to detect when the button becomes pressed. See the StateChangeDetection example in the IDE. Then, when the button becomes pressed run the motor for 200 steps so that it does one revolution and stops. When the button becomes released run the motor for 200 steps in the other direction. A for loop will be handy for making the motor move 200 steps.

The for-loop could it be like this?

{
      digitalWrite(dirPin,HIGH); 
      for(int x = 0; x < 200; x++) 
            {
            digitalWrite(stepPin,HIGH); 
            delayMicroseconds(500); 
            digitalWrite(stepPin,LOW); 
            delayMicroseconds(500); 
            }
    }

The StateChangeDetection I found on the pages of Arduino but I can't figure it out how to do it!

The StateChangeDetection I found on the pages of Arduino but I can't figure it out how to do it!

Look carefully at what the program does. It reads the current state of a pin and compares it with the state it read the previous time. If they are not the same then the pin has changed state which means that the switch connected to it has become closed or become open. By looking at the current state it is possible to determine whether it opened or closed.