Servo speed control

Hi there everyone!

I need your help to improve my code by adding a speed control to be able to change the speed of the servo,
any help is much appreciated! :slight_smile: :slight_smile: :slight_smile: :slight_smile:

//SETTINGS

//DELAY

int T1 = 500; // Forward delay in ms
int T2 = 500; // Reverse delay in ms

//BUTTON SETTINGS

int InchStepsL = 5; // Inch rotation degrees 0-160
int InchStepsR = 5; // Inch rotation degrees 0-160
int HoldButton = 3000; // Hold button time for instat full rotation in ms

////SAFE ZONE
//
//int SafeZone = 100; // Safe zone position degrees 0-160
//                    // after power surge
                    
//CODE

#include <Servo.h>

Servo Left;  //Left Servo Name
Servo Right; //Right Servo Name

const int LeftServo = 2;  //Left Servo Pin
const int RightServo = 3; //Right Servo Pin

const int Forward = 4; //Forward Button Pin
const int Reverse = 6; //Reverse Button Pin

const int LOCK = 8; //Lock Pin

const int LeftPot = A0;  //Left Pot Pin
const int RightPot = A1; //Left Pot Pin

int LeftAngle =  0;
int RightAngle = 0;

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

  pinMode(Forward, INPUT_PULLUP);
  pinMode(Reverse, INPUT_PULLUP);
  pinMode(LOCK, OUTPUT);
  

//  LeftAngle = analogRead(LeftPot);
//  LeftAngle = map(LeftAngle, 1028, 0, 160, 0);
//  RightAngle = analogRead(RightPot);
//  RightAngle = map(RightAngle, 1028, 0, 160, 0);


  Serial.print("Left Angle = ");
  Serial.println(LeftAngle);
  Serial.print("Right Angle = ");
  Serial.println(RightAngle);

  Left.attach(LeftServo);
  Right.attach(RightServo);

  Left.write(LeftAngle);
  Right.write(RightAngle);

  delay(1000);

  Left.detach();
  Right.detach();

  digitalWrite(LOCK, HIGH);
  
}

void loop() {
  
  if (digitalRead(Forward) == HIGH) {
    Serial.println("FORWARD");
    Serial.println("");
    unsigned long StartF = millis();
    
    while (digitalRead(Forward) == HIGH) {
      Serial.println("FORWARD");
      Serial.println("");
      
    if (millis() - StartF < HoldButton) {
      digitalWrite(LOCK, LOW);
      Serial.println("LESS THAN 3 SECONDS(FORWARD)");
      Serial.println("");
      RightAngle += InchStepsR;
      LeftAngle += InchStepsL;

      if (RightAngle >= 160) {
        RightAngle = 160;
      }
       if (LeftAngle >= 160) {
        RightAngle = 160;
      }

      Right.attach(RightServo);
      Left.attach(LeftServo);
      
      Right.write(RightAngle);
      delay(T2);
      Left.write(LeftAngle);

      delay(500);

      Left.detach();
      Right.detach();

      digitalWrite(LOCK, HIGH);
      
    }

    else if (millis() - StartF >= HoldButton) {
      digitalWrite(LOCK, LOW);
      Serial.println("MORE THAN 3 SECONDS(FORWARD)");
      Serial.println("");
      RightAngle = 160;
      LeftAngle = 160;
      
      Right.attach(RightServo);
      Left.attach(LeftServo);
      
      Right.write(RightAngle);
      delay(T2);
      Left.write(LeftAngle);
      
      delay(1000);

      Left.detach();
      Right.detach();

      digitalWrite(LOCK, HIGH);
      
    }
   }
  }

  if (digitalRead(Reverse) == HIGH) {
    Serial.println("REVERSE");
    Serial.println("");
    unsigned long StartR = millis();
    
    while (digitalRead(Reverse) == HIGH) {
      Serial.println("REVERSE");
      Serial.println("");
    
    if (millis() - StartR < HoldButton) {
      digitalWrite(LOCK, LOW);
      Serial.println("LESS THAN 3 SECONDS(REVERSE)");
      Serial.println("");

      RightAngle -= InchStepsR;
      LeftAngle -= InchStepsL;

      if (RightAngle <= 0) {
        RightAngle = 0;
        
      }
      
      if (LeftAngle <= 0) {
        LeftAngle = 0;
        
      }

      Left.attach(LeftServo);
      Right.attach(RightServo);

      Left.write(LeftAngle);
      delay(T1);
      Right.write(RightAngle);

      delay(500);

      Left.detach();
      Right.detach();

      digitalWrite(LOCK, HIGH);
      
    }

    else if (millis() - StartR >= HoldButton) {
      digitalWrite(LOCK, LOW);

      Serial.println("MORE THAN 3 SECONDS(REVERSE)");
      Serial.println("");

      RightAngle = 0;
      LeftAngle = 0;

      Left.attach(LeftServo);
      Right.attach(RightServo);

      Left.write(LeftAngle);
      delay(T1);
      Right.write(RightAngle);

      delay(1000);

      Left.detach();
      Right.detach();

      digitalWrite(LOCK, HIGH);
      
    }
   }
  }
 }

You can't directly control the speed of a servo but you can give the impression of speed control by moving it in small steps with an interval between the steps.

Have look at how the servo is controlled in Several Things at a Time

...R

There is a library for that:

First post with proper use of code tags! YAY! Karma++

vinceherman:
First post with proper use of code tags! YAY! Karma++

A rare bird indeed! :slight_smile: Karma++ ++

Thanks guys I'll add more comments throughout the whole code as it's complete! since everything I do is open source, how in the hell are people supposed to know how the code works if it's the first time they open it up?? not everyone is a pro coder after all!

I did my research before posting and I came across this simple code that does the job pretty well, problem is that I can't figure out how to integrate it in my code and where since it uses the for condition which I'm not familiar with, perhaps you guys can point me in the right direction?

#include <Servo.h> 
 
Servo myservo;                  
int pos = 0;    
 
void setup() 
{ 
  myservo.attach(2);  
} 
 
void loop() 
{ 
  for(pos = 0; pos <= 180; pos += 1) 
  {                                  
    myservo.write(pos);      
    delay(45);                    
  } 
  for(pos = 180; pos>=0; pos-=1)     
  {                                
    myservo.write(pos);              
    delay(0);                     
  } 
}

johnwasser:
There is a library for that:
GitHub - netlabtoolkit/VarSpeedServo: Arduino library for servos that extends the standard servo.h library with the ability to set speed, and wait for position to complete

I have indeed tried that but I get an error when compiling about a missing library #include <WProgram.h>, not sure how to fix it, hence why I scrapped this idea.

Robin2:
You can't directly control the speed of a servo but you can give the impression of speed control by moving it in small steps with an interval between the steps.

Have look at how the servo is controlled in Several Things at a Time

...R

I'll have a read trough now! Thanks :slight_smile:

floxia:
I have indeed tried that but I get an error when compiling about a missing library #include <WProgram.h>, not sure how to fix it, hence why I scrapped this idea.

I think you need to edit the Library code and change that to #include <Arduino.h>.

IIRC WProgram.h was only in the very early versions of the Arduino IDE

...R

floxia:
I have indeed tried that but I get an error when compiling about a missing library #include <WProgram.h>, not sure how to fix it, hence why I scrapped this idea.

You seem to have an antique version of VarSpeedServo. That was fixed a long time ago. Just download the current version.

Steve

Thanks guys, I fixed it by updating the library!