-
福利一海量deepseek资料包(持续更新)
-
福利二ComfyUI工作流&模型&插件
-
福利三AI工具集合包以及AI绘画解决方案
与所有电机一样,步进电机也包括固定部分(定子)和活动部分(转子)。定子上有缠绕了线圈的齿轮状突起,而转子为永磁体或可变磁阻铁芯。稍后我们将更深入地介绍不同的转子结构。
步进电机的基本工作原理为:


ABCD为定子,上面绕有线圈,为四相,与之相对应的对面四个定子上面也有线圈,相对应的两个定子之间线圈是相互连接形成一个绕组。
如当前为初始状态,B相导通,对0的吸引力最大。
接下来B断开,C导通,1和C相之间夹角最小被吸引过去,被吸引过去之前2和D相之间夹角为1和C相之间夹角的2倍,1被吸引到C以后,2和D之间最近,此时0和A之间的夹角为2和D之间的2倍,
接下来C断开,D导通,2被吸引到D,此时0距离A最近
D断开A导通,0被吸引到A相,至此一个周期完成
每次给两个线圈通电,通过改变通电的线圈从而使步进电机转动 五线四相步进电机:在双拍工作方式下,线圈的通电方式依次是:AB、BC、CD、DA 即单拍工作方式下,线圈的通电方式依次是:A、B、C、D
单双拍工作方式就是单拍工作方式和双拍工作方式交替进行。 五线四相步进电机:A、AB、B、BC、C、CD、D、DA;
| 模块引脚 | ESP32引脚 |
|---|---|
| IN1 | GPIO27 |
| IN2 | GPIO14 |
| IN3 | GPIO12 |
| IN4 | GPIO13 |
| 5V | 5V(VIN) |
| GND | GND |

我们先通过代码来了解,如何通过 ULN2003 驱动步进电机转动指定步数,我们已经知道八拍模式下,4096 个节拍转动一圈,那我们如果想要转动半周,也就是 180°,就需要 2048 拍,我们的代码,每次循环走每 8 拍(四拍模式下虽然走的是四拍,但是与八拍转动相同的角度)。因此,我们需要循环 2048/8=256 次,才能转动 180°。
那如果我们想要转动其他角度就可以通过这么一个公式 4096/8 * 角度/360 来计算。
import time
from machine import Pin
a = Pin(13, Pin.OUT)
b = Pin(12, Pin.OUT)
c = Pin(14, Pin.OUT)
d = Pin(27, Pin.OUT)
delay_time = 2 # 这个时间不能设置太小,否则电机来不及响应
print("单四拍模式")
for i in range (256): # 顺时针转动180度
a.value(1)
b.value(0)
c.value(0)
d.value(0)
time.sleep_ms(delay_time)
a.value(0)
b.value(1)
c.value(0)
d.value(0)
time.sleep_ms(delay_time)
a.value(0)
b.value(0)
c.value(1)
d.value(0)
time.sleep_ms(delay_time)
a.value(0)
b.value(0)
c.value(0)
d.value(1)
time.sleep_ms(delay_time)
# 改变脉冲的顺序, 可以方便的改变转动的方向
for i in range (256): # 逆时针转动转动180度
a.value(0)
b.value(0)
c.value(0)
d.value(1)
time.sleep_ms(delay_time)
a.value(0)
b.value(0)
c.value(1)
d.value(0)
time.sleep_ms(delay_time)
a.value(0)
b.value(1)
c.value(0)
d.value(0)
time.sleep_ms(delay_time)
a.value(1)
b.value(0)
c.value(0)
d.value(0)
time.sleep_ms(delay_time)
# 双四拍模式
print("双四拍模式")
for i in range (256): # 顺时针转动 180 度
a.value(1)
b.value(1)
c.value(0)
d.value(0)
time.sleep_ms(delay_time)
a.value(0)
b.value(1)
c.value(1)
d.value(0)
time.sleep_ms(delay_time)
a.value(0)
b.value(0)
c.value(1)
d.value(1)
time.sleep_ms(delay_time)
a.value(1)
b.value(0)
c.value(0)
d.value(1)
time.sleep_ms(delay_time)
print('八拍模式')
for i in range(256):
a.value(1)
b.value(0)
c.value(0)
d.value(0)
time.sleep_ms(delay_time)
a.value(1)
b.value(1)
c.value(0)
d.value(0)
time.sleep_ms(delay_time)
a.value(0)
b.value(1)
c.value(0)
d.value(0)
time.sleep_ms(delay_time)
a.value(0)
b.value(1)
c.value(1)
d.value(0)
time.sleep_ms(delay_time)
a.value(0)
b.value(0)
c.value(1)
d.value(0)
time.sleep_ms(delay_time)
a.value(0)
b.value(0)
c.value(1)
d.value(1)
time.sleep_ms(delay_time)
a.value(0)
b.value(0)
c.value(0)
d.value(1)
time.sleep_ms(delay_time)
a.value(1)
b.value(0)
c.value(0)
d.value(1)
time.sleep_ms(delay_time)
# 步进电机停止后需要使四个相位引脚都为低电平,否则步进电机会发热
a.value(0)
b.value(0)
c.value(0)
d.value(0)
我们也可以使用 ULN2003 的第三方模块驱动步进电机,把代码上传保存 uln2003.py 文件中。
# uln2003.py
import time
# only test for uln2003
class Uln2003:
FULL_ROTATION = int(4075.7728395061727 / 8)
HALF_STEP = [
[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],
[1, 0, 0, 1],
]
FULL_STEP = [
[1, 1, 0, 0],
[0, 1, 1, 0],
[0, 0, 1, 1],
[1, 0, 0, 1]
]
def __init__(self, pin1, pin2, pin3, pin4, delay, mode='FULL_STEP'):
if mode == 'FULL_STEP':
self.mode = self.FULL_STEP
else:
self.mode = self.HALF_STEP
self.pin1 = pin1
self.pin2 = pin2
self.pin3 = pin3
self.pin4 = pin4
self.delay = delay # Recommend 10+ for FULL_STEP, 1 is OK for HALF_STEP
# Initialize all to 0
self.reset()
def step(self, count, direction=1):
"""Rotate count steps. direction = -1 means backwards"""
if count < 0:
direction = -1
count = -count
for x in range(count):
for bit in self.mode[::direction]:
self.pin1(bit[0])
self.pin2(bit[1])
self.pin3(bit[2])
self.pin4(bit[3])
time.sleep_ms(self.delay)
self.reset()
def angle(self, r, direction=1):
self.step(int(self.FULL_ROTATION * r / 360), direction)
def reset(self):
# Reset to 0, no holding, these are geared, you can't move them
self.pin1(0)
self.pin2(0)
self.pin3(0)
self.pin4(0)
接着在其他程序中调用 Uln2003 这个类即可,代码如下:
from machine import Pin
from uln2003 import Uln2003
motor = Uln2003(pin1=Pin(13), pin2=Pin(12), pin3=Pin(14), pin4=Pin(27), delay=2, mode='HALF_STEP')
motor.angle(180, -1)