Pages: 1 [2] 3   Go Down
Author Topic: 2 motors controlled by one joystick  (Read 10254 times)
0 Members and 1 Guest are viewing this topic.
Queens, New York
Offline Offline
Faraday Member
**
Karma: 83
Posts: 3390
"Of all the things I've ever lost, I miss my mind the most" -Ozzy Osbourne
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Why do this?

Quote
servoVal3 = map(servoVal3, 0, 1023,1000, 1750);    // scale it to use it with the servo (result  between 0 and 180)
servoVal4 = map(servoVal4, 0, 1023, 1250, 1750);     // scale it to use it with the servo (result between 70 and 180)
.....
servoVal1 = map(servoVal1, 0, 1023,1000, 1750);     // scale it to use it with the servo (result  between 0 and 180)
servoVal2 = map(servoVal2, 0, 1023, 1250, 1750);     // scale it to use it with the servo (result between 70 and 180)

Don't you want to get values between 0 - 90, and 90 - 180? You need to use IF statements like how I have done. If you don't isolate the values, and use them when you need them, you have problems controlling the robot.
Logged

Created Libraries:
NPV2 (NewPasswordV2),  TFT_Extension, OneWireKeypad, SerialServo.
Will provide libraries if asked in PM or forum.

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 285
Posts: 25629
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Don't you want to get values between 0 - 90, and 90 - 180?
No, the "write" method interprets values outside the normal range of "angles" as pulse lengths expressed in microseconds.
Those mapping ranges look OK to me.
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

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

Quote
i managed to get the 2 motors to make zero point turns, however i now cant get any headway into running at the same time to go forwards and backwards. any ideas/ help would be massively appreciated.

I'd first make two separate pieces of code specific to each pot (forward/reverse pot and turn pot). Get each working to do its specific function, then work on ways to integrate the two working code sections into single code.
Logged

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

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

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

    servoVal3 = analogRead(joyV);
    servoVal4 = analogRead(joyV);
I still don't understand this code. Write some data to the serial port. Then, get the data to be written. Isn't the horse on the wrong end of the cart?
Logged

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

This is the problem, I cannot find for the life of me a statement or a string of statements that would allow both Val 3 and Val 4 to equal analogRead(joyV) while keeping the map functions different, is there anything that I am missing? Or would it be better to go with tank controls instead of arcade (I only want to do this if it is impossible), again any help would be readily accepted and deeply appreciated.
Logged

Queens, New York
Offline Offline
Faraday Member
**
Karma: 83
Posts: 3390
"Of all the things I've ever lost, I miss my mind the most" -Ozzy Osbourne
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I showed you how to do it.
Quote
int DRV2 = map(z, -15, 0, 255, 0); range -15 to 0 => reverse
int DRV1 = map(z, 0, 15, 0, 255); range 0 to 15 => forward
int STRL = map(y, -10, 0, 255, 0); left
int STRR = map(y, 0, 10, 0, 255); right

Yours should be,
Code:
    servoDrive = analogRead(joyV);
    servoVal3 = map(servoDrive, 0, 1023,1000, 1750);     // scale it to use it with the servo (result  between 0 and 180) FORWARD
    servoVal4 = map(servoDrive, 0, 1023, 1250, 1750);     // scale it to use it with the servo (result between 70 and 180) REVERSE

// Read the horizontal joystick value  (value between 0 and 1023)

    servoTurn = analogRead(joyH);
    servoVal1 = map(servoTurn, 0, 1023,1000, 1750);     // scale it to use it with the servo (result  between 0 and 180) LEFT
    servoVal2 = map(servoTurn, 0, 1023, 1250, 1750);     // scale it to use it with the servo (result between 70 and 180) RIGHT

Again, your map values I dont think are correct. "(result between 70 and 180), (result  between 0 and 180)"
Logged

Created Libraries:
NPV2 (NewPasswordV2),  TFT_Extension, OneWireKeypad, SerialServo.
Will provide libraries if asked in PM or forum.

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

I don't have any servos or pots setup for testing, but the below (modified knob code) might be a way to loop and trap the pot that leaves the centered position and read it in a sub loop until it returns to the centered position again, at which the main loop is reentered. Hopefully only one non centered pot at a time would be in control of the servos to prevent control conflicts. Not that familiar with looping operations.

Code:
#include <Servo.h>

Servo myservo1;  // create servo object to control a servo
int potpin1 = 0;  // analog pin used to connect the potentiometer
int val1;    // variable to read the value from the analog pin

Servo myservo2;  // create servo object to control a servo
int potpin2 = 0;  // analog pin used to connect the potentiometer
int val2;    // variable to read the value from the analog pin

void setup()
{
  myservo1.attach(8);  // attaches the servo on pin 8 to the servo object
  myservo2.attach(9);  // attaches the servo on pin 9 to the servo object
}

void loop()
{
  if ((500 < (analogRead(potpin1)) || (analogRead(potpin1)) > 523)){
    while ((500 < (analogRead(potpin1)) || (analogRead(potpin1)) > 523)){ 
      val1 = analogRead(potpin1);             
      val1 = map(val1, 0, 1023, 0, 180);       
      myservo1.write(val1);                   
      myservo2.write(val1);                 
      delay(15);                           
    }
  }

  if (500 < (analogRead(potpin2)) || (analogRead(potpin2)) > 523){
    while (500 < (analogRead(potpin2)) || (analogRead(potpin2)) > 523){ 
      val2 = analogRead(potpin2);             
      val2 = map(val2, 0, 1023, 0, 180);       
      myservo1.write(val2);                   
      myservo2.write(180-val2);                   
      delay(15);                           
    }
  }
}

Logged

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

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

Code:
#include <Servo.h>

const int servo1 = 3;       // first servo
const int servo2 = 10;       // second servo
const int joyH = 3;        // L/R Parallax Thumbstick
const int joyV = 4;        // U/D Parallax Thumbstick

int servoDrive;
int servoTurn;
int servoVal1;           // variable to read the value from the analog pin
int servoVal2;
int servoVal3;
int servoVal4;
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();
    servoDrive = analogRead(joyV);

    servoTurn = analogRead(joyH);
    servoVal1 = map(servoTurn, 0, 1023,1000, 1750);     // scale it to use it with the servo (result  between 0 and 180)
    servoVal2 = map(servoTurn, 0, 1023, 1250, 1750);     // scale it to use it with the servo (result between 70 and 180)

    // scale it to use it with the servo (result  between 0 and 180)
    servoVal3 = 435 + servoVal4 - servoDrive;
   
    servoVal4 = map(servoDrive, 0, 1023, 1250, 1750);
   
    // scale it to use it with the servo (result between 70 and 180)
   
   myservo2.write(servoVal3);                         // sets the servo position according to the scaled value   
   myservo1.write(servoVal4);
   
    // Read the horizontal joystick value  (value between 0 and 1023)
    //servoTurn = analogRead(joyH);

    //servoDrive = analogRead(joyV);
   
   
    myservo2.write(servoVal1);                         // sets the servo position according to the scaled value   
    myservo1.write(servoVal2);
 


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

}


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

    Serial.print(analogRead(joyV));
    Serial.print ("----------------");
    Serial.print(analogRead(joyH));
    Serial.println ("----------------");
}
this is the code i have now, it works when the two parts are separate. forwards and backwards:
Code:
#include <Servo.h>

const int servo1 = 3;       // first servo
const int servo2 = 10;       // second servo
const int joyH = 3;        // L/R Parallax Thumbstick
const int joyV = 4;        // U/D Parallax Thumbstick

int servoDrive;
int servoTurn;
int servoVal;
int servoVal1;           // variable to read the value from the analog pin
int servoVal2;
int servoVal3;
int servoVal4;
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();

    servoDrive = analogRead(joyV);

    // scale it to use it with the servo (result  between 0 and 180)
     servoVal3 = 435 + servoVal4 - servoDrive;
   
    servoVal4 = map(servoDrive, 0, 1023, 1250, 1750);
   
    // scale it to use it with the servo (result between 70 and 180)
   
   myservo2.write(servoVal3);                         // sets the servo position according to the scaled value   
   myservo1.write(servoVal4);
   delay(15);                                       // waits for the servo to get there


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

    Serial.print(analogRead(joyH));
    Serial.print ("---");
    Serial.print(analogRead(joyV));
    Serial.println ("----------------");
}

and zero point turns:
Code:
#include <Servo.h>

const int servo1 = 3;       // first servo
const int servo2 = 10;       // second servo
const int joyH = 3;        // L/R Parallax Thumbstick
const int joyV = 4;        // U/D Parallax Thumbstick

int servoDrive;
int servoTurn;
int servoVal1;           // variable to read the value from the analog pin
int servoVal2;
int servoVal3;
int servoVal4;
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();

    servoTurn = analogRead(joyH);
    servoVal1 = map(servoTurn, 0, 1023,1000, 1750);     // scale it to use it with the servo (result  between 0 and 180)
    servoVal2 = map(servoTurn, 0, 1023, 1250, 1750);     // scale it to use it with the servo (result between 70 and 180)

   
    // Read the horizontal joystick value  (value between 0 and 1023)
    //servoTurn = analogRead(joyH);
   
   
    myservo2.write(servoVal1);                         // sets the servo position according to the scaled value   
    myservo1.write(servoVal2);
 


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

}


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

    Serial.print(analogRead(joyV));
    Serial.print ("----------------");
    Serial.print(analogRead(joyH));
    Serial.println ("----------------");
}
for some reason (its one i cant find) whenever the 2 parts of the code are together like then one at the top, all of the code for the Forwards and backwards portion are ignored and the robot cannot move forward. is there anything in the code that makes this Occur? if not does anyone have any advice? as always any help would be appreciated and anyone that has posted so far has been of extreme help.
Logged

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

OK it took me a while to figure out how to do it for my own project and this is one of the top posts that come up when googling it, so here is how it is done.

First there is two aspects, motor distribution and speed. Normally distribution and speed is determined by x and y respectfully. However this doesn't work for us.

Instead speed is equal to the distance from the center. (which we will refer to as 0,0).
Next to get the distribution we need the angle of the point with respect to the X-axis.

 Specifically: 0 degrees being X=MaxRight, Y=0; 90 degrees X=0, Y=MaxUp; 180 degrees y=0, X= maxleft; 270 degrees x=0, y=maxdown

Let +1=100% of power and -1=-100% power (ie reverse)
Then (* == degrees)
90* => +1, +1
180* => -1,+1
270* => -1,-1
360*/0* => +1,-1

Now as the points move around the circle there needs to be a transition between +1 and -1. Specifically in the first quadrant:
Quadrant one (angle <90*)

at 0* it is +1, -1
at 22.5* it is +1, -.5
at 45* it is +1,0
at 67.5 it is +1, +.5
at 90* it is +1, +1.

Now programmablly the code is

Code:
double right_dist;
double left_dist;
if(angle <= 90){

left_dist= +1;
if(angle<45.0){
right_dist= -1*((45.0-angle)/45.0);
}
else{
right_dist= 1*( (angle-45.0)/45.0);
}
}
else if(angle <= 180){
angle = angle - 90;
right_dist= +1;
if(angle<45.0){
left_dist= 1*((45.0-angle)/45.0);
}
else{
left_dist= -1*( (angle-45.0)/45.0);
}
}
else if(angle <= 270){
angle = angle - 180;
left_dist= -1;
if(angle<45.0){
right_dist= 1*((45.0-angle)/45.0);
}
else{
right_dist= -1*( (angle-45.0)/45.0);
}
}
else{ // if(angle <= 360){
angle = angle - 270;
right_dist= -1;
if(angle<45.0){
left_dist= -1 *((45.0-angle)/45.0);
}
else{
left_dist= 1*( (angle-45.0)/45.0);
}
}
                      motor_left_speed=left_dist*distance
                      motor_right_speed=right_dist*distance

Logged

Upton, Ma
Offline Offline
Newbie
*
Karma: 0
Posts: 1
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm new to this but I want to achieve something similar but a little less complicated, well in my mind it is . I'm usig a single joystick and 2 motors for an underwater ROV project. Along the y axis its pretty straight foward. stick up both motors full speed fwd, stick down both motors full speed rev and everything in between. Lets call the motors M1 and M2. when i'm refering to the speed of the motors I will just say that full fwd speed is +127, 0 is off and full rev is -127.  If that should be different let me know, but for now thats burned into my mind. Ok fwd and rev are cake, turning isn't that hard either. if the joystick is all the way left then m1 is -127 and m2 is +127. if the joystick is half left then m1 is -63 and m2 is +63.

Programming this alone doesn't seem that difficult  but when i want to turn while moving forward... joystick all the way to the left and up M1 is 0 and m2 is +127

I have no Idea where to start with this but If it cant happen i can just use two sticks.
Logged

Queens, New York
Offline Offline
Faraday Member
**
Karma: 83
Posts: 3390
"Of all the things I've ever lost, I miss my mind the most" -Ozzy Osbourne
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm new to this but I want to achieve something similar but a little less complicated, well in my mind it is . I'm usig a single joystick and 2 motors for an underwater ROV project. Along the y axis its pretty straight foward. stick up both motors full speed fwd, stick down both motors full speed rev and everything in between. Lets call the motors M1 and M2. when i'm refering to the speed of the motors I will just say that full fwd speed is +127, 0 is off and full rev is -127.  If that should be different let me know, but for now thats burned into my mind. Ok fwd and rev are cake, turning isn't that hard either. if the joystick is all the way left then m1 is -127 and m2 is +127. if the joystick is half left then m1 is -63 and m2 is +63.

Programming this alone doesn't seem that difficult  but when i want to turn while moving forward... joystick all the way to the left and up M1 is 0 and m2 is +127

I have no Idea where to start with this but If it cant happen i can just use two sticks.


It is possible to do with one stick and this post has a few solutions on it already. But if your still having trouble, post what you have already and we will see what we can do.
Logged

Created Libraries:
NPV2 (NewPasswordV2),  TFT_Extension, OneWireKeypad, SerialServo.
Will provide libraries if asked in PM or forum.

Derbyshire, UK
Offline Offline
Newbie
*
Karma: 0
Posts: 5
Hello Everyone!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,

I solved this problem a few months ago with the help of a very clever member of the Arduino community...

Search for this thread:

Differential Steering using a joystick / programming question....

I hope that helps.

Tim
Logged

Phoenix, Arizona USA
Offline Offline
Faraday Member
**
Karma: 39
Posts: 5551
Where's the beer?
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,

I solved this problem a few months ago with the help of a very clever member of the Arduino community...

Search for this thread:

Differential Steering using a joystick / programming question....

I hope that helps.

Tim

Here it is:

http://forum.arduino.cc/index.php?topic=172581.0
Logged

I will not respond to Arduino help PM's from random forum users; if you have such a question, start a new topic thread.

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

Quote
I solved this problem a few months ago with the help of a very clever member of the Arduino community...

Quote
One potentiometer controls the left wheel, and the other controls the right.  There is currently no reverse, although by remapping the pots  to say, -10 to 245 and using an if statement that could easily be handled.

Did you actually provide for reverse?
Logged

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

Phoenix, Arizona USA
Offline Offline
Faraday Member
**
Karma: 39
Posts: 5551
Where's the beer?
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
One potentiometer controls the left wheel, and the other controls the right.  There is currently no reverse, although by remapping the pots  to say, -10 to 245 and using an if statement that could easily be handled.

Did you actually provide for reverse?

I actually never understood what he was saying in that statement, either - my algorithm, IIRC, as written will automagically handle reverse (I think).
Logged

I will not respond to Arduino help PM's from random forum users; if you have such a question, start a new topic thread.

Pages: 1 [2] 3   Go Up
Jump to: