我們有二種的工作模式
- Full-step:
- Half-step.
Example1 :
half step control:
import time
import sys
import RPi.GPIO as GPIO
def step_8 (p):
if p==0:
GPIO.output(5,0)
GPIO.output(6,0)
GPIO.output(12,0)
GPIO.output(13,0)
if p==1:
GPIO.output(5,1)
GPIO.output(6,0)
GPIO.output(12,0)
GPIO.output(13,0)
if p==2:
GPIO.output(5,1)
GPIO.output(6,1)
GPIO.output(12,0)
GPIO.output(13,0)
if p==3:
GPIO.output(5,0)
GPIO.output(6,1)
GPIO.output(12,0)
GPIO.output(13,0)
if p==4:
GPIO.output(5,0)
GPIO.output(6,1)
GPIO.output(12,1)
GPIO.output(13,0)
if p==5:
GPIO.output(5,0)
GPIO.output(6,0)
GPIO.output(12,1)
GPIO.output(13,0)
if p==6:
GPIO.output(5,0)
GPIO.output(6,0)
GPIO.output(12,1)
GPIO.output(13,1)
if p==7:
GPIO.output(5,0)
GPIO.output(6,0)
GPIO.output(12,0)
GPIO.output(13,1)
if p==8:
GPIO.output(5,1)
GPIO.output(6,0)
GPIO.output(12,0)
GPIO.output(13,1)
def step_4 (p):
if p==0:
GPIO.output(5,0)
GPIO.output(6,0)
GPIO.output(12,0)
GPIO.output(13,0)
if p==1:
GPIO.output(5,1)
GPIO.output(6,1)
GPIO.output(12,0)
GPIO.output(13,0)
if p==2:
GPIO.output(5,0)
GPIO.output(6,1)
GPIO.output(12,1)
GPIO.output(13,0)
if p==3:
GPIO.output(5,0)
GPIO.output(6,0)
GPIO.output(12,1)
GPIO.output(13,1)
if p==4:
GPIO.output(5,1)
GPIO.output(6,0)
GPIO.output(12,0)
GPIO.output(13,1)
用另一種寫法
def steps_8(value):
print value
global pas
if(value<0):
for i in range (0,abs(value)):
step_8(pas)
time.sleep(0.005)
pas+=1
if(pas>=9):
pas=1;
else:
for i in range (0,abs(value)):
step_8(pas)
time.sleep(0.005)
if(pas==1):
pas=9;
pas-=1
step_8(0)
def steps_4(value):
print value
global pas
if(value<0):
for i in range (0,abs(value)):
step_4(pas)
time.sleep(0.005)
pas+=1
if(pas>=5):
pas=1;
else:
for i in range (0,abs(value)):
step_4(pas)
time.sleep(0.005)
if(pas==1):
pas=5;
pas-=1
step_4(0)
主程式
if __name__ == "__main__":
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(5, GPIO.OUT)
GPIO.setup(6, GPIO.OUT)
GPIO.setup(12, GPIO.OUT)
GPIO.setup(13, GPIO.OUT)
step_4(0)
pas=1
print len(sys.argv)
if(len(sys.argv)<2):
print ("Parameter error")
print ("Usage: sudo python steeper.py val mode")
print ("val = step number >0clockwise, <0 anticlockwise ")
print ("mode = 0: 8 phase 2: 1 phase ")
else:
st=int(sys.argv[1])
if(len(sys.argv)==3 and sys.argv[2]=="1"):
print("8 phase moving")
steps_8(st)
else:
print("4 phase moving")
steps_4(st)
測試:
python stepper.py -500 0
# 500 steps anti clockwise full step mode
python stepper.py 800 1
# 800 steps clockwise, half-step mode.
#----------------------------------
Example2:
Python: stepper.py
#!/usr/bin/python
# Import required libraries
import
sys
import
time
import
RPi.GPIO as GPIO
# Use BCM GPIO references
# instead of physical pin numbers
GPIO.setmode(GPIO.BCM)
# Define GPIO signals to use
# Physical pins 11,15,16,18
# GPIO17,GPIO22,GPIO23,GPIO24
StepPins
=
[
17
,
22
,
23
,
24
]
# Set all pins as output
for
pin
in
StepPins:
print
"Setup pins"
GPIO.setup(pin,GPIO.OUT)
GPIO.output(pin,
False
)
# Define advanced sequence
# as shown in manufacturers datasheet
Seq
=
[[
1
,
0
,
0
,
1
],
[
1
,
0
,
0
,
0
],
[
1
,
1
,
0
,
0
],
[
0
,
1
,
0
,
0
],
[
0
,
1
,
1
,
0
],
[
0
,
0
,
1
,
0
],
[
0
,
0
,
1
,
1
],
[
0
,
0
,
0
,
1
]]
StepCount
=
len
(Seq)
StepDir
=
1
# Set to 1 or 2 for clockwise
# Set to -1 or -2 for anti-clockwise
# Read wait time from command line
if
len
(sys.argv)>
1
:
WaitTime
=
int
(sys.argv[
1
])
/
float
(
1000
)
else
:
WaitTime
=
10
/
float
(
1000
)
# Initialise variables
StepCounter
=
0
# Start main loop
while
True
:
print
StepCounter,
print
Seq[StepCounter]
for
pin
in
range
(
0
,
4
):
xpin
=
StepPins[pin]
# Get GPIO
if
Seq[StepCounter][pin]!
=
0
:
print
" Enable GPIO %i"
%
(xpin)
GPIO.output(xpin,
True
)
else
:
GPIO.output(xpin,
False
)
StepCounter
+
=
StepDir
# If we reach the end of the sequence
# start again
if
(StepCounter>
=
StepCount):
StepCounter
=
0
if
(StepCounter<
0
):
StepCounter
=
StepCount
+
StepDir
# Wait before moving on
time.sleep(WaitTime)
python stepper.py 20
測試 20 milliseconds
#--------------------------------------
Example3 : A Python class to move the stepper motor
where-clock/Stepper.py (Source)
#!/usr/bin/env python
# the 28BJY-48 stepper motor with ULN2003 control board.
from time import sleep
import RPi.GPIO as GPIO
class Motor(object):
def __init__(self, pins, mode=3):
"""Initialise the motor object.
pins -- a list of 4 integers referring to the GPIO pins that the IN1, IN2
IN3 and IN4 pins of the ULN2003 board are wired to
mode -- the stepping mode to use:
1: wave drive (not yet implemented)
2: full step drive
3: half step drive (default)
"""
self.P1 = pins[0]
self.P2 = pins[1]
self.P3 = pins[2]
self.P4 = pins[3]
self.mode = mode
self.deg_per_step = 5.625 / 64 # for half-step drive (mode 3)
self.steps_per_rev = int(360 / self.deg_per_step) # 4096
self.step_angle = 0 # Assume the way it is pointing is zero degrees
for p in pins:
GPIO.setup(p, GPIO.OUT)
GPIO.output(p, 0)
def _set_rpm(self, rpm):
"""Set the turn speed in RPM."""
self._rpm = rpm
# T is the amount of time to stop between signals
self._T = (60.0 / rpm) / self.steps_per_rev
# This means you can set "rpm" as if it is an attribute and
# behind the scenes it sets the _T attribute
rpm = property(lambda self: self._rpm, _set_rpm)
def move_to(self, angle):
"""Take the shortest route to a particular angle (degrees)."""
# Make sure there is a 1:1 mapping between angle and stepper angle
target_step_angle = 8 * (int(angle / self.deg_per_step) / 8)
steps = target_step_angle - self.step_angle
steps = (steps % self.steps_per_rev)
if steps > self.steps_per_rev / 2:
steps -= self.steps_per_rev
print "moving " + `steps` + " steps"
if self.mode == 2:
self._move_acw_2(-steps / 8)
else:
self._move_acw_3(-steps / 8)
else:
print "moving " + `steps` + " steps"
if self.mode == 2:
self._move_cw_2(steps / 8)
else:
self._move_cw_3(steps / 8)
self.step_angle = target_step_angle
def __clear(self):
GPIO.output(self.P1, 0)
GPIO.output(self.P2, 0)
GPIO.output(self.P3, 0)
GPIO.output(self.P4, 0)
def _move_acw_2(self, big_steps):
self.__clear()
for i in range(big_steps):
GPIO.output(self.P3, 0)
GPIO.output(self.P1, 1)
sleep(self._T * 2)
GPIO.output(self.P2, 0)
GPIO.output(self.P4, 1)
sleep(self._T * 2)
GPIO.output(self.P1, 0)
GPIO.output(self.P3, 1)
sleep(self._T * 2)
GPIO.output(self.P4, 0)
GPIO.output(self.P2, 1)
sleep(self._T * 2)
def _move_cw_2(self, big_steps):
self.__clear()
for i in range(big_steps):
GPIO.output(self.P4, 0)
GPIO.output(self.P2, 1)
sleep(self._T * 2)
GPIO.output(self.P1, 0)
GPIO.output(self.P3, 1)
sleep(self._T * 2)
GPIO.output(self.P2, 0)
GPIO.output(self.P4, 1)
sleep(self._T * 2)
GPIO.output(self.P3, 0)
GPIO.output(self.P1, 1)
sleep(self._T * 2)
def _move_acw_3(self, big_steps):
self.__clear()
for i in range(big_steps):
GPIO.output(self.P1, 0)
sleep(self._T)
GPIO.output(self.P3, 1)
sleep(self._T)
GPIO.output(self.P4, 0)
sleep(self._T)
GPIO.output(self.P2, 1)
sleep(self._T)
GPIO.output(self.P3, 0)
sleep(self._T)
GPIO.output(self.P1, 1)
sleep(self._T)
GPIO.output(self.P2, 0)
sleep(self._T)
GPIO.output(self.P4, 1)
sleep(self._T)
def _move_cw_3(self, big_steps):
self.__clear()
for i in range(big_steps):
GPIO.output(self.P3, 0)
sleep(self._T)
GPIO.output(self.P1, 1)
sleep(self._T)
GPIO.output(self.P4, 0)
sleep(self._T)
GPIO.output(self.P2, 1)
sleep(self._T)
GPIO.output(self.P1, 0)
sleep(self._T)
GPIO.output(self.P3, 1)
sleep(self._T)
GPIO.output(self.P2, 0)
sleep(self._T)
GPIO.output(self.P4, 1)
sleep(self._T)
if __name__ == "__main__":
GPIO.setmode(GPIO.BOARD)
m = Motor([18,22,24,26])
m.rpm = 5
print "Pause in seconds: " + `m._T`
m.move_to(90)
sleep(1)
m.move_to(0)
sleep(1)
m.mode = 2
m.move_to(90)
sleep(1)
m.move_to(0)
GPIO.cleanup()
the motor round by 90 degrees, pause for 1 second, move it back again
#--------------------------------
28BYJ-48 Stepper Motor with ULN2003 driver and Arduino Uno
5 volts DC => about 15+ RPM
12 volts DC => about 25+ RPM.
28BYJ-48 Stepper Motor 特性
Motor Type | Unipolar stepper motor |
Connection Type | 5 Wire Connection (to the motor controller) |
Voltage | 5-12 Volts DC |
Frequency | 100 Hz |
Step mode | Half-step mode recommended (8 step control signal sequence) |
Step angle | Half-step mode: 8 step control signal sequence (recommended) 5.625 degrees per step / 64 steps per one revolution of the internal motor shaftFull Step mode: 4 step control signal sequence 11.25 degrees per step / 32 steps per one revolution of the internal motor shaft |
Gear ratio | Manufacturer specifies 64:1. Some patient and diligent people on the Arduino forumshave disassembled the gear train of these little motors and determined that the exact gear ratio is in fact 63.68395:1. My observations confirm their findings. These means that in the recommended half-step mode we will have:64 steps per motor rotation x 63.684 gear ratio = 4076 steps per full revolution (approximately). |
Wiring to the ULN2003 controller | A (Blue), B (Pink), C (Yellow), D (Orange), E (Red, Mid-Point) |
Weight |
30g |
Model : 28BYJ-48
Rated voltage : 5VDC
Number of Phase : 4
Speed Variation Ratio : 1/64
Stride Angle : 5.625° /64
Frequency : 100Hz
DC resistance : 50Ω±7%(25℃)
Idle In-traction Frequency : > 600Hz
Idle Out-traction Frequency : > 1000Hz
In-traction Torque >34.3mN.m(120Hz)
Self-positioning Torque >34.3mN.m
Friction torque : 600-1200 gf.cm
Pull in torque : 300 gf.cm
Insulated resistance >10MΩ(500V)
Insulated electricity power :600VAC/1mA/1s
Insulation grade :A
Rise in Temperature <40K(120Hz)
Noise <35dB(120Hz,No load,10cm)
參考資料:
https://www.raspberrypi-spy.co.uk/2012/07/stepper-motor-control-in-python/
http://ingeniapp.com/en/stepper-motor-control-with-raspberry-pi/
http://blog.scphillips.com/posts/2012/12/a-python-class-to-move-the-stepper-motor/
http://42bots.com/tutorials/28byj-48-stepper-motor-with-uln2003-driver-and-arduino-uno/
留言列表