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. 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.

In Python, I have tried to create a function in a variety of ways. I used tkinter to get the mouse position on the screen, it moves in the x axis rotating the stepper. 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. +5, -5 The function I have tried to create should work like this.

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 = 'rn'
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 = 'rn'
        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. step(10) stepper moves 10 steps, do it again the motor does nothing as it is already at 10 steps. If I do step(15) it would only move another 5 as it is at 10 steps. Edit2 Clarification: By function I mean

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

Answer

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 = 'rn'
        current = steps
        neg = past - 5 # tolerance both are unused atm
        pos = past + 5 # tolerance
        needed = current - past
        print(needed, steps)
        if current != past:
                if steps > 0:
                        serialsteps = str(needed).encode('utf_8')
                        ser.write(dir1 + sender)
                        ser.write(serialsteps + sender)
                if steps < 0:
                        needed = needed * -1
                        serialstepss = str(needed).encode('utf_8')
                        ser.write(dir2 + sender)
                        ser.write(serialstepss + sender)
        past = steps

For me it goes to a Arduino, the Arduino is not programmed to accept negative numbers. 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.

Leave a Reply

Your email address will not be published. Required fields are marked *