Go Down

Topic: Help controlling 2 servos with joystick (Read 1 time) previous topic - next topic

ThisGuy1

Jul 04, 2013, 04:21 am Last Edit: Jul 05, 2013, 02:53 am by ThisGuy1 Reason: 1
Hi,

I've done some research but still struggling trying to make the pan/tilt motion with servos. I've made one move as it should, played around and don't seem to be getting anywhere. Maybe my connections are off, maybe I've overcomplicated the code (is that possible?)

Materials:
Hextronik HX5010 Twin Bearing Servo
TowerPro MG995 DIGI HI-SPEED Servo
Arduino Duemilanove
Breadboard (Came with starter kit, I guess it's medium size as I've seen longer?)
Smaller breadboard that fits perfectly inside the Arduino (I got one servo moving perfectly with this, have struggled with 2)
9V Battery with adaptor to Arduino
Joystick: Keyes_SJoys (Ebay Search: Black Thumb Joystick Module w 5 Pin Replacement for Arduino High Quality)

I have the Joystick pins hooked up for Analog 3, 4 & 0 respectively.
The Servos hooked up to Digital 4 & 10.
(And Ground and 5V's)

Code:


#include <Servo.h>

//CONSTANTS
const int servo1 = 4;       // first servo
const int servo2 = 10;       // second servo

//VARIABLE
int VRx = 3;        // VRx Thumbstick
int VRy = 4;        // VRy Thumbstick
int SW = 0;       // SW Thumbstick
int VRxPos = 90;
int VRyPos = 90;
int SWPos = 90;
boolean logging = false;

Servo myservo1;  // create servo object to control a servo
Servo myservo2;  // create servo object to control a servo

void setup() {

 // Servo  
 myservo1.attach(servo1);  // attaches the servo
 myservo2.attach(servo2);  // attaches the servo
             

 // Inizialize Serial
 Serial.begin(9600);
}


void loop(){

   // Display Joystick values using the serial monitor
   outputJoystick();

   // Read the horizontal joystick value  (value between 0 and 1023)
   VRxPos = analogRead(VRx);          
   VRxPos = map(VRxPos, 0, 1023, 0, 180);     // scale it to use it with the servo (result  between 0 and 180)

   myservo2.write(VRxPos);                         // sets the servo position according to the scaled value    

   // Read the horizontal joystick value  (value between 0 and 1023)
   VRyPos = analogRead(VRy);          
   VRyPos = map(VRyPos, 0, 1023, 0, 180);     // scale it to use it with the servo (result between 70 and 180)

   myservo1.write(VRyPos);                           // sets the servo position according to the scaled value

   

   delay(50);                                       // waits for the servo to get there

}


/**
* Display joystick values
*/
void outputJoystick(){

   Serial.print(VRxPos);
   Serial.print ("---");
   Serial.print(VRyPos);
   Serial.println ("----------------");
   Serial.print(SWPos);    
   Serial.println("------------");

}

Only question about the code is about the SW... do you assign it to anything in the loop?

Any help at all would be appreciated.

Grumpy_Mike

Read the how to use this forum sticky PLEASE and post the code correctly.

You are outputting numbers to the serial port that never change. They are just the pin numbers of the analogue port you are using.

LarryD

The way you have it in your schematic isn't the same as how you have it wired up!

ThisGuy1

1st of all, very much appreciate the quick replies.

I appreciate it's probably a basic error but could you type a solution to the coding issue you mentioned? What should be in the serial port?

I'm powering the motors with an Energizer 9V Battery (2nd to last on the Materials list) with the little cord adaptor running to the Duemilanove

Thanks in advance

LarryD

#4
Jul 04, 2013, 05:34 am Last Edit: Jul 04, 2013, 05:37 am by LarryD Reason: 1
Quote
What should be in the serial port?

Quote
They are just the pin numbers of the analogue port you are using.

   Serial.print(VRxPos);
   Serial.print(VRyPos);
Quote
I'm powering the motors with an Energizer 9V Battery

Look up the voltage/current rating of your motors
The way you have it in your schematic isn't the same as how you have it wired up!

Grumpy_Mike

Quote
but could you type a solution to the coding issue you mentioned

No not until you do as requested and post the code correctly. There is a modify button on the post.

Quote
What should be in the serial port?

What do you want it to be. At the moment it just prints the same numbers over doesn't it.

Quote
I'm powering the motors with an Energizer 9V Battery

They don't last long.

ThisGuy1

Thanks for putting up with my stupidity thus far.

Is it modified correctly? To tell it to turn 180 I feel like I need to change the int VRxPos = 90 (originally wanted it turning 90) to something like VRxPos = (0, 180);, which would theoretically tell the serial port what to do, but then isn't that the point of VRxPos = map(VRxPos, 0, 1023, 0, 180); in the loop?

Am I getting any closer or going way off-road with this?

zoomkat

Below is some simple code I made to tinker with pots and servos. It is set up to view the output in the serial monitor.

Code: [Select]

//zoomkat dual pot/servo test 12-29-12
//view output using the serial monitor

#include <Servo.h>
Servo myservo1;
Servo myservo2;

int potpin1 = 0;  //analog input pin A0
int potpin2 = 1;

int newval1, oldval1;
int newval2, oldval2;

void setup()
{
  Serial.begin(9600); 
  myservo1.attach(2); 
  myservo2.attach(3);
  Serial.println("testing dual pot servo"); 
}

void loop()
{
  newval1 = analogRead(potpin1);           
  newval1 = map(newval1, 0, 1023, 0, 179);
  if (newval1 < (oldval1-2) || newval1 > (oldval1+2)){ 
    myservo1.write(newval1);
    Serial.print("1- ");
    Serial.println(newval1);
    oldval1=newval1;
  }

  newval2 = analogRead(potpin2);
  newval2 = map(newval2, 0, 1023, 0, 179);
  if (newval2 < (oldval2-2) || newval2 > (oldval2+2)){ 
    myservo2.write(newval2);
    Serial.print("2- ");   
    Serial.println(newval2);
    oldval2=newval2;
  }
  delay(50);
}

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

moriartynz

I see you are using the Keyes_SJoys PS2 Joystick Game Controller Breakout Module For Arduino from ebay. If yours are anything like mine, then they are of no use for fine control. Attaching this to my multimeter (between GND and VRx or VRy) gives very non-linear results:

At rest in the middle gives approximately 3.5kohm. Pressed to one extreme gives a value of 100-130 ohms (depending on which pot I am reading). This value does not appreciably change as you relax the stick towards rest for a good third of its travel. Then the resistance actually goes DOWN to between 50-100ohms and then rapidly climbs back up to 3.5kohm in the last third of its travel. It is also not reproducable in the change region. i.e. if I reverse direction to a previous position, I do not get very reproducable results.

Going the other direction is much the same. At its extreme, I get about 4.6kohms, then UP to 5kohm as I relax it towards the rest (middle point) and then down again to 3.5 kohm at its central rest position.

The results are not reproducable, do not change appreciably for a good third of travel at the extremes and in the middle are completely counter-intuitive (reversing resistance direction for some of its travel). At best, these devices will only be usable as a detection for extreme up, left, right, down and middle. Also, they can be used for 45 degree angles of up and left, bottom and right, etc. The advertised momentary button (SW) also only works in the rest position (middle).  I would not use them for detecting any form of graduated change in direction.

Even for the detection of the extremes, there is a potential for false detection if a user simply bumps the stick slightly into the resistance reversing region while making a change in another intended direction. They are truly not great products, but then you often get what you pay for ...

I bought these as a very cheap system of getting a simple input for menu selection and basic navigation because I can still use them with just 3 pins on my AVR as low pincount is an issue in my design, so they kind of work. Effectively, they permit a total of 8 detectable positions plus the central rest position together with the momentary button, which is not too shabby for the use of just 3 pins.

Unfortunately, the quirks of these devices will cost me a lot of time and code in programming to detect whether we are truly at an extreme or whether we are just passing fleetingly through the resistance reversing direction. I think I might just require multiple consitent ADC (with a given tolerance) as an indicator that we are not fleetingly in the reversing area.

I am not unique in having these issues with these types of devices. See the comments on the sparkfun website (https://www.sparkfun.com/products/9032) for their similar item.

Also note that the momentary button has no resistance associated with it. This might be an issue for you depending on what you are trying to drive with it as use of any appreciable amount of current through this switch is reported to burn out these joysticks.

Given the other issues you have had with your code, these issues with this device are likely to make your project very difficult for you.

Regards
Mark

Go Up