简体   繁体   English

将步进电机移动到精确的 position

[英]Move a stepper motor to an exact position

My setup: An Arduino that reads numbers from serial(steps), then it moves the stepper motor that many steps.我的设置:一个 Arduino 从串行(步数)读取数字,然后它将步进电机移动许多步。 It uses a4988 driver, a 12 volt power supply, 1.5 amp Nema 17. All of that is fine, my issue is on the Python side.它使用 a4988 驱动器,12 伏电源,1.5 安培 Nema 17。一切都很好,我的问题是在 Python 方面。

In Python, I have tried to create a function in a variety of ways.在 Python 中,我尝试以多种方式创建 function。 I used tkinter to get the mouse position on the screen, it moves in the x axis rotating the stepper.我使用 tkinter 将鼠标 position 放在屏幕上,它在 x 轴上移动,旋转步进器。 The stepper has a flashlight just to shine it at anything I point at with my mouse.步进器有一个手电筒,可以照亮我用鼠标指向的任何东西。

Say there is a camera below the stepper, if I move my mouse over to an object it would move there, within a tolerance of 5 steps either way.假设步进器下方有一个摄像头,如果我将鼠标移到 object 上,它会移动到那里,误差在 5 步以内。 +5, -5 The function I have tried to create should work like this. +5, -5 我尝试创建的 function 应该像这样工作。

while True:
#I change direction by writing 400, clockwise, or 401, anti clockwise to serial.
    step(10)#move only 10 steps
    step(10)#it should do nothing as it has already moved 10 steps.
    step(15)#it should move 5 steps as it has moved 10 already
    step(5)#change direction and move back 10 steps
I am somewhat decent at python(or so I think)
here is my most promising code so far:
#I have direction changes done by writing a 400 for clockwise or 401 for anti clockwise to serial.
import tkinter as tk
import serial
ser = serial.Serial("COM8", 9600)
root = tk.Tk()
wi = root.winfo_screenwidth() / 2
width = root.winfo_screenwidth()
hi = root.winfo_screenheight() / 2
height = root.winfo_screenheight()
sere = '\r\n'
sender = sere.encode('utf_8')
pps = height / 200 
# p.p.s pixels per step divide that by the same thing to get correct.
#how many pixels are for 1 step
print(pps)
#number of pixels difference divided by pps to get steps, then round for ease of use
past = 0
print(height, width, wi) # height divided by pps should always = max steps in my case 200
def send(steps):
        global past
        global current
        sere = '\r\n'
        current = steps
        neg = past - 5
        pos = past + 5
        if current != past:
                if current > pos or current < neg:
                        if steps > 1:
                                sender = sere.encode('utf_8')
                                e = str(steps).encode('utf_8')
                                ser.write(e + sender)
        past = steps
while True:
        pos = root.winfo_pointerx() - wi
        steps = round(pos / pps)
        print(pos, steps) # shows cursor position
#direction code is not in here as I have no need for it atm.For one simple reason, IT DOESN'T WORK!

Please explain answers if possible, I am a long time lurker, and only made a account just now for this.Thank you all for any assistance.如果可能的话请解释答案,我是一个长期的潜伏者,只是为了这个才注册了一个帐户。谢谢大家的帮助。 Edit: The question is how to make a function that moves a stepper motor to a certain number of steps.If you command it to do 10 steps twice, it only moves 10 steps.编辑:问题是如何制作一个 function 将步进电机移动到一定数量的步数。如果你命令它两次执行 10 步,它只移动 10 步。 step(10) stepper moves 10 steps, do it again the motor does nothing as it is already at 10 steps. step(10) 步进器移动 10 步,再做一次电机什么也不做,因为它已经是 10 步了。 If I do step(15) it would only move another 5 as it is at 10 steps.如果我执行第(15)步,它只会再移动 5 步,因为它是 10 步。 Edit2 Clarification: By function I mean Edit2 澄清:function 我的意思是

def step(steps):
    #logic that makes it work

For anyone else who has this problem and people seem to not help a ton, heres my new code to drive it,对于遇到此问题且人们似乎无能为力的其他人,这是我的新代码来驱动它,

past = 0
sender = sere.encode('utf_8')
dir1 = str(400).encode('utf_8')
dir2 = str(401).encode('utf_8')
def send(steps):
        global past
        global current
        global sender
        global dir1
        global dir2
        global stepstaken
        sere = '\r\n'
        current = steps
        neg = past - 5 # tolerance both are unused atm
        pos = past + 5 # tolerance
        needed = current - past
        print(needed, steps)
        if current != past:
                if needed > 0:
                        serialsteps = str(needed).encode('utf_8')
                        ser.write(dir1 + sender)
                        ser.write(serialsteps + sender)
                if needed < 0:
                        needed = needed * -1
                        serialstepss = str(needed).encode('utf_8')
                        ser.write(dir2 + sender)
                        ser.write(serialstepss + sender)
        past = steps

Here is my full code for mouse to stepper motor,这是我的鼠标到步进电机的完整代码,

import tkinter as tk
root = tk.Tk()
import serial
import struct
import time
stepstaken = 0
ardunioport = "COM" + str(input("Ardunio Port Number:")) # port number only
ser = serial.Serial(ardunioport, 9600)
wi = root.winfo_screenwidth() / 2
width = root.winfo_screenwidth()
hi = root.winfo_screenheight() / 2
height = root.winfo_screenheight()
sere = '\r\n' #still don't understand why but it does not work without this.
sender = sere.encode('utf_8')
pps = width / 200 #how many pixels are in 1 step
past = 0
sender = sere.encode('utf_8')
dir1 = str(400).encode('utf_8')
dir2 = str(401).encode('utf_8')
def send(steps):
        global past
        global current
        global sender
        global dir1
        global dir2
        global stepstaken
        #need overcome overstepping
        sere = '\r\n'
        current = steps
        neg = past - 5 # tolerance 
        pos = past + 5 # tolerance
        needed = current - past
        print(needed, steps)
        if current != past:
                if needed > 0:
                        serialsteps = str(needed).encode('utf_8')
                        ser.write(dir1 + sender)
                        ser.write(serialsteps + sender)
                if needed < 0:
                        needed = needed * -1
                        serialstepss = str(needed).encode('utf_8')
                        ser.write(dir2 + sender)
                        ser.write(serialstepss + sender)
        past = steps

while True:
        pos = root.winfo_pointerx() - wi
        steps = round(pos / pps)
        #print("Mouse Position " + str(pos) + " Steps Needed" + str(steps)) # shows cursor position
        send(steps)        

For me it goes to a Arduino, the Arduino is not programmed to accept negative numbers.对我来说,它转到 Arduino,Arduino 没有被编程为接受负数。 Instead it removes the - sign, multiply negative by negative = positive.相反,它删除了 - 符号,将负数乘以负数 = 正数。 It sends the opposite direction code/number then the steps needed to get there.它发送相反方向的代码/号码,然后发送到达那里所需的步骤。 Good luck everyone.大家好运。 This code works for me, no promise it will work for you.If it does not I am sorry.这段代码对我有用,没有 promise 它会为你工作。如果没有,我很抱歉。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM