How to controll a servo with 5 wires?

Hi.

I have two servos I want to test if I can controll with my arduino uno and arduino pro. When searching for this, I oly found tutorials for a servo with 3 wires. But mine has 5. It is taken from an old rc car, and I am going to controll the rc car with the arduino. But the problem is, how?

Tree of the wires goes to a variable resistor, and the two others goes to the dc motor. I was thinking to read the resistor value and make the servo stop at that value, but then I have to find out how to do that, and how many ohms for example 180 degreeds is. So is there an easy way to controll a 5 wire servo with an arduino?

I attached a picture of the inside on the servo.

Hi, I think this is a servo that worked with the RC card circuit board and all the servo electronics were on that board.

Basically you have "part" of a modern servo.. You would have to drive the motor with a driver board/shield and handle the position from the potentiometer in Arduino software.

At the price of servos these days, might not be worth it.

But the plus is you'd learn stuff!

So, I will need a controller chip or a shield for it? Isn't there an way to controll some outputs high and low while the analogpin reads a spesific value?

For me it will be worth it if I can do it with the arduino and the servo alone, or with a cheap shield if I must have one.. I want to learn how to controll this :slight_smile:

And thanks for the reply :slight_smile:

At a minimum, you will need some kind of motor driver shield to control the motor direction; you might be OK with an L293-based shield, but you might want to measure the current of the motor when it is stalled first, then get a shield that can handle that current. I doubt, though, that you'll need anything more than either an L293 (1 amp) or L298 (2 amp; 4 amp in bridged mode) based motor driver shield.

This shield would then connect to the motor, to control its direction. You would then hook up the other wires from the potentiometer as a voltage divider (with the wiper pin going to an analog input). Once you have control of the motor, and you are also reading good values from the potentiometer, you have the basics and are ready for the control part of the software. The basic algorithm is:

A. Read potentiometer.
B. Compare reading with set-point (where you want it to be).
C. If reading is greater than the set-point plus some window value (deadband), turn motor in direction that will decrease reading.
D. If reading it less than the set-point minus some window value (deadband), turn the motor in the direction that will increase reading.
E. Goto A

There are more advanced algorithms available (like PID) that work better, but the above should get you going for basic control. I do agree with Terry, though: At the price of servos these days, it isn't really worth it if your goal/need is servo control. However, as he noted, by working with this you -will- gain a very good understanding of how servos work (especially if you implement and understand PID controllers), which might be a far more valuable lesson, as such feedback and control systems are useful for a lot more than just servos.

This I know for certain - I just finished the Udacity CS373 class, and we had to implement a PID controller in Python to control the steering of a (virtual) car around a (virtual) racetrack; you can read my article about my implementation for the homework:

http://www.phoenixgarage.org/show_article/161

:slight_smile:

Hi, thanks for your reply.

You say I need a shield to controll the motor. But I have controlled the motor direction with 4 transistors, and I got some of them here, so that will be cheaper for me than buing a new shield.

But then it is the software part. How can I make the arduino make for example pin 2 high and 3 low to get it to go one way, and 3 high and 2 low to get it go the other way, with a reading as set-point?

Well - if you are familiar enough to build your own h-bridge out of transistors (and you know they will support the current requirements), then a shield isn't necessary.

Just use digitalWrite(): digitalWrite() - Arduino Reference

When you set the pin, it will keep it's status to what it was last set; from that point you can loop and use analogRead() to read the pin your potentiometer is connected to, and take action based on that reading.

I suggest that you make three functions for your motor control - one that stops the motor, one that turns is one direction, and one that turns it the other direction. Then, when you initialize the Arduino, call the "motorStop()" function (which basically will set both pins to LOW). Then, in each of the direction controlling functions, -before- you set the two pins to HIGH and LOW, call the "motorStop()" function again; this way you won't get a "shoot-through" condition on the transistors which might cause them to burn out.

Note that the above kind of functions won't work for PID control; for that, you should make sure that the connections are to PWM pins, and that you pass in to the direction control functions a parameter to indicate speed. Just something to keep in mind for any future upgrade of the code.

Hi.

I guess I need four functions. Right, left, middle and stop. I need the middle to drive the rc car straigt forward. But ofcorse, I can start with three.

A function can be like this, right?

void left() {
digitalWrite(10, HIGH);
digitalWrite(9, LOW);
}

The only problem here is that I have to get pin 10 high untill the value from the potmeter is the same as the set point for the function left. But how can I add that, and if the motor has to go the other way, how to change 9 to high instead? I dont remeber how many pins I needed for those 4 transistors right now..

No - you really only need three for a simple windowing servo control. I'll give you a better pseudo-code implementation in a bit...

Yes - but to avoid shoot-through, you should always set the LOW then the HIGH; ideally, you set both LOW first.

Well - you only need to set one pair of the transistors HIGH and the other pair LOW - so two pins (and if you are having this question, yet you somehow built an h-bridge using transistors, I sincerely have to question your capability to handle the task as a whole; I mean, if you are building discrete component h-bridges - you should -know- how many pins you need for any configuration).

Ok - pseudo-code time. Remember I posted this as the algorithm:

A. Read potentiometer.
B. Compare reading with set-point (where you want it to be).
C. If reading is greater than the set-point plus some window value (deadband), turn motor in direction that will decrease reading.
D. If reading it less than the set-point minus some window value (deadband), turn the motor in the direction that will increase reading.
E. Goto A

Ok - here is the Arduino implementation of it (note: I have coded this "blind" and I am -not- claiming this code compiles or even works properly, but it should give you an idea of what is going on):

int motorPinA = 9; // should be whatever you need them to be
int motorPinB = 10;

int potPin = 0;

int dbWindow = 32; // deadband of 32 units on either side of "setPoint"

void motorStop() {
  digitalWrite(motorPinA, LOW);
  digitalWrite(motorPinB, LOW);

  delay(100); // wait for motor to stop; may not be needed
}

void motorCCW() {
  motorStop();

  digitalWrite(motorPinA, LOW);
  digitalWrite(motorPinB, HIGH);
}

void motorCW() {
  motorStop();

  digitalWrite(motorPinB, LOW);
  digitalWrite(motorPinA, HIGH);
}

int readPot() {
  return analogRead(potPin);
}

void positionServo(int setPoint) {
  int curPoint = readPot();

  if (curPoint > setPoint + dbWindow) {
    motorCCW();
  }

  if (curPoint < setPoint - dbWindow) {
    motorCW();
  }
}

void setup() {
  Serial.begin(9600);

  pinMode(motorPinA, OUTPUT);
  pinMode(motorPinB, OUTPUT);

  motorStop();
}

void loop() {
  // somewhere in here we get the position value for
  // the servo, but for now, we'll just fake it
  int setPoint = 512; // "center" value for the servo

  positionServo(setPoint);
}

Something to keep in mind about the above code is that it is constantly polling the analog input for the servo position - so if the position is shifted by an outside force (and the value falls outside the deadband) then it will shift back properly, like a servo should (that is, it will attempt to "hold" a position).

You can increase or decrease the deadband depending on the accuracy of the potentiometer, the needed degree of precision for positioning, and the speed of the movement - just don't decrease it too much, or the servo will constantly hunt (or rotate to the end-stops and mechanically fail or something). If you find you can't make it accurate enough with this system, then it might be rotating too fast or something, and you'll need to implement a PID controller or something similar to allow you to accelerate and decelerate the motor as it nears the set position.

There are likely better ways to implement this code, but what is there shows the basics.

Hi, sorry for the late reply..

I did not remember how many pins needed at that time. I have built 4 h-brigdes since my last post, and used 4 pins to controll a dc motor.

The code you gave me did not work for the servo. I do not know why, yet. I will try to make a new code, but the readings from analog pin, how to do that? I have not used the analog pins before..