风筝
发表于: 2022-7-28 15:17:09 | 显示全部楼层

本帖最后由 风筝 于 2022-7-28 15:17 编辑

步进电机广泛用​​于控制我们每天看到的众多常见设备。从百叶窗、3D打印机和DVD播放器到安全摄像头和CNC机器,步进电机比您想象的更接近我们的生活。


探索步进电机的第一步是使用28BYJ-48步进电机。它们通常附带有基于ULN2003的驱动电路板,这使得它们非常易于使用。


你知道这些步进电机是如何工作的吗?

这些步进电机使用一个带齿的轮子(有32个齿)和四个在轮子周围形成一个环的电磁铁。


发送的每个高脉冲都会使线圈通电,吸引最靠近齿轮的齿,并以精确且固定的角度增量(称为步进)旋转电机。

Stepper-Motor-Working-Animation.gif


向这些线圈发送脉冲的方式会极大地影响电机的行为。

●    脉冲序列决定了电机的旋转方向。

●    脉冲的频率决定了电机的速度。

●    脉冲数决定了电机将转动多远。


28BYJ-48步进电机

28BYJ-48是一款5线单极步进电机,运行电压为5V。


这种电机最大的优势是它可以一次精确地定位一次步进。在需要精确定位的项目中它表现良好,例如打开和关闭通风口。

28BYJ48-Stepper-Motor.jpg


另一个优点是它的运动相对精确,并且由于电机不使用接触刷而非常可靠。


考虑到它的尺寸,电机在大约15RPM的速度下可提供34.3mN.m的不错扭矩。它即使在静止状态下也能提供良好的扭矩,只要向电机供电就​​可以保持这种扭矩。唯一的缺点是它有点耗电,即使它不移动也会消耗电力。


引脚排列

28BYJ-48是5线步进电机。引脚排列如下:

28BYJ48-Stepper-Motor-Pinout.jpg


28BYJ-48由两个线圈组成,每个线圈都有一个中心抽头。两个中心抽头在内部连接并作为第5根线(红线)引出。


线圈的一端和中心抽头一起形成一个相位。因此28BYJ-48共有4个相位。

28BYJ48-Stepper-Motor-Coil-Structure.jpg


红线一直是高电平。当另一条引线拉低时,该相通电。


只有当相位以称为步进时序的逻辑顺序通电时,步进电机才会旋转。


齿轮减速比

根据数据表,当28BYJ-48电机在全步模式下运行时,每步对应于11.25°的旋转。这意味着每转有32步 (360°/11.25° = 32)。

28BYJ48-Stepper-Motor-Gear-Ratio-Explanation.jpg


除此之外,电机还有1/64减速齿轮组。 (实际上它是1/63.68395,但对于大多数用途来说,1/64是一个足够好的近似值)


这意味着实际上有2038步(每转 32*63.68395 步 = 2037.8864 大约2038步)。


功耗

28BYJ-48通常消耗大约 240mA。


由于电机消耗大量电流,因此最好直接从外部5V电源为其供电,而不是从Arduino获取电量。


请注意,即使在静止状态下,电机也会消耗电量以保持其位置。


技术规格

以下是完整的规格:

工作电压
5VDC
工作电流
240mA(典型)
相数
4
齿轮减速比
64:1
步距角
5.625°/64
频率
100Hz
牵引扭矩
>34.3mN.m(120Hz)
自定位扭矩
>34.3mN.m
摩擦力矩
600-1200 gf.cm
拉入扭矩
300 gf.cm

该电机的有关详细信息,请参阅下面的数据手册:28BYJ-48数据手册


ULN2003驱动板

由于28BYJ-48步进电机消耗大电流,像Arduino这样的微控制器无法直接控制电机。它需要一个像ULN2003这样的驱动器IC来控制电机,所以这个电机通常带有一个基于ULN2003的驱动板。


ULN2003以其大电流和高电压能力而闻名,它提供比单个晶体管更高的电流增益,并使微控制器的低电压低电流输出能够驱动高电流步进电机。


ULN2003由一组七个达林顿晶体管对组成,每对能够驱动高达500mA和50V的负载。该驱动板上使用了七对中的四对。

ULN2003-Stepper-Motor-Driver-Overview.jpg


电路板有一个molex连接器,可以完美地连接电机线,从而非常容易地将电机连接到电路板。有四个控制输入和一个电源连接。


该驱动板有四个LED,显示四个控制输入线上的活动(以指示步进状态)。它们在不进时提供了良好的指示。该板还带有一个开/关跳线,用于隔离步进电机的电源。


ULN2003步进驱动板引脚排列

ULN2003步进驱动板的管脚如下:

ULN2003-Stepper-Motor-Driver-Pinout.jpg


IN1 – IN4 引脚用于驱动电机。将它们连接到Arduino上的数字输出引脚。

GND 是公共接地引脚。

VDD 引脚为电机供电。将其连接到外部5V电源。因为电机会消耗大量电流,所以切勿使用Arduino的5V电源来驱动此步进电机。

Motor Connector(电机连接器) 这是电机插入的地方。连接器是键控的,所以它只有这一种连接方式。


将28BYJ-48步进电机和ULN2003驱动器连接到Arduino开发板

现在了解了有关电机的所有信息,我们可以开始将它连接到Arduino。


首先将电源连接到ULN2003驱动器。使用独立的5V电源为步进电机供电。


之后,将该电源的接地连接到Arduino的接地。这非常重要,这样我们就可以在两者之间建立相同的电压基准。


现在将驱动板的IN1、IN2、IN3、IN4分别连接到Arduino数字引脚8、9、10和11。最后将电机电缆从步进电机连接到驱动板。


按照如下所示连接所有组件。

Wiring-28BYJ48-Stepper-Motor-with-ULN2003-Driver-and-Arduino.jpg


Arduino代码 - 使用内置的Stepper库

对于第一个实验,我们将使用与随Arduino IDE一起安装的Arduino Stepper库


Stepper库负责处理步进时序,并可以轻松控制各种步进电机,包括单极和双极。


以下是使步进电机顺时针缓慢旋转然后逆时针快速旋转的简单草图。

  1. //Includes the Arduino Stepper Library
  2. #include <Stepper.h>

  3. // Defines the number of steps per rotation
  4. const int stepsPerRevolution = 2038;

  5. // Creates an instance of stepper class
  6. // Pins entered in sequence IN1-IN3-IN2-IN4 for proper step sequence
  7. Stepper myStepper = Stepper(stepsPerRevolution, 8, 10, 9, 11);

  8. void setup() {
  9.         // Nothing to do (Stepper Library sets pins as outputs)
  10. }

  11. void loop() {
  12.         // Rotate CW slowly at 5 RPM
  13.         myStepper.setSpeed(5);
  14.         myStepper.step(stepsPerRevolution);
  15.         delay(1000);
  16.         
  17.         // Rotate CCW quickly at 10 RPM
  18.         myStepper.setSpeed(10);
  19.         myStepper.step(-stepsPerRevolution);
  20.         delay(1000);
  21. }
复制代码

代码说明

首先在草图代码中包含内置的Stepper库。

  1. #include <Stepper.h>
复制代码

接下来,我们定义一个常量stepsPerRevolution,它保存电机完成一圈所需的步数。在例子中,它的值是2038。

  1. const int stepsPerRevolution = 2038;
复制代码

28BYJ-48单极步进电机步进顺序为IN1-IN3-IN2-IN4。我们将使用这些信息来驱动电机,方法是创建一个名为myStepper实例,其引脚顺序为8、10、9、11。


确保你做对了,否则电机将无法正常工作。

  1. Stepper myStepper = Stepper(stepsPerRevolution, 8, 10, 9, 11);
复制代码

setup()函数中无需设置任何内容,因为Stepper库在内部将四个I/O引脚设置为输出。

  1. void setup() {
  2. }
复制代码

loop()函数中,我们使用setSpeed()函数来设置希望步进电机移动的速度,然后使用step()函数告诉它要旋转多少步。将负数传递给step()函数会反转电机的旋转方向。


第一个代码片段使电机顺时针旋转非常缓慢。另一个使电机以非常高的速度逆时针旋转。

  1. void loop() {
  2.         // Rotate CW slowly at 5 RPM
  3.         myStepper.setSpeed(5);
  4.         myStepper.step(stepsPerRevolution);
  5.         delay(1000);
  6.         
  7.         // Rotate CCW quickly at 10 RPM
  8.         myStepper.setSpeed(10);
  9.         myStepper.step(-stepsPerRevolution);
  10.         delay(1000);
  11. }
复制代码

跳转到指定楼层
风筝
发表于: 2022-7-28 15:55:16 | 显示全部楼层

Arduino代码 – 使用AccelStepper库

AccelStepper库非常适合简单的单个电机应用。但是当你想控制多个步进电机时,你需要一个更好的库。


因此,对于接下来的实验,我们将使用一个名为AccelStepper库的高级步进电机库。它在几个方面比标准的Arduino Stepper库要好得多:

●   它支持加速和减速。

●   支持半步步进。

●   它可以同时支持多个步进电机,每个步进电机上具有独立的并发步进。


该库不包含在Arduino IDE中,因此您需要先安装它。


库安装

要安装库,请导航至 Sketch > Include Libraries > Manage Libraries... 等待库管理器下载库索引并更新已安装库的列表。

Manage-Libraries.jpg


通过输入“accelstepper”过滤搜索。单击第一个条目,然后选择安装。

Installing-AccelStepper-Library.jpg


Arduino代码

以下是一个简单的草图,它在一个方向上加速步进电机,然后减速停止。一旦电机转一圈,它就会改变旋转方向。代码一遍又一遍地这样做。

  1. // Include the AccelStepper Library
  2. #include <AccelStepper.h>

  3. // Define step constant
  4. #define FULLSTEP 4

  5. // Creates an instance
  6. // Pins entered in sequence IN1-IN3-IN2-IN4 for proper step sequence
  7. AccelStepper myStepper(FULLSTEP, 8, 10, 9, 11);

  8. void setup() {
  9.         // set the maximum speed, acceleration factor,
  10.         // initial speed and the target position
  11.         myStepper.setMaxSpeed(1000.0);
  12.         myStepper.setAcceleration(50.0);
  13.         myStepper.setSpeed(200);
  14.         myStepper.moveTo(2038);
  15. }

  16. void loop() {
  17.         // Change direction once the motor reaches target position
  18.         if (myStepper.distanceToGo() == 0)
  19.                 myStepper.moveTo(-myStepper.currentPosition());

  20.         // Move the motor one step
  21.         myStepper.run();
  22. }
复制代码

代码说明

首先包含新安装的AccelStepper库。

  1. #include <AccelStepper.h>
复制代码

现在,由于我们希望电机以全步运行,因此将为它定义一个常数。如果您希望电机以半步运行,请将常数设置为8。

  1. #define FULLSTEP 4
复制代码

接下来,我们创建一个名为myStepper实例,其引脚序列为8、10、9、11(请记住,这些电机的步进顺序为IN1-IN3-IN2-IN4)。

  1. AccelStepper myStepper(FULLSTEP, 8, 10, 9, 11);
复制代码

setup()函数中,我们首先将电机的最大速度设置为1000,这与这些电机的速度差不多。然后我们为电机设置一个加速因子,为步进电机的运动添加加速和减速。


然后我们将常规速度设置为200,并将步数设置为2038(因为28BYJ-48及其齿轮传动装置每转需要2038步)。

  1. void setup() {
  2.         myStepper.setMaxSpeed(1000.0);
  3.         myStepper.setAcceleration(50.0);
  4.         myStepper.setSpeed(200);
  5.         myStepper.moveTo(2038);
  6. }
复制代码

loop()函数中,我们使用if语句检查电机需要驱动多远(通过读取distanceToGo属性),直到它到达目标位置(由 moveTo 设置)。一旦 distanceToGo 达到零,我们将通过将moveTo位置更改为其当前位置的负值,以相反的方向移动电机。


现在在loop()函数的底部,您将看到我们调用了一个 run() 函数。这是最重要的函数,因为在执行该函数之前步进器不会移动。

  1. void loop() {
  2.         // Change direction once the motor reaches target position
  3.         if (myStepper.distanceToGo() == 0)
  4.                 myStepper.moveTo(-myStepper.currentPosition());

  5.         // Move the motor one step
  6.         myStepper.run();
  7. }
复制代码

回复

使用道具 举报

风筝
发表于: 2022-7-28 16:07:02 | 显示全部楼层

同时控制两台28BYJ-48步进电机

对于接下来的实验,我们将在Arduino中添加第二个28BYJ-48步进电机,实现同时驱动两个电机。


硬件连接

保留您之前所做的连接,并按如下方式连接新的步进电机:


我们将再次使用单独的5V电源为ULN2003驱动板供电。 还要确保你有共同的地。现在将第二块驱动板的IN1、IN2、IN3、IN4分别连接到Arduino 数字引脚4、5、6和7。


下图显示了实际的接线方式。

Wiring-Two-28BYJ48-Stepper-Motors-with-Arduino.jpg


Arduino代码

以下草图以全步驱动另一个电机,以半步驱动另一个电机,并进行一些加速和减速。当电机转一圈时,它们的旋转方向就会改变。

  1. // Include the AccelStepper Library
  2. #include <AccelStepper.h>

  3. // Define step constants
  4. #define FULLSTEP 4
  5. #define HALFSTEP 8

  6. // Creates two instances
  7. // Pins entered in sequence IN1-IN3-IN2-IN4 for proper step sequence
  8. AccelStepper stepper1(HALFSTEP, 8, 10, 9, 11);
  9. AccelStepper stepper2(FULLSTEP, 4, 6, 5, 7);

  10. void setup() {
  11.         // set the maximum speed, acceleration factor,
  12.         // initial speed and the target position for motor 1
  13.         stepper1.setMaxSpeed(1000.0);
  14.         stepper1.setAcceleration(50.0);
  15.         stepper1.setSpeed(200);
  16.         stepper1.moveTo(2038);

  17.         // set the same for motor 2
  18.         stepper2.setMaxSpeed(1000.0);
  19.         stepper2.setAcceleration(50.0);
  20.         stepper2.setSpeed(200);
  21.         stepper2.moveTo(-2038);
  22. }

  23. void loop() {
  24.         // Change direction once the motor reaches target position
  25.         if (stepper1.distanceToGo() == 0)
  26.                 stepper1.moveTo(-stepper1.currentPosition());
  27.         if (stepper2.distanceToGo() == 0)
  28.                 stepper2.moveTo(-stepper2.currentPosition());

  29.         // Move the motor one step
  30.         stepper1.run();
  31.         stepper2.run();
  32. }
复制代码

代码说明

首先包含AccelStepper库。

  1. #include <AccelStepper.h>
复制代码

现在,我们要以全步驱动另一台电机,以半步驱动另一台电机,我们将定义两个常数。

  1. #define FULLSTEP 4
  2. #define HALFSTEP 8
复制代码

之后创建两个电机对象,每个电机一个。我们使用引脚定义和步进定义设置这些。

  1. AccelStepper stepper1(HALFSTEP, 8, 10, 9, 11);
  2. AccelStepper stepper2(FULLSTEP, 4, 6, 5, 7);
复制代码

setup()函数中,我们首先将步进电机1的最大速度设置为1000。然后我们为电机设置一个加速因子,为步进电机的运动添加加速和减速。然后我们将常规速度设置为200,并将步数设置为2038。


我们将对步进电机做同样的事情,除了我们将指示它移动到-2038,因为我们希望它以相反的方向旋转。

  1. void setup() {
  2.         // settings for motor 1
  3.     stepper1.setMaxSpeed(1000.0);
  4.     stepper1.setAcceleration(50.0);
  5.     stepper1.setSpeed(200);
  6.     stepper1.moveTo(2038);

  7.         // settings for motor 2
  8.     stepper2.setMaxSpeed(1000.0);
  9.     stepper2.setAcceleration(50.0);
  10.     stepper2.setSpeed(200);
  11.     stepper2.moveTo(-2038);
  12. }
复制代码

loop()函数中,我们使用两个if语句,每个电机一个,检查电机需要驱动多远(通过读取 distanceToGo 属性),直到它们到达目标位置(由 moveTo 设置)。一旦 distanceToGo 达到零,我们会将它们的 moveTo 位置更改为它们当前位置的负值,以便它们开始向相反方向移动。


最后,我们通过调用 run() 函数来设置它们。

  1. void loop() {
  2.         // Change direction once the motor reaches target position
  3.         if (stepper1.distanceToGo() == 0)
  4.                 stepper1.moveTo(-stepper1.currentPosition());
  5.         if (stepper2.distanceToGo() == 0)
  6.                 stepper2.moveTo(-stepper2.currentPosition());

  7.         // Move the motor one step
  8.         stepper1.run();
  9.         stepper2.run();
  10. }
复制代码

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

主题 714 | 回复: 1501



手机版|

GMT+8, 2024-12-21 20:57 , Processed in 0.042257 second(s), 6 queries , Gzip On, MemCache On. Powered by Discuz! X3.5

YiBoard一板网 © 2015-2022 地址:河北省石家庄市长安区高营大街 ( 冀ICP备18020117号 )

快速回复 返回顶部 返回列表