Pages: [1]   Go Down
Author Topic: Need help on telling servo to return to a specific angle or location  (Read 383 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 35
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

In my code, I am controling a servo with a rotary encoder and 4 buttons. The encoder is acting like a pot. I could not get smooth servo movement with the pot so am trying this. It works really well. Only issue at the moment is that when the buttons take over control of the servo, the pot is allowed to spring back to 0 degree and therefore when the button control is released back to the Pot, the servo knows its position.

With the encoder however, when it springs back to its position and the button releases control, the servo goes back to its last known position before the puttons took over.

I have tried adding another loop to write to the servo a specific angle. With a delay it will do this but then goes right back to the last known angle. I

I tried to redirect to the encoder loop but same thing.

at this point in the code is where the buttons are released
Code:
    else if (bouncer3.read() == HIGH)
    {
      btnControlEnabled = 0; //Set loop exit condition
      throttleServo.write(180);


    }
    else if (bouncer4.read() == HIGH)
    {
      throttleServo.write(180);
      btnControlEnabled = 0; //Set loop exit condition


    }
    //If nothing pressed...
    else
    {
      //...do nothing at all, go back to start of loop

Code:
#include <Bounce.h>
#include <Servo.h>

void setup(){
  buttonSetup();
  throttleSetup();
}

void loop(){
  throttleLoop();
  buttonLoop();
}

int servoPosition = 20; //Old val1, used to store servo position. Allows use by whole program
Servo throttleServo; // Define throttle Servo
int servoPos = 0;    // Initial power up “servo position”
int moveServoAmount = 7;    // move the servo 10 degrees per 1/24 pulse
const int pin_A = A0;  // pin 15
const int pin_B = A1;  // pin 14
unsigned char encoder_A;
unsigned char encoder_B;
unsigned char encoder_A_prev=0;

// set pin numbers:
const int buttonPin = 10; // the number of the pushbutton pin
const int buttonPin2 = 8;
const int buttonPin3 = 4;
const int buttonPin4 = 2;

long debounceDelay = 50;    // the debounce time; increase if the output flickers

//Debounce objects
// Instantiate a Bounce object with a 5 millisecond debounce time
Bounce bouncer1 = Bounce(buttonPin, debounceDelay);
Bounce bouncer2 = Bounce(buttonPin2, debounceDelay);
Bounce bouncer3 = Bounce(buttonPin3, debounceDelay);
Bounce bouncer4 = Bounce(buttonPin4, debounceDelay);

void throttleSetup()  {
  throttleServo.attach(12); // servo on digital pin 12
  pinMode(pin_A, INPUT);
  digitalWrite(pin_A, HIGH);// turn on pullup resistor
  pinMode(pin_B, INPUT);
  digitalWrite(pin_B, HIGH);// turn on pullup resistor
}

void throttleLoop()  {

  encoder_A = digitalRead(pin_A); // Read encoder pins
  encoder_B = digitalRead(pin_B);
  if((!encoder_A) && (encoder_A_prev)){
    // A has gone from high to low
    if(encoder_B) {
      // B is high so clockwise
      // increase the throttle, dont go over 255
      if(servoPos + moveServoAmount <= 220) servoPos += moveServoAmount;
    }
    else {
      // B is low so counter-clockwise
      // decrease the throttle, dont go below 20
      if(servoPos - moveServoAmount >= 20) servoPos -= moveServoAmount;
    }
  }
  encoder_A_prev = encoder_A;     // Store value of A for next time
  // set the new location of servo:
  throttleServo.write(servoPos);
}

void buttonSetup(){
  // initialize the pushbutton pin as an input:
  pinMode(buttonPin, INPUT);
  pinMode(buttonPin2, INPUT);
  pinMode(buttonPin3, INPUT);
  pinMode(buttonPin4, INPUT);
}

void buttonLoop(){
  //Update debounce tool
  bouncer1.update();
  bouncer2.update();
  //Do not need to update these here are they are not used
  //bouncer3.update();
  //bouncer4.update();
  if (bouncer1.read() == HIGH)
  {
    serloop1(); //Enters button control loop
  }
  if (bouncer2.read() == HIGH)
  {
    serloop1(); //Enters button control loop
  }
}

/**
 * If button control is enabled, loop and handle control buttons
 * If exit buttons (To return to pot control) are pressed, exit loop and return
 * to pot control
 */
void serloop1(){
  servoPosition = throttleServo.read(); //reads current servo location
  int btnControlEnabled = 1; //If button control is enabled this equals 1, else it equals 0
  while(btnControlEnabled == 1)
  {
    //Update all debounce tools
    bouncer1.update();
    bouncer2.update();
    bouncer3.update();
    bouncer4.update();
    if (bouncer1.read() == HIGH)
    {
      throttleServo.write(servoPosition + 2); //SUBTRACT 2 degrees to servo position for increased motor rpm
      servoPosition = throttleServo.read(); //Read new servo position
      delay(40); //allows time for switch ro reset
    }
    //If first button not pressed, check the next...
    else if (bouncer2.read() == HIGH)
    {
      throttleServo.write(servoPosition - 2); //ADDS 2 degrees to servo position for decreased motor rpm
      servoPosition = throttleServo.read(); //Read new servo position
      delay(40); //allows time for switch ro reset
    }
    else if (bouncer3.read() == HIGH)
    {
      btnControlEnabled = 0; //Set loop exit condition
      throttleServo.write(180);


    }
    else if (bouncer4.read() == HIGH)
    {
      throttleServo.write(180);
      btnControlEnabled = 0; //Set loop exit condition


    }
    //If nothing pressed...
    else
    {
      //...do nothing at all, go back to start of loop
    }
  }
}
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48556
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
Bounce bouncer1 = Bounce(buttonPin, debounceDelay);
Bounce bouncer2 = Bounce(buttonPin2, debounceDelay);
Bounce bouncer3 = Bounce(buttonPin3, debounceDelay);
Bounce bouncer4 = Bounce(buttonPin4, debounceDelay);
Surely these bouncers (dumb ass name) have some physical or mental meaning. Give these instances MEANINGFUL names.

Code:
      throttleServo.write(servoPosition + 2); //SUBTRACT 2 degrees to servo position for increased motor rpm
That's hardly the correct mathematical symbol to perform SUBTRACTion.

Code:
      throttleServo.write(servoPosition - 2); //ADDS 2 degrees to servo position for decreased motor rpm
Or addition.

Code:
    //If nothing pressed...
    else
    {
      //...do nothing at all, go back to start of loop
    }
If there is nothing to do, you hardly need 5 lines of code to not do it.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 35
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

thanks Paul, any chance you can help with my question though?

Code:
#include <Bounce.h>
#include <Servo.h>

void setup(){
  buttonSetup();
  throttleSetup();
}

void loop(){
  throttleLoop();
  buttonLoop();
}

int servoPosition = 20; //Old val1, used to store servo position. Allows use by whole program
Servo throttleServo; // Define throttle Servo
int servoPos = 0;    // Initial power up “servo position”
int moveServoAmount = 7;    // move the servo 10 degrees per 1/24 pulse
const int pin_A = A0;  // pin 15
const int pin_B = A1;  // pin 14
unsigned char encoder_A;
unsigned char encoder_B;
unsigned char encoder_A_prev=0;

// set pin numbers:
const int buttonPin = 10; // the number of the pushbutton pin
const int buttonPin2 = 8;
const int buttonPin3 = 4;
const int buttonPin4 = 2;

long debounceDelay = 50;    // the debounce time; increase if the output flickers

//Debounce objects
// Instantiate a Bounce object with a 5 millisecond debounce time
Bounce cruiseUp = Bounce(buttonPin, debounceDelay);
Bounce cruiseDn = Bounce(buttonPin2, debounceDelay);
Bounce releaseToThrottle1 = Bounce(buttonPin3, debounceDelay);
Bounce releaseToThrottle2 = Bounce(buttonPin4, debounceDelay);

void throttleSetup()  {
  throttleServo.attach(12); // servo on digital pin 12
  pinMode(pin_A, INPUT);
  digitalWrite(pin_A, HIGH);// turn on pullup resistor
  pinMode(pin_B, INPUT);
  digitalWrite(pin_B, HIGH);// turn on pullup resistor
}

void throttleLoop()  {

  encoder_A = digitalRead(pin_A); // Read encoder pins
  encoder_B = digitalRead(pin_B);
  if((!encoder_A) && (encoder_A_prev)){
    // A has gone from high to low
    if(encoder_B) {
      // B is high so clockwise
      // increase the throttle, dont go over 255
      if(servoPos + moveServoAmount <= 220) servoPos += moveServoAmount;
    }
    else {
      // B is low so counter-clockwise
      // decrease the throttle, dont go below 20
      if(servoPos - moveServoAmount >= 20) servoPos -= moveServoAmount;
    }
  }
  encoder_A_prev = encoder_A;     // Store value of A for next time
  // set the new location of servo:
  throttleServo.write(servoPos);
}

void buttonSetup(){
  // initialize the pushbutton pin as an input:
  pinMode(buttonPin, INPUT);
  pinMode(buttonPin2, INPUT);
  pinMode(buttonPin3, INPUT);
  pinMode(buttonPin4, INPUT);
}

void buttonLoop(){
  //Update debounce tool
  cruiseUp.update();
  cruiseDn.update();
  //Do not need to update these here are they are not used
  //bouncer3.update();
  //bouncer4.update();
  if (cruiseUp.read() == HIGH)
  {
    serloop1(); //Enters button control loop
  }
  if (cruiseDn.read() == HIGH)
  {
    serloop1(); //Enters button control loop
  }
}

/**
 * If button control is enabled, loop and handle control buttons
 * If exit buttons (To return to pot control) are pressed, exit loop and return
 * to pot control
 */
void serloop1(){
  servoPosition = throttleServo.read(); //reads current servo location
  int btnControlEnabled = 1; //If button control is enabled this equals 1, else it equals 0
  while(btnControlEnabled == 1)
  {
    //Update all debounce tools
    cruiseUp.update();
    cruiseDn.update();
    releaseToThrottle1.update();
    releaseToThrottle2.update();
    if (cruiseUp.read() == HIGH)
    {
      throttleServo.write(servoPosition + 2); //Add 2 degrees to servo position for increased motor rpm
      servoPosition = throttleServo.read(); //Read new servo position
      delay(40); //allows time for switch ro reset
    }
    //If first button not pressed, check the next...
    else if (cruiseDn.read() == HIGH)
    {
      throttleServo.write(servoPosition - 2); //Subtract 2 degrees to servo position for decreased motor rpm
      servoPosition = throttleServo.read(); //Read new servo position
      delay(40); //allows time for switch ro reset
    }
    else if (releaseToThrottle1.read() == HIGH)
    {
      btnControlEnabled = 0; //Set loop exit condition
      throttleServo.write(180);


    }
    else if (releaseToThrottle2.read() == HIGH)
    {
      throttleServo.write(180);
      btnControlEnabled = 0; //Set loop exit condition
    }
  }
}
« Last Edit: March 07, 2013, 01:46:38 pm by msumrell » Logged

UK
Offline Offline
Shannon Member
****
Karma: 223
Posts: 12577
-
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I had to re-read that several times to figure out what behaviour you're after, and I'm still not sure I have got it right. I think the idea is that you have a servo that tracks the movement of the joystick so that when the joystick moves left the servo moves left etc. There is a switch which can conceptually disconnect the servo (so that it stays in place and does not track the joystick movement); when the switch is released the servo resumes tracking the movement of the joystick.

That sounds like a problem that would be much easier with an encoder than with a pot, because you're not interested in getting an absolute position from the encoder - only movement.

I have only skimmed through the code so I don't know how close it is, but essentially I'd expect to have a variable holding the current position of the servo, and increment/decrement that as the encoder moves. When the switch is closed, ignore encoder movement. Is that what you're after?
Logged

I only provide help via the forum - please do not contact me for private consultancy.

0
Offline Offline
Tesla Member
***
Karma: 141
Posts: 9470
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I too am a little confused as to what you want to do. I made a webcam pan/tilt joystick setup a long time back where the servos were sent control signals only when a button on the stick was pushed. Press the button, aim the cam, release the button, release the joystick, and the cam stays aimed. Push the button with the joystick in its return position and the cam returns to the neutral position. Move the joystick, push the button, the cam immediately goes to that joystick position.
Logged

Consider the daffodil. And while you're doing that, I'll be over here, looking through your stuff.   smiley-cool

Anacortes, WA
Offline Offline
Full Member
***
Karma: 2
Posts: 146
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm also not sure what your trying to do, but it does look like dropping your servoPosition variable might simplify things.

servoPosition = throttleServo.read();

From what I see here, it looks like this info is already being managed by the servo object itself. Don't duplicate the effort and possibly cause your own errors by co-managing it.

Hope this helps..

-jim lee
Logged

Pages: [1]   Go Up
Jump to: