Question

I have a continuous rotation servo that I need to go clockwise and counterclockwise. I have found the mid point being at 100, and the clockwise and counterclockwise speeds I've found to be the most appropriate are 110 and 85, respectively. The servo rotates clockwise when button A is pushed, and counterclockwise when B is pushed.

I want a way to slow down the servo, once the button is released, at an exponential rate, so that it would say go from 110 to 100, or 85 to 100 in t (user definable) seconds. Is there a function anyone knows of that might help me accomplish this? or a way of doing this. Detailed answers appreciated as I am an Arduino noob.

#include <Servo.h>

Servo myservo; // create servo object to control a servo

// CONSTANTS

// PINS
const int crServo = 12; // sets pin 12 as servo
const int buttonPinCW = 2; // sets pin 2 as button; CW => clockwise => FOCUS FAR
const int buttonPinCC = 3; // sets pin 3 as button; CC => counterclockwise => FOCUS NEAR
const int ledPinB = 4; // sets pin 10 as LED
const int ledPinG = 5; // sets pin 10 as LED
const int ledPinR = 6; // sets pin 10 as LED

// SERVO PROPERTIES
const int crSpeedDefault = 100; // is the stay still position, motor should not turn
const int crSpeedCW = 110; // turns the motor full speed clockwise
const int crSpeedCC = 85; // turns the motor full speed counter-clockwise

// SET BUTTON STATES
int buttonStateCW = 0; //sets button 1 as off
int buttonStateCC = 0; // sets button 2 as off

void setup()
{
  myservo.attach(crServo); // attaches the servo on pin 12 to the servo object
  pinMode (buttonPinCW, INPUT); // sets button as input
  pinMode (buttonPinCC, INPUT); // sets button as input
  pinMode (ledPinB, OUTPUT); // sets led as output
  pinMode (ledPinG, OUTPUT); // sets led as output
  pinMode (ledPinR, OUTPUT); // sets led as output
  myservo.write(crSpeedDefault); // default servo to crSpeedDefault
  startup();
}

int startup() {
  blinker(2, ledPinB);
  blinker(1, ledPinG);
  blinker(1, ledPinR);
}

void blinker(int count, int pin) {
    for ( int x = 0; x < count; x++ )
    {
      digitalWrite(pin, HIGH);
      delay(1000);
      digitalWrite(pin, LOW);
      delay(1000);
    }
}

void loop()
{
  buttonStateCW = digitalRead(buttonPinCW);
  buttonStateCC = digitalRead(buttonPinCC);
  // clockwise rotation
  if (buttonStateCW == HIGH) {
    digitalWrite(ledPinR, HIGH);
    myservo.write(crSpeedCW);
    // counterclockwise rotation
  } 
  else if (buttonStateCC == HIGH) {
    digitalWrite(ledPinG, HIGH);
    myservo.write(crSpeedCC);
  } 
  else {
    myservo.write(crSpeedDefault);
    digitalWrite(ledPinR, LOW); 
    digitalWrite(ledPinG, LOW);     // turn the LED off by making the voltage LOW
  }
}

Updated with RMI's answer

#include <Servo.h>

Servo myservo; // create servo object to control a servo

// CONSTANTS

// PINS
const int crServo = 12; // sets pin 12 as servo
const int buttonPinCW = 2; // sets pin 2 as button; CW => clockwise => FOCUS FAR
const int buttonPinCC = 3; // sets pin 3 as button; CC => counterclockwise => FOCUS NEAR
const int ledPinB = 4; // sets pin 10 as LED
const int ledPinG = 5; // sets pin 10 as LED
const int ledPinR = 6; // sets pin 10 as LED

const int t = 1;  // slow down

// SERVO PROPERTIES
const int crSpeedDefault = 100; // is the stay still position, motor should not turn
const int crSpeedCW = 107; // turns the motor full speed clockwise
const int crSpeedCC = 87; // turns the motor full speed counter-clockwise

// SET BUTTON STATES
int buttonStateCW = 0; //sets button 1 as off
int buttonStateCC = 0; // sets button 2 as off

void setup()
{
  myservo.attach(crServo); // attaches the servo on pin 12 to the servo object
  pinMode (buttonPinCW, INPUT); // sets button as input
  pinMode (buttonPinCC, INPUT); // sets button as input
  pinMode (ledPinB, OUTPUT); // sets led as output
  pinMode (ledPinG, OUTPUT); // sets led as output
  pinMode (ledPinR, OUTPUT); // sets led as output
  myservo.write(crSpeedDefault); // default servo to crSpeedDefault
  startup();
}

int startup() {
  //blinker(2, ledPinB);
  //blinker(1, ledPinG);
  //blinker(1, ledPinR);
}

void blinker(int count, int pin) {
  for (int x = 0; x < count; x++)
  {
    digitalWrite(pin, HIGH);
    delay(1000);
    digitalWrite(pin, LOW);
    delay(1000);
  }
}

void loop()
{
  buttonStateCW = digitalRead(buttonPinCW);
  buttonStateCC = digitalRead(buttonPinCC);
  // clockwise rotation
  if (buttonStateCW == HIGH) {
    digitalWrite(ledPinR, HIGH);
    float speed = crSpeedCW;
    Serial.print("CLOCKWISE-ROTATION \n");
    for (int i = 0; i < t * 5; i++) {
      speed += ((float)crSpeedDefault - speed)/ 10;
      Serial.print(speed);
      Serial.print("\n");
      myservo.write((int)speed);
      delay(100);
    }
    myservo.write(crSpeedCW);
  } 
  else if (buttonStateCC == HIGH) {
      digitalWrite(ledPinG, HIGH);
      float speed = crSpeedCC;
      Serial.print("COUNTER-CLOCKWISE-ROTATION \n");
      for (int i = 0; i < t * 5; i++) {
        speed += ((float)crSpeedDefault - speed) / 10;
        Serial.print(speed);
        Serial.print("\n");
        myservo.write((int)speed);
        delay(100);
      }
      myservo.write(crSpeedCC);
    } 
  else {
    myservo.write(crSpeedDefault);
    digitalWrite(ledPinR, LOW); 
    digitalWrite(ledPinG, LOW);     // turn the LED off by making the voltage LOW
  }
}
Was it helpful?

Solution

Try This.

void loop()
{
  ...
  // clockwise rotation
  if (buttonStateCW == HIGH) {
    digitalWrite(ledPinR, HIGH);
    float speed = crSpeedCW;
    for (int i = 0; i < t * 5; i++) {
        speed -= (speed - (float)crSpeedDefault) / 10;
        myservo.write((int)speed);
        delay(200);
    }
    myservo.write(crSpeedCW);
  } 
  else if (buttonStateCC == HIGH) {
    digitalWrite(ledPinG, HIGH);
    // Do the same here in reverse
    myservo.write(crSpeedCC);
  } 
  else {
    ...
  }
}

This will slow down the speed exponentially. You have to adjust hard coded numbers to suit your the ranges.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top