Alex
Alex

Reputation: 9265

continuous rotation servo (arduino) responding to button press

I am trying to make a continous rotation servo move clockwise if button on pin2 is pressed, and counterclockwise if button on pin3 is pressed. I want the servo to keep moving in the direction set according to the button until the button is released. This is the code I have so far (I am new to arduino):

#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 ledPin = 10; // sets pin 10 as LED

    // SERVO PROPERTIES
    const int crSpeedDefault = 1500; // 1500 is the stay still position, motor should not turn
    const int crSpeedCW = 1300; // 1300 turns the motor full speed clockwise
    const int crSpeedCC = 1700; // 1700 turns the motor full speed counter-clockwise
    const int crStepDefault = 2;

// 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 (ledPin, OUTPUT); // sets led as output
    myservo.write(crSpeedDefault); // default servo to crSpeedDefault
}

int slowFocusPull(int x){
  int result;
  result = abs(x - crSpeedDefault) / crStepDefault;
  return result;
}

void loop()
{
    buttonStateCW = digitalRead(buttonPinCW);
    buttonStateCC = digitalRead(buttonPinCC);
    // clockwise rotation
    if (buttonStateCW == HIGH) {
        digitalWrite(ledPin, HIGH);
        myservo.write(slowFocusPull(crSpeedCW));
    // counterclockwise rotation
    } else if (buttonStateCC == HIGH) {
        digitalWrite(ledPin, HIGH);
        myservo.write(slowFocusPull(crSpeedCC));
    } else {
        digitalWrite(ledPin, LOW);
    }
}

The issue lies in the function slowFocusPull. Basically I just want to be able to adjust the speed with just modifying the constant. Without this function everything works fine.


UPDATE: final loop for reference

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
  }
}

Upvotes: 0

Views: 11134

Answers (1)

gskielian
gskielian

Reputation: 184

Looks like your project would benefit from using Hardware Interrupts, which asynchronously call functions when events (like button presses) occur (these are perfect for controllers, and remove the overhead of polling).

Try wiring up the two pins and wiring up the buttons to pins 2 and 3 as is shown in this diagram:

enter image description here

Hardware interrupts literally interrupt the code, the uno has two such pins: digital pin 2 and digital pin 3 (this is really useful for robotics, also the mega has 6 such pins!)

here's a skeleton for how your code might want to look

void setup() {
  attachInterrupt(0, goClockwise, RISING); //the "0" places arduino uno's interrupt pin 2 (for uno r3)
  attachInterrupt(1, goCounterClockwise, RISING); //the "1" places interrupt for arduino uno's pin 3
  }

void loop() {
  delay(1000); dummy delay, code is handled in interrupt functions
}

void goClockwise () {
 //runs when pin 2's button is pressed
 //code for making servo go clockwise
}

void goCounterClockwise () { 
 //code triggered when pin 3's button is pressed
 //code for ccw goes here
}

If you have any questions on I'd be happy to work through them with you.

Here's a link to the Arduino ref page for hardware interrupts:

click here to learn more about arduino hardware interrupts

Upvotes: 4

Related Questions