|
""" |
|
Repka-Pi 3 H5 LED and Servo example using PCA9685 board and Adafruit CircuitPython libs (RoboIntellect RM001 M02) |
|
|
|
Adafruit libraries usage example |
|
Hardware: |
|
- Repka-Pi (any other i2c microcontroller is suitable: Raspberry, Orange, Banana, ODROID, ESP8266, etc.) |
|
- PCA9685 |
|
- RGB LED |
|
- Servos (in this example 4 servos are used on the RoboIntellect RM001 M02 |
|
|
|
Dependencies: |
|
adafruit-circuitpython-servokit |
|
|
|
Heavily depends on these changes: |
|
- https://github.com/adafruit/Adafruit_Python_PlatformDetect/pull/336 |
|
- https://github.com/adafruit/Adafruit_Blinka/pull/772 |
|
""" |
|
|
|
from time import sleep |
|
|
|
import board |
|
import busio |
|
|
|
from adafruit_motor.servo import Servo |
|
from Adafruit_PureIO import smbus |
|
from adafruit_servokit import ServoKit |
|
from adafruit_pca9685 import PCA9685 |
|
|
|
SDA = board.SDA |
|
SCL = board.SCL |
|
|
|
|
|
def set_angle_smooth(servo: Servo, angle: int, step: int = 1, wait: float = 0.003) -> None: |
|
""" |
|
Set angle step by step. |
|
|
|
:param servo: |
|
:param angle: |
|
:param step: |
|
:param wait: |
|
:return: |
|
""" |
|
if servo.angle is None: |
|
servo.angle = angle |
|
return |
|
current = int(servo.angle) |
|
if current > angle: |
|
step = -step |
|
for i in range(current, angle, step): |
|
servo.angle = i |
|
sleep(wait) |
|
|
|
|
|
def demo_write_raw_bytes(i2c_bus: busio.I2C) -> None: |
|
""" |
|
Sometimes you need to write raw bytes. |
|
|
|
:param i2c_bus: |
|
:return: |
|
""" |
|
bus: smbus.SMBus = i2c_bus._i2c._i2c_bus |
|
addr = 64 # you have to know the address |
|
buf = b"\x00" # you have to know bytes |
|
bus.write_bytes(addr, buf) |
|
|
|
|
|
def main(): |
|
# it's just a constant |
|
max_duty_cycle = 0xffff |
|
# Create the I2C bus interface. |
|
# you can pass other pins if you need to. |
|
i2c_bus = busio.I2C(SCL, SDA) |
|
|
|
# if you want to control PCA9685 directly: |
|
# Create a simple PCA9685 class instance. |
|
pca = PCA9685(i2c_bus) |
|
|
|
# Set the PWM frequency to 60hz. (or any other frequency_ |
|
pca.frequency = 60 |
|
|
|
# I have LED connected to the last three pins on the PCA9685 board |
|
RED = pca.channels[len(pca.channels) - 1] |
|
GREEN = pca.channels[len(pca.channels) - 2] |
|
BLUE = pca.channels[len(pca.channels) - 3] |
|
|
|
# reset |
|
for idx in range(len(pca.channels)): |
|
pca.channels[idx].duty_cycle = 0 |
|
|
|
print("Set some color") |
|
# set some color (full red + half green) |
|
RED.duty_cycle = max_duty_cycle # full |
|
GREEN.duty_cycle = 0x7FFF # middle |
|
BLUE.duty_cycle = 0 # off |
|
|
|
# wait so human eye can see the change |
|
sleep(1) |
|
print("Set LED to 50%") |
|
# Set the PWM duty cycle for channel zero to 50%. duty_cycle is 16 bits to match other PWM objects |
|
# but the PCA9685 will only actually give 12 bits of resolution. |
|
for idx in range(len(pca.channels) - 3, len(pca.channels)): |
|
pca.channels[idx].duty_cycle = 0x7FFF |
|
|
|
|
|
# wait so human eye can see the change |
|
sleep(1) |
|
|
|
print("Smooth on and off LED two times") |
|
times = 2 |
|
max_brightness = max_duty_cycle |
|
step = 100 |
|
for _ in range(times): |
|
# Increase brightness: |
|
for i in range(0, max_brightness - 1, step): |
|
for idx in range(len(pca.channels) - 3, len(pca.channels)): |
|
pca.channels[idx].duty_cycle = i |
|
|
|
# Decrease brightness: |
|
for i in range(max_brightness, 0, -step): |
|
for idx in range(len(pca.channels) - 3, len(pca.channels)): |
|
pca.channels[idx].duty_cycle = i |
|
|
|
sleep(1) |
|
|
|
print("Set LED to Blue") |
|
RED.duty_cycle = 0 |
|
GREEN.duty_cycle = 0 |
|
BLUE.duty_cycle = max_duty_cycle |
|
sleep(1) |
|
|
|
print("Start moving servos. Make sure you have external power connected to the PCA9685 board") |
|
|
|
# idk if you need to change the frequency |
|
pca.frequency = 50 |
|
# i2c should be automatically detected! |
|
kit = ServoKit(channels=16) |
|
# if not, you can set the bus by yourself: |
|
# kit = ServoKit(channels=16, i2c=i2c_bus) |
|
|
|
# you can change servos rules (actuation_range, PWM range) |
|
# servos = 4 |
|
# for idx in range(servos): |
|
# servo = kit.servo[idx] |
|
# set_angle_smooth() |
|
# # servo.actuation_range = 180 |
|
# # servo.set_pulse_width_range(1000, 2000) |
|
|
|
|
|
# Example for RoboIntellect RM001 M02 https://t.me/RepkaPitalk/24150 |
|
servo_base = kit.servo[0] |
|
servo_claw = kit.servo[1] |
|
servo_pull = kit.servo[2] |
|
servo_raise = kit.servo[3] |
|
|
|
# open claw |
|
set_angle_smooth(servo_claw, 180, wait=0.05, step=1) |
|
sleep(0.2) |
|
|
|
# raise high |
|
set_angle_smooth(servo_raise, 0, wait=0.05, step=1) |
|
sleep(0.2) |
|
|
|
# center |
|
set_angle_smooth(servo_base, 60, wait=0.05, step=1) |
|
sleep(0.2) |
|
|
|
# pull to self |
|
set_angle_smooth(servo_pull, 170, wait=0.01, step=2) |
|
sleep(0.2) |
|
|
|
|
|
# set LED to RED |
|
RED.duty_cycle = max_duty_cycle |
|
GREEN.duty_cycle = 0 |
|
BLUE.duty_cycle = 0 |
|
sleep(1) |
|
|
|
# action!! |
|
# pos |
|
# set_angle_smooth(servo_raise, 5) |
|
set_angle_smooth(servo_pull, 90) |
|
set_angle_smooth(servo_base, 0) |
|
|
|
# open claw |
|
set_angle_smooth(servo_claw, 180) |
|
|
|
# lower |
|
set_angle_smooth(servo_raise, 50) |
|
sleep(0.5) |
|
# claw |
|
set_angle_smooth(servo_claw, 100, wait=0.005, step=1) |
|
sleep(0.5) |
|
|
|
# raise high |
|
set_angle_smooth(servo_raise, 0, wait=0.005, step=1) |
|
sleep(0.2) |
|
|
|
# rotate |
|
set_angle_smooth(servo_base, 170) |
|
sleep(0.2) |
|
|
|
# lower |
|
set_angle_smooth(servo_raise, 50, wait=0.01) |
|
|
|
# open claw |
|
set_angle_smooth(servo_claw, 180) |
|
sleep(0.1) |
|
|
|
# raise high |
|
set_angle_smooth(servo_raise, 0) |
|
sleep(0.2) |
|
|
|
# center |
|
set_angle_smooth(servo_base, 60, wait=0.001, step=1) |
|
sleep(0.2) |
|
|
|
# pull to self |
|
set_angle_smooth(servo_pull, 170, wait=0.001, step=2) |
|
sleep(0.2) |
|
|
|
|
|
# Set LED to green |
|
RED.duty_cycle = 0 |
|
GREEN.duty_cycle = max_duty_cycle |
|
BLUE.duty_cycle = 0 |
|
print("done :)") |
|
|
|
|
|
|
|
if __name__ == "__main__": |
|
main() |