首页 > 解决方案 > 记住步进电机的角位置

问题描述

我正在寻找有关如何定义电机初始位置的建议,以便我可以跟踪相对于该点的当前角位置。我正在使用步进电机,因此要移动到给定的角度,我会计算步数。我目前有一个功能可以伪造一种 PWM 信号,并以一定的速度和方向通过给定的角度移动电机。它看起来像这样:

def RotMotor(SPIN, DPIN, direction, degrees, speed):
    GPIO.output(DPIN, direction)
    #For precise control the number of steps required to move to a given angle 
    #is calculated by the following line of code
    num_steps = (float(degrees) / float(360)) * 800
    #The sleep time is derived from the input RPM by converting RPM to time 
    #between each step
    sleeptime = 1 / ((float(speed) * 800) / 60)
    print('Taking ' + str(num_steps) + ' steps at ' + str(speed) + ' RPM.')
    #This while loop will take the calulated number of steps and count each 
    #step the motor makes in moving to its next point
    while num_steps > 0:
        GPIO.output(SPIN, 1)
        #The sleep function is called twice (High duration + Low Duration)
        time.sleep(sleeptime / 2)
        GPIO.output(SPIN, 0)
        #Second call of sleep function. Sleep function 1 + Sleep function 2 = 
        #Time for One Step
        time.sleep(sleeptime / 2)
        #Count 1 step
        num_steps -= 1

我想要做的是开发一种方法,我可以为这个函数提供一个职位列表,以便它将:

1.) 知道它从哪里开始是零 2.) 知道如果它在 90 度并且它被告知去 180 然后它移动 90 度。

之前我说过我的函数将通过角度移动。我的目标是移动到角度。然后,当我的列表结束时,它会回到零,而不必在列表中包含该坐标。

我对我需要做什么有一个模糊的想法,但在这一点上我非常愿意接受建议。感谢您的任何反馈。

标签: pythonraspberry-pirobotics

解决方案


对于那些对这个问题感兴趣的人,我想出了一个简单的解决方案。而不是解释我只是在这里发布代码供任何人尝试。

'''
This code is used to drive two NEMA 17 stepper motors both driven by their own A4988 
driver circuit. The step resolution is set to 1/4 steps, which results in 800 steps 
per revolution for this specific motor. If you use this code be sure to change the number 
800 anywhere in this code to your own motors steps per revolution.
'''
#!/usr/bin/env python

#Importing all relevant packages

import os
import RPi.GPIO as GPIO
import numpy
import time

#Defining GPIO setup (STEP PINS (odd) AND DIRECTION PINS (even) FOR EACH MOTOR)

PINS = [11, 12, 15, 16]
GPIO.setmode(GPIO.BOARD)
GPIO.setwarnings(False)
GPIO.setup(PINS, GPIO.OUT)

#Initialize a list that stores the amount of steps taken for each coordinate for the duration of the program

mem1 = [0]
mem2 = [0]

#Function to tell a motor how to move based on direction (CW / CCW), how many degrees to move, and what speed to move at (RPM)
#For precise control the number of steps required to move to a given angle is calculated by the following line of code

def RotMotor(SPIN, DPIN, direction, degrees, speed, memory):
    pos = sum(memory)
    num_steps = ((float(degrees) / float(360)) * 800) - pos
    memory.append(num_steps)
    if num_steps < 0:
        x = abs(num_steps)
        dir = GPIO.output(DPIN, 1)
    else:
        x = num_steps
        GPIO.output(DPIN, 0)
    sleeptime = 1 / ((float(speed) * 800) / 60)
    print('Taking ' + str(num_steps) + ' steps at ' + str(speed) + ' RPM.')
    while x > 0:
        GPIO.output(SPIN, 1)
        time.sleep(sleeptime / 2)
        GPIO.output(SPIN, 0)
        time.sleep(sleeptime / 2)
        x -= 1

#THE FOLLOWING LINES ARE QUICK CODE FOR TESTING.

Motor1Ins = []
Motor2Ins = []

angles = [45, 90, 135, 180, 225, 270, 315, 360, 315, 270, 225, 180, 135, 90, 45, 0]

for i in angles:
   Motor1Ins.append([11, 12, i, 20, mem1])
   Motor2Ins.append([15, 16, i, 20, mem2])

try:
   while True:
      for s, d, theta, t, MotMem in Motor1Ins:
         RotMotor(s, d, theta, t, MotMem)
         time.sleep(0.5)
      for s, d, theta, t, MotMem in Motor2Ins:
         RotMotor(s, d, theta, t, MotMem)
         time.sleep(0.5)
except KeyboardInterrupt():
   RotMotor(11, 12, 0, 20, mem1)
   RotMotor(15, 16, 0, 20, mem2)

GPIO.cleanup()

本质上,我创建了一个充当记忆的列表,然后使用一些逻辑来根据它所记住的内容来决定动作应该如何工作。我想我应该在其他地方写入文件,然后替换当前的内存值,而不是因为内存原因让列表不断增长,但这目前有效。


推荐阅读