I am trying to control the angle of a servo motor via an Android app that I built, installed on my phone. My phone sends the angle data (i.e. -90 to +90 degrees) to the raspberry pi via a TCP socket. I have identified my desired duty cycles i.e. 50 to 80. Using linear graph theory I derived an equation which takes angle as input and gives the desired duty cycle.

The problem I am facing is that the servo turns on one side and stays there. Although the print statement in th while loop shows that the DutyCycle variable is changing as I rotate my mobile. I have even tried to add a little time delay in the loop, still the problem persists

The code below demonstrates my methodology:

import RPi.GPIO as GPIO
import socket
import os
import re

## TODO: Port network information on background thread.

class CarController:

    @param port: port for connectivity
    def __init__(self,port):
        ## Intialize parameters of communication.
        self.command= os.popen('ifconfig wlp6s0 | grep "inet\ addr" | cut -d: -f2 | cut -d" " -f1') #Works for WiFi only.
        self.TCP_IP = self.command.read()[0:-1]
        self.TCP_PORT = port
        self.BUFFER_SIZE = 8
        self.pattern = re.compile('-*[0-9]+\|[0-9]+$')

        ##Intialize the connection
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.sock.bind((self.TCP_IP, self.TCP_PORT))
        print 'Connect to: %s:%d'%(self.TCP_IP,self.TCP_PORT)
        #Blocking call.
        self.conn, self.addr = self.sock.accept()
        print 'Connected with: ',self.addr

    @return speed,angle
    def getParameters(self):
        data = self.conn.recv(self.BUFFER_SIZE)
        if(data == 'stop\n'):
            return -1,-1
        if(self.pattern.match(data) != None):
            return int(angle),int(speed);
            print 'Frame dropped'
            return self.getParameters()
controller = CarController(14002)
speed,angle,dc = 0,0,0
#print "The angle is: %d and speed is: %d"%(angle,speed)

#----------------For driving the car-----------------------
servo= GPIO.PWM(13,50)

while 1:
    angle,speed = controller.getParameters()
    print "The angle is: %d ,speed is: %d and DutyCycle: %d"%(angle,speed,dc)

1 Answer 1


I am not going to look in detail.

I will point out that servos are controlled by pulse widths, the duty cycle is irrelevant.

Most servos require a pulse width in the range 1000-2000 µs although some like the 9g hobby servos can work in the range 500-2500 µs.

Commanding a servo outside the pulse width range it is designed for may damage the servo beyond repair.

You need to either determine the pulse width range empirically or use the relatively safe zone of 1000-2000 µs.

Mark space PWM at 50 Hz has pulse slots 20000 µs long.

1000 = 5% (1000 µs pulse needs a duty cycle of 1000/20000 * 100)
1500 = 7.5%
2000 = 10%

Software timed PWM is not the best idea for servos, the jitter when the system is more than very lightly loaded, or more than one servo is being used, will cause the servos to twitch, get very warm, and shorten their lifespan.

  • I have to control the speed of 2 DC motors and a servo motor. So what do you suggest? Shall in use one hardware pwm for the servo, and software pwm for the DC motors.
    – CR7
    Apr 19, 2018 at 9:54
  • The RPi.GPIO module does not support hardware PWM. Software timed PWM will be fine for motors, the jitter will be masked by inertia. I'd look at one of the modules which generates hardware timed PWM, e.g. servoblaster, RPIO.GPIO, or my pigpio etc. As a matter of interest my pigpio Python module seems to run quite happily using QPython3 on my Android phone.
    – joan
    Apr 19, 2018 at 10:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.