Servo positioning

Hey guys,

So I have this project where I'm using a ps3 controller to control several servos,

Everything so far is working fine expect that I have noticed that when I use the the ps3 joysticks to move the servos, they automatically reset themselves to their standard 0 degrees when I take my thumb of the joystick.

How can I change it so the servo stays in the position it was last left in even when I let go of the joystick?

I am using the HITEC HS311 STANDARD SERVO
DF-SER0002.

Thanks everyone

Hi, we need to see your programming and how it is setup to give you any advice.
At the moment the servos are mimicking the exact position of the joysticks.
You are after a direction/speed rather than absolute positioning type control.

Tom..... :slight_smile:

thanks for the reply Tom,

Iv'e only done some tests on the servos to check everything was working so I Havn't exactly written out my whole prokect code...

This is the what im using to move the servo with the ps3 controller

Servo.write(map(.getAnalogHat(RightHatx), 0 ,255, 0, 180

Ive only done some minor test so I didn't go to the details of speed or delay yet...

I gave advice on something similar a long time ago.

...R

Thanks Robin,

I'm not sure I understand what you're trying to make me see, although the man building the excavator's problem is very similar to mine, I failed to see any real improvements in his problem.

Im sorry i'm not very good at Arduino. but their must be a piece of code that makes the servo understand that it shouldn't go back to its original positon

Thanks again

FWIW servos hold their position if the voltage applied is steady. So the signal must be going back to zero volts. I think that this is what you designed it to do if you are using joysticks that spring back to the neutral position. So the only way to get it to hold position is to take out the joystick springs (but then they'll be floppy) OR code a button press where you press a button, grab the value off the joystick input, and hold and continue to send that output value to the servo. Then you'll likely need it to unlock after another button press.

walshlg:
OR code a button press where you press a button, grab the value off the joystick input, and hold and continue to send that output value to the servo. Then you'll likely need it to unlock after another button press.

There are other threads apart from the one Robin2 linked which advocate that approach. Not sure of the success though. Problem is the "unlocking" as you call it: where does the servo go then? There could be a huge jerk if it flew to the new value of where the stick was when it was unlocked.

The new forum engine seems to have lost the little decent search that it had, so finding the other threads may be a problem

FWIW servos hold their position if the voltage applied is steady. So the signal must be going back to zero volts.

That's not strictly true. A servo holds its position if the signal wire receives a pulse to hold it. In "Arduino C" (sorry purists, but allow me that liberty for now), the pulse as specified with the servo.write() or servo.writeMicroseconds() is repeated every 20ms to keep the servo in position. That pulse continues until a new servo.write or a servo.detach.

But you're right conceptually, in that a typical sketch will re-position the servo to some "central" position when the stick is centred.

BlaiseyRex:
I'm not sure I understand what you're trying to make me see,

Sorry. That does not seem to be the correct link.

I thought this code was in that Thread

#include <Servo.h>

#define mainArm 0
#define jib 1
#define bucket 2
#define slew 3

Servo servo[4];

byte angle[4] = {90, 90, 90, 90};

byte potPin[4] = {A0, A1, A2, A3};
byte servoPin[4] = {12, 11, 10, 9};

void setup() {

  Serial.begin(9600);
  Serial.println("Starting DiggerCode.ino");


  for (byte n = 0; n < 4; n++) {
    servo[n].attach(servoPin[n]);
  }
}

void loop() {
  readPotentiometers();
  moveServos();
  delay(10);
}

void readPotentiometers() {
  int potVal;
  for (byte n = 0; n < 4; n++) {
    potVal = analogRead(potPin[n]);
    
    if (potVal < 450) {
      angle[n] += 1;
      if (angle[n] > 170) {
        angle[n] = 170;
      }
    }
    
    if (potVal > 570) {
      angle[n] -= 1;
      if (angle[n] < 10) {
        angle[n] = 10;
      }
    }

  }
}

void moveServos() {
  for (byte n = 0; n < 4; n++) {
    servo[n].write(angle[n]);
  }
}

...R

what about PWM?

I just need to temporarily kill the power until i retouch the joysticks, and it has to be done really fast as well.

I don't think physically modifying the joysticks is a good ides, and I don't wanna pay more money for other servos

If you don't want to attempt to defeat the springs in the joystick, then you may need to consider a different mode of control. The below discussion has some ideas. In the past for a pc and a serial servo controller I made a program where the joystick was only active when the joystick button was pressed. This had issues with being to exactly position the joystick to its previous position before pushing the button again.

http://forum.arduino.cc/index.php?PHPSESSID=2bai725l4dfmtu4bj3vsti51b0&topic=220396.msg1604441#msg1604441

BlaiseyRex:
what about PWM?

I don't know what you are thinking about, but this is not the answer to anything to do with servos. The servo library does the necessary.

I just need to temporarily kill the power until i retouch the joysticks, and it has to be done really fast as well.

No you don't. The code I posted does what you want without any modifications to the joysticks.

...R

No you don't. The code I posted does what you want without any modifications to the joysticks.

Could You elaborate on which part Robin? Fairly knew to programming

BlaiseyRex:
Could You elaborate on which part Robin? Fairly knew to programming

The function readPotentiometers()

It increments the position when you move a joystick one way (from centre) and decrements the position when you move it the other way. When the joystick returns to centre nothing happens.

Try it and see. The Arduino system is great for learning-by-doing.

...R

Thanks Robin,

Sorry for the slow reply,

I understand the function of the readPotientiometers() and I thank you so much for an answer :slight_smile:

How could I incorporate this into my code? do I have to add any syntax or anything?

Thanks again,

BlaiseyRex:
How could I incorporate this into my code? do I have to add any syntax or anything?

That is a huge question - and the second part does not make sense.

Make your best attempt and post what you get as a basis for further discussion. Don't try to build the whole program at once. Take it step by step. Maybe it would be easier to ADD the extra bits in your project to my code - or at least think about how you might do that.

The Thread planning and implementing a program may give you some ideas for using functions to compartmentalize chunks of code.

hey Robin,

Iv'e taken your advice and broken my code down so I can experiment a bit,

This is the code I'm using to control 2 servo with my ps3 controller:

#include <PS3BT.h>                    //Include the necessary libraries. 
#include <Servo.h> 

USB Usb; 
BTD Btd(&Usb); 
PS3BT PS3(&Btd);   

Servo servo1;                    //Create instances of type Servo. servo1 is the steering servo and servo2 is the ESC. 
Servo servo2; 

void setup() { 
    Serial.begin(115200);                     
    if (Usb.Init() == -1) {                     
      Serial.print(F("\r\nOSC did not start")); 
      while(1); //halt 
    } 
    Serial.print(F("\r\nPS3 Bluetooth Library Started"));                
    
    servo1.attach(7);                    //Steering servo on digital pin 5 
    servo2.attach(6);                   //ESC on sigital pin 3 
} 
void loop()   
{ 
    Usb.Task(); 

    if(PS3.PS3Connected || PS3.PS3NavigationConnected) { 
        
      servo1.write(map(PS3.getAnalogHat(RightHatX), 0, 255, 0, 180)); 
      servo2.write(map(PS3.getAnalogHat(LeftHatY), 0, 255, 180, 0)); 
    } 
    else   
     { 
      servo1.write(90); 
      servo2.write(90); 
     } 
        
      if(PS3.getButtonClick(PS)) { 
        PS3.disconnect(); 
     } 
}

I still have a few questions like;

What is incrementing and decrementing? what's it used for?
How will the arduino code recognise that the joysticks are the potentiometers in the ReadPotentiomrers() sketch?

      servo1.write(map(PS3.getAnalogHat(RightHatX), 0, 255, 0, 180)); 
      servo2.write(map(PS3.getAnalogHat(LeftHatY), 0, 255, 180, 0));

The PS3 method may, or may not, be returning a valid value. Do you have a clue what value(s) is it returning?

You are mapping that value to a value that may pr may not be valid. Do you have a clue what you are mapping the PS3's value to?

Until you can answer these questions with absolute certainty, "wasting" 4 bytes of SRAM, so you can print the values is a good thing. Even after that, are you really so short on SRAM that you can't afford 4 bytes? Can you afford 2?

None of that answers my question PaulS,

My values are correct and my piece of code Absolutely works,

I'm not sure How printing the values into the SRAM will be of any help as they already are in the PS3BT library.

Im happy to be enlightened about all my flaws.

And I would d still like to know how I can incorporate the ReadPotentiometers into the code I have given.

I'm not sure How printing the values into the SRAM will be of any help as they already are in the PS3BT library.

You wouldn't print them to SRAM. You'd print them to the serial port. That way, you'd KNOW whether the PS3 library was working correctly. Debugging based on step 37 is MUCH harder than debugging based on step 1.

And I would d still like to know how I can incorporate the ReadPotentiometers into the code I have given.

What is the function reading? You are replacing the potentiometers with the joystick(s), right? So, you don't need readPotentiometers(). The values it was getting are the values that you are mapping and sending to the servos. If you need them for some other purposes, you can store them in variables or read the PS3 thing again.

What is the function reading?

Nothing, my code works perfectly, the Read Potentiometers() value is so My servos can Stay at the postion they are curently in without returning to their original value after I stop moving the joysticks