线条厂各设备控制代码
This commit is contained in:
210
RK1106/stepper_motor.py
Normal file
210
RK1106/stepper_motor.py
Normal file
@ -0,0 +1,210 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
# @Time : 2026/1/5 15:50
|
||||
# @Author : reenrr
|
||||
# @File : stepper_motor.py
|
||||
# @Desc : 控制步进电机从初始位置移动10cm,移动后回到初始位置
|
||||
'''
|
||||
import time
|
||||
from periphery import GPIO
|
||||
import logging
|
||||
|
||||
# ------------参数配置-------------
|
||||
# 1. 脉冲(PUL)引脚配置 → GPIO32
|
||||
PUL_Pin = 32
|
||||
|
||||
# 2. 方向(DIR)引脚配置 → GPIO33
|
||||
DIR_Pin = 33
|
||||
|
||||
# 3. 驱动器参数(根据拨码调整,默认不变)
|
||||
PULSES_PER_ROUND = 400 # 每圈脉冲数(SW5~SW8拨码,默认400)
|
||||
PULSE_FREQUENCY = 2500 # 脉冲频率(Hz)
|
||||
|
||||
# ------------ 日志+参数配置 ------------
|
||||
script_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
log_file_path = os.path.join(script_dir, "stepper_motor.log")
|
||||
|
||||
logging.basicConfig(
|
||||
level=logging.INFO,
|
||||
format='[%(asctime)s.%(msecs)03d] [%(levelname)s] %(message)s',
|
||||
datefmt='%Y-%m-%d %H:%M:%S',
|
||||
handlers=[
|
||||
logging.StreamHandler(),
|
||||
logging.FileHandler(log_file_path, encoding='utf-8')
|
||||
]
|
||||
)
|
||||
|
||||
class StepperMotor:
|
||||
"""新力川MA860H驱动器步进电机控制类"""
|
||||
# 方向常量定义
|
||||
CLOCKWISE = "clockwise" # 顺时针
|
||||
COUNTER_CLOCKWISE = "counterclockwise" # 逆时针
|
||||
|
||||
def __init__(self,
|
||||
pul_pin: int = PUL_Pin,
|
||||
dir_pin: int = DIR_Pin,
|
||||
pulses_per_round: int = PULSES_PER_ROUND,
|
||||
pulse_frequency: int = PULSE_FREQUENCY,
|
||||
clockwise_level: bool = True,
|
||||
counter_clockwise_level: bool = False):
|
||||
"""
|
||||
初始化步进电机控制器
|
||||
:param pul_pin: 脉冲引脚
|
||||
:param dir_pin: 方向引脚
|
||||
:param pulses_per_round: 每圈脉冲数(SW5~SW8拨码,默认400)
|
||||
:param pulse_frequency: 脉冲频率(Hz,)
|
||||
:param clockwise_level: 顺时针对应的DIR电平
|
||||
:param counter_clockwise_level: 逆时针对应的DIR电平
|
||||
"""
|
||||
# 硬件配置参数
|
||||
self.pul_pin = pul_pin
|
||||
self.dir_pin = dir_pin
|
||||
|
||||
# 驱动器参数
|
||||
self.pulses_per_round = pulses_per_round
|
||||
self.pulse_frequency = pulse_frequency
|
||||
self.clockwise_level = clockwise_level
|
||||
self.counter_clockwise_level = counter_clockwise_level
|
||||
|
||||
# GPIO对象初始化
|
||||
self.pul_gpio = None
|
||||
self.dir_gpio = None
|
||||
|
||||
# 初始化GPIO
|
||||
self._init_gpio()
|
||||
|
||||
def _init_gpio(self):
|
||||
"""初始化PUL和DIR引脚"""
|
||||
try:
|
||||
# 初始化脉冲引脚(输出模式)
|
||||
self.pul_gpio = GPIO(self.pul_pin, "out")
|
||||
# 初始化方向引脚(输出模式)
|
||||
self.dir_gpio = GPIO(self.dir_pin, "out")
|
||||
|
||||
# 初始电平置低(避免电机误动作)
|
||||
self.pul_gpio.write(False)
|
||||
self.dir_gpio.write(False)
|
||||
|
||||
logging.info(f"PUL引脚初始化完成:{self.pul_pin} 引脚")
|
||||
logging.info(f"DIR引脚初始化完成:{self.dir_pin} 引脚")
|
||||
|
||||
except PermissionError:
|
||||
raise RuntimeError("权限不足!请用sudo运行程序(sudo python xxx.py)")
|
||||
except Exception as e:
|
||||
raise RuntimeError(f"GPIO初始化失败:{str(e)}") from e
|
||||
|
||||
def _validate_rounds(self, rounds: float) -> bool:
|
||||
"""验证圈数是否合法(内部方法)"""
|
||||
if rounds <= 0:
|
||||
logging.info("圈数必须为正数")
|
||||
return False
|
||||
return True
|
||||
|
||||
def _validate_direction(self, direction: str) -> bool:
|
||||
"""验证方向参数是否合法(内部方法)"""
|
||||
if direction not in [self.CLOCKWISE, self.COUNTER_CLOCKWISE]:
|
||||
logging.info(f"方向参数错误:仅支持 {self.CLOCKWISE}/{self.COUNTER_CLOCKWISE}")
|
||||
return False
|
||||
return True
|
||||
|
||||
def rotate(self, rounds: float, direction: str = CLOCKWISE):
|
||||
"""
|
||||
控制电机旋转(支持正反转)
|
||||
:param rounds: 旋转圈数(可小数,如0.5=半圈)
|
||||
:param direction: 方向(clockwise=顺时针,counterclockwise=逆时针)
|
||||
"""
|
||||
# 参数验证
|
||||
if not self._validate_rounds(rounds) or not self._validate_direction(direction):
|
||||
return
|
||||
|
||||
# 设置旋转方向(DIR电平)
|
||||
if direction == self.CLOCKWISE: # 顺时针
|
||||
self.dir_gpio.write(self.clockwise_level)
|
||||
logging.info(f"\n=== 顺时针旋转 {rounds} 圈 ===")
|
||||
else: # 逆时针
|
||||
self.dir_gpio.write(self.counter_clockwise_level)
|
||||
logging.info(f"\n=== 逆时针旋转 {rounds} 圈 ===")
|
||||
|
||||
# 计算总脉冲数和时序(精准控制,避免丢步)
|
||||
total_pulses = int(rounds * self.pulses_per_round)
|
||||
pulse_period = 1.0 / self.pulse_frequency # 脉冲周期(秒)
|
||||
half_period = pulse_period / 2 # 占空比50%(MA860H最优)
|
||||
|
||||
logging.info(f"总脉冲数:{total_pulses} | 频率:{self.pulse_frequency}Hz | 周期:{pulse_period * 1000:.2f}ms")
|
||||
start_time = time.perf_counter() # 高精度计时(避免丢步)
|
||||
|
||||
# 发送脉冲序列(核心:占空比50%的方波)
|
||||
for _ in range(total_pulses):
|
||||
# 高电平
|
||||
self.pul_gpio.write(True)
|
||||
# 精准延时(比time.sleep稳定,适配高频脉冲)
|
||||
while time.perf_counter() - start_time < half_period:
|
||||
pass
|
||||
# 低电平
|
||||
self.pul_gpio.write(False)
|
||||
# 更新下一个脉冲的起始时间
|
||||
start_time += pulse_period
|
||||
|
||||
logging.info("旋转完成")
|
||||
|
||||
def stop(self):
|
||||
"""紧急停止(置低脉冲引脚)"""
|
||||
if self.pul_gpio:
|
||||
self.pul_gpio.write(False)
|
||||
logging.info("电机已停止")
|
||||
|
||||
def close(self):
|
||||
"""释放GPIO资源"""
|
||||
# 安全释放GPIO资源(关键:避免引脚电平残留)
|
||||
if self.pul_gpio:
|
||||
self.pul_gpio.write(False) # 脉冲引脚置低
|
||||
self.pul_gpio.close()
|
||||
logging.info("\n PUL引脚已关闭(电平置低)")
|
||||
|
||||
if self.dir_gpio:
|
||||
self.dir_gpio.write(False) # 方向引脚置低
|
||||
self.dir_gpio.close()
|
||||
logging.info("DIR引脚已关闭(电平置低)")
|
||||
|
||||
# 重置GPIO对象
|
||||
self.pul_gpio = None
|
||||
self.dir_gpio = None
|
||||
|
||||
def __del__(self):
|
||||
"""析构函数:确保资源释放"""
|
||||
self.close()
|
||||
|
||||
|
||||
#---------控制步进电机外部接口--------------
|
||||
def stepper_motor_control():
|
||||
motor = None
|
||||
try:
|
||||
# 创建电机实例(使用默认配置)
|
||||
motor = StepperMotor()
|
||||
logging.info("\n=== 步进电机控制程序启动 ===")
|
||||
|
||||
# 靠近电机方向 逆时针
|
||||
motor.rotate(rounds=10.0, direction=motor.COUNTER_CLOCKWISE)
|
||||
time.sleep(5) # 暂停5秒
|
||||
# 远离电机方向 顺时针
|
||||
motor.rotate(rounds=10.0, direction=motor.CLOCKWISE)
|
||||
time.sleep(5) # 暂停5秒
|
||||
|
||||
except PermissionError:
|
||||
logging.info("\n 权限不足:请用 sudo 运行!")
|
||||
logging.info("命令:sudo python3 double_direction_motor.py")
|
||||
except ImportError:
|
||||
logging.info("\n 缺少依赖:请安装python-periphery")
|
||||
logging.info("命令:pip install python-periphery")
|
||||
except Exception as e:
|
||||
logging.info(f"\n 程序异常:{str(e)}")
|
||||
finally:
|
||||
if motor:
|
||||
motor.close()
|
||||
logging.info("程序退出完成")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
stepper_motor_control()
|
||||
|
||||
Reference in New Issue
Block a user