1

I've got an LED on bcm 18 and a servo motor on bcm 8. My code appears here.

from gpiozero import LED
import RPi.GPIO as GPIO
import time

GPIO.setmode(GPIO.BCM)
GPIO.setup(8,GPIO.OUT)
servo = GPIO.PWM(8, 50)
servo.start(0)
led = LED(18)

led.on()
servo.ChangeDutyCycle(7)
time.sleep(0.5)
servo.ChangeDutyCycle(0)

servo.ChangeDutyCycle(2) # needs to be parameterized
time.sleep(.5)
servo.stop()
GPIO.cleanup()

print("done")

When I run, I get an error. It seems to occur AFTER the done command has executed and there's no code of mine that's left to run.

I suspect it's related to importing both gpiozero and RPi.GPIO, but I don't know what to do about it. I learned how to program the LED using gpiozero and learned the servo using RPi.GPIO.

Can anyone tell me how to fix the code?

pi@wpi: ~ $ p3 err.py  
done  
Error in atexit._run_exitfuncs:  
Traceback (most recent call last):  
  File "/usr/local/lib/python3.7/dist-packages/gpiozero/devices.py", line 595, in _shutdown
    _devices_shutdown()  
  File "/usr/local/lib/python3.7/dist-packages/gpiozero/devices.py", line 588, in _devices_shutdown  
    dev.close()  
  File "/usr/local/lib/python3.7/dist-packages/gpiozero/output_devices.py", line 225, in close
    super(DigitalOutputDevice, self).close()  
  File "/usr/local/lib/python3.7/dist-packages/gpiozero/mixins.py", line 110, in close
    super(SourceMixin, self).close()  
  File "/usr/local/lib/python3.7/dist-packages/gpiozero/devices.py", line 540, in close
    self._pin.close()  
  File "/usr/local/lib/python3.7/dist-packages/gpiozero/pins/rpigpio.py", line 137, in close
    GPIO.cleanup(self.number)  
**RuntimeError: Please set pin numbering mode using GPIO.setmode(GPIO.BOARD) or GPIO.setmode(GPIO.BCM)**  
Exception ignored in: <function GPIOBase.__del__ at 0xb654d8e8>  
Traceback (most recent call last):  
  File "/usr/local/lib/python3.7/dist-packages/gpiozero/devices.py", line 151, in __del__  
  File "/usr/local/lib/python3.7/dist-packages/gpiozero/output_devices.py", line 225, in close  
  File "/usr/local/lib/python3.7/dist-packages/gpiozero/mixins.py", line 110, in close  
  File "/usr/local/lib/python3.7/dist-packages/gpiozero/devices.py", line 540, in close  
  File "/usr/local/lib/python3.7/dist-packages/gpiozero/pins/rpigpio.py", line 137, in close  
**RuntimeError: Please set pin numbering mode using GPIO.setmode(GPIO.BOARD) or GPIO.setmode(GPIO.BCM)**  
pi@wpi: ~ $   
2

It is inadvisable to mix libraries.

You can control a servo with

https://gpiozero.readthedocs.io/en/stable/recipes.html#servo

See https://gpiozero.readthedocs.io/en/stable/api_output.html#servo for documentation of the servo class.

NOTE that gpiozero, by default uses RPi.GPIO

GPIO Zero builds on a number of underlying pin libraries, including RPi.GPIO and pigpio, each with their own benefits. You can select a particular pin library to be used, either for the whole script or per-device, according to your needs. See the section on changing the pin factory.

NOTE GPIO.cleanup() is superfluous as gpiozero automatically cleans up on exit.

4
  • I removed GPIO.cleanup() and the errors went away. Thanks. At first, I tried using gpiozero for the servo, but the .min(), .max() and .mid() did not move the arm to their extreme positions like .ChangeDutyCycle(...) was able to do. I'll come back and checkmark the solution after I take a second look at using gpiozero for the servo. – MACE Mar 12 '20 at 12:39
  • @MACE When you create a servo you can specify the minumum and maximum pulsewidth. classgpiozero.Servo(pin, *, initial_value=0, min_pulse_width=1/1000, max_pulse_width=2/1000, frame_width=20/1000, pin_factory=None). Try a minimum of 0.0005 and a maximum of 0.0025. – joan Mar 12 '20 at 13:24
  • @joan, thanks. My app naturally uses degrees between 0 and 180. I tried playing around with those parameters. While I could see the servo position react to the PW min and max that I was setting, I couldn't find the combination of values that resulted in accurate 0, 45, 90, 135 and 180 angles. So, I think I'm going to stick with the RPi.GPIO methods. I experimented with setting ,CurrentDutyCycle to values between 0 and 12 and came up with the following correspondence between angles and CDC: {'q':0,'0':2, '45':4.2, '90':7, '135':8.5, '180':12}. – MACE Mar 13 '20 at 16:49
  • 1
    I would not use 2%, that equates to a pulsewidth of 400µs which is probably damaging your servo. The pulsewidths you are using are 0-400µs 45-840µs 90-1400µs 135-1700µs 180-2400µs. The servo seems a bit hit and miss. I'd expect a stronger correlation between pulsewidth and angle. – joan Mar 13 '20 at 17:06

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.