1

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.setmode(GPIO.BCM)
 GPIO.setup(servoPIN, GPIO.OUT)
 p = GPIO.PWM(servoPIN, 50) #this line shows the error
 p.start(2.5) # Initialization
 try:
 p.ChangeDutyCycle(5)
 time.sleep(4)
 p.ChangeDutyCycle(10)
 time.sleep(4)
 except KeyboardInterrupt:
 p.stop()
 except:
 #print ("exception")
 GPIO.cleanup()

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

tlfong01
4,8573 gold badges12 silver badges24 bronze badges
asked May 11, 2019 at 17:29
3
  • 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; Commented May 12, 2019 at 1:28
  • where should i use this and how its work Commented May 12, 2019 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. :) Commented May 12, 2019 at 6:03

2 Answers 2

1

Question

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)
 moveServo(position)
 else
 pass
 return

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():
  GPIO.setmode(GPIO.BCM)
  GPIO.setwarnings(False)
  return
def cleanupGpio():
  GPIO.cleanup()
  return
# *** GPIO Input/Output Mode Setup and High/Low Level Output ***
def setGpioPinLowLevel(gpioPinNum):
  lowLevel = 0
  GPIO.output(gpioPinNum, lowLevel)
  return
def setGpioPinHighLevel(gpioPinNum):
  highLevel = 1
  GPIO.output(gpioPinNum, highLevel)
  return
def setGpioPinOutputMode(gpioPinNum):
  GPIO.setup(gpioPinNum, GPIO.OUT)
  setGpioPinLowLevel(gpioPinNum)
  return
# *** GPIO PWM Mode Setup and PWM Output ***
def setGpioPinPwmMode(gpioPinNum, frequency):
  pwmPinObject = GPIO.PWM(gpioPinNum, frequency)
  return pwmPinObject
def pwmPinChangeFrequency(pwmPinObject, frequency):
  pwmPinObject.ChangeFrequency(frequency)
  return
def pwmPinChangeDutyCycle(pwmPinObject, dutyCycle):
  pwmPinObject.ChangeDutyCycle(dutyCycle)
  return
def pwmPinStart(pwmPinObject):
  initDutyCycle = 50
  pwmPinObject.start(initDutyCycle)
  return
def pwmPinStop(pwmPinObject):
  pwmPinObject.stop()
  return
# *** Test Functions ***
def setHighLevelGpioPin18():
  print(' Begin setHighLevelGpioPin18, ...')
  gpioPinNum  = 18
  sleepSeconds = 2  
  setupGpio()
  setGpioPinOutputMode(gpioPinNum)
  setGpioPinHighLevel(gpioPinNum)
  sleep(sleepSeconds)
  cleanupGpio()
  print(' End setHighLevelGpioPin18, ...\r\n')
  return
def setPwmModeGpioPin18():
  print(' Begin setPwmModeGpioPin18, ...')
  
  gpioPinNum  =  18
  sleepSeconds =  10
  frequency  = 1000
  dutyCycle  =  50
  setupGpio()
  setGpioPinOutputMode(gpioPinNum)
  
  pwmPinObject = setGpioPinPwmMode(gpioPinNum, frequency)
  pwmPinStart(pwmPinObject)
  pwmPinChangeFrequency(pwmPinObject, frequency)
  pwmPinChangeDutyCycle(pwmPinObject, dutyCycle)
  sleep(sleepSeconds)
  pwmPinObject.stop()
  cleanupGpio()  
  print(' End  setPwmModeGpioPin18, ...\r\n')
  return
# *** Main ***
print('Begin testing, ...\r\n')
setHighLevelGpioPin18()
setPwmModeGpioPin18()
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
 setupGpio()
 setGpioPinOutputMode(gpioPinNum)
 pwmPinObject = setGpioPinPwmMode(gpioPinNum, frequency)
 pwmPinStart(pwmPinObject)
 pwmPinChangeFrequency(pwmPinObject, frequency)
 pwmPinChangeDutyCycle(pwmPinObject, dutyCycle)
 sleep(sleepSeconds)
 pwmPinObject.stop()
 cleanupGpio() 
 print(' End servoPwmBasicTimingTestGpioPin18, ...\r\n')
 return

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

References

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

answered May 12, 2019 at 6:27
3
  • okay i will try and let you know Commented May 12, 2019 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. Commented May 12, 2019 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. Commented May 12, 2019 at 9:40
0

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.

answered May 11, 2019 at 17:37
8
  • yes i given p = GPIO.PWM(servoPIN, 50) out of the for loop but it still gives same error on this line Commented May 11, 2019 at 18:05
  • @rahraj are you sure that there is nothing else in the code before the snippet that you have posted? Commented May 11, 2019 at 18:38
  • yeah sure , please help me Commented May 11, 2019 at 19:00
  • @rahraj You need to post the complete script. Commented May 11, 2019 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) Commented May 12, 2019 at 4:26

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.