Search code examples
raspberry-pii2cadafruitservo

Adafruit's "adafruit_servokit" library returns error on setting angle of servo


I'd like to control a servo by a given angle.

I am using a RaspberryPi 4 Model B which is running Raspian. The servos are connected to a Adafruit PCA9685 16-Channel Servo Driver. The servo driver is connected to the RaspberryPi via i2c.

Python version 3.7.

I used the following tutorial: https://learn.adafruit.com/16-channel-pwm-servo-driver/python-circuitpython

I am able to properly control a LED (just like in the above tutorial) with the setup.

The LED is connected to the servo driver on channel 8, whereas the servo is connected at channel 2.

So here's my code (controlling the LED also included):

import board
import busio
import adafruit_pca9685
from adafruit_servokit import ServoKit

i2c = busio.I2C(board.SCL, board.SDA)
pca = adafruit_pca9685.PCA9685(i2c)
pca.frequency = 60
pca.channels[8].duty_cycle = 0x7FFF

kit = ServoKit(channels=16)
kit.servo[2].angle = 180

And here's the error code I get in return:

Traceback (most recent call last):
  File "/home/pi/rover/Main.py", line 12, in <module>
    kit.servo[2].angle = 180
  File "/home/pi/.local/lib/python3.7/site-packages/adafruit_servokit.py", line 147, in __getitem__
    servo = adafruit_motor.servo.Servo(self.kit._pca.channels[servo_channel])
  File "/usr/local/lib/python3.7/dist-packages/adafruit_motor/servo.py", line 89, in __init__
    super().__init__(pwm_out, min_pulse=min_pulse, max_pulse=max_pulse)
  File "/usr/local/lib/python3.7/dist-packages/adafruit_motor/servo.py", line 29, in __init__
    self.set_pulse_width_range(min_pulse, max_pulse)
  File "/usr/local/lib/python3.7/dist-packages/adafruit_motor/servo.py", line 33, in set_pulse_width_range
    self._min_duty = int((min_pulse * self._pwm_out.frequency) / 1000000 * 0xFFFF)
  File "/home/pi/.local/lib/python3.7/site-packages/adafruit_pca9685.py", line 56, in frequency
    return self._pca.frequency
  File "/home/pi/.local/lib/python3.7/site-packages/adafruit_pca9685.py", line 134, in frequency
    return self.reference_clock_speed / 4096 / self.prescale_reg
ZeroDivisionError: float division by zero

Solution

  • I solved the problem myself. Here's what I did:

    I was confused by the difference between circuitpython and regular python. As far as I understand this, circuitpython is a whole programming language with its environment. If that is even possible to install on the RaspberryPi, I am not sure. I checked on circuitpython's official website and it does not seem to be supported, check the download's page. In case you have circuitpython installed, you can refer to this Github page: https://github.com/adafruit/Adafruit_CircuitPython_PCA9685

    Anyway, what I am looking for is Adafruit's library for "regular" python. This can be pulled from here: https://github.com/adafruit/Adafruit_Python_PCA9685 Check out the readme.md for setup instructions. With this, it worked for me. Controlling servos is now fairly easy.