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
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
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)