Accelstepper run() question

Code below instructs the steppermotor to run for a given distance (input over serial monitor).
The input from the serial monitor is well received and parsed. For example f 1000 100 means forward, distance 1000, speed 100.
However the motor does not move. The if-loop where the motor is instructed to run loops forever and rvcdDistCopy is never reached.

What is wrong?

#include <AccelStepper.h>
#define MotorInterfaceType 4  // type 4 = unipolar motor controlled by 4 transistors ie ULN9003
uint32_t rcvdDistance, rcvdSpeed, rcvdAccel, rcvdDistCopy; //number of steps, speed, acceleration value from compute, character for commands:
// each character needs two variables: distance and speed. Example: s 2000 500 means 2000 steps at 500 steps/second
/* f = forward (CW) // needs steps and speed values
   r = reverse (CCW) // needs steps and speed values
   a = set acceleration // needs acceleration value
   s = stop right now! // just the 's' is needed
*/
bool newData, runOk = true; // booleans for new data from serial, and run allowed flag
const byte numChars = 32;
char myData[numChars] = {0};
char rcvddChars[numChars], tempChars[numChars], rcvdCmd[numChars];
// Pins entered in sequence IN1-IN3-IN2-IN4 for proper step sequence
AccelStepper myStepper(MotorInterfaceType, 8, 9, 10, 11);

void setup() {
  Serial.begin(9600);
  delay(500);
  Serial.println("DCCpp_turntable_controller_v1");
  // set the maximum speed, acceleration factor,
  // initial speed and the target position
  myStepper.setMaxSpeed(500.0);
  myStepper.setAcceleration(10.0);
  myStepper.setSpeed(200);
  myStepper.moveTo(2000);
  // myStepper.disableOutputs();
}

void loop() {
  // Change direction once the motor reaches target position
  if (Serial.available() > 0) //if something comes
  {
    int i = i++;
    Serial.print(" i = "); Serial.println(i);
    char * strtokIndx; // this is used by strtok() as an index. It creates the variable
    byte m = Serial.readBytesUntil('\n', myData, numChars);
    myData[m] = '\0'; //null-byte

    strtokIndx = strtok(myData, " "); // this continues where the previous call left off
    //    rcvdCmd = Serial.read(); // this will read the command character
    strcpy (rcvdCmd, strtokIndx);
    Serial.print("char = "); Serial.println(rcvdCmd);

    strtokIndx = strtok(NULL, " "); // this continues where the previous call left off
    uint32_t rcvdDistance = atol(strtokIndx);
    Serial.print("long uint y1 = "); Serial.println(rcvdDistance);

    strtokIndx = strtok(NULL, " "); // this continues where the previous call left off
    uint32_t rcvdSpeed = atol(strtokIndx);
    Serial.print("long uint y2 = "); Serial.println(rcvdSpeed);
    // float y2 = atof(strtokIndx);
    // Serial.print("float y2 = "); Serial.println(y2, 2);

    rcvdDistCopy = rcvdDistance;
    char cmd = rcvdCmd[0];
    switch (cmd)
    {
      case 'f':
        runOk = true;
        Serial.print(" char case = "); Serial.println(rcvdCmd);
        Serial.print(" fwd distance = "); Serial.println(rcvdDistance);
        Serial.print(" fwd speed = "); Serial.println(rcvdSpeed);
        // myStepper.move(rcvdDistance);
        // myStepper.setMaxSpeed(rcvdSpeed);
        // runOk = false;
        break;
      case'r':
        runOk = true;
        Serial.print(" char case = "); Serial.println(rcvdCmd);
        // myStepper.move(-1 * rcvdDistance);
        // myStepper.setMaxSpeed(rcvdSpeed);
        // runOk = false;
        break;
      case 'a':
        runOk = false; //disable running
        Serial.print(" char case = "); Serial.println(rcvdCmd);
        rcvdAccel = Serial.parseFloat(); //receive the acceleration from serial
        myStepper.setAcceleration(rcvdAccel); //update the value of the variable
        Serial.println(" Accel. updated "); //confirm update by message
        break;
      case 's':
        runOk = false; //we still keep running disabled, since we just update a variable
        Serial.print(" char case = "); Serial.println(rcvdCmd);
        Serial.println(" STOP "); //print action
        myStepper.setCurrentPosition(0); // reset position
        myStepper.stop(); //stop motor
        //myStepper.disableOutputs(); //disable power
        break;
    }
  }

  if (runOk == true)
  {
    Serial.print(" currentPosition = "); Serial.println(abs(myStepper.currentPosition()));
    Serial.print(" received distance = "); Serial.println(rcvdDistCopy);

    if (abs(myStepper.currentPosition()) < rcvdDistCopy) //abs() is needed because of the '<'
    {
      Serial.println(" stepper active");
      // myStepper.enableOutputs(); //enable pins
      // myStepper.setMaxSpeed(rcvdSpeed);
      // myStepper.moveTo(rcvdDistCopy); //Set the target motor position (i.e. turn motor for 3 full revolutions)
      // myStepper.runToPosition(); // Run the motor to the target position
      // myStepper.move(rcvdDistance);
      myStepper.run(); //step the motor (this will step the motor by 1 step at each loop)
    }
    else //program enters this part if the required distance is completed
    {
      Serial.println(" stepper stopped");
      runOk = false; //disable running -> the program will not try to enter this if-else anymore
      // myStepper.disableOutputs(); // disable power
      Serial.print("POS: ");
      Serial.println(myStepper.currentPosition()); // print pos -> this will show you the latest relative number of steps
      myStepper.setCurrentPosition(0); //reset the position to zero
      Serial.print("POS: ");
      Serial.println(myStepper.currentPosition()); // print pos -> this will show you the latest relative number of steps; we check here if it is zero for real
    }
  }
}

Be sure to set your compiler warning level to "All" and look at warning messages. The compiler is good at pointing out things that will compile but not do what you intended.

Try this version:

#include <AccelStepper.h>
#define MotorInterfaceType 4                                // type 4 = unipolar motor controlled by 4 transistors ie ULN9003
uint32_t rcvdDistance, rcvdSpeed, rcvdAccel, rcvdDistCopy;  //number of steps, speed, acceleration value from compute, character for commands:
// each character needs two variables: distance and speed. Example: s 2000 500 means 2000 steps at 500 steps/second
/* f = forward (CW) // needs steps and speed values
   r = reverse (CCW) // needs steps and speed values
   a = set acceleration // needs acceleration value
   s = stop right now! // just the 's' is needed
*/

const byte numChars = 32;
char myData[numChars];
char rcvdCmd[numChars];

// Pins entered in sequence IN1-IN3-IN2-IN4 for proper step sequence
AccelStepper myStepper(MotorInterfaceType, 8, 9, 10, 11);

void setup()
{
  Serial.begin(9600);
  delay(500);

  Serial.println("DCCpp_turntable_controller_v1");
  // set the maximum speed, acceleration factor,
  // initial speed and the target position
  myStepper.setMaxSpeed(500.0);
  myStepper.setAcceleration(10.0);
  myStepper.setSpeed(200.0);
  myStepper.moveTo(2000);
  // myStepper.disableOutputs();
}

void loop()
{
  // Give the stepper an opportunity to step
  myStepper.run();

  if (Serial.available() > 0)  //if something comes
  {
    static int i = 0;
    i++;
    Serial.print(" i = ");
    Serial.println(i);

    char* strtokIndx;  // this is used by strtok() as an index. It creates the variable

    byte m = Serial.readBytesUntil('\n', myData, numChars - 1);
    myData[m] = '\0';  //null-byte

    strtokIndx = strtok(myData, " ");  // this continues where the previous call left off
    strcpy(rcvdCmd, strtokIndx);
    Serial.print("rcvdCmd = ");
    Serial.println(rcvdCmd);

    switch (rcvdCmd[0])
    {
      case 'f':                          // Forward <distance> <speed>
        {
          strtokIndx = strtok(NULL, " ");  // this continues where the previous call left off
          uint32_t rcvdDistance = atol(strtokIndx);
          Serial.print("rcvdDistance = ");
          Serial.println(rcvdDistance);

          strtokIndx = strtok(NULL, " ");  // this continues where the previous call left off
          float rcvdSpeed = atof(strtokIndx);
          Serial.print("rcvdSpeed = ");
          Serial.println(rcvdSpeed);

          myStepper.setMaxSpeed(rcvdSpeed);
          myStepper.move(rcvdDistance);
        }
        break;


      case 'r':  // Reverse <distance> <speed>
        {
          strtokIndx = strtok(NULL, " ");
          uint32_t rcvdDistance = atol(strtokIndx);
          Serial.print("rcvdDistance = ");
          Serial.println(rcvdDistance);

          strtokIndx = strtok(NULL, " ");  // this continues where the previous call left off
          float rcvdSpeed = atof(strtokIndx);
          Serial.print("rcvdSpeed = ");
          Serial.println(rcvdSpeed);

          myStepper.setMaxSpeed(rcvdSpeed);
          myStepper.move(-1 * rcvdDistance);
        }
        break;

      case 'a':  // acceleration <acceleration>
        {
          strtokIndx = strtok(NULL, " ");
          float rcvdAccel = atof(strtokIndx);
          Serial.print("rcvdAccel = ");
          Serial.println(rcvdAccel);

          myStepper.setAcceleration(rcvdAccel);  //update the value of the variable
        }
        break;

      case 's':                           // stop
        {
          myStepper.setCurrentPosition(0);  // reset position
          myStepper.stop();                 // Set target to closest stopping point
          myStepper.runToPosition();
          // myStepper.disableOutputs(); //disable power
        }
        break;
    }
  }
}

Thanks for your reply johnwasser;
just a few questions:

  1. why float for rcvdSpeed, rcvdAccel?
  2. why parsing in the switch case, and not prior to that?
  3. why numChars-1 in byte m = ?
  4. on startup the stepper starts without any command given in the serial monitor: how to prevent? But also see here below: .5
  5. how to get the stepper powered only after a command is given, and unpower after command is executed?
  6. after one time command given no more subsequent commands are executed?

Because they take float arguments. It allows for speeds less than 1 step per second.

Your code read all of the line first, and parsed it for rcvdDistance and rcvdSpeed, but then in case 'a' you called Serial.parseFloat() to read input that was already read. You would always get a timeout and 0.0 for acceleration.

You have to save space for the null terminator or 'myData[m] = '\0'; ' might write past the end of the array.

In setup() you have myStepper.moveTo(2000);. If you don't want it to move to 2000, take out that line.

Before each 'myStepper.move();' put 'myStepper.enableOutputs();'
After myStepper.run(); at the top of loop, put:

  if (myStepper.distanceToGo() == 0)
    myStepper.disableOutputs();

Your code stops reading at '\n' (Newline or NL). If your Serial Monitor is set to send '\n\r' ("Both NL and CR") there will be a 'CR' character at the beginning of the next input. Try changing the line ending to "Newline".

1 Like

Thanks again johnwasser for your input.

Some issues remain:

  1. power still not shut off, not at startup and not after a move
  2. reversing does not work
  3. where to find definitions (and use examples?) of
    setMaxSpeed()
    setSpeed()
    currentPosition()
    runToPosition
    moveTo()
    move()
    distanceToGo()
    run()
    I would love to find explanation of the purpose of each of these commands, and the difference between for example move() and moveTo() and runToPosition()

Code as it currently is:

#include <AccelStepper.h>
#define MotorInterfaceType 4  // type 4 = unipolar motor controlled by 4 transistors ie ULN9003
float rcvdSpeed, rcvdAccel;
uint32_t rcvdDistance, rcvdDistCopy; //number of steps, speed, acceleration value from compute, character for commands:
// each character needs two variables: distance and speed. Example: s 2000 500 means 2000 steps at 500 steps/second
/* f = forward (CW) // needs steps and speed values
   r = reverse (CCW) // needs steps and speed values
   a = set acceleration // needs acceleration value
   s = stop right now! // just the 's' is needed
*/
bool newData, runOk = true; // booleans for new data from serial, and run allowed flag
const byte numChars = 32;
char myData[numChars] = {0};
char rcvddChars[numChars], tempChars[numChars], rcvdCmd[numChars];
// Pins entered in sequence IN1-IN3-IN2-IN4 for proper step sequence
AccelStepper myStepper(MotorInterfaceType, 8, 9, 10, 11);

void setup() {
  Serial.begin(9600);
  delay(500);
  Serial.println("DCCpp_turntable_controller_v1");
  // set the maximum speed, acceleration factor,
  // initial speed and the target position
  myStepper.setMaxSpeed(500.0);
  myStepper.setAcceleration(10.0);
  myStepper.setSpeed(200.0);
  // myStepper.moveTo(2000);
  myStepper.disableOutputs();
}

void loop() {
  // Give the stepper an opportunity to step
  myStepper.run();
  
  if (Serial.available() > 0) //if something comes
  {
    static int i = 0;
    i++;
    Serial.print(" i = "); Serial.println(i);
    char * strtokIndx; // this is used by strtok() as an index. It creates the variable
    //    byte m = Serial.readBytesUntil('\n', myData, numChars - 1);
    byte m = Serial.readBytesUntil("\Newline", myData, numChars - 1);
    myData[m] = '\0'; //null-byte

    strtokIndx = strtok(myData, " "); // this continues where the previous call left off
    //    rcvdCmd = Serial.read(); // this will read the command character
    strcpy (rcvdCmd, strtokIndx);
    Serial.print(" rcvdCmd = "); Serial.println(rcvdCmd);

    rcvdDistCopy = rcvdDistance;
    // char cmd = rcvdCmd[0];
    switch (rcvdCmd[0])
    {
      case 'f': // Forward <distance> <speed>
        {
          // runOk = true;
          strtokIndx = strtok(NULL, " "); // this continues where the previous call left off
          rcvdDistance = atol(strtokIndx);
          Serial.print(" rcvdDistance = "); Serial.println(rcvdDistance);

          strtokIndx = strtok(NULL, " "); // this continues where the previous call left off
          rcvdSpeed = atof(strtokIndx);
          Serial.print(" rcvdSpeed = "); Serial.println(rcvdSpeed, 2);

          myStepper.enableOutputs();
          myStepper.move(rcvdDistance);
          myStepper.setMaxSpeed(rcvdSpeed);
          if (myStepper.distanceToGo() == 0)
            myStepper.disableOutputs();
          // runOk = false;
        }
        break;
      case'r':  // Reverse <distance> <speed>
        {
          // runOk = true;
          strtokIndx = strtok(NULL, " "); // this continues where the previous call left off
          rcvdSpeed = atol(strtokIndx);
          Serial.print(" rcvdSpeed = "); Serial.println(rcvdSpeed);          // myStepper.move(-1 * rcvdDistance);

          strtokIndx = strtok(NULL, " "); // this continues where the previous call left off
          rcvdSpeed = atof(strtokIndx);
          Serial.print(" rcvdSpeed = "); Serial.println(rcvdSpeed, 2);

          myStepper.enableOutputs();
          myStepper.move(-1 * rcvdDistance);
          myStepper.setMaxSpeed(rcvdSpeed);
          if (myStepper.distanceToGo() == 0)
            myStepper.disableOutputs();
          // runOk = false;
        }
        break;
      case 'a': // acceleration <acceleration>
        {
          // runOk = false; //disable running
          strtokIndx = strtok(NULL, " ");
          rcvdAccel = atof(strtokIndx);
          Serial.print("rcvdAccel = "); Serial.print(rcvdAccel, 2);
          myStepper.setAcceleration(rcvdAccel);  //update the value of the variable
          Serial.println(" Accel. updated "); //confirm update by message

          /*
            Serial.print(" char case = "); Serial.println(rcvdCmd);
            rcvdAccel = Serial.parseFloat(); //receive the acceleration from serial
            myStepper.setAcceleration(rcvdAccel); //update the value of the variable
            Serial.println(" Accel. updated "); //confirm update by message
          */
        }
        break;
      case 's': // stop
        {
          // runOk = false; //we still keep running disabled, since we just update a variable
          myStepper.setCurrentPosition(0);  // reset position
          myStepper.stop();                 // Set target to closest stopping point
          myStepper.runToPosition();
          myStepper.disableOutputs(); //disable power
          /*
            Serial.print(" char case = "); Serial.println(rcvdCmd);
            Serial.println(" STOP "); //print action
            myStepper.setCurrentPosition(0); // reset position
            myStepper.stop(); //stop motor
            //myStepper.disableOutputs(); //disable power
          */
        }
        break;
    }
  }

I would love to find explanation of the purpose of each of these commands, and the difference between for example move() and moveTo() and runToPosition()

I find this to be a good reference.

https://hackaday.io/project/183279-accelstepper-the-missing-manual

2 Likes

In the doc folder inside the AccelStepper folder inside the libraries folder.

This is auto generated documentation so it might get some getting used to.
However, you have access to the full code in the AccelStepper.h and AccelStepper.cpp files. There is also an examples folder in there as well.

1 Like

Top!!!

... and now the last two issues on the program; but I wait for johnwasser to appear.

To get power disconnected I changed in the void loop

myStepper.run();

to

  if (!myStepper.run())
    myStepper.disableOutputs();

Then parsing for reversing was wrong for the move():
corrected the parsing for rcvdDistance:

          strtokIndx = strtok(NULL, " "); // this continues where the previous call left off
          rcvdDistance = atol(strtokIndx);
          Serial.print(" rcvdDistance = "); Serial.println(rcvdDistance);

And also uint16_t was used for rcvDistance, that must be int to allow negative values.

But reversing still does not work.

Full code:

#include <AccelStepper.h>
#define MotorInterfaceType 4  // type 4 = unipolar motor controlled by 4 transistors ie ULN9003
float rcvdSpeed, rcvdAccel;
int rcvdDistance, rcvdDistCopy; //number of steps, speed, acceleration value from compute, character for commands:
// each character needs two variables: distance and speed. Example: s 2000 500 means 2000 steps at 500 steps/second
/* f = forward (CW) // needs steps and speed values
   r = reverse (CCW) // needs steps and speed values
   a = set acceleration // needs acceleration value
   s = stop right now! // just the 's' is needed
*/
bool newData, runOk = true; // booleans for new data from serial, and run allowed flag
const byte numChars = 32;
char myData[numChars] = {0};
char rcvddChars[numChars], tempChars[numChars], rcvdCmd[numChars];
// Pins entered in sequence IN1-IN3-IN2-IN4 for proper step sequence
AccelStepper myStepper(MotorInterfaceType, 8, 9, 10, 11);

void setup() {
  Serial.begin(9600);
  delay(500);
  Serial.println("DCCpp_turntable_controller_v1");
  // set the maximum speed, acceleration factor,
  // initial speed and the target position
  myStepper.setMaxSpeed(500.0);
  myStepper.setAcceleration(10.0);
  myStepper.setSpeed(200.0);
  // myStepper.moveTo(2000);
  myStepper.disableOutputs();
  Serial.println(" output disabled ");

}

void loop() {
  // Give the stepper an opportunity to step
  // myStepper.run();

  if (!myStepper.run())
    myStepper.disableOutputs();

  if (Serial.available() > 0) //if something comes
  {
    static int i = 0;
    i++;
    Serial.print(" i = "); Serial.println(i);
    char * strtokIndx; // this is used by strtok() as an index. It creates the variable
    //    byte m = Serial.readBytesUntil('\n', myData, numChars - 1);
    byte m = Serial.readBytesUntil("\Newline", myData, numChars - 1);
    myData[m] = '\0'; //null-byte

    strtokIndx = strtok(myData, " "); // this continues where the previous call left off
    //    rcvdCmd = Serial.read(); // this will read the command character
    strcpy (rcvdCmd, strtokIndx);
    Serial.print(" rcvdCmd = "); Serial.println(rcvdCmd);

    rcvdDistCopy = rcvdDistance;
    // char cmd = rcvdCmd[0];
    switch (rcvdCmd[0])
    {
      case 'f': // Forward <distance> <speed>
        {
          // runOk = true;
          strtokIndx = strtok(NULL, " "); // this continues where the previous call left off
          rcvdDistance = atol(strtokIndx);
          Serial.print(" rcvdDistance = "); Serial.println(rcvdDistance);

          strtokIndx = strtok(NULL, " "); // this continues where the previous call left off
          rcvdSpeed = atof(strtokIndx);
          Serial.print(" rcvdSpeed = "); Serial.println(rcvdSpeed, 2);

          myStepper.enableOutputs();
          myStepper.move(rcvdDistance);
          myStepper.setMaxSpeed(rcvdSpeed);
          /*
          if (myStepper.distanceToGo() == 0)
            // if (!myStepper.run())
          {
            myStepper.disableOutputs();
            Serial.println(" output disabled ");
          }
          */
          // runOk = false;
        }
        break;
      case'r':  // Reverse <distance> <speed>
        {
          // runOk = true;
          strtokIndx = strtok(NULL, " "); // this continues where the previous call left off
          rcvdDistance = atol(strtokIndx);
          Serial.print(" rcvdDistance = "); Serial.println(rcvdDistance);

          strtokIndx = strtok(NULL, " "); // this continues where the previous call left off
          rcvdSpeed = atof(strtokIndx);
          Serial.print(" rcvdSpeed = "); Serial.println(rcvdSpeed, 2);

          myStepper.enableOutputs();
          myStepper.move(-1 * rcvdDistance);
          myStepper.setMaxSpeed(rcvdSpeed);
          /*
          if (myStepper.distanceToGo() == 0)
            // if (!myStepper.run())
          {
            myStepper.disableOutputs();
            Serial.println(" output disabled ");
          }
          */
          break;
        case 'a': // acceleration <acceleration>
          {
            // runOk = false; //disable running
            strtokIndx = strtok(NULL, " ");
            rcvdAccel = atof(strtokIndx);
            Serial.print("rcvdAccel = "); Serial.print(rcvdAccel, 2);
            myStepper.setAcceleration(rcvdAccel);  //update the value of the variable
            Serial.println(" Accel. updated "); //confirm update by message

            /*
              Serial.print(" char case = "); Serial.println(rcvdCmd);
              rcvdAccel = Serial.parseFloat(); //receive the acceleration from serial
              myStepper.setAcceleration(rcvdAccel); //update the value of the variable
              Serial.println(" Accel. updated "); //confirm update by message
            */
          }
          break;
        case 's': // stop
          {
            runOk = false; //we still keep running disabled, since we just update a variable
            myStepper.setCurrentPosition(0);  // reset position
            myStepper.stop();                 // Set target to closest stopping point
            myStepper.runToPosition();
            myStepper.disableOutputs(); //disable power
            /*
              Serial.print(" char case = "); Serial.println(rcvdCmd);
              Serial.println(" STOP "); //print action
              myStepper.setCurrentPosition(0); // reset position
              myStepper.stop(); //stop motor
              //myStepper.disableOutputs(); //disable power
            */
          }
          break;
        }
    }
  }
}

Hey there, I'm using the same library and it's a littile hard to understand.
For the reversing the direction I've used the
setPinsInverted() function:

setPinsInverted(true,true);

You can probably use this function aswell to disable the ENABLE, but I haven't tried yet. Maybe it doesn't work in your case since you are calling this in a loop.

setPinsInverted(false,false,true);
  • setPinsInverted() This function can invert the sense of any interface pin. The pins are positional; setting the value for a pin true inverts it while setting it false leaves it un-inverted. This function is used most often to invert the enable signal. There are two forms of this function:
    setPinsInverted (directionPin, stepPin, enablePin) This form is for step/direction drivers. To set just the enable signal inverted, use setPinInverted(false, false, true). If an enable pin is not used, no value needs to be specified.
    setPinsInverted(pin1, pin2, pin3, pin4, enablePin) This form is for the 2, 3, and 4 pin driver types. Place a value of true in the position of any pin that is to be inverted. If an enable pin is not used, a value must still be specified! (This is a bug - but it's easy to work around.)
    If the enable pin is to be inverted, call setPinsInverted() before calling setEnablePin(). If pins other than the enable pin are to be inverted, you may want to create the AccelStepper objects with a concluding argument of false. That will keep the enableOutputs() function from being called until the pins are inverted. Then call enableOutputs().
    Example inverting only the enable pin of a step/direction driver.
    setPinsInverted (false, false, true);
    Example inverting only the step/direction pins of a step/direction driver. The enable pin is not used and may be omitted.
    setPinsInverted (true, true);
    Example inverting the interface pins of a 4 pin driver. The enable pin is not used but must be specified anyway.
    setPinsInverted (true, true, true, true, false);*

You might want to do simpler program if you don't need the acceleration, this library is a little bit challenging. Programming your own functions is more easy to understand, something like this would work in your case:

  void SimpleSteps(int steps) {
    for (int x = 0; x < steps; x++) {
      digitalWrite(Step, HIGH);
      delayMicroseconds(5);
      digitalWrite(Step, LOW);
      delayMicroseconds(tdelay);

    }
  }

In this example you can reverse by writting the DIR pin LOW or HIGH if you need to go forward or backwards.
Hope this helped

The pins do not need to be inverted. Reversing a steppermotor requires inverting the sequence of pins.

You are right.

Try calling myStepper.setSpeed(value), after the move function. Is what worked for me.

Caution: move() also recalculates the speed for the next step. If you are trying to use constant speed movements, you should call setSpeed() after calling move().

Constant speed is not used; that is why accelstepper library is used.

The documentation is:
https://www.airspayce.com/mikem/arduino/AccelStepper/index.html

You are right.

This confused me.

Try to call myStepperDistanceToGo() before each call to myStepper.run()); to see if a step is due.
If there's a step due and its not moving there may be something wrong with the motor.
Is the motor active when you try to move in a reverse direction ?

You can check the definitions of the functions here.

There's a simple method here that works.

moveTo() moves to a target position. But what I need is a move relative from the current position: http://www.airspayce.com/mikem/arduino/AccelStepper/classAccelStepper.html.

Reading an analog input as variable yields positive values.

What I need is for the servo to move counterclockwise, ie with a negative move(); yet that does not work (yet) with the simple servodriver (ULN9003, 4 wires).

Why?

EDIT: when set for reverse, the motor moves forward.

I don't see the benefit.

There can still be .distanceToGo() when a step is not due. Especially with slow speeds. For example:

myStepper.setSpeed(0.1);
myStepper.moveTo(myStepper.currentPosition()+100UL);
if (myStepper.DistanceToGo()>0) {
  myStepper.run();
}

...would not move for 10 seconds while myStepper.distanceToGo() remains true for 1000 seconds, and call myStepper.run() every time.

Also myStepper.run() itself does the check for whether a step is due, and also returns the boolean value of the test (myStepper.distanceToGo() > 0).

So it isn't functionally much different than:

if (myStepper.run()) myStepper.run();
// or just:
myStepper.run();

myStepper.moveTo() sets a target position.

myStepper.moveTo(myStepper.currentPosition()+1000);

or

myStepper.moveTo(myStepper.currentPosition()-1000);

would set a target relative to the current position.

Strange; same issue: with the r command the motor keeps turning forward, same direction as with the f command.