Arduino Star Tracker - Stepper Motor Questions

Hello everyone,

So I'm running into some issues trying to follow these instructions here. I have everything created but I can't seem to get the stepper to work, it doesn't turn it just vibrates. However in my frustration trying to troubleshoot I'm wondering if there is an easier way to do what I need.

The LCD is nice but all I need is the stepper to turn at a one particular speed. I am ok with it a starting up once the stepper and arduino have power. Don't need buttons or a display. Any help would be appreciated, I just need to get this stepper motor running at 271.6 steps per second. Any guidance would be appreciated. Go easy I'm pretty new to all of this.

I am not familiar with the 28BYJ stepper that is shown in the pictures (and I presume that is what you are using).

However my general advice is to start by writing a short program to get the stepper to move properly. There are example programs on the AccelStepper library website.

...R

I just tested a bare-bones version of the example sketch, with the same motor and driver as those shown in the “DIY. An Astro Tracker in Two Nights” article, and the motor works fine. I just commented out all code except that required to run the motor at a set speed. ie No LCD, buttons etc.

Here’s the code I tested:-

// BareBonesStarTracker.ino

#include <AccelStepper.h>
//#include <LiquidCrystal.h>

#define HALFSTEP 8

//LiquidCrystal lcd(8, 13, 9, 4, 5, 6, 7);
//int adc_key_val[5] ={50, 200, 400, 600, 800 };
// Motor pin definitions
#define motorPin1  3     // IN1 on the ULN2003 driver 1
#define motorPin2  4     // IN2 on the ULN2003 driver 1
#define motorPin3  5     // IN3 on the ULN2003 driver 1
#define motorPin4  6     // IN4 on the ULN2003 driver 1
//int NUM_KEYS = 5;
//int adc_key_in;
//int key = -1;
//int isRun;
double speeds = 271.6;
int maxspeed = 1245;

AccelStepper stepper1(HALFSTEP, motorPin1, motorPin3, motorPin2, motorPin4);

void setup()
{
    //    lcd.clear();
    //    lcd.begin(16, 2);
    //    lcd.setCursor(0, 0);
    //    lcd.print("    Stopped     ");
    //    lcd.setCursor(0, 1);
    //    lcd.print("Speed ");
    //    lcd.print(speeds);
    //    lcd.print("   ");
    //    isRun = 0;
    stepper1.setMaxSpeed(maxspeed);
    stepper1.setSpeed(speeds);
}

void loop()
{
//    adc_key_in = analogRead(0);    // read the value from the sensor
//    key = get_key(adc_key_in);  // convert into key press
//    if (key >= 0)   // if keypress is detected
//    {
//        if (key == 1)
//        {
//            speeds += 0.1;
//            delay(50);
//        }
//        if (key == 2 && speeds > 0)
//        {
//            speeds -= 0.1;
//            delay(50);
//        }
//        if (key == 0)
//        {
//            speeds += 10;
//        }
//        if (key == 3)
//        {
//            speeds -= 10;
//        }
//        if (speeds > maxspeed)
//        {
//            speeds = maxspeed;
//        }
//        if (speeds < -maxspeed)
//        {
//            speeds = -maxspeed;
//        }
//        if (key == 4)
//        {
//            isRun = 1 - isRun;
//            lcd.setCursor(0, 0);
//            if (isRun == 1)
//            {
//                lcd.print("+++ Running +++ ");
//            }
//            else
//            {
//                lcd.print("    Stopped     ");
//            }
//            delay(250);
//        }
//        lcd.setCursor(0, 1);
//        lcd.print("Speed ");
//        lcd.print(speeds);
//        lcd.print("       ");
//        stepper1.setSpeed(speeds);
//        delay(50);
//    }
//    if (isRun == 1)
//    {
        stepper1.runSpeed();
//    }
}

//int get_key(unsigned int input)
//{
//    int k;
//    for (k = 0; k < NUM_KEYS; k++)
//    {
//        if (input < adc_key_val[k])
//            return k;
//    }
//    if (k >= NUM_KEYS)
//        k = -1;  // No valid key pressed
//    return k;
//}

You could test this code and refer to the pics below to ensure that your connections are correct.
Then you only need to uncomment the rest of the code to get everything working.

Here’s a pic of the full test setup while running:-
(Right-click and ‘View image’ or similar for a full-size view.)
Full setup running.JPG

And here’s a shot clearly showing the wiring:-
(Again, right-click and ‘View image’ or similar for a full-size view.)
Wiring details.JPG

This gave me a chance to test out the “AccelStepper” library. I’d never got around to it until now. :slight_smile:

Let us know how you go.

I have to wonder why 271.6 steps a second. Where the hell does a number like that come from? Is this a case of making the barn door first without any thought to construction accuracy, and then clear up all the mistakes in software?

Nick_Pyner:
I have to wonder why 271.6 steps a second. Where the hell does a number like that come from? Is this a case of making the barn door first without any thought to constru8ction accuracy, and then clear up all the mistakes in software?

You do know that the apparent motion of the stars doesn't take exactly 24 hours to go around the Earth? And then maybe he wants to track the moon?

Nick_Pyner:
I have to wonder why 271.6 steps a second. Where the hell does a number like that come from? Is this a case of making the barn door first without any thought to constru8ction accuracy, and then clear up all the mistakes in software?

I think it would be very difficult to get the gearing precisely right so that a nice, round whole number could be used. It would be easier to get it close, then fine-tune in firmware. There is provision in the full program for adjusting the speed in increments of 0.1, so the article's author has probably done that and came up with 271.6 for his setup, so used that as the default.

OldSteve:
I think it would be very difficult to get the gearing precisely right so that a nice, round whole number could be used. It would be easier to get it close, then fine-tune in firmware. There is provision in the full program for adjusting the speed in increments of 0.1, so the article's author has probably done that and came up with 271.6 for his setup, so used that as the default.

Thank you for your help. I just tested it and it works great! A few last questions. I was just planning on doing the setup you have except utilizing a USB 10,000 mah battery back up. One arudino would just give power to the motor and the other arduino runs the code. There are two powered usb outs from the battery pack. I assume that should work fine (just tested out the motor doing the same thing except using usb from my computer for power). Any concerns with the setup I explained?

Any ideas on what I should do if I wanted to add a start stop button to this setup?

Lastly someone mentioned the 271.6 setting. The reason has to do with the 4:1 gear ratio I have set up and the threaded rod I'm using. I need the 64 tooth gear to move at 1rpm. Someone smarter than I did the calculations. I just tested it and and with that setting it's definitely at 1rpm give or take less than a second.

paulornothing:
A few last questions. I was just planning on doing the setup you have except utilizing a USB 10,000 mah battery back up. One arudino would just give power to the motor and the other arduino runs the code. There are two powered usb outs from the battery pack. I assume that should work fine (just tested out the motor doing the same thing except using usb from my computer for power). Any concerns with the setup I explained?

I don't quite understand why you feel that you need a second Arduino just to provide power. Ignore what the guy who wrote that article did.

I assume that the outputs from the battery pack are 5V, so why connect a second Arduino? Connect one 5V output to the stepper driver, the other to the Arduino, and you're good to go. (They should share a common ground, so you shouldn't need to do that externally.)
Make sure that you connect the 5V supply to the Arduino's 5V rail, NOT to the Vin input or the barrel jack. In my test, I just used a single supply as shown, a 12V 7Ah SLA battery regulated by a 5V 5A DC-DC converter. I put a 100uF cap on the 5V rail for smoothing any noise created by the motor.

Any ideas on what I should do if I wanted to add a start stop button to this setup?

Needless to say, you'll have to write some code to do that. You'll need a button debounce, and a 'state' variable to flag whether the motor should be running or stopped.
Something like:-boolean runEnabled;
Use the button press to toggle that variable between true and false like this:-runEnabled ^= 1;then:-

if(runEnabled)
    stepper1.runSpeed();

I won't write it for you - it's a good chance for you to learn a bit, but this might help with debounce:-

/* SimpleDebounce.ino
*
*  Notes:-
*  A test of a simple but effective button debounce function.
*  
*  This returns true if the button has been pressed:-
*  bool checkButton(byte currentButton, unsigned long *pPrevButtonMillis)
*/

// Defines:-
#define DEBOUNCE_DELAY 250

// Pin allocations:-
const byte button1Pin = 2;
const byte led1Pin = 3;
const byte button2Pin = 4;
const byte led2Pin = 5;

void setup()
{
    pinMode(button1Pin, INPUT_PULLUP);
    pinMode(button2Pin, INPUT_PULLUP);
    pinMode(led1Pin, OUTPUT);
    pinMode(led2Pin, OUTPUT);
}

void loop()
{
    static bool led1State = 0;
    static bool led2State = 0;
    static unsigned long prevButton1Millis = 0;
    static unsigned long prevButton2Millis = 0;
    
    // Check pushbutton1:-
    if (checkButton(button1Pin, &prevButton1Millis))
    {
        led1State ^= 1;
        digitalWrite(led1Pin, led1State);
    }

    // Check pushbutton2:-
    if (checkButton(button2Pin, &prevButton2Millis))
    {
        led2State ^= 1;
        digitalWrite(led2Pin, led2State);
    }
}

bool checkButton(byte currentButton, unsigned long *pPrevButtonMillis)
{
    unsigned long currentMillis = millis();
    if (currentMillis - *pPrevButtonMillis >= DEBOUNCE_DELAY)
    {
        if (digitalRead(currentButton) == LOW)
        {
            *pPrevButtonMillis = currentMillis;
            return true;
        }
    }
    return false;
}

So yes the battery pack has two USB outs that are 5v each. I guess that would mean I would need to cut up a USB cable so that I could send power to the stepper controller. When you say common ground, what would be the easiest way for me to accomplish that?

I'll work on the button later, I appreciate the walk through. I really just want to make sure the rest of my assembly is correct and take some test shots first. I'll post some pics once I get it assembled.

paulornothing:
When you say common ground, what would be the easiest way for me to accomplish that?

As I said, regarding the two 5V ouputs from your battery pack:-

They should share a common ground, so you shouldn't need to do that externally.

I don't think you'll need to do anything to connect the grounds. They'll be internally connected in the battery pack, I would think.

paulornothing:
Lastly someone mentioned the 271.6 setting. The reason has to do with the 4:1 gear ratio I have set up and the threaded rod I'm using. I need the 64 tooth gear to move at 1rpm. Someone smarter than I did the calculations. I just tested it and and with that setting it's definitely at 1rpm give or take less than a second.

I think the 271.6 has more to do with the distance of the threaded rod from the hinge than anything else. The rod is effectively a portion of a worm wheel. The diameter of this "wheel", and therefore the number of teeth, is determined by its distance from the hinge - which is the hardest thing to measure.

I guess the internal ratio in the motor "of about 63.68395:1" doesn't help much either. It implies the gearing is more complicated than one would suppose, maybe to minimise tooth wear.

I've got one of those cheapo steppers. I will have to give it a go with Steve's notes.

Nick_Pyner:
I guess the internal ratio in the motor “of about 63.68395:1” doesn’t help much either. It implies the gearing is more complicated than one would suppose, maybe to minimise tooth wear.

In the article he says 63.68395:1, and I’ve seen a similar figure quoted elsewhere, but is that really accurate?

I have a datasheet here for a 28BYJ-48 stepper motor, and it just says 64:1. It quotes the step angle to 3 decimal places, 5.625°. I would think that if the motor wasn’t really exactly 64:1, they wouldn’t state the step angle to that precision.
(Actually, I have two datasheets from two different manufaturers for this motor type, (the 5V and the 12V versions), and both state 64:1 / 5.625°.)
I’ve attached one below.

Edit: Incidentally, the way to tell the difference between the two motor versions is that the 5V version has a coil resistance of 50 ohms whereas the 12V version has 300 ohm coils. (If they’re not labelled or the label has worn off. )

Stepper-Motor-28BJY-48-Datasheet.pdf (164 KB)

The 28BYJ-48 steppers that I have are not quite 64:1 and with mine, it is actually impossible to have the output shaft make exactly one revolution.

There seem to be several models with different gear ratios, as discussed here. Mine seem to be the RioRand ones, with 2038 steps = 1.000056 output shaft revolutions.

OldSteve:
In the article he says 63.68395:1, and I’ve seen a similar figure quoted elsewhere, but is that really accurate?

I have a datasheet here for a 28BYJ-48 stepper motor, and it just says 64:1. It quotes the step angle to 3 decimal places, 5.625°. I would think that if the motor wasn’t really exactly 64:1, they wouldn’t state the step angle to that precision.

Ye says “about 63.68395” which baffles me a bit but, as I said, it may have something to do with distributed wear. And yes, I think I recall seeing something like that elsewhere. It put me off a bit, I now realise unnecessarily. The 5.625 is simply 360/64 steps, so that’s OK. I see my motor has four shafts after the armature.

edit: After seeing that stuff in remington’s link, “about 63.68395” sounds pretty reasonable and about as good as you will ever get. Thank God for software.

"about 63.68395" which baffles me a bit but, as I said, it may have something to do with distributed wear

It is a gear ratio that can be expressed exactly using integers, which turns out to be "about 63.68395" in decimal notation.

jremington:
edit: After seeing that stuff in remington's link, "about 63.68395" sounds pretty reasonable and about as good as you will ever get.

Yep, provided you have the RioRand-type motors. :slight_smile:

All very interesting.
I hope there aren't other variations besides the two tested by Graham Wideman.
I have no idea which version I have, so I feel some testing coming on, when I get some spare time.
(I've saved a copy of the article for reference. Thanks for the link jremington.)

At least the info from the article will help. I'll feed the stepper 513 steps and see how far it travels:-

513 steps = 0.999933 turns
2038 steps = 1.000056 turns