Stepper motor starting and stopping problems (code wise)

Hey everyone
Hopefully i put this question of mine in the right section.

I started a project for my final project for school and it included using an arduino which i am very basic with, such as blink a light on and off or making a stepper motor turn in one direction and playing around with the variables.
My question to you guys is that I've been having a lot of trouble coding my stepper motor to turn an X amount of steps and then delay for an X amount of time before repeating this process over and over.

My project is basically a battery swapping exchange station for drones and there is a large drum on one side with will allow me to turn the battery into position and then stop to allow the battery time to get out of the drum and into the drone. If anyone can help me with this code that ive been trying to look for it would help me greatly.

Ive been using a basic arduino with a motor controller shield here: 2 Channel H-Bridge Motor Driver Shield for Arduino | Freetronics

As well as a 200 step, stepper motor:

Everything runs off a 12V power supply

This is the code that im currently using

#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, 4, 7, 3, 2);

int stepCount = 0;         // number of steps the motor has taken

void setup() {
  // initialize the serial port:
  Serial.begin(9600);
}

void loop() {
  // step one step:
  myStepper.step(1);
  Serial.print("steps:" );
  Serial.println(stepCount);
  stepCount++;
  delay(100);
}

Please help :slight_smile:

This video might help you understand what im trying to talk about :slight_smile:

oliver_laver:
My question to you guys is that I've been having a lot of trouble coding my stepper motor to turn an X amount of steps and then delay for an X amount of time before repeating this process over and over.

You have not told us what your code does and how that differs from what you want it to do ?

I think you need to do something when the step count reaches a certain number. For example

if (stepCount >= 100) {
   // do something
}

You probably should not use delay() for timing. If the project gets more complex it will get in the way. Use millis() to manage timing as illustrated in several things at a time.

Also have a look at planning and implementing a program - especially the business of writing down clearly what needs to happen and the business of putting the code into small functions that can be tested on their own.

...R

Robin2:
You have not told us what your code does and how that differs from what you want it to do ?

Im not sure if this explains this but the code simply steps my stepper motor one step at a time in a continuous loop and the delay is what controls the speed.

To be honest im not 100% certain on what my code does however all i know is that because my stepper motor have a steps per revolution of 200 steps i can use

const int stepsPerRevolution = 200;

and that the delay is 100 because is controls the speed.

i understand a little bit about what the code you showed me was talking about how would i use it in my lines?

i read your description on what the millis() function does however how would i replace it with the code i have now? i tried to replace it where the delay was originally but it did not work for some reason and im puzzled with how to use it.

The video in the first comment briefly shows how the motor simply moves step-by-step. all the code allows me to do from what i know is control the speed.

To be honoust there must be an easier/simple way to start and stop a stepper without the use of a switch or other input.

and the task that this code will be used for will only be used for turning on and off the motor for a set amount of time to allow the drum to reach its desired position.

Sorry for not understanding what you were saying before, and for messing up my reply with a massive quote instead of a small line

To be honest im not 100% certain on what my code does

You certainly better get certain before you have to explain it as part of your final grade.

PaulS:
You certainly better get certain before you have to explain it as part of your final grade.

My project isn't to do with the software. My Design and Technology class that i take at school will only want to see the code in my folio to show how it moves with a few annotations showing what a few parts do. The teachers that mark these projects wouldn't know anything about arduinos and coding in the first place usually. As long as it works and i document how i developed to the stage of how to make it work they would give me the marks. Not to mention, not many kids in the cource will use any sort of code or microprocessors for their projects.

Although saying that i do need to understand the code as you said, however im really struggling and ive been trying to look at a number of tutorials to understand how to apply it to my project, but i just can't make the connection if you know what i mean.

I don't really understand how that code is supposed to accomplish what you say you want it to.

The loop() function is called over and over. Without the useless comments and the printing stuff, your loop() function boils down to step, wait, repeat.

At some point, you need to break that cycle.

Use a for loop to step and wait a fixed number of times. Then wait for however long is needed. Repeat.

void loop()
{
   for(byte b=0; b<requiredNumberOfSteps; b++)
   {
      myStepper.step(1);
      delay(100);
   }

   twiddleThumbsUntilTimeToGoAgain();
}

By making requiredNumberOfSteps a variable, you can easily change it's value, if you need to change the diameter of the drum, for instance, or use gearing because the motor doesn't have enough torque.

My calling a function that wastes the time, you can easily change what makes the drum move again. Now, you say that it should simply stop for a period of time. But, you might decide that there should be a switch to make the drum move again. Next, you might decide that the switch should be replaced with a coin/bill acceptor, so you can charge for fresh batteries.

By using a function, you can change how the function decides it is ready to return, without having to change loop.

And, small functions with meaningful names are easier to explain, since, mostly, they don't need explaining.

My project isn't to do with the software.

The main focus of your project may not be the software. But, without the software, your project is dead in the water. So, you need to understand it, and be prepared to explain it, at least well enough to determine that it does, indeed, meet all the requirements.

I used the original void loop because it was the only code i could understand to a point where i could make the motor move. I knew that this void loop would be a problem however i showed the code since it was all i had to show and i guess showed how bad i am at this hahaha.

So by changing the "requirednumberofsteps" to something like 20 then the drum technically would go 20 steps, with each step being 100 miliseconds apart from eachother.

Ive heard a little about the for loop but i dont understand it completly. So it pretty does the same thing as a void loop however it is able to be stopped?

And im not sure if you wanted me to do this, however i put the code in like this and it said that the " twiddleThumbsUntilTimeToGoAgain" was unexpected. Is that because the command is not in the void setup?

 #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, 4, 7, 3, 2);

int stepCount = 0;         // number of steps the motor has taken

void setup() {
  // initialize the serial port:
  Serial.begin(9600);
}

void loop()
{
   for(byte b=0; b<20; b++)
   {
      myStepper.step(1);
      delay(100);
   }

   twiddleThumbsUntilTimeToGoAgain();
}

PaulS:
without the software, your project is dead in the water. So, you need to understand it, and be prepared to explain it, at least well enough to determine that it does, indeed, meet all the requirements.

That's very true, i didn't mean for it to sound like it was nothing, it is an important part of the project for sure :slight_smile:

So by changing the "requirednumberofsteps" to something like 20 then the drum technically would go 20 steps, with each step being 100 miliseconds apart from eachother.

Not exactly. The stepper motor will step 20 times, 1/10 of a second apart. What that does to the drum, I could not say. That is why you might need to change the value of requiredNumberOfSteps - so that the drum moves the required amount.

Ive heard a little about the for loop but i dont understand it completly. So it pretty does the same thing as a void loop however it is able to be stopped?

No. The loop() function is called in an infinite loop. The for statement creates is a looping construct that typically iterates a fixed number of times.

It is possible to write a for loop that iterates a variable number of times, such as when stepping through a linked list, but there are other statements that are conceptually better suited for such tasks.

As a beginner, just think of the for loop iterating a fixed number of times.

And im not sure if you wanted me to do this, however i put the code in like this and it said that the " twiddleThumbsUntilTimeToGoAgain" was unexpected. Is that because the command is not in the void setup?

When I compile your code, I get this (Note, this is what you should be posting, not a summary of what you think the message(s) were):

sketch_aug05a.ino: In function 'void loop()':
sketch_aug05a:24: error: 'twiddleThumbsUntilTimeToGoAgain' was not declared in this scope

What that means is that the compiler has no idea what twiddleThumbsUntilTimeToGoAgain is. If you add

void twiddleThumbsUntilTimeToGoAgain();

before setup(), the compiler will know what twiddleThumbsUntilTimeToGoAgain is (a function that can be called), but the linker won't be able to find the code for twiddleThumbsUntilTimeToGoAgain.

The thing you added there is called a function prototype. It defines that there will be a function, that the function has a name, a return type, and describes the argument types, if there are to be arguments.

Normally, the IDE creates function prototypes for you, so you could just add

void twiddleThumbsUntilTimeToGoAgain()
{
   delay(5000);
}

after loop(). Then, the stepper will step a number of times, and then the twiddleThumbsUntilTimeToGoAgain function will be called, which will take a 5 second nap.

Hi,
Wouldn't it be easier to have magnets on the drum located where each battery is, then a magnetic reed switch where you need to stop and dispense a battery.

Then all you need to do is

  1. drive until
  2. the switch senses the magnet and stop,
  3. dispense
  4. wait (see blink without delay)
    5 loop back to 1

You may want to put a counter in to stop the process when your drum is empty.

Tom... :slight_smile:

TomGeorge:
Hi,
Wouldn't it be easier to have magnets on the drum located where each battery is, then a magnetic reed switch where you need to stop and dispense a battery.

Hey Tom, that idea from what i can understand can work however i don't think it would work properly as i need to have it slide into the 'drone battery dock' if you can call it that and then goout and back into the drum to charge. Also this project is due in 9 days and have finished my half yearly exams allowing me to focus mainly on this, Due to this lack of time if i were to buy all these parts it would take a while to ship to australia and expensive since there are no good hobby electronic stores around.

PaulS:
The stepper motor will step 20 times, 1/10 of a second apart. What that does to the drum, I could not say. That is why you might need to change the value of requiredNumberOfSteps - so that the drum moves the required amount.

So when this code works with the motor i can guess and check with how many steps i should be doing to therefore get the desired angle which i need, keeping in mind the gears which increase my stepper torque.

Just so that we dont have to write that long function prototype, i called it

TimeToGoAgain

I think i compiled it as you told me to however it still had these errors:

sketch_aug06a.ino:18:1: error: expected initializer before 'void'

sketch_aug06a.ino:22:1: error: expected unqualified-id before '{' token
Error compiling.




This is what i wrote down



#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, 4, 7, 3, 2);

int stepCount = 0;        // number of steps the motor has taken
void TimeToGoAgain();

void setup() {
  // initialize the serial port:
  Serial.begin(9600);
}

void loop()
void TimeToGoAgain()
{
  delay(5000);
}
{
  for(byte b=0; b<50; b++) //if 50 was the required amount of steps theoretically
 
      myStepper.step(1);
      delay(100);
  }




Am i getting closer?

Am i getting closer?

Close,. but no cigar. You can't define a function inside another function. When I sap to create the function after void loop(), I meant after the closing curly brace for the function.

#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, 4, 7, 3, 2);

int stepCount = 0;         // number of steps the motor has taken
void TimeToGoAgain();

void setup()
{
  // initialize the serial port:
  Serial.begin(9600);
}

void loop()
{ 
   for(byte b=0; b<50; b++) //if 50 was the required amount of steps theoretically
   {
      myStepper.step(1);
      delay(100);
   }
}

void TimeToGoAgain()
{
   delay(5000);
}

PaulS:
I meant after the closing curly brace for the function.

Ahh i understand now wher you put it hahaha. I tried the code with the stepper motor just now, however the stepper motor was still turning continuously without stopping for 5 seconds

void TimeToGoAgain()
{
   delay(5000);

Is there something im missing to do?

I used the same code as you and uploaded

#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, 4, 7, 3, 2);

int stepCount = 0;         // number of steps the motor has taken
void TimeToGoAgain();

void setup()
{
  // initialize the serial port:
  Serial.begin(9600);
}

void loop()
{ 
   for(byte b=0; b<50; b++) //if 50 was the required amount of steps theoretically
   {
      myStepper.step(1);
      delay(100);
   }
}

void TimeToGoAgain()
{
   delay(5000);
}

Thank you for helping me with this by the way, since i live in Australia and its 1:12am i better go to bed and wake up later so that i can get this thing running :slight_smile:

Oops. One of us left out the call to the function.

void loop()
{ 
   for(byte b=0; b<50; b++) //if 50 was the required amount of steps theoretically
   {
      myStepper.step(1);
      delay(100);
   }

   TimeToGoAgain();
}

PaulS:
Oops. One of us left out the call to the function.

Was the call function when we write

TimeToGoAgain();

i replaced the loop with what you wrote down like this

 #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, 4, 7, 3, 2);

int stepCount = 0;         // number of steps the motor has taken
void TimeToGoAgain();

void setup()
{
  // initialize the serial port:
  Serial.begin(9600);
}

void loop()
{ 
   for(byte b=0; b<50; b++) //if 50 was the required amount of steps theoretically
   {
      myStepper.step(1);
      delay(100);
   }

   TimeToGoAgain();
}

However it still says

sketch_aug06a.cpp.o: In function `loop':
/Arduino/sketch_aug06a.ino:26: undefined reference to `TimeToGoAgain()'
collect2: error: ld returned 1 exit status
Error compiling.

What am i missing?

i think i also forgot this

 delay(5000);

Which may have been an issue because the TimeToGoAgain wasn't doing anything as a function?

I included it within my code but now the error is saying

sketch_aug06b.ino: In function 'void loop()':
sketch_aug06b.ino:29:1: error: expected '}' at end of input
Error compiling.

Does that mean that there is a bracket that shouldnt be there?

This is what i have now

#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, 4, 7, 3, 2);

int stepCount = 0;         // number of steps the motor has taken
void TimeToGoAgain();

void setup()
{
  // initialize the serial port:
  Serial.begin(9600);
}

void loop()
{
   for(byte b=0; b<50; b++) //if 50 was the required amount of steps theoretically
   {
      myStepper.step(1);
      delay(100);
   }

   TimeToGoAgain();
{
   delay(5000);
}

This is what i have now

It should look like this:

#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, 4, 7, 3, 2);

int stepCount = 0;         // number of steps the motor has taken
void TimeToGoAgain();

void setup()
{
  // initialize the serial port:
  Serial.begin(9600);
}

void loop()
{
   for(byte b=0; b<50; b++) //if 50 was the required amount of steps theoretically
   {
      myStepper.step(1);
      delay(100);
   }

   TimeToGoAgain();
}

void TimeToGoAgain()
{
   delay(5000);
}

The TimeToGoAgain() bit in loop() is the call to the function. The last 4 lines are the function implementation.