Featured image of post R2D2 Arm Connected to RPI3 With PCA9685

R2D2 Arm Connected to RPI3 With PCA9685

Building R2D2 Arms using RPI3 and PCA9685. Also tried a Maestro Micro and RPI3 alone.

RPI3

You can use the RPI3 to use the servos. But the servo power will need to separte from the RPI3. The RPI3’s 5V is not enough to use servos long term. For initial testing they will work. But what you will find is the servos will glitch if connected to the RPI3’s header. The RPI3 causes the glitches. So eventually you need to find an alternative way to run the servos. There are two options I had on hand: a Maestro Mirco and PCA9685.

PCA9685

The PCA9685 requires 2 power inputs: 3.3V and 5V. The 3.3V is for the PCA9685 board. The 5V is for the Servo Power. You will use the RPI3’s 3.3V to power the PCA9685 board. But you will need to use an alternative 5V supply to power the servos. The RPI3’s 5V is not enough to power the servos. It may work a little, but it cannot be used long term. The USB cell phone battery charges can be used as the 5V supply.

This board can handle up to 16 servos or motor controllers. On my DonkeyCar I control the steering and motors using this board and it has been very responsive. This should fit all my needs for servo controls. In my dome I will have a lot of servos to control, up to 10 I believe. I may have a separte one of these boards just for the dome. These boards can also be daisy chained. You just need to change the address by soldering 2 pads together.

Next step, create a Node and Topic and wires this all up to the Flask API.

Schematic

1
2
3
4
5
6
RPI3                 PCA9685
------------------------------
Pin 1 (3.3V)         VCC
Pin 3 (GPIO2)        SDA
Pin 5 (GPIO3)        SCL
Pin 9 (GND)          GND

Servo Color Code

1
2
3
Brown  = GND
Red    = Power 
Orange = Signal
1
2
3
4
Power Supply         PCA9685
------------------------------
5V                   5V
GND                  GND

RPI3 Servo PCA9685 R2D2 Arms

RPI3 and PCA9685 Running the Servos

Code

Packages to install on Ubuntu

1
2
sudo apt install python-smbus
sudo apt install i2c-tools

Packages to install in Python

1
pip install adafruit-circuitpython-servokit

Source Code Used

https://github.com/ricoai/R2D2/blob/master/controls/adafruit_servo_driver.py

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
from adafruit_servokit import ServoKit
import time

class AdafruitServoControl:
    """
    Use the Adafruit PCA9685 board to control the servos.
    https://learn.adafruit.com/adafruit-16-channel-servo-driver-with-raspberry-pi?view=all
    pip install adafruit-circuitpython-servokit
    sudo apt-get install python-smbus
    sudo apt-get install i2c-tools
    """

    def __init__(self, min_servo=750, max_servo=2500):
        """
        Initialize the maestro.  Set the comm port if you need to set the specific.  Set the min
        and max servo pulse width if not default.
        :param comm_port: Comm port of the maestro.
        :param min_servo: Min servo pulse width in quarter seconds.
        :param max_servo: Max servo pulse width in quarter seconds.
        """
        self.kit = None                                         # Hold the Adafruit Servokit

        self.min_servo = min_servo                              # Min pulse width of servo in quarter seconds
        self.max_servo = max_servo                              # Max pulse width of servo in quarter seconds

        self.setup_controller()                                 # Setup maestro

    def setup_controller(self):
        """
        Setup the maestro controller
        :return:
        """
        self.kit = ServoKit(channels=16)
        self.kit.servo[0].set_pulse_width_range(self.min_servo, self.max_servo)
        self.kit.servo[1].set_pulse_width_range(self.min_servo, self.max_servo)
        self.kit.servo[0].angle = 0
        self.kit.servo[1].angle = 0

    def center(self):
        """
        Center the servo.
        :return:
        """
        self.set_angle(0.0)  # CENTER (6000)

    def set_angle(self, chan, angle):
        """
        Set the servo to the given angle.
        :param chan: Servo channel to move
        :param angle: Angle to move the servo
        :return:
        """
        if angle > 180:
            angle = 180
        if angle < 0:
            angle = 0

        self.kit.servo[chan].angle = angle
        print("Chan: " + str(chan) + " angle: " + str(self.kit.servo[chan].angle))


if __name__ == '__main__':
    servo = AdafruitServoControl()
    time.sleep(1.0)
    servo.set_angle(0, 180)
    servo.set_angle(1, 180)
    time.sleep(1.5)
    servo.set_angle(0, 0)
    servo.set_angle(1, 0)

Parts List

The R2D2 arm holder can be found at http://astromech.com/

comments powered by Disqus