Go Down

Topic: Help with simple uStepper control (Read 667 times) previous topic - next topic

richard_23

Hi,

I've got simple requirements for my NEMA17 stepper motor and uStepper controller, but I can't get it to do what I want. I'm completely new to Arduino.

My requirements are:

1. Move a carriage 20cm in one direction (CCW) over 8 hours;
2. Move the carriage 40 cm in the opposite direction (CW) EITHER over 8 hours, or if possible just quickly and then pause for eight hours;
3. Move the carriage 20cm in one direction (CCW) back to the middle point over 8 hours.
4. Repeat

The reason for the repeat of steps 1 and 3 are that I need this to run from 6:00 - 22:00, then return to the start position. By starting the code in the middle I can set the experiment running at 14:00 rather than 6:00. This experiment should run continuously for four months.

Some data to support the code:

Distance/rev (mm):   60
Steps/rev:   3200?
Time (hours):   8
time (secs):   28800
Distance 1 (mm):   200
Distance 2 (mm):   400
Move 1 (200mm) steps:   10666.66667
Move 2 (400mm) steps   21333.33333
Move 1 speed (steps/sec):   0.37037037
Move 2 speed (steps/sec):   0.740740741

According to the documentation, the NEMA17 stepper motor has 200 steps/rev, having from testing it it seems to be around 3200. Ideally I'd want a precise number, perhaps using moveAngle instead if I don't know the step number.

Either way, I can't get this simple code to work, and any help would be very appreciated!

Here's what I've got:

Code: [Select]

#include <uStepper.h>

uStepper stepper;

void setup() {
  // put your setup code here, to run once:
  stepper.setup();
  Serial.begin(115200);
}

void loop() {
  // put your main code here, to run repeatedly:
  stepper.setMaxVelocity(0.37037);
  stepper.moveSteps(10667, CCW, HARD);
  stepper.setMaxVelocity(0.74074);
  stepper.moveSteps(21334, CW, HARD);
  stepper.setMaxVelocity(0.37037);
  stepper.moveSteps(10667, CCW, HARD);
}


Many thanks.

MorganS

If you don't know how many steps the motor has then how is your code going to know? Perhaps you have the stepper controller in 1/16 microstepping mode?

"Can't get it to work" is obvious. You would not be here if it worked.  What does your code actually do?
"The problem is in the code you didn't post."

Robin2

Post a link to the source of ĀµStepper library - it is not one that everyone is familar with.

Post a link to the datasheet for your stepper motor. Nema17 just defines the size of the front face.

What stepper motor driver are you using?

What stepper motor power supply have you got (volts and amps)

...R
Stepper Motor Basics
Simple Stepper Code
Two or three hours spent thinking and reading documentation solves most programming problems.

richard_23

Hi Morgan and Robin, thanks for your replies.

Microstepping would make sense with those numbers (200 steps x 16 = 3200 microsteps).

Stepper motor info. I'm using the 1.8 degrees, 2A model. The power supply is a 3A 12V DC adaptor connected to the uStepper.

uStepper product sheet. The uStepper is a stepper driver with an Arduino chip built in.

uStepper library.

The motor seems to rotate continuously in one direction, regardless of whether moveSteps is set as 200 or 3200. Further, setMaxVelocity and setMaxAcceleration doesn't seem to work as I'd expect. Setting the velocity to 3200, with a high acceleration (e.g. 20000) doesn't turn the spindle one revolution per second.

Thanks again,

Richard

ustepper

Hi Richard,

Your calculations look correct. the motor has 200 steps per revolution as you mention, which is why you get 3200 microsteps per revolution when using 1/16th microstepping setting.

The reason you can't get it to work is because you assume that "moveSteps()" does not return before the steps are made. this is not the case.

Therefore you have to wait for the uStepper to finish the movement before starting the next. the code below should do what you want:

Code: [Select]
#include <uStepper.h>

uStepper stepper;
uint8_t state = 0;

void setup() {
  // put your setup code here, to run once:
  stepper.setup();
  Serial.begin(115200);
}

void loop() {
  // put your main code here, to run repeatedly:
  if(!stepper.getMotorState())
  {
    switch(state)
    {
      case 0:
        stepper.setMaxVelocity(0.37037);
        stepper.moveSteps(10667, CCW, HARD);
        state = 1;
        break;
      case 1:
        stepper.setMaxVelocity(0.74074);
        stepper.moveSteps(21334, CW, HARD);
        state = 2;
        break;
      case 2:
        stepper.setMaxVelocity(0.37037);
        stepper.moveSteps(10667, CCW, HARD);
        state = 0;
        break;
    }
  }
}


Best Regards,
Thomas olsen

richard_23

Thank you so much Thomas! Yes, it's working now :D

Another quick question: Is there a better way to add a pause than what I've done?

I tried:

Code: [Select]
      case 2:
        int delay = 10
        state = 3;
        break; 


but the delay didn't end. Neither did it when I set it to 1.

Currently I've added:

Code: [Select]
      case 2:
        stepper.setMaxVelocity(1);
        stepper.moveSteps(2, CCW, HARD);
        state = 3;
        break; 


to practically add a 2 second delay, and I'd remove those 2 "delay steps" from the next case.

Thanks again,

Richard

MorganS

You declared a variable with the name "delay". That does not make a delay.

If you just want to delay 10 milliseconds then use the delay() function.

If you have a longer delay, make it a state. Record millis() when you started that state and check millis() and any other inputs while you are in that state.
"The problem is in the code you didn't post."

ustepper

Hi Richard,

That is good to hear :)

As morgan said, to get a delay just add a case with the "delay()" function like so:

Code: [Select]

case 2:
    delay(2000);   //delay for 2000ms
    state = 3;
    break;

richard_23

Thanks again Morgan and Thomas. I've got the delay to work and I can now see what I was doing wrong. Also, my very first attempt was:

Code: [Select]
      case 2:
        stepper.delay(1000);
        state = 0;
        break;


and that created an exit error. I realise now that's because it's an Arduino function, not a stepper function. Just thought I'd mention that for any other readers learning similar tasks.

Currently I'm wondering what safeguards I can add to prevent the motor attempting to run the carriage past the end brackets, e.g. in the event of a power cut resetting the script with the carriage in the wrong place.

I'm looking into:

Code: [Select]
      case 0:
        stepper.setMaxVelocity(3200);
        stepper.moveToEnd(CCW);
        state = 1;
        break;


instead of using moveSteps().

Do either of you have any comments on that? I plan on testing it in the lab tomorrow, but feedback would be appreciated beforehand just in case it won't work!

MorganS

It is called "homing" the stepper. Make one step or a small number of steps, then check the home switch. Repeas as many times as necessary. Usually homing is done relatively slowly.

I did not look at the library to see what moveToEnd() does.
"The problem is in the code you didn't post."

Go Up