Continuous rotation servos and joystick

Hey guys, I’m new to the forum and electronics in general. I’m working on a class project and need to make a small XY plotter for a “drawing machine”. I have 2 MG995 servos that were modified for continuous rotation that i would use for each axis (UP/DOWN + LEFT/RIGHT). I want to be able to control them with a joystick. I have found lots of code such as this one :

#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 servoVal;           // variable to read the value from the analog pin

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)
   servoVal = analogRead(joyH);          
   servoVal = map(servoVal, 0, 1023, 0, 180);     // scale it to use it with the servo (result  between 0 and 180)

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

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

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

   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 ("----------------");
}

It sort of works, but the servos keep rotating without any input form the joystick. I know it is because the servos no longer have a potentiometer to tell them their position and they don’t know their neutral position. I’ve done research on the forum there are lots of related topics but I never understand what I need to change. I’ve read that i need to use the writeMicroseconds function, but I frankly have no idea how. Would anyone be kind enough to explain what I need to change to get this to work ? Thank you so much !

Welcome to the Forum. Please read the two posts

How to use this forum - please read.
and
Read this before posting a programming question …

at the top of this Forum on guidelines for posting here, especially the use of code tags which make the code look

like this

when posting source code files.

If you have already posted without using code tags, open your message and select “modify” from the pull down menu labelled, “More”, at the lower left corner of the message. Highlight your code by selecting it (it turns blue), and then click on the “</>” icon at the upper left hand corner. Click on the “Save” button.

aarg:
Welcome to the Forum. Please read the two posts

How to use this forum - please read.
and
Read this before posting a programming question …

at the top of this Forum on guidelines for posting here, especially the use of code tags which make the code look

like this

when posting source code files.

If you have already posted without using code tags, open your message and select “modify” from the pull down menu labelled, “More”, at the lower left corner of the message. Highlight your code by selecting it (it turns blue), and then click on the “</>” icon at the upper left hand corner. Click on the “Save” button.

Sorry, I’ve edited my post.

I am confused. The code shows that the servos are to be positioned, and this is what I would expect of an XY plotter where the plotter "arms" are connected directly to the servos.

However, there was a description of "...2 MG995 servos that were modified for continuous rotation..." which means that the position CANNOT be determined, only the rotational speed can be controlled. How can this work?

Furthermore, the servos are controlled by a pulse train, where the width of the pulses determines the speed. A 50% pulse width would be stopped, but 50% to the Arduino may not be 50% to the servos. This difference has to be calibrated out, but why bother? These are the wrong servos I think.

When modifying servos for continuous rotation and the original pot is still in the servo, the pot needs to be adjusted such that the servo is stopped when being sent a 1500us command. The speed/direction control of most DIY continuous rotation servos is ~200us range, best used in the 1400us to 1600us range with 1500us being stopped. Below is some servo test code that might be of use testing your servos.

// zoomkat 3-28-14 serial servo incremental test code
// using serial monitor type a character (s to increase or a 
// to decrease) and enter to change servo position 
// (two hands required, one for letter entry and one for enter key)
// use strings like 90x or 1500x for new servo position 
// for IDE 1.0.5 and later
// Powering a servo from the arduino usually *DOES NOT WORK*.

#include<Servo.h>
String readString;
Servo myservo;
int pos=1500; //~neutral value for continous rotation servo
//int pos=90;

void setup()
{
  myservo.attach(7, 400, 2600); //servo control pin, and range if desired
  Serial.begin(9600);
  Serial.println("serial servo incremental test code");
  Serial.println("type a character (s to increase or a to decrease)");
  Serial.println("and enter to change servo position");
  Serial.println("use strings like 90x or 1500x for new servo position");
  Serial.println();
}

void loop()
{
  while (Serial.available()) {
    char c = Serial.read();  //gets one byte from serial buffer
    readString += c; //makes the string readString
    delay(2);  //slow looping to allow buffer to fill with next character
  }
  if (readString.length() >0) {
    if(readString.indexOf('x') >0) { 
      pos = readString.toInt();
    }

    if(readString =="a"){
      (pos=pos-1); //use larger numbers for larger increments
      if(pos<0) (pos=0); //prevent negative number
    }
    if (readString =="s"){
      (pos=pos+1);
    }

    if(pos >= 400) //determine servo write method
    {
      Serial.println(pos);
      myservo.writeMicroseconds(pos);
    }
    else
    {   
      Serial.println(pos);
      myservo.write(pos); 
    }
  }
  readString=""; //empty for next input
}

BadAtArduino:
but the servos keep rotating without any input form the joystick.

You need to describe very clearly what you want to happen - it will probably help you as much as us.

Assuming the joysticks self centre it would be simple to use that position to signal the servos to stop moving and the further you move the joystick from centre the faster the motor moves.

It would be a good idea to program in a deadband so that the joystick has to move a lttle bit from the centre before the servos start moving.

…R

Using continuous rotation "servos" for an XY plotter seems doomed to failure to me. Surely what you need is for the XY positions to be proportional to the joystick position whereas as the "servos" you are using mean that the speed of movement will be proportional to the joystick position and no amount of scaling/mapping/etc is going to change that.

If you want to achieve a controlled X,Y position, you will need some form of positional feedback. This could be something linear on the axis, or something rotary on the motor shaft. I suggest the latter is easier. Use a rotary encoder, e.g. https://www.sparkfun.com/products/9117 or make something like this http://letsmakerobots.com/blog/aniss1001/homemade-wheel-encoder count the pulses and you know the x,y position. You can move the motor at constant speed until demanded position = actual position, or you can get flash and use a PID control if you want extra points

..or if you can live with open-loop control i.e movement comanded by the joystick, but you are not worried about repeatable x,y positioning, they you would be better of using a stepper motor rather than the servo

Ho55:
If you want to achieve a controlled X,Y position, you will need some form of positional feedback.

I don’t think you would if you just want to make something like an Etch-a-Sketch.

…R