Why won't my stepper re-start?

Hi, my stepper won’t restart after I reduce the speed to zero RPM, unless I either de-power the H Bridge or press the Reset button on the UNO.

The sketch drives the motor at a varying rate in each revolution, and the overall RPM is controlled by a 10K pot.

I am using an Arduino UNO, with a 10k pot, a freetronics 2-Channel H-Bridge, and an Adafruit 200 steps/rev, 12V 350mA stepper motor.

I have tried changing “this” line in the sketch " if (motorSpeed > 0)" from > 0 to >= 0, but no difference.

I can vary the RPM from 60 RPM down to about 1.5 RPM using the pot, but any lower the motor stops,(which will not be an issue in the project,) But it won’t restart even if I turn the pot back up to max RPM. (Which WILL be an issue in the project!)

Is there an issue with the sketch, or is at a generic thing that stepper motors don’t like restarting? (As some brush-less motors tend to burst into life on start-up?)

Thank you

Mick

/*
 Based on example by Tom Igoe included in Arduino IDE
 at File -> Examples -> Stepper -> stepper_oneRevolution

 Modified to suit pinouts of Freetronics HBridge Shield
*/
/* use 10k pot, center to A0, outsides to 5v and ground.
*/


#include <Stepper.h>

const int stepsPerRevolution = 200;  // change this to fit the number of steps per revolution
                                     // for your motor



// initialize the stepper library using the default pins on the HBridge Shield:
Stepper myStepper(stepsPerRevolution, 4, 7, 3, 2);

void setup() {
  
  // set the speed at 60 rpm:
  myStepper.setSpeed(60);
  // initialize the serial port:
  Serial.begin(9600);
}

void loop() {
   //read sensor value
  int sensorReading = analogRead(A0);
  //map it to a range from 0 to 100
  int motorSpeed = map(sensorReading, 0, 1023, 0, 100);
  if (motorSpeed > 0) 
  
  // 0 step 1/20 revolution in one direction:
  Serial.println("clockwise");
  
  myStepper.step(stepsPerRevolution /20);
  myStepper.setSpeed(1 * motorSpeed);
  
  
  //read sensor value
   sensorReading = analogRead(A0);
  //map it to a range from 0 to 100
   motorSpeed = map(sensorReading, 0, 1023, 0, 100);
  if (motorSpeed > 0)
  
  // 1 step 1/20
  Serial.println("clockwise");
 
  myStepper.step(stepsPerRevolution /20);
  myStepper.setSpeed(.92 * motorSpeed);
  
  
  //read sensor value
   sensorReading = analogRead(A0);
  //map it to a range from 0 to 100
   motorSpeed = map(sensorReading, 0, 1023, 0, 100);
  if (motorSpeed > 0)
  
  // 2 step 1/20
  Serial.println("clockwise");
  
  myStepper.step(stepsPerRevolution /20);
  myStepper.setSpeed(.83 * motorSpeed);
  
  
  //read sensor value
   sensorReading = analogRead(A0);
  //map it to a range from 0 to 100
   motorSpeed = map(sensorReading, 0, 1023, 0, 100);
  if (motorSpeed > 0)
  
   // 3 step 1/20
  Serial.println("clockwise");
  
  myStepper.step(stepsPerRevolution /20);
  myStepper.setSpeed(.75 * motorSpeed);
  
  
  //read sensor value
   sensorReading = analogRead(A0);
  //map it to a range from 0 to 100
   motorSpeed = map(sensorReading, 0, 1023, 0, 100);
  if (motorSpeed > 0)
  
  // 4 step 1/20
  Serial.println("clockwise");
  
  myStepper.step(stepsPerRevolution /20);
  myStepper.setSpeed(.67 * motorSpeed);
  
  
  //read sensor value
   sensorReading = analogRead(A0);
  //map it to a range from 0 to 100
   motorSpeed = map(sensorReading, 0, 1023, 0, 100);
  if (motorSpeed > 0)
  
  // 5 step 1/20
  Serial.println("clockwise");
  
  myStepper.step(stepsPerRevolution /20);
  myStepper.setSpeed(.58 * motorSpeed);
  
  
  //read sensor value
   sensorReading = analogRead(A0);
  //map it to a range from 0 to 100
   motorSpeed = map(sensorReading, 0, 1023, 0, 100);
  if (motorSpeed > 0)
  
  //  6 step 1/20
  Serial.println("clockwise");

  
  myStepper.step(stepsPerRevolution /20);
  myStepper.setSpeed(.50 * motorSpeed);
  
  
  //read sensor value
   sensorReading = analogRead(A0);
  //map it to a range from 0 to 100
   motorSpeed = map(sensorReading, 0, 1023, 0, 100);
  if (motorSpeed > 0)
  
   // 7 step 1/20
  Serial.println("clockwise");
  
  
  myStepper.step(stepsPerRevolution /20);
  myStepper.setSpeed(.42 * motorSpeed);
  
  
  
  //read sensor value
   sensorReading = analogRead(A0);
  //map it to a range from 0 to 100
   motorSpeed = map(sensorReading, 0, 1023, 0, 100);
  if (motorSpeed > 0)
   
  // 8 step 1/20
  Serial.println("clockwise");
  
  
  myStepper.step(stepsPerRevolution /20);
  myStepper.setSpeed(.33 * motorSpeed);
  
  
  
  //read sensor value
   sensorReading = analogRead(A0);
  //map it to a range from 0 to 100
   motorSpeed = map(sensorReading, 0, 1023, 0, 100);
  if (motorSpeed > 0)
  
  // 9 step 1/20 revolution in one direction:
  Serial.println("clockwise");
  
  
  myStepper.step(stepsPerRevolution /20);
  myStepper.setSpeed(.25 * motorSpeed);
  
  
  
  //read sensor value
   sensorReading = analogRead(A0);
  //map it to a range from 0 to 100
   motorSpeed = map(sensorReading, 0, 1023, 0, 100);
  if (motorSpeed > 0)
  
  // 11 step 1/20 revolution in one direction:
  Serial.println("clockwise");
  
  
  myStepper.step(stepsPerRevolution /20);
  myStepper.setSpeed(.25 * motorSpeed);
  
  
  
  //read sensor value
   sensorReading = analogRead(A0);
  //map it to a range from 0 to 100
   motorSpeed = map(sensorReading, 0, 1023, 0, 100);
  if (motorSpeed > 0)
  
  // 12 step 1/20 revolution in one direction:
  Serial.println("clockwise");
  
  
  myStepper.step(stepsPerRevolution /20);
  myStepper.setSpeed(.33 * motorSpeed);
  
  
  
  //read sensor value
   sensorReading = analogRead(A0);
  //map it to a range from 0 to 100
   motorSpeed = map(sensorReading, 0, 1023, 0, 100);
  if (motorSpeed > 0)
  
  // 13 step 1/20 revolution in one direction:
  Serial.println("clockwise");
  
  
  myStepper.step(stepsPerRevolution /20);
  myStepper.setSpeed(.42 * motorSpeed);
  
  
  
  //read sensor value
   sensorReading = analogRead(A0);
  //map it to a range from 0 to 100
   motorSpeed = map(sensorReading, 0, 1023, 0, 100);
  if (motorSpeed > 0)
  
  // 14 step 1/20 revolution in one direction:
  Serial.println("clockwise");
  
  
  myStepper.step(stepsPerRevolution /20);
  myStepper.setSpeed(.50 * motorSpeed);
  
  
  
  //read sensor value
   sensorReading = analogRead(A0);
  //map it to a range from 0 to 100
   motorSpeed = map(sensorReading, 0, 1023, 0, 100);
  if (motorSpeed > 0)
  
  // 15 step 1/20 revolution in one direction:
  Serial.println("clockwise");
  
  
  myStepper.step(stepsPerRevolution /20);
  myStepper.setSpeed(.58 * motorSpeed);
  
  
  
  //read sensor value
   sensorReading = analogRead(A0);
  //map it to a range from 0 to 100
   motorSpeed = map(sensorReading, 0, 1023, 0, 100);
  if (motorSpeed > 0)
  
  // 16 step 1/20 revolution in one direction:
  Serial.println("clockwise");
  
  
  myStepper.step(stepsPerRevolution /20);
  myStepper.setSpeed(.67 * motorSpeed);
  
  
  
  //read sensor value
   sensorReading = analogRead(A0);
  //map it to a range from 0 to 100
   motorSpeed = map(sensorReading, 0, 1023, 0, 100);
  if (motorSpeed > 0)
  
  // 17 step 1/20 revolution in one direction:
  Serial.println("clockwise");
  
  
  myStepper.step(stepsPerRevolution /20);
  myStepper.setSpeed(.75 * motorSpeed);
  
  
  
  //read sensor value
   sensorReading = analogRead(A0);
  //map it to a range from 0 to 100
   motorSpeed = map(sensorReading, 0, 1023, 0, 100);
  if (motorSpeed > 0)
  
  // 18 step 1/20 revolution in one direction:
  Serial.println("clockwise");
  
  
  myStepper.step(stepsPerRevolution /20);
  myStepper.setSpeed(.83 * motorSpeed);
  
  
  
  //read sensor value
   sensorReading = analogRead(A0);
  //map it to a range from 0 to 100
   motorSpeed = map(sensorReading, 0, 1023, 0, 100);
  if (motorSpeed > 0)
  
  // 19 step 1/20 revolution in one direction:
  Serial.println("clockwise");
  
  
  myStepper.step(stepsPerRevolution /20);
  myStepper.setSpeed(.92 * motorSpeed);
  
  
  
  //read sensor value
   sensorReading = analogRead(A0);
  //map it to a range from 0 to 100
   motorSpeed = map(sensorReading, 0, 1023, 0, 100);
  if (motorSpeed > 0)
  
  // 20 step 1/20 revolution in one direction:
  Serial.println("clockwise");
  
  
  myStepper.step(stepsPerRevolution /20);
  myStepper.setSpeed(1.0 * motorSpeed);
  
  
  
}

OMG, lets start by losing the copy/paste and rewrite loop() using a variable for the speed and a function to update it. Repeating the same code over and over again is not the way to create a maintainable bug free sketch!

Thanks Mark

Using this sketch, much simpler, the result is still the same, the motor won’t restart from zero RPM

Mick

/*
 Based on example by Tom Igoe included in Arduino IDE
 at File -> Examples -> Stepper -> stepper_oneRevolution

 Modified to suit pinouts of Freetronics HBridge Shield
*/
/* 10K pot, center wire to A0, outside to 5v and ground(just next to A0)
*/

#include <Stepper.h>

const int stepsPerRevolution = 200;  // change this to fit the number of steps per revolution
                                     // for your motor

// initialize the stepper library using the default pins on the HBridge Shield:
Stepper myStepper(stepsPerRevolution, 4, 7, 3, 2);

void setup() {
  // set the speed at 30 rpm:
  myStepper.setSpeed(30);
  // initialize the serial port:
  Serial.begin(9600);
}

void loop() {
  //read sensor value
  int sensorReading = analogRead(A0);
  //map it to a range from 0 to 100
  int motorSpeed = map(sensorReading, 0, 1023, 0, 100);
  //set the motor speed
  if (motorSpeed > 0) {
  myStepper.setSpeed(0.4 * motorSpeed);
  // step 1/100 of a revolution
  myStepper.step(stepsPerRevolution/100);
  // step one revolution  in one direction:
   Serial.println("clockwise");
  myStepper.step(stepsPerRevolution);
  }
  
  
  
}

MickyK: Using this sketch, much simpler, the result is still the same, the motor won't restart from zero RPM

Maybe the library is not intended to work with 0 RPM - it may be doing a divide by RPM internally and getting a divide by zero error.

I can't see any need for zero RPM - just don't do any steps and it won't move.

Also you have

myStepper.setSpeed(0.4 * motorSpeed);

and I suspect that this won't work with the decimal value as it expects a long integer, not a floating point value.

...R

Yes, the Stepper library fails to check for zero being passed to setSpeed(), and if you do pass zero it will jam the motor for a very very long time (minutes, days, years, who knows).

One solution is to prevent 0 getting through:

myStepper.setSpeed(1 + 0.4 * motorSpeed);

A more mature solution is to test for actual zero rpm:

float speed_factor = 0.4 ;

void loop() 
{
  //read sensor value
  int sensorReading = analogRead(A0);
  //map it to a range from 0 to 100
  int motorSpeed = map(sensorReading, 0, 1023, 0, speed_factor * 100);
  //set the motor speed
  if (motorSpeed > 0) {
    myStepper.setSpeed(motorSpeed);
    ....
  }
}

So calculate the actual long value to be passed to setSpeed() before comparing to zero. The original code would get map returning 1, then calculate 0.4*1 then detect that this is not zero, then implicitly cast to a long (giving zero) and pass that to setSpeed()

Thank you gentlemen,

This seems to be a solution to my problem.

I'll try it on the weekend, or before, depending on work issues.

I will let everyone know how I go.

Mick