Stopping a servo before it reaches final position?

I'm having trouble coming up with a solution for a project. Currently, there is a servo-motor actuating a robotic finger. The position of the servo determines the curl in the finger (straight finger -> servo 0 degrees, curved inwards -> servo 100 degrees). On the finger-tip there is a pressure sensor.

Let's say I tell the servo to move to 100 degrees. The finger will curl until the finger-tips comes into contact with an object. When the pressure sensor senses the finger is squeezing above X amount of pressure on the object, the servo will stop at its current position, say 50 degrees.

The problem is I don't know how to make the servo stop at its current position. The servo always goes to the final position I initially set it at. How can this be implemented?

I have thought of 2 solutions, none of which are ideal:

1. When the pressure sensor reaches a threshold, turn off PWM to the servo completely. This should stop the servo from moving further but I don't think it'll hold the position. Also this creates challenges for the next movement command.
2. Have another sensor that measures the current position (degrees) of the servo. When the pressure sensor crosses threshold, take down the current position and update the duty cycle to the current position. Problem with this is that I need to find a way to measure current position.

Can anyone advise on a better way of implementing this?

• Why instead of moving from 0 to 100 degrees you don't move 1 by 1 degree ? Or maybe 5 by 5 degrees if you don't need much precision? When the sensor detects the object you simply exit the loop responsible for increment the angle. Does that makes sense? – Talk2 Jan 15 '16 at 4:58
• Yes, it makes sense but that may affect the responsiveness of the robotic hand. Currently rotating the servo from 0 to 100 degrees takes 400ms under a small load, I'm afraid moving it by 5 degrees from 0 to 100 would only increase the response time. Good point though, I'll give it a try and see. – Splaty Jan 15 '16 at 5:06
• The other option, now that you mentioned timing. If you know the time, for example, 400ms to reach 100 degrees and you sensor identifies the object after 200ms. You might use your first suggestion, turning off the PWM, but turning it on back again with a new calculated value for the servo, in this case 50 degrees. If the servo speed isn't be constant you might need a formula to calculate the new position with better precision, but should be doable. – Talk2 Jan 15 '16 at 5:12
• Yes in theory this sounds like a good idea but it is susceptible to so many problems. For example what if the load causes the servo to be slower, meaning after 200ms it only actually moved 40 degrees, but in the calculations it predicted current position is 50 degrees. Another problem is this method requires time-stamp tracking of all 5 fingers from the moment of instruction to the moment of pressure sensor stop. This requires at least 5 timer modules! – Splaty Jan 15 '16 at 5:26
• Honestly I think best way is to have access to current position of the servo. I'm using HK15298B servos. Wondering if I could open it up and wire up to potentiometer as seen in this tutorial: forums.trossenrobotics.com/tutorials/how-to-diy-128/… – Splaty Jan 15 '16 at 5:28

You don't have to tell the servo "go from 0 to 100 degrees."

You can step it by single degrees in a loop, and read the pressure sensor in the loop.

Like this:

Angle=0 while (pressure<threshold and Angle<100) SetServoPostion(Angle) sleep(4) //wait 4 mSecondsfor servo to move pressure=ReadAnalogInput(pressuresensor) Angle=Angle+1 end while

Alternatively, you have a timer that calls the increment routine every 10mS or whatever, and have it check the pressure before making the next increment.

Along with not crushing what ever your servo is supposed to hold, this method also leaves you with a fairly good idea of exactly where the servo is - you don't need a second sensor for that, and you don't need to hack the servo to read its position potentiometer.

The given delay in the example will still close the gripper in 400mSeconds, so you still have the same responsiveness.

This is a cheap, cheater solution, but here goes.

You need to close the feedback loop, and the only feedback you have is a pressure sensor.

1. Set the position to a place farther than the object you expect to collide with
2. Collide with the object, which activates the pressure sensor and stalls the servo
3. Adjust the target position of the servo downward until you detect a decrease in pressure
4. Adjust your position to get the amount of force you want.

This has some pretty obvious disadvantages compared with using something more advanced than an RC servo, but use what you've got, right?

Now, if you don't mind breaking open the servos, there is a potentiometer in there that should output the relative position for you....

• I'm thinking of opening up the servos and following this guide: forums.trossenrobotics.com/tutorials/how-to-diy-128/…. – Splaty Jan 15 '16 at 5:29
• Or, if you don't mind it taking longer to collide, start increasing the position until you get a collision via the pressure sensor. – Daniel Jan 15 '16 at 5:29
• The solution you initially posted doesn't work very well for my application because having the finger place that much pressure on the object while decreasing position may break the object it's trying to hold. Need to quickly detect and avoid going over pressure threshold. – Splaty Jan 15 '16 at 5:31
• If it's that touchy you need direct control over the motor, not cheap servos. – Daniel Jan 15 '16 at 5:36
• And bonus, if you current control them, you can set a maximum closing torque! – Daniel Jan 15 '16 at 5:36