地瓜机器人的板子和电源板也是共地的,但是舵机云台就是一动不动,下面是我的程序,求大佬帮忙看一下哪里有问题
#!/usr/bin/env python3
import sys
import signal
import time
import os
import subprocess
配置舵机参数 (使用物理引脚号)
SERVO_PAN_PIN = 33 # 水平旋转舵机连接的物理引脚 (BOARD编号)
SERVO_TILT_PIN = 32 # 俯仰舵机连接的物理引脚 (BOARD编号)
舵机参数 (根据270度舵机调整)
MIN_PULSE = 500 # 最小脉冲宽度 (微秒)
MAX_PULSE = 2500 # 最大脉冲宽度 (微秒)
MAX_ANGLE = 270 # 最大角度 (度)
PERIOD = 20000 # 50Hz的周期(微秒)
安全角度范围 (根据机械结构限制)
PAN_MIN = 0
PAN_MAX = 270
TILT_MIN = 30
TILT_MAX = 240
def cleanup():
“”“确保所有PWM通道被禁用”“”
print(“\n清理PWM资源…”)
try:
# 禁用所有PWM通道
subprocess.run([“sudo”, “sh”, “-c”, f"echo 0 > /sys/class/pwm/pwmchip0/pwm{SERVO_PAN_PIN}/enable"], check=True)
subprocess.run([“sudo”, “sh”, “-c”, f"echo 0 > /sys/class/pwm/pwmchip0/pwm{SERVO_TILT_PIN}/enable"], check=True)
# 取消导出PWM通道
subprocess.run(["sudo", "sh", "-c", f"echo {SERVO_PAN_PIN} > /sys/class/pwm/pwmchip0/unexport"], check=True)
subprocess.run(["sudo", "sh", "-c", f"echo {SERVO_TILT_PIN} > /sys/class/pwm/pwmchip0/unexport"], check=True)
print("PWM资源已释放")
except Exception as e:
print(f"清理资源时出错: {e}")
def setup_pwm(pin):
“”“设置指定引脚的PWM通道”“”
try:
# 导出PWM通道
subprocess.run([“sudo”, “sh”, “-c”, f"echo {pin} > /sys/class/pwm/pwmchip0/export"], check=True)
time.sleep(0.1) # 等待系统创建文件
# 设置周期 (50Hz = 20000ns)
subprocess.run(["sudo", "sh", "-c", f"echo {PERIOD} > /sys/class/pwm/pwmchip0/pwm{pin}/period"], check=True)
# 初始脉宽为0
subprocess.run(["sudo", "sh", "-c", f"echo 0 > /sys/class/pwm/pwmchip0/pwm{pin}/duty_cycle"], check=True)
# 启用PWM
subprocess.run(["sudo", "sh", "-c", f"echo 1 > /sys/class/pwm/pwmchip0/pwm{pin}/enable"], check=True)
print(f"PWM通道 {pin} 初始化成功")
return True
except subprocess.CalledProcessError as e:
print(f"设置PWM通道 {pin} 时出错: {e}")
return False
except Exception as e:
print(f"未知错误: {e}")
return False
def set_servo_angle(pin, angle, servo_name=“”):
“”“设置指定引脚的舵机角度”“”
try:
# 角度范围限制
if “pan” in servo_name.lower():
angle = max(PAN_MIN, min(angle, PAN_MAX))
elif “tilt” in servo_name.lower():
angle = max(TILT_MIN, min(angle, TILT_MAX))
else:
angle = max(0, min(angle, MAX_ANGLE))
# 计算脉冲宽度 (微秒)
pulse_width = MIN_PULSE + (MAX_PULSE - MIN_PULSE) * angle / MAX_ANGLE
# 转换为纳秒 (sysfs使用纳秒)
pulse_width_ns = int(pulse_width * 1000)
# 设置占空比
subprocess.run(["sudo", "sh", "-c", f"echo {pulse_width_ns} > /sys/class/pwm/pwmchip0/pwm{pin}/duty_cycle"], check=True)
print(f"设置{servo_name}舵机角度: {angle}°, 脉宽: {pulse_width:.0f}μs")
return True
except Exception as e:
print(f"设置舵机角度时出错: {e}")
return False
def main():
# 确保清理之前的资源
cleanup()
time.sleep(1)
# 设置PWM通道
if not setup_pwm(SERVO_PAN_PIN):
print("无法初始化水平舵机PWM通道")
return
if not setup_pwm(SERVO_TILT_PIN):
print("无法初始化俯仰舵机PWM通道")
return
try:
# 初始位置 (135°居中)
set_servo_angle(SERVO_PAN_PIN, 135, "水平")
set_servo_angle(SERVO_TILT_PIN, 135, "俯仰")
time.sleep(1) # 等待舵机到位
print("270度舵机云台控制开始 (Ctrl+C退出)")
print(f"舵机参数: {MAX_ANGLE}度范围, 脉宽{MIN_PULSE}-{MAX_PULSE}μs, 频率50Hz")
# 示例动作序列
while True:
# 水平扫描
print("\n水平扫描...")
for angle in [0, 90, 180, 270]:
set_servo_angle(SERVO_PAN_PIN, angle, "水平")
time.sleep(0.8)
# 俯仰动作
print("\n俯仰运动...")
set_servo_angle(SERVO_TILT_PIN, 30, "俯仰") # 抬头
time.sleep(0.8)
set_servo_angle(SERVO_TILT_PIN, 135, "俯仰") # 中间位置
time.sleep(0.8)
set_servo_angle(SERVO_TILT_PIN, 240, "俯仰") # 低头
time.sleep(0.8)
set_servo_angle(SERVO_TILT_PIN, 135, "俯仰") # 返回中间位置
time.sleep(0.8)
except KeyboardInterrupt:
print("\n程序终止")
finally:
# 安全关闭舵机
set_servo_angle(SERVO_PAN_PIN, 135, "水平")
set_servo_angle(SERVO_TILT_PIN, 135, "俯仰")
time.sleep(0.5)
cleanup()
def signal_handler(sig, frame):
“”“信号处理函数”“”
print(f"\n收到信号 {sig},程序终止")
# 安全关闭舵机
set_servo_angle(SERVO_PAN_PIN, 135, “水平”)
set_servo_angle(SERVO_TILT_PIN, 135, “俯仰”)
time.sleep(0.5)
cleanup()
sys.exit(0)
if name == ‘main’:
# 注册信号处理
signal.signal(signal.SIGINT, signal_handler)
signal.signal(signal.SIGTERM, signal_handler)
# 检查是否以root权限运行
if os.geteuid() != 0:
print("错误: 此脚本必须使用sudo以root权限运行")
print("请使用: sudo ./servo_control.py")
sys.exit(1)
# 运行主程序
main()