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

  • 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 at 1:28
  • where should i use this and how its work – rahraj May 12 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 at 6:03
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.

  • 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 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 at 18:38
  • yeah sure , please help me – rahraj May 11 at 19:00
  • @rahraj You need to post the complete script. – joan May 11 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 at 4:26
0

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

  • okay i will try and let you know – rahraj May 12 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 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 at 9:40

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.