Shop OBEX P1 Docs P2 Docs Learn Events
Please help - controling servos with Potentiometer and BS2 - Servos are shaking — Parallax Forums

Please help - controling servos with Potentiometer and BS2 - Servos are shaking

MrosMros Posts: 3
edited 2009-02-27 15:03 in BASIC Stamp
Good evening Gentleman,

I am a student seeking help in the following issue.

I am using a parallax BOE board with a BS2 controller.

I am attempting to run (4) standard servos. They are put together in the Lynxmotion ALD5 robotics arm.

The way I wish to use / run the servos is with potentiometers (one potentiometer per servo) since my goal is that when I move a potentiometer a servo moves and stays in place.

For this I am using the “RCTIME” command. The set up I have is very similar to the one used in pg. 207 -208 of the “robotics with the Boe-Bot” manual, but in lieu of connecting a light sensor I am basically connecting / considering the center pin of the pot as the ground and the two outer pins are being used as inputs to control the pulse. I am using .01uf capacitors and 220 ohm resistors, just like the book says.

My problem is the following, if I run a single servo or basically, create the code for a single servo, it runs perfect. If I use the code for more than 1 servo, the whole assembly shakes (the servos jitter), and does not respond to me turning the potentiometers unless I help it move. I thought first it was a power issue, (too little power when using 4AA batteries) but I am now using a regulated power supply to run the electronics, I have tried supplying more amps to suffice the demand and it helps since it allows for the servos to move by themselves rather than with my assistance, but it does NOT stop the shaking.

The code I used is below.

Can you please help me determine what the issue could be? Perhaps my code needs work.

I thank you for any help you can assist me with.

Code:

'
[noparse][[/noparse] Title and explanation of project ]

'Robotics with the Boe Bot Project # 1 - Group 1.bs2
'This program will be designed to make the Boe Bot Board from Parallax,
'control the AL5D Robotic Arm Kit from Lynxmotion. The purpose of this
'project is to analyze / design a "3 - DOF Master - Slave system Robot"



' {$STAMP BS2} 'Target device = BASIC Stamp 2
' {$PBASIC 2.5} 'Language = PBASIC 2.5

'
[noparse][[/noparse] Input / Output Pin Definitions ]

'Controls for the Lynxmotion ALD5 Robotic Arm Kit - Base


Base_Rotate_Servo PIN 15 'This indicates that the Servo
'motor that rotates the base is
'being comanded by Pin # 15.

Base_Rotate_Potvalue_CW PIN 1 'This indicates that the
'Potentiometer value to turn
'the base Clock Wise is being
'evaluated by Pin # 1.

Base_Rotate_Potvalue_CCW PIN 2 'This indicates that the
'Potentiometer value to turn the
'base Counter - Clock Wise is being
'evaluated by Pin # 2.


'Controls for the Lynxmotion ALD5 Robotic Arm Kit - Shoulder


Shoulder_Servo PIN 14 'This indicates that the Servo
'motor that controls the shoulder is
'being comanded by Pin # 14.

Shoulder_Rotate_Potvalue_CW PIN 3 'This indicates that the
'Potentiometer value to turn
'the shoulder Clock Wise is being
'evaluated by Pin # 3.

Shoulder_Rotate_Potvalue_CCW PIN 4 'This indicates that the
'Potentiometer value to turn the
'soulder Counter - Clock Wise is being
'evaluated by Pin # 4.


'Controls for the Lynxmotion ALD5 Robotic Arm Kit - Elbow


Elbow_Servo PIN 13 'This indicates that the Servo
'motor that controls the elbow is
'being comanded by Pin # 13.

Elbow_Rotate_Potvalue_CW PIN 5 'This indicates that the
'Potentiometer value to turn
'the elbow Clock Wise is being
'evaluated by Pin # 5.

Elbow_Rotate_Potvalue_CCW PIN 6 'This indicates that the
'Potentiometer value to turn the
'elbow Counter - Clock Wise is being
'evaluated by Pin # 6.


'Controls for the Lynxmotion ALD5 Robotic Arm Kit - Wrist

Wrist_Servo PIN 12 'This indicates that the Servo
'motor that controls the wrist is
'being comanded by Pin # 12.

Wrist_Rotate_Potvalue_CW PIN 7 'This indicates that the
'Potentiometer value to turn
'the wrist Clock Wise is being
'evaluated by Pin # 7.

Wrist_Rotate_Potvalue_CCW PIN 8 'This indicates that the
'Potentiometer value to turn the
'wrist Counter - Clock Wise is being
'evaluated by Pin # 8.


'Controls for the Lynxmotion ALD5 Robotic Arm Kit - Wrist_Rotate^2


Wrist_Rotate_Servo PIN 11 'This indicates that the Servo
'motor that controls the wrist rotation
'is being comanded by Pin # 11.

Wrist_Rotate2_Potvalue_CW PIN 9 'This indicates that the
'Potentiometer value to turn
'the wrist^2 Clock Wise is being
'evaluated by Pin # 9.

Wrist_Rotate2_Potvalue_CCW PIN 10 'This indicates that the
'Potentiometer value to turn the
'wrist^2 Counter - Clock Wise is being
'evaluated by Pin # 10.


'
[noparse][[/noparse] Values that will be used as Constants ]


Scale_Base CON $0068 'This constant will allow the
'command "RCTIME" to be scaled
'to the values 0 - 250.

Scale_Shoulder CON $0068 'This constant will allow the
'command "RCTIME" to be scaled
'to the values 0 - 250.

Scale_Elbow CON $0068 'This constant will allow the
'command "RCTIME" to be scaled
'to the values 0 - 250.

Scale_Wrist CON $0068 'This constant will allow the
'command "RCTIME" to be scaled
'to the values 0 - 250.

Scale_Wrist_Rotate CON $0068 'This constant will allow the
'command "RCTIME" to be scaled
'to the values 0 - 250.


'
[noparse][[/noparse] Declaring the different variables ]


Base_Rotate_Right VAR Word 'This declares the variable
'Base_Rotate_Right as a word
'which holds the max value
'of 0 to 65535.

Base_Rotate_Left VAR Word 'This declares the variable
'Base_Rotate_Left as a word
'which holds the max value
'of 0 to 65535.

Base_Servo_Position VAR Word 'This declares the variable
'Base_Servo_Position as a word
'which holds the max value
'of 0 to 65535.

Shoulder_Rotate_Right VAR Word 'This declares the variable
'Shoulder_Rotate_Right as a word
'which holds the max value
'of 0 to 65535.

Shoulder_Rotate_Left VAR Word 'This declares the variable
'Shoulder_Rotate_Left as a word
'which holds the max value
'of 0 to 65535.

Shoulder_Servo_Position VAR Word 'This declares the variable
'Shoulder_Servo_Position as a word
'which holds the max value
'of 0 to 65535.

Elbow_Rotate_Right VAR Word 'This declares the variable
'Elbow_Rotate_Right as a word
'which holds the max value
'of 0 to 65535.

Elbow_Rotate_Left VAR Word 'This declares the variable
'Elbow_Rotate_Left as a word
'which holds the max value
'of 0 to 65535.

Elbow_Servo_Position VAR Word 'This declares the variable
'Elbow_Servo_Position as a word
'which holds the max value
'of 0 to 65535.

Wrist_Rotate_Right VAR Word 'This declares the variable
'Wrist_Rotate_Right as a word
'which holds the max value
'of 0 to 65535.

Wrist_Rotate_Left VAR Word 'This declares the variable
'Wrist_Rotate_Left as a word
'which holds the max value
'of 0 to 65535.

Wrist_Servo_Position VAR Word 'This declares the variable
'Wrist_Servo_Position as a word
'which holds the max value
'of 0 to 65535.

'Wrist2_Rotate_Right VAR Word 'This declares the variable
'Wrist^2_Rotate_Right as a word
'which holds the max value
'of 0 to 65535.

'Wrist2_Rotate_Left VAR Word 'This declares the variable
'Wrist^2_Rotate_Left as a word
'which holds the max value
'of 0 to 65535.

'Wrist2_Servo_Position VAR Word 'This declares the variable
'Wrist^2_Servo_Position as a word
'which holds the max value
'of 0 to 65535.


'
[noparse][[/noparse] Program Initialization ]


FREQOUT 0, 500, 3200
PAUSE 200


'
[noparse][[/noparse] Main Program Code ]

Main:

'This part of the program code controls the base of the ALD5 Arm.

HIGH Base_Rotate_Potvalue_CW 'PotCW ' discharge caps
PAUSE 1/5

RCTIME Base_Rotate_Potvalue_CW, 1, Base_Rotate_Right 'rcRt ' read clockwise

HIGH Base_Rotate_Potvalue_CCW 'PotCCW ' discharge caps
PAUSE 1/5

RCTIME Base_Rotate_Potvalue_CCW, 1, Base_Rotate_Left 'rcLf ' read counter-clockwise


Base_Rotate_Right = (Base_Rotate_Right */ Scale_Base) MAX 250 * 2 ' scale RCTIME to 0-250

Base_Rotate_Left = (Base_Rotate_Left */ Scale_Base) MAX 250 * 2 '3/2

Base_Servo_Position = Base_Rotate_Right - Base_Rotate_Left ' calculate position (-250 to 250)


GOSUB Rotate_Base

'This part of the program code controls the Shoulder of the ALD5 Arm.


HIGH Shoulder_Rotate_Potvalue_CW 'PotCW ' discharge caps
PAUSE 1/5

RCTIME Shoulder_Rotate_Potvalue_CW, 1, Shoulder_Rotate_Right 'rcRt ' read clockwise

HIGH Shoulder_Rotate_Potvalue_CCW 'PotCCW ' discharge caps
PAUSE 1/5

RCTIME Shoulder_Rotate_Potvalue_CCW, 1, Shoulder_Rotate_Left 'rcLf ' read counter-clockwise


Shoulder_Rotate_Right = (Shoulder_Rotate_Right */ Scale_Shoulder) MAX 250 '* 2 ' scale RCTIME to 0-250

Shoulder_Rotate_Left = (Shoulder_Rotate_Left */ Scale_Shoulder) MAX 250 * 3/2

Shoulder_Servo_Position = Shoulder_Rotate_Right - shoulder_Rotate_Left ' calculate position (-250 to 250)


GOSUB Rotate_Shoulder

'This part of the program code controls the Elbow of the ALD5 Arm.


HIGH Elbow_Rotate_Potvalue_CW 'PotCW ' discharge caps
PAUSE 1/5

RCTIME Elbow_Rotate_Potvalue_CW, 1, Elbow_Rotate_Right 'rcRt ' read clockwise

HIGH Elbow_Rotate_Potvalue_CCW 'PotCCW ' discharge caps
PAUSE 1/5

RCTIME Elbow_Rotate_Potvalue_CCW, 1, Elbow_Rotate_Left 'rcLf ' read counter-clockwise


Elbow_Rotate_Right = (Elbow_Rotate_Right */ Scale_Elbow) MAX 250 * 2 ' scale RCTIME to 0-250 'I need to fix these values!!! 02-08-09

Elbow_Rotate_Left = (Elbow_Rotate_Left */ Scale_Elbow) MAX 250 * 7/2

Elbow_Servo_Position = Elbow_Rotate_Right - Elbow_Rotate_Left ' calculate position (-250 to 250)


GOSUB Rotate_Elbow

'This part of the program code controls the Wrist of the ALD5 Arm.


HIGH Wrist_Rotate_Potvalue_CW 'PotCW ' discharge caps
PAUSE 1/5

RCTIME Wrist_Rotate_Potvalue_CW, 1, Wrist_Rotate_Right 'rcRt ' read clockwise

HIGH Wrist_Rotate_Potvalue_CCW 'PotCCW ' discharge caps
PAUSE 1/5

RCTIME Wrist_Rotate_Potvalue_CCW, 1, Wrist_Rotate_Left 'rcLf ' read counter-clockwise


Wrist_Rotate_Right = (Wrist_Rotate_Right */ Scale_Wrist) MAX 250 * 13/4'* 2 ' scale RCTIME to 0-250 'I need to fix these values!!! 02-08-09

Wrist_Rotate_Left = (Wrist_Rotate_Left */ Scale_Wrist) MAX 250 * 13/4 'I need to fix these values!!! 02-08-09

Wrist_Servo_Position = Wrist_Rotate_Right - Wrist_Rotate_Left ' calculate position (-250 to 250)


GOSUB Rotate_Wrist


GOTO Main


'
[noparse][[/noparse] Subroutines - Rotate Base ]

Rotate_Base:

PULSOUT Base_Rotate_Servo, (750 + Base_Servo_Position) ' move the servo

PAUSE 20

RETURN

'
[noparse][[/noparse] Subroutines - Rotate Shoulder ]

Rotate_Shoulder:

PULSOUT Shoulder_Servo, (750 + Shoulder_Servo_Position) ' move the servo

PAUSE 20

RETURN



'
[noparse][[/noparse] Subroutines - Rotate Elbow ]

Rotate_Elbow:

PULSOUT Elbow_Servo, (750 + Elbow_Servo_Position) ' move the servo

PAUSE 20

RETURN



'
[noparse][[/noparse] Subroutines - Rotate Wrist ]

Rotate_Wrist:

PULSOUT Wrist_Servo, (750 + Wrist_Servo_Position) ' move the servo

PAUSE 20

RETURN

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2009-02-27 04:29
    Servos have to get a control pulse about every 20ms or they shut down until the next control pulse comes along. That's what's causing the shaking. For each PULSOUT statement, you have a PAUSE of 20ms. If you activate each servo in turn, that's 80ms at least between control pulses for a particular servo. In addition, you're reading the pot values and doing some computation, all of which takes time. Take out the PAUSE 20 statements and put in one PAUSE statement just before the GOTO Main statement. Try 10ms for the time. You may need to adjust that for smoothest action.

    Check out Emesystems' website (www.emesystems.com) for a lot of information on using the Stamps including a discussion of execution time for various statements and operations.
  • MrosMros Posts: 3
    edited 2009-02-27 05:19
    Mike,

    Thank you..

    I will try that ASAP.
  • Beau SchwabeBeau Schwabe Posts: 6,559
    edited 2009-02-27 05:44
    Mros,

    Your code reminds me of the days when I was involved in robotic prosthetic research and development...

    Based on your comment, that "if I run a single servo or basically, create the code for a single servo, it runs perfect." ... see if my attached code modification works out better for you, it basically updates·ALL servos,·but then uses the delay of the program under the RCTIME and the·PAUSEs' you have in there to take place of the required 20 ms PAUSE command.

    I have a feeling that the RCTIME is going ot get you... if so, you will need to adjust your·resistor and capacitor values to produce your values in·a shorter amount of time, since this will add to the needed 20 ms delay.· You might·also consider·using· a·multi-channel external ADC and resort to reading values from that rather than using the·RCTIME command all together.

    4 Channel ADC: http://www.parallax.com/Store/Microcontrollers/BASICStampModules/tabid/134/txtSearch/ADC/List/1/ProductID/240/Default.aspx?SortField=ProductName%2cProductName



    Edit - Try version 2 as well, it has more of an interleave as far as updating the servo's







    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Beau Schwabe

    IC Layout Engineer
    Parallax, Inc.

    Post Edited (Beau Schwabe (Parallax)) : 2/27/2009 8:08:35 AM GMT
  • MrosMros Posts: 3
    edited 2009-02-27 15:03
    Beau,

    Thank you for your help.

    I will try the code ASAP.
Sign In or Register to comment.