Notifications
Clear all

WAS simple pan tilt

3 Posts
1 Users
0 Reactions
323 Views
Spyder
(@spyder)
Member
Joined: 6 years ago
Posts: 851
Topic starter  

TLDR

I've got a broken leg, very frustrating

Can't even swing my leg under my computer desk

So I need a rover to be near mom if she hollers for help

I've got a Sphero RVR which I DID have a 3d printed pan tilt cam thing with servos and pca9685 and a Pi3B+

I upgraded the 3B+ to a Pi 5, and Bookworm...

 

And nothing old works in Bookworm

 

Everything I google turns out to be either for a HAT or old enough that it doesn't work on Bookworm

I guess I could got back to Buster or Jessie, but I really like the piconnect thing, and I don't wanna buy a HAT

Has anybody got a simple CURSES type Pan-Tilt control for pca9685 that works under Bookworm ?

I just wanna pan tilt, I don't need cv or object tracking, and I can already move the Rover


   
Quote
Spyder
(@spyder)
Member
Joined: 6 years ago
Posts: 851
Topic starter  

Found something

from gpiozero import AngularServo
from time import sleep

# Initialize the servo on GPIO pin 14
# min_pulse_width and max_pulse_width may need to be adjusted for your servo
servo = AngularServo(14, min_angle=0, max_angle=180, min_pulse_width=0.5/1000, max_pulse_width=2.5/1000)

# Function to set the servo angle
def set_angle(angle):
    servo.angle = angle
    sleep(1)

# Main program loop
try:
    while True:
        angle = int(input("Enter angle (0 to 180): "))  # User input for angle
        set_angle(angle)  # Set servo to entered angle
except KeyboardInterrupt:
    print("Program stopped by user")

Best so far cuz it has gpiozero instead of rpigpio

Only one servo, no problem, one thing at a time

Now I need to move the servo

 


   
ReplyQuote
Spyder
(@spyder)
Member
Joined: 6 years ago
Posts: 851
Topic starter  

I think I'm close

GPIOZERO just wasn't working for me, so I stopped using it

The Pi shouldn't be powering the servos anyway

I know, there's only 2

Power up works fine

Program start works fine

PTZ control should be up, down, left, right arrow keys

Problem...

Press any arrow key and the thing swings all the way to the right and locks there. I have to depower the pca9685 in order to release the servo

So, it moves when I hit an arrow key

import curses
from adafruit_pca9685 import PCA9685
import board
import busio
import time

# Configure I2C for PCA9685
i2c = busio.I2C(board.SCL, board.SDA)
pca = PCA9685(i2c)
pca.frequency = 50  # Set servo frequency to 50Hz

# Servo parameters
SERVO_MIN = 150  # Minimum pulse width (for 0 degrees)
SERVO_MAX = 600  # Maximum pulse width (for 180 degrees)
PAN_CHANNEL = 0   # PCA9685 channel for the pan servo
TILT_CHANNEL = 1  # PCA9685 channel for the tilt servo
PAN_STEP = 5      # Degrees to move per key press
TILT_STEP = 5     # Degrees to move per key press

# Initialize angles
pan_angle = 90
tilt_angle = 90

def angle_to_duty_cycle(angle):
    """
    Convert an angle (0 to 180) to a duty cycle value for the PCA9685.
    """
    pulse_range = SERVO_MAX - SERVO_MIN
    return int(SERVO_MIN + (pulse_range * angle / 180))

def move_servo(channel, angle):
    """
    Move a servo on a specified channel to a desired angle.
    """
    duty_cycle = angle_to_duty_cycle(angle)
    pca.channels[channel].duty_cycle = duty_cycle
    print(f"Moving channel {channel} to angle {angle} (Duty Cycle: {duty_cycle})")  # Debug info

def main(stdscr):
    global pan_angle, tilt_angle

    # Clear screen and initialize
    stdscr.clear()
    stdscr.refresh()
    stdscr.addstr("Use arrow keys to move the servos. Press 'q' to quit.\n")

    # Move the servos to the initial positions
    move_servo(PAN_CHANNEL, pan_angle)
    move_servo(TILT_CHANNEL, tilt_angle)

    while True:
        char = stdscr.getch()  # Wait for user input

        if char == curses.KEY_UP:
            tilt_angle = min(tilt_angle + TILT_STEP, 180)
            move_servo(TILT_CHANNEL, tilt_angle)
            stdscr.addstr(1, 0, "Tilt angle: {tilt_angle}   ")
        elif char == curses.KEY_DOWN:
            tilt_angle = max(tilt_angle - TILT_STEP, 0)
            move_servo(TILT_CHANNEL, tilt_angle)
            stdscr.addstr(1, 0, "Tilt angle: {tilt_angle}   ")
        elif char == curses.KEY_LEFT:
            pan_angle = max(pan_angle - PAN_STEP, 0)
            move_servo(PAN_CHANNEL, pan_angle)
            stdscr.addstr(2, 0, "Pan angle: {pan_angle}   ")
        elif char == curses.KEY_RIGHT:
            pan_angle = min(pan_angle + PAN_STEP, 180)
            move_servo(PAN_CHANNEL, pan_angle)
            stdscr.addstr(2, 0, "Pan angle: {pan_angle}   ")
        elif char == ord('q'):
            break  # Exit program

        stdscr.refresh()
        time.sleep(0.1)  # Add a small delay

# Run the curses application
curses.wrapper(main)

   
ReplyQuote