Pages: [1] 2   Go Down
Author Topic: Turning a motor into a servo  (Read 2080 times)
0 Members and 1 Guest are viewing this topic.
Overijse, VL
Offline Offline
Newbie
*
Karma: 0
Posts: 39
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,

I described my problem on Pololu's forum (http://forum.pololu.com/viewtopic.php?f=15&t=3592) but a short summary:

I have 2 brushed DC motors, a dual motor driver (with PWM control), a arduino UNO and 4 linear continuous rotation pots. I thought of making my own servo's cause I wanted a 1-on-1 angular positioning control (for tele-operation). I mean that each motor has a pot on its axis and I control its position with another but identical pot. I thought it would have been easy and just write a simple code where the two pot readouts must reach the same value but the motors where loud and unprecise. Pololu told me to use a PID feedback code for a good result (it would offer me Jrk-like performance - http://www.pololu.com/catalog/product/1392). I know what it is briefly (saw it in class) but they told me the code would be complicated.

I looked around and found some stuff about PID but I can't find my way in it. Does anyone know a code that would give servo-like perfomance with the hardware I have?? It would be very nice and efficient cause I don't want two buy 2 Jrk's if I can get the same with my motor driver and Arduino.

Thanks a lot.
Logged

Australia
Offline Offline
Full Member
***
Karma: 8
Posts: 161
You dont have to touch powerlines for them to kill you, even looking at them for too long will make them angry.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

 I would expect that the noise you are experiencing is PWM hum, the only way to solve this is to make your PWM switch at much higher frequency which i i have NFI how to do on an Arduino. As far as the continuous pots, PID seems to be the way to go here, it will require some complex maths but it should work. A short intro here if u don't quite get it. Basically your motor driver would be told "move motor forward a bit" and would send PWM signal to motor to turn forwards. The controller then looks at the value that the pot changed and compares it to the change in PWM signal it sent. it does some maths here and thinks, if i want to turn it x amount, i change the PWM signal by x*4  (for example) and it does this constantly, adapting for changes in torque etc. this enables much higher amounts of accuracy. As to how to code this, it'd be fun, but quite challenging.
Logged

"Human beings, who are almost unique in having the ability to learn from the experience of others, are also remarkable for their apparent di

0
Offline Offline
Tesla Member
***
Karma: 144
Posts: 9612
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

If you are on a beer budget, you may want to take a diffrent approach for your tele-operation (I assume a cam pan/tilt). You can make a cam pan/tilt platform using large standard hobby servos. If you can live with only +-45 deg. of movement (you might find or make one for a larger range), you can use an inexpensive servo tester like below to control each servo. Bottom are some more expensive cam mounts.

http://www.hobbycity.com/hobbycity/store/uh_viewItem.asp?idProduct=8296
http://www.hobbycity.com/hobbycity/store/uh_viewItem.asp?idProduct=14774



http://www.servocity.com/html/pan_tilt_roll___accessories.html
http://www.servocity.com/html/pt-2100_pan__tilt_system.html
Logged

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

Overijse, VL
Offline Offline
Newbie
*
Karma: 0
Posts: 39
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

@ fliggygeek,
I forgot about the switching frequency of the PWM signal. I have to look it up thanks. But I don't think it is the only reason for the bad servo attitude but I'll have to try it again with a higher frequency. I used the code you can see below and like you can see it is pretty simple. I use the difference of both pot positions for poistioning. The bigger the difference the higher speed I give the motor. But like you say, PID would be much better and it would be a challenge to write. Thanks for explaining the basics. I'll have to think about a clever feedback code. But aren't any standard PID algorithms in circulation?

@ zoomkat,
It is indeed a pan/tilt setup I would like to control with my head (with the help of a headset). Later on I would like to add the roll too but you got to start 'simple'. I don't know why I tried servo's first but I am not sure if servo's can make precise angle reproduction... it follows your pots' movement very well but can you make it move 59,5 degrees if your turn your pot 59,5 degrees?? Is it simpel to setup like the 'Knob' tutorial (http://arduino.cc/en/Tutorial/Knob)? I have to learn more about servo's I guess. I thought of using the hardware I have and it should work with the right software but I must check out the local RC stores for some quality/price ideas. I need more or less a 170° and a 120° movement. Those servo testers are simple useful things its seems. Those large pan/tilt setups use about the same motors that I have I think. Thanks for the links!

/*
  Motor Position Control
  Control a motor's position with two potentiometers.
  */
void setup()
{
  Serial.begin(9600);
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
}
void loop()
{
  int sensorposition = analogRead(0);
  int motorposition = analogRead(1);
  int difference = sensorposition - motorposition;
  Serial.println(difference, DEC);
  if (difference > 0)
  {
    digitalWrite(8, HIGH);
    digitalWrite(9, LOW);
    if (difference > 255)
    { analogWrite(10, 255); }
    else { analogWrite(10, difference); }
  }
  if (difference < 0)  
  {
    digitalWrite(8, LOW);
    digitalWrite(9, HIGH);
    if (abs(difference) < 255)
    { analogWrite(10, abs(difference)); }
    else { analogWrite(10, 255); }
  }
  if (difference == 0)  
  {
    digitalWrite(8, HIGH);
    digitalWrite(9, HIGH);
    analogWrite(10, 0);
  }
}
« Last Edit: February 13, 2011, 02:00:17 pm by Fons1302 » Logged

0
Offline Offline
Tesla Member
***
Karma: 144
Posts: 9612
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
It is indeed a pan/tilt setup I would like to control with my head (with the help of a headset).

This is the part that you will probably find not workable for what you want to do unless you accept some limitations.
Logged

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

Overijse, VL
Offline Offline
Newbie
*
Karma: 0
Posts: 39
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

@ zoomkat: Why would that be? It has to turn 90°left/right and about 60° down/up. It must be fast so it will have to be powered by larger motors. But for a start I can make some limitations!
Logged

0
Offline Offline
Tesla Member
***
Karma: 144
Posts: 9612
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I don't know why I tried servo's first but I am not sure if servo's can make precise angle reproduction... it follows your pots' movement very well but can you make it move 59,5 degrees if your turn your pot 59,5 degrees??

If you are looking for smooth .5 deg control resolution using your head, I doubt it will happen. I made a simple joystick control for my servo based webcam pan/tilt and learned a lot. You could get a pair of plastic safety glasses and attach a laser pointer to see how well you can make the laser dot stay on target. What do you do if you need to move your head without moving the cam? If you manage that, how do you get the cam and head controller back in sync? I'd do some simple proof of concept testing before starting to invest serious $$$.
Logged

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

Australia
Offline Offline
Full Member
***
Karma: 8
Posts: 161
You dont have to touch powerlines for them to kill you, even looking at them for too long will make them angry.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

If you are looking for fast .5 degree resolution control, servos arent what you need, you can find some good sized stepper motors that with a 2-1 gear ratio will give you incredibly fast speed and .5 degree or better resolution. these are what they use for CNC mills so you can be sure they're the best option.
Logged

"Human beings, who are almost unique in having the ability to learn from the experience of others, are also remarkable for their apparent di

Overijse, VL
Offline Offline
Newbie
*
Karma: 0
Posts: 39
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

If you are looking for smooth .5 deg control resolution using your head, I doubt it will happen. I made a simple joystick control for my servo based webcam pan/tilt and learned a lot. You could get a pair of plastic safety glasses and attach a laser pointer to see how well you can make the laser dot stay on target. What do you do if you need to move your head without moving the cam? If you manage that, how do you get the cam and head controller back in sync? I'd do some simple proof of concept testing before starting to invest serious $$$.

I guess reaching 0.5° precision is hard if you got a tight budget and maybe it is too precise too but with stepper motors (like fliggygeek proposes) it must work. Thanks for letting me realize it. The problem if you want to turn your head without the camera's is not an issue with my project. It goes into a larger project where you are stuck into a suit that allows you to control a humanoid from far away  smiley. The person in the suit has video glasses that show both camera's of the robot (giving you 3D sense). Moving your head will give you the feeling of being in the robot's position. I know it is too big for me to start but that is why I just will start with the head control part. And dreaming doesn't hurt!

If you are looking for fast .5 degree resolution control, servos arent what you need, you can find some good sized stepper motors that with a 2-1 gear ratio will give you incredibly fast speed and .5 degree or better resolution. these are what they use for CNC mills so you can be sure they're the best option.

I never stood still with the possibility of using stepper motors because I thought using DC motors was the way to walk. Got to check them out, thanks. But I hope I can use my DC motors for something else or for a proof of concept setup. But I need absolute position sensing so I must still use a pot or make some memory/preset function.
« Last Edit: February 14, 2011, 08:14:15 am by Fons1302 » Logged

SW Scotland
Offline Offline
Edison Member
*
Karma: 17
Posts: 1389
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

To interpret head movement why not use a 3-axis accelerometer chip.  This will give you the required three degrees of rotation.
jack
Logged

Overijse, VL
Offline Offline
Newbie
*
Karma: 0
Posts: 39
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

@ jackrae:

I have a mechanical setup in mind that is quite compact and simple.
I have some problems with using accelerometers:
- I need the orientation (and not the movement) of my head relative to my torso. If I move my whole body (running in all directions) the accelerometer will give values while I keep my head still relative to my torso.
- The accuracy is not great, I would like to have about 1,5° of accuracy. I think it is not the case with acelerometers.
- I need a sensor that detects the horizontal plane and measures the difference with its plane relative to the horizontal. I don't know if accelerometers can do that. Which sensors can measure the deviation from the horizontal plane? I know that an Iphone can sense the horizontal.
- I would like to try mechanical feedback (if you can't move your robot head it should give you the feeling you can't move your head).
- I must convert the accelerometers data into angles. With my mechanical approach I must only copy-paste the absolute position of the encoder to the robot head. OK once you got the code this is not an issue.

Correct me if I'am wrong, judging with falls information is not a good judge.

UPDATE:

When I use PWM signals at 10kHz the motor makes a small noise but doesn't move. I guess 10kHz is too much for my DC motor?? If that is the case my motors are not good for precision positioning (http://www.pololu.com/catalog/product/1107) and I need other ones, perhaps with a larger gearing? Or what else can make precision positioning possible?? The motor driver can handle 20kHz PWM pulses so no problem with that.
« Last Edit: February 14, 2011, 03:20:36 pm by Fons1302 » Logged

Australia
Offline Offline
Full Member
***
Karma: 8
Posts: 161
You dont have to touch powerlines for them to kill you, even looking at them for too long will make them angry.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

http://www.sparkfun.com/products/9238 Stepper Motor
http://www.sparkfun.com/products/10267 Stepper Driver board (does two steppers)

http://translate.google.com/translate?js=n&prev=_t&hl=en&ie=UTF-8&layout=2&eotf=1&sl=auto&tl=en&u=http%3A%2F%2Flusorobotica.com%2Findex.php%2Ftopic%2C106.0.html Tutorial (Sorry its in translated Portuguese)

Whole setup should cost you no more than $60USD, will get you running in no time.
Use the analog inputs for your continuous rotation pots, the serial for the driver board, you'll be all set.
Logged

"Human beings, who are almost unique in having the ability to learn from the experience of others, are also remarkable for their apparent di

Overijse, VL
Offline Offline
Newbie
*
Karma: 0
Posts: 39
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Great links fliggygeek!

I must make a tough decision now. I consider three choices:
- continue with what I have and look for a good working PID code. Not sure if I ever can achieve good results but it is the cheapest choice.
- Use a stepper motor setup (from sparkfun) like fliggygeek proposed. It fits in my budget and looks straightforward and relatively simple to set up and use.
- Get a Jrk motor controller from Pololu. Here I'am sure about the results (seen a video and goes fast and accurate). The price for a single controller is not cheap but maybe I can use the motors I have.

For the first and third option I doubt that my 131:1 motors are good for it. At high PWM frequency it doesn't move at all (just makes noise). My motor driver looks pretty useless for positioning tasks as long as I don't have good code. Maybe I can sell them!

Thanks everybody for the input. My view on the subject has surely improved and I am reconsidering different aspects of my project (which is good cause I went a bit to fast for a beginner).
Logged

Australia
Offline Offline
Full Member
***
Karma: 8
Posts: 161
You dont have to touch powerlines for them to kill you, even looking at them for too long will make them angry.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

"Output loads can be pulse width modulated (PWM-ed) at frequencies up to 20 kHz." got that off your motor driver site, seems the driver IC works, I might suggest getting some cheap DC motors and chuck them on the driver to see if they work at the higher frequency. This will determine if it is an issue with your motors or the driver circuit.
Logged

"Human beings, who are almost unique in having the ability to learn from the experience of others, are also remarkable for their apparent di

Overijse, VL
Offline Offline
Newbie
*
Karma: 0
Posts: 39
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Yes indeed. It can make up to 20kHz PWM signals. But the limitation is the Arduino's PWM frequency limits I think. I don't know how much it is but I use the code below to test the motor at variable pulse width and frequency. Should it work?? Cause I can only get the motor turning (sloooow) at freq= 900 with pusle=850 and freq=1000 with pulse=900 (all in microseconds). If this code is correct its clearly the motor reached its limits (1kHz is too much).

void setup()
{
  Serial.begin(9600);
  pinMode(13, OUTPUT); //motor B output
  pinMode(12, OUTPUT); //motor A output
  pinMode(11, OUTPUT); //PWM output
}

void loop()
{
  int freq = analogRead(0); //change PWM frequency in microseconds (100 = 10kHz)
  int pulse = analogRead(1); //change pulse width in microseconds (1000 = 1kHz)
  freq = map(freq, 0, 1023, 50, 1000);
  pulse = map(pulse, 0, 1023, 50, 1000);
  Serial.print("pulse:"); // use this code so I can check both values during testing
  Serial.print(pulse, DEC);
  Serial.println();
  Serial.print("freq:");
  Serial.print(freq, DEC);
  digitalWrite(13, LOW);
  digitalWrite(12, HIGH);
  digitalWrite(11, HIGH);
  delayMicroseconds(pulse);
  digitalWrite(11, LOW);
  delayMicroseconds(freq-pulse);
}
« Last Edit: February 16, 2011, 02:01:09 pm by Fons1302 » Logged

Pages: [1] 2   Go Up
Jump to: