How to turn stepper motor at rpm precisely?

I'm a Arduino noob, but I'm trying to make a barn door tracker for astrophotography. I need the stepper to revolve at 1 RPM exactly. I'm using an Uno with the EasyStepper and my motor is a 10V 200 step bipolar stepper 1.8 degrees a step. Pin 8 is Dir and Pin 9 is Step and GND is GND on the Arduino-Easy Driver respectively.

I tried using the directions on the Stepper - Arduino Reference
but they don't seem to work and I'm not sure if that is because I'm using the EasyDriver. I wasn't able to get them to work with or without the motor driver board.

I've been looking on the forums but I haven't seen anyone trying to get a precise low RPM. Can anyone point me to a good post?

I'm really confused about which library to use. I don't need to accelerate, so the AccelStepper seems overkill.

Below is something I based on Tom Igoe's stepper blog. I wish it was this easy, but this moves the motor much slower than 1 RPM.

#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 and 9:
Stepper myStepper(stepsPerRevolution, 8, 9);

void setup() {
  myStepper.setSpeed(1);
}

void loop() {

   
    // step 200/60 of a revolution:
    myStepper.step(3.3333);
  
}

Thanks.

Try this simple stepper test code that does not use any library. You can adjust the "gap" between steps to give any speed you want.

...R
Stepper motor basics

The easydriver defaults to 8 microsteps, so 8 x 200 = 1600 steps per revolution
Try 1600 in your code, might be more what you were expecting.

The AccelStepper library is work downloading and checking out.

I am working on a RA driver for a telescope, which is basically the same thing you are doing.

Do not use the stepper libraries, they are more catered for precise position, not precise speed.

Just set up a togged output and change the timing for your needs.

I have not confirmed if the Arduino ceramic resonator (yep) is good enough for our needs. I intend on replacing with a TCXO.

In your case you may find it usefull to use a analog input and a pot to vary your speed.

I could write a rough sketch if you ask me really politely...

Thanks so much for your responses! I found the EasyStepper does indeed use 1600 microsteps not the 200, but my code still does not work properly. I also came to the same conclusion as rcorr. The stepper libraries are more for position than RPM. Looks like I'll have to dive into the math a little heavier.

I was looking closer at a design by David Hash. On that article is a link to his Reddit page that has a sketch. It is way more complicated than I expected. See sketch at link.

Good Stuff.

Here is a quick sketch, You will have to adjust the Speed variable for it to track better.

// Barn Door Tracker for astrophotography
// Stepper motor with Easystepper driver    
// For evodov
//

int Dir = 8;      // direction pin
int Step = 9;     // step pin  9
int PulseStatus = 0;  // status of step pin

//Timing Speed
                  //  stepper = 200 steps/revolution  
                  //  driver  = 8 micro steps  depends on you driver board settings
                  //  Total   = 200*8= 1600 steps/revolution 
                  //  1rpm = 1600/60sec = 26.666steps  per sec
                  //  period   1/x = 0.0375sec
                  //  = 37500 in microsec 
unsigned long Speed = 37500;  //  Ajust for proper speed in your setup
                    //  The Arduino uses a ceramic oscillatior...

unsigned long NextTime = 0;   //  Timing register             

// the setup function runs once when you press reset or power the board
void setup() {
  // initialize outputs.
  pinMode(Dir, OUTPUT);  // Direction output pin
  pinMode(Step, OUTPUT); // Step output pin
    
  //  change output value
  digitalWrite(Dir, HIGH);  // Direction - High or Low change for your needs
  
}

// the loop function runs over and over again forever
void loop() {
  
  if (micros() > NextTime){     
    digitalWrite(Step, HIGH);  // give high pulse
    NextTime += Speed;         // reset for next pulse
    PulseStatus=1;                 // update pulse status
  }
  if ( PulseStatus & micros() > NextTime - (Speed/2)){   // after half the period make low pulse
    digitalWrite(Step, LOW);
    PulseStatus=0;              // update pulse status
  }                                
  
}

Try this out and if necessary I can add in a variable pot for fine speed adjust.

BarnDoor.ino (1.56 KB)

evodev:
I was looking closer at a design by David Hash. On that article is a link to his Reddit page that has a sketch. It is way more complicated than I expected. See sketch at link.

Did you try my simple stepper code from Reply #1. I don't think it would be possible to make it simpler.

...R