树莓派控制步进电机28BYJ48

步进电机控制原理

油管小哥介绍自己DIY的雕刻机

参考自 A Raspberry Pi controlled mini CNC Laser engraver

The central spinner of the bipolar stepper motor can be regarded as a bar magnet (actually it is circular). Obviously from the figure above that if we successively conduct current in coil a1, b2, a2 and b1, the spinner will spin in the desired sequence. To do this, we can apply a voltage sequence to a1, b2, a2, b1 as:1) high, low, low, low. So only a1 and a2 are activated. Since a1 a2 have same polarity (or opposite depending on how you define it), the spinner is pointing to a1
2)low, high, low, low. So only b2 and b1 are activated. Spinner is pointing to b2
3)low, low, high, low. So only a2 and a2 are activated. Spinner points to a2
4)low, low, low, high. Spinner points to b1.
go to 1).

Denote high as 1 and low as 0. The sequence can be written as 1000,0100,0010,0001

The advantage of this configuration is that it is very easy to understand and usually the stepper motor moves very precisely. However, since in each step only one pair of coils is activated, the torque applied on the spinner is not very great.

To achieve high torque, a more popular way is to apply the following sequence: 1100,0110,0011,1001. And the spinner will be pointing to middle of a1 and b2, middle of b2 and a2, middle of a2 and b1, middle of b1 and a1 consequentially. And the torque is doubled. This is called full-step mode or high torque mode or two phase mode.. and is usually the mode used.

If the torque won’t be a problem then we can use a 8-step sequence: 1000,1100,0100,0110,0010,0011,0001,1001. The spinner will turn 8 steps instead of 4 steps to turn same angle. This doubles the resolution. And the cost is the non-uniform torque being applied on the stepper motor. This is called half-step mode.

总结来说:电机里面的转子相当于一个长条磁铁,通过对不同端子的通断,控制着磁场方向,里面的转子就会跟着磁场方向旋转。如果是8步模式,因为需要两个方向的磁场合成一个磁场,力矩就变大了。

步进电机旋转是以固定的角度一步一步运行的,可以通过控制脉冲(端子的通断,比如:1000)来控制角位移量,从而达到准确定位的目的;同时可以通过控制脉冲频率来控制电机转动的速度和加速度,从而达到调速的目的。

步进电机28BYJ48

减速步进电机直径:28mm,电压:5V,步距角度(一个脉冲,实际转多少度):5.625 x 1/64,减速比:1/64。

步进电机又套了一系列减速齿轮,需要计算输出多少个脉冲,实际输出的齿轮旋转一周:360/(5.625 x 1/64)=4096。

说明:查看资料的时候,发现没有标注这个步距角度是八拍还是四拍的,从样例代码和实际效果来看这个步距角度指的是八拍的,那么推测四拍的步距角度就是5.625 x 2 x 1/64。不论八拍还是四拍,4096/8 = 512圈,也就是里面的电机转512圈,实际输出才1圈,力量是大了不少啊。

接线

驱动板ULN2003的in1,in2,in3,in4,对应步进电机的blu1,pik2,yel3,org4(是的,就是图中线的颜色),blu1和yel3相连(类比于原理图中的a1,a2),pik2和org4相连(类比于原理图中的b1,b2)。

驱动板ULN2003的in1,in2,in3,in4 连接树莓派的GPIO6,GPIO13,GPIO19,GPIO26。相当于GPIO6和GPIO19相连,是原理图中的a1,a2,GPIO13和GPIO26相连,是原理图中的b1,b2。

代码

参考自油管小哥数控雕刻机的代码:https://github.com/iandouglas96/engravR/blob/master/Bipolar_Stepper_Motor_Class.py

import RPi.GPIO as GPIO
import time, os
from os import path
ANGLE_FILE = path.join(path.dirname(path.abspath(__file__)), "angle.log")
class StepperMotor(object):
    # full step sequence.
    phase_seq=[[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]]
    num_phase=len(phase_seq)
    # 当前的phase
    phase=0
    
    def __init__(self,a1,a2,b1,b2):
        GPIO.setwarnings(False)
        GPIO.setmode(GPIO.BCM)
        
        self.a1=a1
        self.a2=a2
        self.b1=b1
        self.b2=b2
        
        GPIO.setup(self.a1,GPIO.OUT)
        GPIO.setup(self.a2,GPIO.OUT)
        GPIO.setup(self.b1,GPIO.OUT)
        GPIO.setup(self.b2,GPIO.OUT)
        
        self.phase=0
        self.dir=0      
        self.position=0
        
        if not os.path.exists(ANGLE_FILE):
            try:          
                angle_file = open(ANGLE_FILE,'w',encoding='utf-8')
                angle_file.write('0')
            except Exception as result:
                return None
            finally:
                angle_file.close()  
    # dir=1 方向:1代表正传,-1代表反转
    # steps 步进数,步进电机28BYJ48,4096是一周
    def move(self, dir=1, steps=4096, delay=0.1):
        for _ in range(steps):
            next_phase=(self.phase+dir) % self.num_phase;
            
            GPIO.output(self.a1, self.phase_seq[next_phase][0]);
            GPIO.output(self.b2, self.phase_seq[next_phase][1]);
            GPIO.output(self.a2, self.phase_seq[next_phase][2]);
            GPIO.output(self.b1, self.phase_seq[next_phase][3]);
            
            self.phase=next_phase;
            
            time.sleep(delay);
        self.unhold()
    # 每次旋转1/16周,22.5度
    def left_rotate(self):
        self.move(1, 256, 0.001)
        angle_now = float(self.get_angle()) + 22.5
        self.set_angle(angle_now)
    # 每次旋转1/16周,22.5度
    def right_rotate(self):
        self.move(-1, 256, 0.001)  
        angle_now = float(self.get_angle()) - 22.5
        self.set_angle(angle_now)
    def reset(self):
        angle_now = float(self.get_angle())
        if angle_now > 0:
            for i in range(0, int(abs(angle_now)/22.5)):
                self.right_rotate()
        else:
            for i in range(0, int(abs(angle_now)/22.5)):
                self.left_rotate()
    def unhold(self):
        GPIO.output(self.a1, False);
        GPIO.output(self.a2, False);
        GPIO.output(self.b1, False);
        GPIO.output(self.b2, False);
    def get_angle(self):
        with open(ANGLE_FILE, 'r') as f:
            return f.read()
    def set_angle(self, angle):
        with open(ANGLE_FILE, 'w') as f:
            f.write(str(angle))        
if __name__ == '__main__':
    GPIO.cleanup()
    MX=StepperMotor(6,19,13,26);
    # 转一圈
    MX.move(-1, 4096, 0.001);
    MX.move(1, 4096, 0.001);
    MX.left_rotate()
    MX.left_rotate()
    MX.right_rotate()
    MX.right_rotate()
    MX.right_rotate()
    MX.reset()
    MX.unhold();
Copyright © 2022,枫糖, 版权所有,禁止转载、演绎、商用。

打赏作者

离开前,建议您浏览一下 归档 页面,或许有更多相关的、有趣的内容!

添加评论

code