summary
I changed my servos for a more powerful one and cannot get it to work, I believe it is because I can't get the right duty cycle calculation in the code
explanation
I have a robotic arm that I started programming for fun, got everything working but the servos that came with the arm where way too weak, someone recommended this one which sure look more robust, today it arrived so I thought it would be just about replace it, for my surprise it doesn't work at all.
after investigating I think it'S because I didn't set the right duty cycle, I never heard about it before but I tried to calculate it with information I found on internet, but after hours I still couldn't get it to work properly.
sometimes it moves but definitely not to the right angle and it is not consistent, but because I'm new in all of this I don't even know if that is the reason.
I'm unsure if I only need to update the SERVO_MIN_DUTY
or if I must change the hertz when I set up the GPIO PWM, too.
Servos
This is the old servo:
- Operating Speed : 0.17sec / 60 degrees (4.8V no load)
- Operating Speed : 0.13sec / 60 degrees (6.0V no load).
- Stall Torque : 13 kg-cm (180.5 oz-in) at 4.8V;
- Stall Torque : 15 kg-cm (208.3 oz-in) at 6V.
this is the new servo:
- Item: DS3218 20KG Large Torque Digital Servo
- Stall Torque (5V): 19 kg/cm (263.8oz/in)
- Stall Torque (6.8V): 21.5 kg/cm (298.5 oz/in)
- Speed : 0.16 sec/60°(5V) / 0.14 sec/60°(6.8V)
- Operating Voltage: 4.8 ~ 6.8 DC Volts
- Dead brand: 3μs
- Weight: 60 g
- Motor Type: DC Motor Gear
- Type: Copper & Aluminum
- Working frequence: 1520μs / 333Hz
- Size: 40 x 20 x 40.5 mm
- Features:
- High performance digital standard servo
- High-precision metal gears with hard anodizing
- CNC aluminium middle Shell
- Dual ball bearings
The original code (I tried to update it using the data I found around without success,mostly from this guide)
import RPi.GPIO as GPIO
import time
OFFSE_DUTY = 0.5 #define pulse offset of servo
SERVO_MIN_DUTY = 2.5+OFFSE_DUTY #define pulse duty cycle for minimum angle of servo
SERVO_MAX_DUTY = 12.5+OFFSE_DUTY #define pulse duty cycle for maximum angle of servo
servoPin = 12
def map( value, fromLow, fromHigh, toLow, toHigh): # map a value from one range to another range
return (toHigh-toLow)*(value-fromLow) / (fromHigh-fromLow) + toLow
def setup():
global p
GPIO.setmode(GPIO.BOARD) # use PHYSICAL GPIO Numbering
GPIO.setup(servoPin, GPIO.OUT) # Set servoPin to OUTPUT mode
GPIO.output(servoPin, GPIO.LOW) # Make servoPin output LOW level
p = GPIO.PWM(servoPin, 50) # set Frequece to 50Hz
p.start(0) # Set initial Duty Cycle to 0
def servoWrite(angle): # make the servo rotate to specific angle, 0-180
if(angle<0):
angle = 0
elif(angle > 180):
angle = 180
p.ChangeDutyCycle(map(angle,0,180,SERVO_MIN_DUTY,SERVO_MAX_DUTY)) # map the angle to duty cycle and output it
def loop():
while True:
for dc in range(0, 181, 1): # make servo rotate from 0 to 180 deg
servoWrite(dc) # Write dc value to servo
time.sleep(0.001)
time.sleep(0.5)
for dc in range(180, -1, -1): # make servo rotate from 180 to 0 deg
servoWrite(dc)
time.sleep(0.001)
time.sleep(0.5)
def destroy():
p.stop()
GPIO.cleanup()
if __name__ == '__main__': # Program entrance
print ('Program is starting...')
setup()
try:
loop()
except KeyboardInterrupt: # Press ctrl-c to end the program.
destroy()
So what exactly do I need from there to know exactly how to update the code for any servo?
The item description says 0.16 for 60° so I expected to be able to get it with a rule of 3 (for 180° I could do a 0.16 x 180 / 60 = 0.48s, but that result seems to high for my little understanding).