Files
ElecScalesMeasur/servo_motor_IO.py

108 lines
4.2 KiB
Python
Raw Permalink Normal View History

2025-09-30 14:57:14 +08:00
#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
# @Time : 2025/9/23 18:21
# @Author : reenrr
# @File : servo_motor.py
# 功能描述RK3506通过GPIO模拟PWM控制DS3235舵机模拟持续旋转
# 参考文档DS3235 Coreless datasheet.pdf、接线图.docx
'''
import time
import signal
from periphery import GPIO
# -------------------------- 1. 硬件配置(必须根据实际接线调整) --------------------------
# 1.1 舵机PWM信号输出引脚RK3506的GPIO编号需与硬件接线对应
# 例若舵机信号线接GPIO3_B2_d对应Linux GPIO编号为10参考你提供的vibration_control-test.py
SERVO_GPIO_NUM = 10 # 替换为你的实际舵机信号引脚GPIO编号
# 1.2 DS3235舵机核心参数来自DS3235规格书
PWM_PERIOD_MS = 20 # PWM周期20ms规格书4-6条“控制频率50Hz”1/50Hz=20ms
MIN_PULSE_US = 500 # 最小脉宽500μsec对应0°规格书4-2条
MAX_PULSE_US = 2500 # 最大脉宽2500μsec对应180°规格书4-2条
ROTATE_DELAY = 0.1 # 角度切换间隔越小转动越“连续”建议0.1-0.5秒)
# 1.3 舵机角度模式选择(根据需求切换,参考接线图.docx
MODE = "180" # 180°模式500μsec=0°2500μsec=180°
# -------------------------- 2. 全局变量初始化 --------------------------
gpio = None # 舵机GPIO引脚对象
is_running = True # 程序运行标志
# -------------------------- 3. PWM信号生成函数 --------------------------
def set_servo_pulse(pulse_us):
'''
生成指定脉宽的PWM信号通过GPIO高低电平模拟
参数pulse_us - 高电平脉宽单位微秒
'''
global gpio
# 脉宽范围限制(避免舵机过载,严格遵循规格书)
pulse_us = max(MIN_PULSE_US, min(MAX_PULSE_US, pulse_us))
# 1. 输出高电平持续pulse_us微秒
gpio.write(True)
time.sleep(pulse_us / 1000000) # 转换为秒单位
# 2. 输出低电平补全PWM周期20ms - 高电平时间)
low_time_ms = PWM_PERIOD_MS - (pulse_us / 1000) # 低电平时间(毫秒)
gpio.write(False)
time.sleep(low_time_ms / 1000) # 转换为秒单位
# -------------------------- 4. 模拟持续旋转函数 --------------------------
def continuous_rotate_sim():
'''
模拟持续旋转交替输出最小脉宽0°最大脉宽180°
'''
global is_running
print(f"DS3235舵机已启动{MODE}°模式按Ctrl+C停止...")
while is_running:
# 第一步输出最小脉宽对应0°
set_servo_pulse(MIN_PULSE_US)
print(f"当前脉宽:{MIN_PULSE_US}μsec")
time.sleep(ROTATE_DELAY)
# 第二步输出最大脉宽对应180°/270°
set_servo_pulse(MAX_PULSE_US)
if MODE == "180":
print(f"当前脉宽:{MAX_PULSE_US}μsec180°")
else:
print(f"当前脉宽:{MAX_PULSE_US}μsec270°")
time.sleep(ROTATE_DELAY)
# -------------------------- 5. 信号处理Ctrl+C优雅退出 --------------------------
def signal_handler(signum, frame):
'''捕获Ctrl+C信号设置退出标志'''
global is_running
print("\n收到停止指令,正在清理资源...")
is_running = False
# -------------------------- 6. 主函数 --------------------------
if __name__ == "__main__":
# 1. 注册信号处理确保Ctrl+C能正常退出
signal.signal(signal.SIGINT, signal_handler)
signal.signal(signal.SIGTERM, signal_handler)
try:
# 2. 初始化舵机GPIO引脚输出模式参考你的vibration_control-test.py风格
gpio = GPIO(SERVO_GPIO_NUM, "out")
print(f"舵机GPIO引脚编号{SERVO_GPIO_NUM})初始化完成")
# 3. 启动模拟持续旋转
continuous_rotate_sim()
except Exception as e:
# 异常处理如GPIO初始化失败
print(f"程序异常:{str(e)}")
finally:
# 4. 资源清理必做避免GPIO引脚异常
if gpio is not None:
gpio.write(False) # 程序结束前拉低GPIO避免舵机持续受力
gpio.close()
print("舵机GPIO引脚已关闭")
print("程序退出完成")