GPIO Servo

Active 2 months ago
Viewed 1k times

iam new to raspberry pi and i got an error while a running servo motor in my object detection script i need to run the servo whenever my if condition is true so the same pin run multiple times if condition satisfies i have done giving servoPIN = 22 GPIO.setmode(GPIO.BCM) GPIO.setup(servoPIN, GPIO.OUT) out of the for loop but doesn’t work

Here is the part of the code all import functions are given on top of code(full script :https://github.com/aswinr22/waste-model/blob/master/picamera1.py)

for i in range (classes.size):

    if(classes[0][i] == 2 and scores[0][i]>0.5):

      servoPIN = 22
      GPIO.setup(servoPIN, GPIO.OUT)
      p = GPIO.PWM(servoPIN, 50)  #this line shows the error
      p.start(2.5) # Initialization

      except KeyboardInterrupt:
          #print ("exception")


output:(motor turns on and immediately showing below error)

Traceback (most recent call last):
  File "Object_detection_picamera.py", line 150, in <module>
    p = GPIO.PWM(servoPIN, 50) # GPIO 17 for PWM with 50Hz
RuntimeError: A PWM object already exists for this GPIO channel

I dont know why this happening please help me

share  edit  follow  close  flag
  • Can I cut irrelevant details to make it as simple as possible, as below? count = 0; while count < 4: { keep positiong servo; sleep 20 mS;}; count = count + 1; – tlfong01 May 12 ’19 at 1:28    
  • where should i use this and how its work – rahraj May 12 ’19 at 4:30
  • Let me see. I am a servo newbie, but Rpi python ninja. You are on the other side of the mirror, a servo ninja, Rpi newbie. Perhaps we can learn together to fix the problem. Now watch my answer. 🙂 – tlfong01 May 12 ’19 at 6:03   

2 Answers



For loop to move servo BCM mode GPIO pin #22 does not work. Why?

Short Answer

Well, I think you are using the wrong pin. BCM GPIO Pin #22 cannot do PWM. See the chart in the long answer below.

Long Answer

I suggest to first write the following little test function.

 def sequentialMoveServo(positionList)
    for position in positionList
       if (position > 0) AND (position < 180)

Then we can the function like below:

sequentialMoveServo([+30, +45, -20, +180, +230])

The servo should move sequentially to the positions as below:

30, 45, and 150 degrees, skipping -20 and +230 degrees

Servo research notes

I read the tutorial “Raspberry Pi Servo Motor Control” and find everything OK. The tutorial uses the TowerPro MG996R servo. I remember I also used the same servo a couple of years ago, using Arduino. I am going to search my junk box to find one.

I luckily found one MG996R. I then skimmed the datasheet and find it OK. I moved to tutorials by SparkFun, SourceForge, and Electronic Wing, and found them good. The AdaFruit’s tutorials as usual are for Arduino guys. So I skipped Lady Ada, …

I found ElectronicWing’s picture on PWM pins assignment very good. So I borrowed them and pasted here.

servo picture

I found Rpi ahs 4 PWM pins. I decided to use Pin 18 to test the water. Below is the hardware setup.

servo motor hardware setup

Now I have debugged a python program to do the following.

  1. Set GPIO pin 18 high for 2 seconds, to switch on Blue LED to full brightness.
  2. Set the same GPIO pin 18 to output PWM of 1kHz, 50% duty cycle, to switch on/off Blue LED to result half brightness.
# Servo_test32 tlfong01 2019may12hkt1506 ***
# Raspbian stretch 2019apr08, Python 3.5.3

import RPi.GPIO as GPIO
from time import sleep

# *** GPIO Housekeeping Functions ***

def setupGpio():

def cleanupGpio():

# *** GPIO Input/Output Mode Setup and High/Low Level Output ***

def setGpioPinLowLevel(gpioPinNum):
    lowLevel = 0
    GPIO.output(gpioPinNum, lowLevel)

def setGpioPinHighLevel(gpioPinNum):
    highLevel = 1
    GPIO.output(gpioPinNum, highLevel)

def setGpioPinOutputMode(gpioPinNum):
    GPIO.setup(gpioPinNum, GPIO.OUT)

# *** GPIO PWM Mode Setup and PWM Output ***

def setGpioPinPwmMode(gpioPinNum, frequency):
    pwmPinObject = GPIO.PWM(gpioPinNum, frequency)
    return pwmPinObject

def pwmPinChangeFrequency(pwmPinObject, frequency):

def pwmPinChangeDutyCycle(pwmPinObject, dutyCycle):

def pwmPinStart(pwmPinObject):
    initDutyCycle = 50

def pwmPinStop(pwmPinObject):

# *** Test Functions ***

def setHighLevelGpioPin18():
    print('  Begin setHighLevelGpioPin18, ...')
    gpioPinNum   = 18
    sleepSeconds =  2    
    print('  End setHighLevelGpioPin18, ...\r\n')

def setPwmModeGpioPin18():
    print('  Begin setPwmModeGpioPin18, ...')
    gpioPinNum   =   18
    sleepSeconds =   10
    frequency    = 1000
    dutyCycle    =   50

    pwmPinObject = setGpioPinPwmMode(gpioPinNum, frequency)
    pwmPinChangeFrequency(pwmPinObject, frequency)
    pwmPinChangeDutyCycle(pwmPinObject, dutyCycle)

    print('  End   setPwmModeGpioPin18, ...\r\n')


# *** Main ***

print('Begin testing, ...\r\n')
print('End   testing.')

# *** End of program ***

Sample Output - 2019may12hkt1319
 RESTART: /home/pi/Python Programs/Python_Programs/test1198/servo_test31_2019may1201.py 
Begin testing, ...

  Begin setHighLevelGpioPin18, ...
  End setHighLevelGpioPin18, ...

  Begin setPwmModeGpioPin18, ...
  End   setPwmModeGpioPin18, ...

End   testing.



The blue LED switch on full and half bright. So far so good. I am going to use a scope to check out if the PWM waveform is clean and sharp.

Ah, Sunday afternoon tea time, see you later, … 🙂

Now I am checking out the timing requirements of the servo. servo timing

Now I know that the timing for servo to move to middle position is 50Hz, 7%, 1.4mS. So I wrote the test function below, and checked the output.

def servoPwmBasicTimingTestGpioPin18():
    print('  Begin servoPwmBasicTimingTestGpioPin18, ...')

    gpioPinNum         =   18
    sleepSeconds       =  120
    frequency          =   50
    dutyCycle          =    7


    pwmPinObject = setGpioPinPwmMode(gpioPinNum, frequency)
    pwmPinChangeFrequency(pwmPinObject, frequency)
    pwmPinChangeDutyCycle(pwmPinObject, dutyCycle)



    print('  End   servoPwmBasicTimingTestGpioPin18, ...\r\n')


Pin18 PWM output looks good.

servo timing 03

Now I can implement the following condition/action table

Condition Action Table

  1. Middle condition = servo moves to Middle action
  2. Leftmost = servo moves to LeftMost action
  3. RightMost condition = servo moves to RightMost action

I have written a little program to loop the above conditions, as show in the following youTube.

Condition Servo Action Program YouTube Demo

/ servo research notes to continue, …


Raspberry Pi Servo Motor control – Rpi Tutorials

Servo MG996R Datasheet – TowerPro

Python (RPi.GPIO) API – SparkFun

Using PWM in RPi.GPIO – SourceForge

Raspberry Pi PWM Generation using Python and C – ElectronicWing

Servo Tutorial – Lady Ada

PWM Tutorial – Lady Ada

Servo Motors Using Arduino – AdaFruit

share  edit  delete  flag
  • okay i will try and let you know – rahraj May 12 ’19 at 6:29
  • No hurry. I am a slow learner. I will first read the servo tutorials and then do some elementary experiments. You might like to remind me if I am making any servo newbie silly mistakes. – tlfong01 May 12 ’19 at 6:35   
  • Now I have completed all the servo functions that enables me to start any servo movement (action) according to a condition (command). You may like to let me know what are the specific “conditions” and the corresponding servo movements. I am going to eat. See you tomorrow. Have a nice weekend. – tlfong01 May 12 ’19 at 9:40   


The script appears to be initialising PWM on the same pin multiple times in the for loop.

Do the p = GPIO.PWM(servoPIN, 50) just once in the script.

share  edit  follow  flag
  • yes i given p = GPIO.PWM(servoPIN, 50) out of the for loop but it still gives same error on this line – rahraj May 11 ’19 at 18:05
  • @rahraj are you sure that there is nothing else in the code before the snippet that you have posted? – Ghanima May 11 ’19 at 18:38
  • yeah sure , please help me – rahraj May 11 ’19 at 19:00
  • @rahraj You need to post the complete script. – joan May 11 ’19 at 19:52
  • basically script is about object detection , my class id is retrieved in the for loop the task is that i have 3 classes so whenever class id =1 then a servo motor should work , similiarly for other classes the corresponding motor should work (the script is so large and hard to indentify thats why i didnt posts the whole script) – rahraj May 12 ’19 at 4:26
  • @rahraj, Oh my goodness, your “full script” belongs to an “advanced” Google AI TensorFlow object detection project. The servo part is sort of just a 1 page out of a 500 pages book. Any way, let me give you an answer to your python GPIO PWM servo servo program troubleshooting question, in the form of a “Servo Newbie Getting Started Guide”, 🙂 – tlfong01 Nov 9 ’19 at 2:19   
  • May I suggest that you create a small file that compiles, runs, and illustrates the problem. Try to find the smallest program that demonstrates the problem. That way you would be able to communicate the problem to us without a huge file. – NomadMaker Dec 8 ’19 at 7:30

Categories: Uncategorized

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: