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
-
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
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.
I found Rpi ahs 4 PWM pins. I decided to use Pin 18 to test the water. Below is the hardware setup.
Now I have debugged a python program to do the following.
- Set GPIO pin 18 high for 2 seconds, to switch on Blue LED to full brightness.
- 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.
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.
Now I can implement the following condition/action table
Condition Action Table
- Middle condition = servo moves to Middle action
- Leftmost = servo moves to LeftMost action
- 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
-
-
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.
-
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
-
-
-
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
-
here it is the full script github.com/aswinr22/waste-model/blob/master/picamera1.py – rahraj May 12 ’19 at 6:16
-
@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