DIY a motor module
A python module is a file .py.Weexpain how to compile step_motor.py throufh a simple stepping motor easyDriver.
Note: the content here require a little bit more knowledge.If you can find a module file compiled by others online,suggesting you should not compile codes yourself and buile wheel repeatedly.
But write a python module is much easier than write a transmittable drive in language C on MCU.
Knowledge:
- Know the drive theory of stepping motor.
- Know the using way to easyDriver
- Know the class to compile Python
Know control theory
First of all.know the stepping motor.
Our hardware is a driving module easyDriver.
We need to figure out how it works.
By looking through datasheet and the source online,we know:
The height of pin DIR decide the direction of electrical motor(corotation/rollback).Give an impulse to pin STEP,stepping motor will move one step.
Theory about stepping motor,take a look of this article please:http://singtown.cc/?p=67
Therefore the train of thought of programming is to abstract a class Stepper to control the height of IO port.
First step:frame
class Stepper:
def __init__(self, step_pin, dir_pin):
#初始化
def steps(self, step_count):
#驱动电机走几步
def rel_angle(self, angle):
#驱动电机旋转相应的角度(相对角度控制)
def abs_angle(self, angle):
#驱动电机旋转到相应的位置(绝对角度控制)
This is a class only without adding material function.
Second step:add constructor
Constructor will be transmitted when instantiate object,can be regarded as initialized function.
Take s = Stepper(xxx) as an example,it will run the procedure in init(xxx).
We import two pin object in parameter,and a step_time is defaulted as 200.Since stepping motor moves step by step,between every step,there is a time lag,here we default it as 200us.
class Stepper:
def __init__(self, step_pin, dir_pin, step_time=200):
#初始化
self.stp = step_pin
self.dir = dir_pin
self.stp.init(Pin.OUT_PP)
self.dir.init(Pin.OUT_PP)
self.step_time = step_time # us
self.steps_per_rev = 1600
self.current_position = 0
def steps(self, step_count):
#驱动电机走几步
def rel_angle(self, angle):
#驱动电机旋转相应的角度(相对角度控制)
def abs_angle(self, angle):
#驱动电机旋转到相应的位置(绝对角度控制)
Add hardware realization
uUdelay is function of timelag us that import from the first sentence import. Realize moving function of stepping motor in steps(xxx). First set PWL of pin dir(control direction),then pin stp send impulse can do.
from pyb import udelay
class Stepper:
def __init__(self, step_pin, dir_pin, step_time=200):
#初始化
self.stp = step_pin
self.dir = dir_pin
self.stp.init(Pin.OUT_PP)
self.dir.init(Pin.OUT_PP)
self.step_time = step_time # us
self.steps_per_rev = 1600
self.current_position = 0
def steps(self, step_count=1):
#驱动电机走几步
self.dir.value(0 if step_count > 0 else 1)#当step_count为正数的时候,设置dir引脚为低电平。否则为高电平。
for i in range(abs(step_count)):#发送step_count数量的脉冲
self.stp.value(1)
udelay(self.step_time)
self.stp.value(0)
udelay(self.step_time)
self.current_position += step_count#记录现在的角度
def rel_angle(self, angle):
#驱动电机旋转相应的角度(相对角度控制)
def abs_angle(self, angle):
#驱动电机旋转到相应的位置(绝对角度控制)
Test steps
Save the code of this class as file stepper.py putting into root directory of OpenMV transmit Stepper in main.py. Test if steps can make stepping motor rotate. Do not foget to supply power to electrical motor.
from stepper import Stepper
from pyb import Pin
dir_pin = Pin(‘P0’)
stp_pin = Pin(‘P1’)
s = Stepper(step_pin=stp_pin, dir_pin=dir_pin)
s.steps()#电机动一步
s.steps(100)#电机动100步
s.steps(-100)#电机反转100步
Add function about angle of rotation
A variable steps_per_rev has been written in init(xxx),1600 here stands for 1600 impulses per circle.Why?Because the model number of electrical motor is 200 impulses(stepping angle is 1.8 degree),easyDriver has 8 subsections.Not knowing about subsections,look through the source of stepping motor.
Since 1600 impulses per circle,then one step is 360/1600.According to this relation,the formula from angle to impulse is :angle/360*1600.
Then in absolute angle control,because we record current position so do some math,then rotate.
from pyb import udelay
class Stepper:
def __init__(self, step_pin, dir_pin, step_time=200):
#初始化
self.stp = step_pin
self.dir = dir_pin
self.stp.init(Pin.OUT_PP)
self.dir.init(Pin.OUT_PP)
self.step_time = step_time # us
self.steps_per_rev = 1600
self.current_position = 0
def steps(self, step_count=1):
#驱动电机走几步
self.dir.value(0 if step_count > 0 else 1)
for i in range(abs(step_count)):
self.stp.value(1)
udelay(self.step_time)
self.stp.value(0)
udelay(self.step_time)
self.current_position += step_count
def rel_angle(self, angle):
#驱动电机旋转相应的角度(相对角度控制)
steps = int(angle / 360 * self.steps_per_rev)
self.steps(steps)
def abs_angle(self, angle):
#驱动电机旋转到相应的位置(绝对角度控制)
steps = int(angle / 360 * self.steps_per_rev)
steps -= self.current_position % self.steps_per_rev
self.steps(steps)
Accomplish
Thus ,a module Stepper is done!What’s more,some extra function can be added like reading angle or rotating xx .
Test code in main.py:
from pyb import Pin
from stepper import Stepper
import time
step_pin = Pin('P0')
dir_pin = Pin('P1')
my_stepper = Stepper(step_pin,dir_pin)
print("relative angle move test begin:", my_stepper.read_pos())
my_stepper.rel_angle(180)#相对角度控制
print("relative angle move test end:", my_stepper.read_pos())
time.sleep_ms(1000)
print("steps angle move test end:", my_stepper.read_pos())
my_stepper.steps(-400)#步进脉冲控制
print("steps angle move test end:", my_stepper.read_pos())
time.sleep_ms(1000)
print("absolute angle move test begin:", my_stepper.read_pos())
my_stepper.abs_angle(0)#绝对角度控制
print("absolute angle move test end:", my_stepper.read_pos())
time.sleep_ms(1000)