Slowing down servo movement.

Hi
I’m trying to run a servo together with some steppers and I need to slow the servo down quite a bit.
The code I have here is doing what I want, but the servo reaches its end position too quickly.
I’ve tried using delay and millis to interrupt it, but I can’t figure out how to do it with the steppers moving at the same time. The servo finishes its run and the the steppers start theirs.

#include <AccelStepper.h>
#include <VarSpeedServo.h>

#define HALFSTEP 5
#define FULLSTEP 8

#define motorPin1 4
#define motorPin2 5
#define motorPin3 6
#define motorPin4 7

#define motorPin5 8
#define motorPin6 9
#define motorPin7 10
#define motorPin8 11

VarSpeedServo servo;

const int panAcc = 10.0;
const int panSpeed = 200; // 1.1 min
const int dollyAcc = 10.0;
const int dollySpeed = 1400; // 800 = 3 min. runtime 1400/2 max/min 

AccelStepper stepper1(HALFSTEP, motorPin1, motorPin2, motorPin3, motorPin4);
AccelStepper stepper2(HALFSTEP, motorPin5, motorPin6, motorPin7, motorPin8);

const int buttonPin = 2;
int buttonState = 0;

void setup() {
  
  servo.attach(3);
  servo.write(50,5,false);
  stepper1.setMaxSpeed(dollySpeed);
  stepper1.setAcceleration(dollyAcc);
  stepper1.move(1);
  
  stepper2.setMaxSpeed(panSpeed);
  stepper2.setAcceleration(panAcc);
  stepper2.move(-1);
  
  pinMode(buttonPin,INPUT);
  
}

void loop() {
  
  buttonState = digitalRead(buttonPin);
  if (buttonState == LOW){
    servo.write(150,1,false);
    stepper1.move(140000); // + away - home 140000 = full
    stepper2.move(8800); // + CCW - CW 4400 ~ 90 deg.
  }
  stepper1.run();
  stepper2.run();
}

When you tell the servo to move, it's like kicking a horse and yelling giddy-up! It takes off screaming to the destination position. What can you do? Tell it to go to another position, only a short ways off. Do that again and again, with small increments, and suitable intervals (NOT delay()s) between the movements. The servo will APPEAR to move slower.

Thanks for the reply. I get that I need to break up the movement. But every time I try, it breaks the stepper movement. Doing the servo movement first and then the steppers. Everything needs to run at the same time. And with the varSpeedServo library it's not quite giddy-up. I can control the tempo to a degree. But with the slowest movement it takes 40 sec. to get from position 50 to 150. I need it to take more along the lines of half an hour.

If you have to move a servo through 100 degrees over thirty minutes, you could set up a simple blink-with-delay style one second update, and each time through, add 100 / 1800 = 0.05555 degrees to the servo postion.

Thanks, but me not smart, me not get it. How would I implement something like that into my code? Everything I try seems to split up the movements. Servo first then steppers.

Outline

#define SERVO_START 50.0
#define SERVO_RANGE  100.0
#define TIME_SPAN (30 * 60)
...
...  
  static float servoAngle = SERVO_START;  
  static unsigned long previousMillis;
  unsigned long currentMillis = millis();
... 
  if(currentMillis - previousMillis >= interval) {
    previousMillis += interval;
    servoAngle += SERVO_RANGE / TIME_SPAN;
    myServo.write (servoAngle);
  }

(obviously uncompiled and untested)

I’m probably doing something wrong, but it isn’t doing anything.
Here’s what I did.

#include <AccelStepper.h>
#include <VarSpeedServo.h>

#define HALFSTEP 5
#define FULLSTEP 8

#define motorPin1 4
#define motorPin2 5
#define motorPin3 6
#define motorPin4 7

#define motorPin5 8
#define motorPin6 9
#define motorPin7 10
#define motorPin8 11

#define SERVO_START 50
#define SERVO_RANGE 100.0
#define TIME_SPAN (30*60)

static float servoAngle = SERVO_START;  
static unsigned long previousMillis;
unsigned long currentMillis = millis();
long interval = 1000;

VarSpeedServo servo;

const int panAcc = 10.0;
const int panSpeed = 200; // 1.1 min
const int dollyAcc = 10.0;
const int dollySpeed = 1400; // 800 = 3 min. runtime 1400/2 max/min 

AccelStepper stepper1(HALFSTEP, motorPin1, motorPin2, motorPin3, motorPin4);
AccelStepper stepper2(HALFSTEP, motorPin5, motorPin6, motorPin7, motorPin8);

const int buttonPin = 2;
int buttonState = 0;

void setup() {
  
  servo.attach(3);
  servo.write(50,5,false);
  stepper1.setMaxSpeed(dollySpeed);
  stepper1.setAcceleration(dollyAcc);
  stepper1.move(1);
  
  stepper2.setMaxSpeed(panSpeed);
  stepper2.setAcceleration(panAcc);
  stepper2.move(-1);
  
  pinMode(buttonPin,INPUT);
  
}

void loop() {
  
  buttonState = digitalRead(buttonPin);
  if (buttonState == LOW){
    stepper1.move(140000); // + away - home 140000 = full
    stepper2.move(8800); // + CCW - CW 4400 ~ 90 deg.
    if(currentMillis - previousMillis >= interval) { 
    previousMillis += interval;
    servoAngle += SERVO_RANGE / TIME_SPAN;
    servo.write (servoAngle);
    }
  }
  stepper1.run();
  stepper2.run();
  
}

t isn't doing anything.

currentMillis ? Just use the standard Servo library.

Sorry. I'm not getting it.

currentMillis ?

Why is that a question?

I thought the varSpeedServo library was the standard servo library with extra features added. I changed it to the standard servo library. Doesn't seem to make a difference.

Why is that a question?

It's shorthand for "What are you doing with currentMillis, and where does it get updated?"

#define SERVO_START 50.0
#define SERVO_RANGE  100.0
#define TIME_SPAN (30 * 60)
...
...  
  static float servoAngle = SERVO_START;  
  static unsigned long previousMillis;
  unsigned long currentMillis = millis();
... 
  if(currentMillis - previousMillis >= interval) {
    previousMillis += interval;
    servoAngle += SERVO_RANGE / TIME_SPAN;
    myServo.write (servoAngle);
  }

Just added what you told me. And I noticed the lack of updating. I added it after the servoangle write.

Jakobberry: Just added what you told me. And I noticed the lack of updating. I added it after the servoangle write.

Does that mean that everything is now working the way you want it?

...R

No. Wasn’t really getting me anywhere. But I figured out a different way of doing it. It seems one of my problems was that I was using a momentary button to start the run. The steppers worked fine with that and there is probably a way of doing it with the servo as well, but I got some code working with a normal switch.

Jakobberry: No. Wasn't really getting me anywhere.

Well, when you don't tell us it is hard to help.

...R