Clockwise is faster than counterclockwise

I have been developing (simple) code to control a stepper motor to lift or lower the head on a milling machine. The speed of movement is set by a potentiometer. The direction is set by one of two buttons (up or down) and movement is stopped by a third button.
The code has lots of Serial.println comments in as I use them to try to debug what is happening.

I have watched the code execute using Serial.println and it appears that clockwise steps occurs significantly faster (the rate at which a serial.println comment appears) than a counterclockwise step.
When the code is used with a stepper driver and suitable power source it runs well in one direction and then on change of direction it basically stops and the built in green LED on the board flickers.
This flickering lead me to use Serial.println to check each part of the code and that is when I found this oddity.
I assume I have something wrong somewhere, but can’t work out the reason for the slow CCW or indeed if this is a problem.

If this problem is because I don’t understand C++ or its derivatives then fine, I’ll keep hunting.

#include <AccelStepper.h>
#include <MultiStepper.h>

#define STEPPER1_DIR_PIN 2 
#define STEPPER1_STEP_PIN 3 
AccelStepper stepper1(AccelStepper::DRIVER, STEPPER1_STEP_PIN, STEPPER1_DIR_PIN);

int sensorPin = A0; //The potentiometer input

unsigned long sensorValue = 0;

byte buttonCCWpin = 6; //Counterclockwise - lower head
byte buttonCWpin = 4; //Clockwise - lift head
byte buttonStoppin = 5; //Stop

boolean buttonCCWpressed = false;
boolean buttonCWpressed = false;
boolean buttonStoppressed = true; //Starting position

void setup() {

  Serial.begin(9600);

  pinMode(STEPPER1_DIR_PIN, OUTPUT);
  pinMode(STEPPER1_STEP_PIN, OUTPUT);
 
  pinMode(A1,OUTPUT); //CCW LED
  pinMode(A2,OUTPUT); //CW LED
  pinMode(A3,OUTPUT); //Stop LED
  
  pinMode(buttonCCWpin, INPUT); //Replaced INPUT_PULLUP with INPUT - appears to make no difference
  pinMode(buttonCWpin, INPUT);
  pinMode(buttonStoppin, INPUT);
 
  
}

void loop() {
	
	readButtons();
	actOnButtons();
        //Serial.println("Read and Act");
        sensorValue = analogRead(sensorPin);
        sensorValue = map(sensorValue,0,1023,0,4000);
        stepper1.setMaxSpeed(sensorValue);
        //Serial.println(sensorValue);
        stepper1.setAcceleration(500.0);
}

void readButtons() {
  
  // Set the LEDs to show what is going on
	if (digitalRead(buttonCCWpin) == HIGH) {
		buttonCCWpressed = true;
                buttonCWpressed = false; 
                buttonStoppressed = false;	
                digitalWrite(A1, HIGH);
                digitalWrite(A2, LOW);
                digitalWrite(A3, LOW);
                Serial.println("Anti-clockwise");
                //stepper1.setCurrentPosition(0);
	}

	if (digitalRead(buttonCWpin) == HIGH) {
                buttonCCWpressed = false;   
                buttonCWpressed = true;
		buttonStoppressed = false;           
                digitalWrite(A1, LOW);
                digitalWrite(A2, HIGH);
                digitalWrite(A3, LOW);
                Serial.println("Clockwise");
                //stepper1.setCurrentPosition(0);
	}

        if (digitalRead(buttonStoppin) == HIGH) {
		buttonCCWpressed = false;
		buttonCWpressed = false;
                buttonStoppressed = true;
                digitalWrite(A1, LOW);
                digitalWrite(A2, LOW);
                digitalWrite(A3, HIGH);        
                //Serial.println("Stop");
                //stepper1.setCurrentPosition(0);
	}
}

void actOnButtons() {
  
        if (buttonCCWpressed == true) {
		digitalWrite(STEPPER1_DIR_PIN, HIGH);
                //Serial.println("CClock");
		singleStepCCW();
                Serial.println("Counter Clockwise");
        }
        
	if (buttonCWpressed == true) {
		digitalWrite(STEPPER1_DIR_PIN, LOW);
                //Serial.println("Clock");
		singleStepCW();
                Serial.println("Clockwise");
	}

         if (buttonStoppressed == true) {
		//digitalWrite(STEPPER1_DIR_PIN, LOW);
                //Make sure this is started with a stopped servo
                digitalWrite(A2, LOW);
                digitalWrite(A3, HIGH);
                digitalWrite(A1, LOW);
        stepper1.stop();
        //Serial.println("Stop");
	}
}

void singleStepCW() { 
  digitalWrite(STEPPER1_DIR_PIN, HIGH);
   stepper1.moveTo(1000000);
   //Serial.println("CW");
    stepper1.run();
      }
 
void singleStepCCW() { 
  digitalWrite(STEPPER1_DIR_PIN, LOW);
   stepper1.moveTo(-100);
   //Serial.println("CCW");
    stepper1.run();
      }

Your single step functions make no sense.

You need a call to stepper1.run() in loop() so it is called as often as possible, that's how accelstepper works, run() does all of the heavy-lifting, the other calls just set up the target position.

If you want to single step, the logic would be:

  stepper1.moveTo (stepper1.currentPosition() + 1) ;

But normally you'd just set the destination and let loop() and run() do the work.

The calls to setAcceleration() and setMaxSpeed() belong in setup() as they are setup.

You might want to call setSpeed() to control the speed, but that's automatically limited to the max speed value.

it basically stops and the built in green LED on the board flickers.

Sounds like you are shorting something or driving to much current.

Put a print statement ( like starting now) at the very beginning of your sketch so that you can tell if the board is resetting. If you see the print statement when you try to go in the bad direction then you should look over your wiring.

One other thing is the way I would implement the setup. Have the direction controlled by a switch (even have the direction the switch is pointing to indicate the direction. Have the movement controlled by a push button. If pressed move.If not don't move.

Follow MarkT's advice and that should solve your problem. I suppose that goes without saying, but your problem is that you have a misunderstanding of how the AccelStepper library works -- not a code problem, per se.

When you're calling that run() the library is doing all sorts of calculations based on your acceleration and max speed settings and checking that against the previous time run() was called -- it keeps track of that too. Then based on the current time it knows how many steps it has to do to keep pace, and how much pausing it has to do, and of course it's also checking for the position you asked it to move to to know if it even has to move the stepper at all. All in all it's an admirable piece of code.

Thank you all for the comments, advice and assistance. I have rewritten the whole program and it now works as suggested.
Holding down a button causes a Clockwise or Counter Clockwise step, the speed is set from the potentiometer and Serial.println reads like I expected.
I can’t test it on the mill untill Sunday but I will report back.

As I now understand it, void setup is called just once, and void loop runs as fast as it can until power is removed.

The original query was based on poor data, the CCW appeared slower as that button was held down for less time. The stepper motor and power and driver are more than man enough to move the wieght balanced mill head.

Are there any other errors that I should sort out? I had removed setAcceleration but that may be necessary - I’ll see on Sunday

#include <AccelStepper.h>
#include <MultiStepper.h>

#define STEPPER1_DIR_PIN 2 //6
#define STEPPER1_STEP_PIN 3 //5
AccelStepper stepper1(AccelStepper::DRIVER, STEPPER1_STEP_PIN, STEPPER1_DIR_PIN);

int sensorPin = A0; //The potentiometer input

unsigned long sensorValue = 0;

byte buttonCCWpin = 6; //Counterclockwise - lower head
byte buttonCWpin = 4; //Clockwise - lift head

void setup() {

  Serial.begin(9600);

  pinMode(STEPPER1_DIR_PIN, OUTPUT);
  pinMode(STEPPER1_STEP_PIN, OUTPUT);

  pinMode(buttonCCWpin, INPUT); //INPUT - test  INPUT_PULLUP - original code
  pinMode(buttonCWpin, INPUT);

}

void loop() {

  sensorValue = analogRead(sensorPin);
  sensorValue = map(sensorValue, 0, 1023, 0, 4000);
  stepper1.setMaxSpeed(sensorValue);
  //Serial.println(sensorValue);
  
  
  if (digitalRead(buttonCWpin) == HIGH) {
    digitalWrite(STEPPER1_DIR_PIN, HIGH);
    stepper1.moveTo(stepper1.currentPosition()+1000000);
    //Serial.println("CW");
    stepper1.run();
  }

  if (digitalRead(buttonCCWpin) == HIGH) {
    digitalWrite(STEPPER1_DIR_PIN, LOW);
    stepper1.moveTo(stepper1.currentPosition()-1000000);
    //Serial.println("CCW");
    stepper1.run();
  }

}

Still have it wrong. It should be more like:

void loop() {
  stepper1.run();

  sensorValue = analogRead(sensorPin);
  sensorValue = map(sensorValue, 0, 1023, 0, 4000);
  stepper1.setMaxSpeed(sensorValue);
  
  if (digitalRead(buttonCWpin) == HIGH) {
    digitalWrite(STEPPER1_DIR_PIN, HIGH);
    stepper1.moveTo(stepper1.currentPosition()+100);
  }

  if (digitalRead(buttonCCWpin) == HIGH) {
    digitalWrite(STEPPER1_DIR_PIN, LOW);
    stepper1.moveTo(stepper1.currentPosition()-100);
  }

}

stepper1.run() need to be in the loop() and not nested within any conditional.

Also, you'll notice that I reduced the steps in your moveTo() calls. It's not the best solution, but this overall program is a little funny in that you're holding down buttons to move a stepper. What's going to happen here is that the motor will start moving whenever you have the button down and then when you release it it will still move an additional 100 steps.

It's kinda like you're using the stepper motor as you would a brushed/brushless motor. It's just a little weird, because steppers are supposed to be used for movements of fixed distance.

Chagrin
Thanks for the re-write. I’ll try that first as it is most likely to succeed.
The reason I am using a stepper motor is because I have one and I thought
a. it would have more power than a brushed motor, and
b. I can move the mill head manually without disengaging the motor drive

I do have 2 old wiper motors, neither of these are particularly easy to take a drive from and would require some form of disengagement if I wanted to manually move the head. I’m not sure what the ideal motor would be hence the stepper experiment. If this fails then I’ll have to tackle the wiper motor.

Looking forward to Sunday’s trial

I tried Chagrin’s code and the motor only runs on release of the button for the 100 steps (I’m guessing that is how far it moves). It will lift and lower the head with ease but after 3 or 4 presses of either up or down it will not move again. Increasing the steps to +/-5000 (see code below) results in a longer run after the button is released.
After the motor stops turning (say on press 4) the green light on the Arduino flashes slowly.
Turning the whole assembly off for a minute or so will allow another 3 to 4 moves.

I added the stop button back in after the first few trials but can easily remove it again if the motor ran whilst the button was pressed.

I have tried a different motor (Bipolar series, 300Ncm, 4.2A per phase) and the same thing happens.
I have a 50v 10a smoothed dc power supply for the stepper controller supply, a 9v supply for the Arduino (from Maplins) and an ArcEuroTrade controller 160-020-00101 4.2A.

I ordered another controller to see if that is the problem but that won’t arrive till Tuesday.

This set up did run on the Y axis successfully (with different code - which I had lost) for about 6 months, same motor, power supplies and controller.

#include <AccelStepper.h>
#include <MultiStepper.h>

#define STEPPER1_DIR_PIN 2 //6
#define STEPPER1_STEP_PIN 3 //5
AccelStepper stepper1(AccelStepper::DRIVER, STEPPER1_STEP_PIN, STEPPER1_DIR_PIN);

int sensorPin = A0; //The potentiometer input

unsigned long sensorValue = 0;

byte buttonCCWpin = 6; //Counterclockwise - lower head
byte buttonStoppin = 5; //Stop
byte buttonCWpin = 4; //Clockwise - lift head

void setup() {

  Serial.begin(9600);

  pinMode(STEPPER1_DIR_PIN, OUTPUT);
  pinMode(STEPPER1_STEP_PIN, OUTPUT);

  pinMode(buttonCCWpin, INPUT); //INPUT - test  INPUT_PULLUP - original code
  pinMode(buttonStoppin, INPUT);
  pinMode(buttonCWpin, INPUT);
  stepper1.setAcceleration(50000.0);  //6000

}

void loop() {
  stepper1.run();

  sensorValue = analogRead(sensorPin);
  sensorValue = map(sensorValue, 0, 1023, 0, 4000);
  stepper1.setMaxSpeed(sensorValue);
 
  if (digitalRead(buttonCWpin) == HIGH) {
    digitalWrite(STEPPER1_DIR_PIN, HIGH);
    stepper1.moveTo(stepper1.currentPosition()+5000);
    Serial.println("Clockwise");
  }

  if (digitalRead(buttonCCWpin) == HIGH) {
    digitalWrite(STEPPER1_DIR_PIN, LOW);
    stepper1.moveTo(stepper1.currentPosition()-5000);
    Serial.println("Anti-clockwise");
  }

  if (digitalRead(buttonStoppin) == HIGH) {
    stepper1.stop();
    Serial.println("Stop");
  }
  
}

I have swapped out each piece of the assembly, the stepper motor, the power supply and the controller but in the end it was the Arduino itself that was causing the problem. A second board worked just fine and when I put the old board back it showed the same symptoms - runs for a few seconds then the power light started flashing and the stepper stopped moving.
The second board is now installed again and the head moves up and down as needed.
I altered the distance per click to 7,500 steps as that gives me about 20mm. Any actual downfeed is managed by the quill. The head can be stopped at anytime with the stop button.

I also removed setting the Step direction pin high as I believe that the AccelStepper handles that by inference on the value of the distance.

I still don’t get a continous run when either button is pressed but it works just fine for now.

Thank you all for your assistance and explanations

#include <AccelStepper.h>
#include <MultiStepper.h>

#define STEPPER1_DIR_PIN 2 
#define STEPPER1_STEP_PIN 3 
AccelStepper stepper1(AccelStepper::DRIVER, STEPPER1_STEP_PIN, STEPPER1_DIR_PIN);

int sensorPin = A0; //The potentiometer input

unsigned long sensorValue = 0;

byte buttonCCWpin = 6; //Counterclockwise - lower head
byte buttonStoppin = 5; //Stop
byte buttonCWpin = 4; //Clockwise - lift head

void setup() {

  Serial.begin(9600);

  pinMode(STEPPER1_DIR_PIN, OUTPUT);
  pinMode(STEPPER1_STEP_PIN, OUTPUT);

  pinMode(buttonCCWpin, INPUT_PULLUP); 
  pinMode(buttonStoppin, INPUT_PULLUP);
  pinMode(buttonCWpin, INPUT_PULLUP);
  stepper1.setAcceleration(50000.0); 

}

void loop() {
  stepper1.run();

  sensorValue = analogRead(sensorPin);
  sensorValue = map(sensorValue, 0, 1023, 0, 4000);
  stepper1.setMaxSpeed(sensorValue);
 
  if (digitalRead(buttonCWpin) == HIGH) {
    stepper1.moveTo(stepper1.currentPosition()+7500);
  }

  if (digitalRead(buttonCCWpin) == HIGH) {
    stepper1.moveTo(stepper1.currentPosition()-7500);
  }

  if (digitalRead(buttonStoppin) == HIGH) {
    stepper1.stop();
  }
  
}