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
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.
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
- 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).