Go Down

Topic: PWM servo control (Read 795 times) previous topic - next topic

BBX

Aug 25, 2012, 07:55 pm Last Edit: Aug 25, 2012, 08:13 pm by BBX Reason: 1
Hi :),

I have two modified servos, with their pots disconnected (I believe in the middle of their range), so they can rotate continuously.

I read http://arduino.cc/en/Tutorial/SecretsOfArduinoPWM?token=ac6oxpqRdJb0OCJp5SMX, and it seemed to be the right idea, but I don't really understand how PWM works, and I want to make my servo turn one direction, and then the other (the other direction).

Right now I have:
Code: [Select]
for (int temp = 0; temp <= 4000; temp++)
      {
        digitalWrite(lockpin , HIGH);
        delayMicroseconds(100);
        digitalWrite(lockpin , LOW);
        delayMicroseconds(900);
      }
     
      delay(1000);
     
   for (int temp = 0; temp <= 1000; temp++)
      {
        digitalWrite(lockpin , HIGH);
        delayMicroseconds(500);
        digitalWrite(lockpin , LOW);
        delayMicroseconds(500);
      }


This works well for one of my servos, but when I change the pin to my second servo, it only turns one direction.
Can I get any hints as to how I can accomplish using the servos as normal pwm motors (or just how pwm works)? I've spent the last hour playing with the values (always equaling 1000 microseconds in each loop).

Thanks!

retrolefty

First, why are you not using the servo library to control your continuous rotation servos? The servo library will handle the automatic updating of the last valid position command sent to the servo at the frequency that the servo is designed to work at, around 50 updates a second. Your manual method is dealing with the width of the control signal sent to the servo but not refreshing the value at the rate the servo requires.

Use the servo library, you will have much better control.

Lefty

BBX

#2
Aug 25, 2012, 08:25 pm Last Edit: Aug 25, 2012, 08:33 pm by BBX Reason: 1
First, thanks for the reply :D

See, I don't know how x(

I feel absolutely ignorant, but once I say:
Code: [Select]

Servo serv;
serv.attach(9);
serv.write(180);


I don't know how to stop the servo. It just keeps spinning.
I don't want to guess where the value of the pot is and try saying serv.write(90), because I don't want the servo to waste energy by spinning slowly to try to satisfy some fraction of a degree difference.

retrolefty

#3
Aug 25, 2012, 08:38 pm Last Edit: Aug 25, 2012, 08:39 pm by retrolefty Reason: 1

First, thanks for the reply :D

See, I don't know how x(

I feel absolutely ignorant, but once I say:
Code: [Select]

Servo serv
serv.attach(9);
serv.write(180);


I don't know how to stop the servo. It just keeps spinning.
I don't want to guess where the value of the pot is and try saying serv.write(90), because I don't want the servo to waste energy by spinning slowly to try to satisfy some fraction of a degree difference.


For a continous rotation servo:

serv.write(180);  //will turn at max speed in one direction
serv.write(0);     // will turn at max speed in opposite direction
serv.write(90);    // will stop rotation

Your actually better off using the serv.writeMicroseconds(uS) command as then you can use actual microsecond values rather then degrees, so:

servo.writeMicroseconds(1000); //will turn at max speed in one direction
servo.writeMicroseconds(2000); // will turn at max speed in opposite direction
servo.writeMicroseconds(1500); // will stop rotation, you may have to tweek this value a little due to actual
                                          //  servo calibration variation due to the disconnected feedback pot.

Lefty


BBX

#4
Aug 25, 2012, 08:41 pm Last Edit: Aug 25, 2012, 09:09 pm by BBX Reason: 1
Okay, cool, that makes more sense  :)

Again, if the pot on my servo is left at 1503 (or just not exactly on the middle of it's range), and I put in 1500 to stop it, will the servo keep doling out a little bit of power to try reaching the home value?

Edit:
Just did a small test using writeMicroseconds.
The servo seems to stand still at serv.writeMicroseconds(1160);
Anything below and it turns ccw, anything above and it turns cw.

?? I'm pretty sure I took the pot and turned it each way to find where the limits were, and then left it in the middle. That number seems pretty far off x.x
/edit

Another edit:
I read somewhere about unsoldering the pot and bridging a connection with a resistor, but I can't seem to find any more details than that x.x

retrolefty


Okay, cool, that makes more sense  :)

Again, if the pot on my servo is left at 1503 (or just not exactly on the middle of it's range), and I put in 1500 to stop it, will the servo keep doling out a little bit of power to try reaching the home value?

Edit:
Just did a small test using writeMicroseconds.
The servo seems to stand still at serv.writeMicroseconds(1160);
Anything below and it turns ccw, anything above and it turns cw.

Well that just means you found the null point to be 1160 for your specific servo.

?? I'm pretty sure I took the pot and turned it each way to find where the limits were, and then left it in the middle. That number seems pretty far off x.x

Another method is to just send a 1500usec command and then just adjust the pot until the motor stops.

/edit

Another edit:
I read somewhere about unsoldering the pot and bridging a connection with a resistor, but I can't seem to find any more details than that x.x

It normally takes two resistors of equal value that total the same resistance when wired in series as the pot has from it's two end terminals. Then just wire in the two series resistors to replace the pot with the junction of the two resistors becoming the 'wiper' connect that the pot used. Really no need to do this, just adjust the pot for a 'centering' value of 1500usecs and you should be good to go.

Lefty



BBX

Lefty, your suggestion to manually tweak the pots worked brilliantly!
Thank you for all of your help!

retrolefty

Glad it worked out for you. Enjoy your projects.

Lefty

Go Up