Strange stepper reaction

Hello all.

I'm a bit confused on what happened when I added some code to my sketch and was hoping someone can tell me what I did to get the strange reaction that I got from my stepper motor.

I have a stepper motor project in which I'm controlling a bi-polar stepper motor (NEMA 23 sized) with an ESP8266 NodeMCU controller and DM556T stepper driver. I have the motor working fine using a joystick (although it's not as fast as I would like it). I am trying to add a couple of hall effect sensors to it to use as end stops. Because I'm also controlling speed (and direction) with the joystick, I have four "sections" in my code that instruct the motor to take a step. There are two of these sections for calculating a "slower" speed and two for calculating a "faster" speed and there is one for each direction. I added a little 'if' statement to each of these to check the sensor value and if tripped, stop the motor. What I got for this sketch is when the joystick hits the "faster" speed section, the motor spins super fast (more like I wanted it to, but wasn't expecting) and then seems to "hang" in one spot, making a whining noise and vibrating. I'm assuming this is because it is getting signals to both coils at the same time, but why? Also why did it all of a sudden go super fast? I didn't change anything to do with the speed at all. I just checked a sensor!

Both sketches are below, but the extra code that I added to each section was this:

if (upStopVal == 0) {
motorStop();
} else {
my original code that didn't change
}

Original sketch:

/* StepperZ_Project_rev28                         */
/* Program to control stepper motor with joystick */

#include <AccelStepper.h>

/* ------- Defining Pins --------------------------------- */
const byte stepPin = D1;
const byte dirPin = D2;
const byte enaPin = D5;
const byte upStop = D6;
const byte downStop = D7;
const byte xJoyPin = A0;

/* ------- Pin Variables --------------------------------- */
int xJoy = 0;
int dirVal = -1;
int upStopVal = 1;
int downStopVal = 1;

/* ------- Variables for Calculations & Settings --------- */
long speedVal = 0.0;
long fastSpeed = 50000.0;
long slowSpeed = 100.0;
long accelFast = 500.0;
long accelSlow = 50.0;
long newPos = 0.0;

AccelStepper xStepper(AccelStepper::DRIVER, stepPin, dirPin);

/* ------------------------------------------------------- */
void setup()
/* ------------------------------------------------------- */
{
  Serial.begin(115200);

  xStepper.setMinPulseWidth(1);

  pinMode(stepPin, OUTPUT);
  pinMode(dirPin, OUTPUT);
  pinMode(enaPin, OUTPUT);
  pinMode(xJoyPin, INPUT);
  pinMode(upStop, INPUT);
  pinMode(downStop, INPUT);

  pinMode(enaPin, LOW);
  pinMode(upStop, LOW);
  pinMode(downStop, LOW);

  delay(5);

  xStepper.setMaxSpeed(fastSpeed);
  xStepper.setAcceleration(accelFast);
  xStepper.setSpeed(0);
}


/* ======================================================= */
void loop()
/* ======================================================= */
{
  xJoy = analogRead(xJoyPin);                 /* check initial value of joystick */
  upStopVal = digitalRead(upStop);
  downStopVal = digitalRead(downStop);

  /*............................................checks for joystick to be "neutral" (no imput) */
  if (xJoy >= 520 && xJoy <= 570)
  {
    digitalWrite(enaPin, HIGH);               /* shuts down driver - i.e. no reaction from input  */

    Serial.println("");
    Serial.print("Neutral statement Joystick = ");
    Serial.println(xJoy);
    Serial.print("Speed is  ");
    Serial.println(speedVal);
    Serial.println("");
  }

  /*........JOYSTICK PUSHED DOWN................as long as joystick value is between 525 and 25
                                                the motor will run the slow rate in conjuction with
  																							the throw of the joystick.  */
  if (xJoy <= 520 && xJoy >= 25)
  {
    dirVal = -1;                               /*  "down" direction  */
    speedVal = 520 - xJoy;
    digitalWrite(enaPin, LOW);                 /*  re-initiates stepper driver  */

    slowStep();

    xStepper.runSpeedToPosition();

    Serial.println("");
    Serial.print("Down slow statement Joystick = ");
    Serial.println(xJoy);
    Serial.print("Speed is  ");
    Serial.println(speedVal);
    Serial.println("");

  }

  /*........JOYSTICK DOWN ALL THE WAY...........once the joystick value drops below 25, the motor
                                                will run at the fast rate until it reaches max speed. */
  if (xJoy < 520 && xJoy	< 25)
  {
    dirVal = -1;                               /*  "down" direction  */
    speedVal = ((520 - xJoy) * 100);
    digitalWrite(enaPin, LOW);

    fastStep();

    xStepper.runSpeedToPosition();

    Serial.println("");
    Serial.print("Down fast statement Joystick = ");
    Serial.println(xJoy);
    Serial.print("Speed is  ");
    Serial.println(speedVal);
    Serial.println("");

  }


  /*........JOYSTICK PUSHED UP..................as long as joystick value is between 550 and 1000
                                                the motor will run the slow rate in conjuction with
  																							the throw of the joystick.  */
  if (xJoy >= 570 && xJoy <= 999)
  {
    dirVal = 1;                               /*  "up" direction  */
    speedVal = xJoy - 570;
    digitalWrite(enaPin, LOW);

    slowStep();

    xStepper.runSpeedToPosition();

    Serial.println("");
    Serial.print("Up slow statement Joystick = ");
    Serial.println(xJoy);
    Serial.print("Speed is  ");
    Serial.println(speedVal);
    Serial.println("");

  }

  /*........JOYSTICK UP ALL THE WAY.............once the joystick value rises above 1000, the motor
                                                will run at the fast rate until it reaches max speed. */
  if (xJoy > 570 && xJoy	> 999)
  {
    dirVal = 1;                               /*  "up" direction  */
    speedVal = ((xJoy - 570) * 100);
    digitalWrite(enaPin, LOW);

    fastStep();

    xStepper.runSpeedToPosition();

    Serial.println("");
    Serial.print("Up Fast statement Joystick = ");
    Serial.println(xJoy);
    Serial.print("Speed is  ");
    Serial.println(speedVal);
    Serial.println("");

  }
}


/* ================= SLOW STEP FUNCTION ================== */
void slowStep()
/* ======================================================= */
{
  xStepper.setMaxSpeed(slowSpeed);
  xStepper.setAcceleration(accelSlow);
  xStepper.move(dirVal);
  xStepper.setSpeed(speedVal);
}


/* ================== FAST STEP FUNCTION ================= */
void fastStep()
/* ======================================================= */
{
  xStepper.setMaxSpeed(fastSpeed);
  xStepper.setAcceleration(accelFast);
  xStepper.move(dirVal);
  xStepper.setSpeed(speedVal);
}

/* ============== MOTOR STOP FUNCTION ==================== */
void motorStop()
/* ======================================================= */
{
  xStepper.stop();
  speedVal = 0.0;
  xStepper.runSpeed();
  digitalWrite(enaPin, HIGH);               /* shuts down driver  */
}

With sensor check:

/* StepperZ_Project_rev28                         */
/* Program to control stepper motor with joystick */

#include <AccelStepper.h>

/* ------- Defining Pins --------------------------------- */
const byte stepPin = D1;
const byte dirPin = D2;
const byte enaPin = D5;
const byte upStop = D6;
const byte downStop = D7;
const byte xJoyPin = A0;

/* ------- Pin Variables --------------------------------- */
int xJoy = 0;
int dirVal = -1;
int upStopVal = 1;
int downStopVal = 1;

/* ------- Variables for Calculations & Settings --------- */
long speedVal = 0.0;
long fastSpeed = 50000.0;
long slowSpeed = 100.0;
long accelFast = 500.0;
long accelSlow = 50.0;
long newPos = 0.0;

AccelStepper xStepper(AccelStepper::DRIVER, stepPin, dirPin);

/* ------------------------------------------------------- */
void setup()
/* ------------------------------------------------------- */
{
  Serial.begin(115200);

  xStepper.setMinPulseWidth(1);

  pinMode(stepPin, OUTPUT);
  pinMode(dirPin, OUTPUT);
  pinMode(enaPin, OUTPUT);
  pinMode(xJoyPin, INPUT);
  pinMode(upStop, INPUT);
  pinMode(downStop, INPUT);

  pinMode(enaPin, LOW);
  pinMode(upStop, LOW);
  pinMode(downStop, LOW);

  delay(5);

  xStepper.setMaxSpeed(fastSpeed);
  xStepper.setAcceleration(accelFast);
  xStepper.setSpeed(0);
}


/* ======================================================= */
void loop()
/* ======================================================= */
{
  xJoy = analogRead(xJoyPin);                 /* check initial value of joystick */
  upStopVal = digitalRead(upStop);
  downStopVal = digitalRead(downStop);

  /*............................................checks for joystick to be "neutral" (no imput) */
  if (xJoy >= 520 && xJoy <= 570)
  {
    digitalWrite(enaPin, HIGH);               /* shuts down driver - i.e. no reaction from input  */

    Serial.println("");
    Serial.print("Neutral statement Joystick = ");
    Serial.println(xJoy);
    Serial.print("Speed is  ");
    Serial.println(speedVal);
    Serial.println("");
  }

  /*........JOYSTICK PUSHED DOWN................as long as joystick value is between 525 and 25
                                                the motor will run the slow rate in conjuction with
  																							the throw of the joystick.  */
  if (xJoy <= 520 && xJoy >= 25)
  {
    if (upStopVal == 0) {
      motorStop();
    } else {
      dirVal = -1;                               /*  "down" direction  */
      speedVal = 520 - xJoy;
      digitalWrite(enaPin, LOW);                 /*  re-initiates stepper driver  */

      slowStep();

      xStepper.runSpeedToPosition();

      Serial.println("");
      Serial.print("Down slow statement Joystick = ");
      Serial.println(xJoy);
      Serial.print("Speed is  ");
      Serial.println(speedVal);
      Serial.println("");
    }
  }

  /*........JOYSTICK DOWN ALL THE WAY...........once the joystick value drops below 25, the motor
                                                will run at the fast rate until it reaches max speed. */
  if (xJoy < 520 && xJoy	< 25)
  {
    if (upStopVal == 0) {
      motorStop();
    } else {
      dirVal = -1;                               /*  "down" direction  */
      speedVal = ((520 - xJoy) * 100);
      digitalWrite(enaPin, LOW);

      fastStep();

      xStepper.runSpeedToPosition();

      Serial.println("");
      Serial.print("Down fast statement Joystick = ");
      Serial.println(xJoy);
      Serial.print("Speed is  ");
      Serial.println(speedVal);
      Serial.println("");
    }
  }


  /*........JOYSTICK PUSHED UP..................as long as joystick value is between 550 and 1000
                                                the motor will run the slow rate in conjuction with
  																							the throw of the joystick.  */
  if (xJoy >= 570 && xJoy <= 999)
  {
    if (upStopVal == 0) {
      motorStop();
    } else {
      dirVal = 1;                               /*  "up" direction  */
      speedVal = xJoy - 570;
      digitalWrite(enaPin, LOW);

      slowStep();

      xStepper.runSpeedToPosition();

      Serial.println("");
      Serial.print("Up slow statement Joystick = ");
      Serial.println(xJoy);
      Serial.print("Speed is  ");
      Serial.println(speedVal);
      Serial.println("");
    }
  }

  /*........JOYSTICK UP ALL THE WAY.............once the joystick value rises above 1000, the motor
                                                will run at the fast rate until it reaches max speed. */
  if (xJoy > 570 && xJoy	> 999)
  {
    if (upStopVal == 0) {
      motorStop();
    } else {
      dirVal = 1;                               /*  "up" direction  */
      speedVal = ((xJoy - 570) * 100);
      digitalWrite(enaPin, LOW);

      fastStep();

      xStepper.runSpeedToPosition();

      Serial.println("");
      Serial.print("Up Fast statement Joystick = ");
      Serial.println(xJoy);
      Serial.print("Speed is  ");
      Serial.println(speedVal);
      Serial.println("");
    }
  }
}


/* ================= SLOW STEP FUNCTION ================== */
void slowStep()
/* ======================================================= */
{
  xStepper.setMaxSpeed(slowSpeed);
  xStepper.setAcceleration(accelSlow);
  xStepper.move(dirVal);
  xStepper.setSpeed(speedVal);
}


/* ================== FAST STEP FUNCTION ================= */
void fastStep()
/* ======================================================= */
{
  xStepper.setMaxSpeed(fastSpeed);
  xStepper.setAcceleration(accelFast);
  xStepper.move(dirVal);
  xStepper.setSpeed(speedVal);
}

/* ============== MOTOR STOP FUNCTION ==================== */
void motorStop()
/* ======================================================= */
{
  xStepper.stop();
  speedVal = 0.0;
  xStepper.runSpeed();
  digitalWrite(enaPin, HIGH);               /* shuts down driver  */
}

What if you undo the change?

DrDiettrich,

It goes right back to working fine. That little snippet of code is doing something to the process, but I don't know what. Would adding just a few lines of code mess up some kind of "timing" within the controller???

The problem resides in motorStop(). Try figure out more.

How do you have your Hall sensors wired up? They typically are open collector, which means they pull to ground when tripped and you need to declare them as INPUT_PULLUP inside setup().

Also, all your long variables are integer type so assigning them floating point values is not correct.

I think the fact that your sketch works so far is more of a coincidence. You are not using the AccelStepper methods properly.
setAcceleration() is only for methods with acceleration/deceleration. But you are not using any of these methods. So these call is useless.
The only method you use to generate step pulses is runSpeedToPosition(). There is no acceleration and no deceleration. As position you always set only one step ( move(dirVal), where dirVal is always 1 or -1 ). How can runSpeedToPosition reasonably determine a step speed? It is always immediately at the destination. I think it would be better to use runSpeed in your usage.
And the 'speedval' values you set cannot be reached in your sketch by far. AccelStepper needs a very fast loop cycletime. RunSpeedToPosition does at most one step per call ( as nearly all run.. methods do - apart from the blocking ones ). But your many Serial.print's slow down the loop significantly.
Remove all your Serial.print and you will see that your step speed is far more than your motor probably can come up with (what microstepping are you using?).

Edit: There is also a big problem with the speed jumps when the joystick switches between slowStep and fastStep. So far, you have not noticed this because the high speeds of fast are not reached at all.

Do you know this description of the AccelStepper? You should study it thoroughly.

And also if you don't use the acceleration features of AccelStepper library you will be greatly limiting the motor performance as steppers will simply stall/miss-step if you don't use speed ramping and try to make them spin fast.

The standard way to use AccelStepper:

setup: setMaxSpeed(), setAcceleration()
loop: run()

And then any where you like call move() or moveTo(), and stop() for stopping.
No delay()s in the code, run() method must run frequently all the time for AccelStepper to do its magic.

Yes, but not only explicit delay() calls. There are many methods to create delays in loop. E.g. that many Serial.prints in the sketch here. And the higher the step speed the more critical it is. Sometimes may be it's needed to call run() more than once in loop.

blh64,

Thank you for responding. The hall sensors only have 3 wires so, I'm pretty sure I have them right. But just in case.... power and ground are hooked up to a 5v power source and the signal wire is connected right to the controller pin. I have them pulled low in set-up, but I noticed that as soon as they are "read" they are showing high.

I put all those long variables in place because the library called out long as the parameter. I was just trying to prevent another error.

Ron.

MicroBahner,

I appreciate your response and information.

LOL! That doesn't surprise me. I have worked on this for way too long just trying to make it work. When it was working, I thought "Finally!". Now to find out it's a coincidence just tops the cake.

I haven't been at this very long and until I started on this project, I had no idea how to even understand ANYTHING written in the libraries. Most of them have little to no documentation to go along with them and if you're new to this, there's no way you can understand what's written in them. I think people (when writing the documentation for these libraries) forget that not everyone can understand code when the look at it. Now the AccelStepper library is a bit different than the others I looked at. It is well documented (comparatively). There was/is quite a bit written in it that I still don't understand, but it had enough included in it that, along with trial and error, I am starting to figure out some of the stuff written in it. I've noticed in a lot of forums, people giving advice tell the people you "have to look at the library", but if your new to this looking at the library does nothing but make you more confused. Anyway, I digress.....

I'm sure there is another library I should be using (or maybe there is enough in the standard Arduino.h ?????) but because of the documentation that was included with AccelStepper that is the library I went with.

So....it looks like I'm back to square 1. I'll have to try and get the motor controlled properly with the joystick somehow and then come back with the end-stop questions.

Thank you all for the information and tips.
Ron.

Did you try what happens if you omit your Serial.Prints :wink:

Well, I could propose my MobaTools lib. That would work even with your many prints ... and there is a documentation :wink:

No, you don't.

This does not make sense. You need to use digitalWrite() to set a pin HIGH or LOW

blh64,

Hmm. Good to know. Thank you!

What does 'pinMode' do then? I thought this was used to "set" a pin high or low before the loop???

MicroBahner,

No I didn't try without the Serial.Prints. I figure if I'm not using the the library the way it's intended and I pretty much just go lucky with the joystick working, I should try to write a sketch using a different library and try to write it more correctly.

I took a look at your MobaTools library. It's very impressive and you do have a LOT of documentation. Unfortunately, I'm too new to this field and started getting lost on the first page of the .PDF. There's a lot of terminology that I don't know yet I get lost pretty easy when there are multiple words I don't understand being used.

I appreciate your help. I'm sure I'll be back with another issue once I get a sketch written as far as I can take it.

Thank you again and I hope you (and everyone here on the forum) has a Peaceful Holiday.

Ron.

That's the wrong place to look at. Instead look at the examples coming with each library to learn how to use it.

You obviously prefer not to read the Arduino Reference that explains the standard functions.

The pinMode sets the mode for the pin e.g. INPUT_PULLUP, OUTPUT, INPUT etc. You set the pin to a high or a low using digitalWrite or analogWrite.

Don't be afraid to use Google - or the online documentation

You should do to understand what happens.

It seems to me that you want to go on a big trip by car, but without learning how to drive first. This will lead to many accidents. You should practice a bit on the training ground before starting your big trip :wink: .

Hi,
Can you post a circuit diagram, including component name and pin labels, please also incude your power supply?

Thanks.. Tom.... :grinning: :+1: :coffee: :australia: