4、窗帘动起来:步进电机工作原理、ULN2003驱动板接线、28BYJ-48电机控制、正反转与角度控制

好,到了这一章,我们终于要让窗帘真正动起来了。

前面几章我们把传感器、继电器都玩了一遍,但那都是「开关量」控制。窗帘不一样,它需要精确地走到某个位置,开一半、关一半,或者只开30%。这时候,普通的直流电机就搞不定了。我们需要一种能精确控制角度的家伙——步进电机。

4.1 步进电机是什么?

步进电机,说白了就是一种「数字电机」。你给它一个脉冲,它就转一个固定的角度。不给脉冲,它就停在原地不动。你想想看,这多适合做窗帘?

我刚开始接触这个的时候,总觉得它跟伺服电机差不多。后来踩了坑才发现,步进电机是开环控制,没有反馈。你让它转100步,它就转100步,至于有没有被卡住,它不管。所以做窗帘的时候,一定要加限位开关,不然电机堵转了还在那使劲,容易烧。

核心概念:步进电机 = 脉冲数 × 步距角 = 转动角度

比如一个步进电机步距角是5.625°,你给它64个脉冲,它就转一圈(5.625° × 64 = 360°)。

4.2 28BYJ-48 步进电机详解

我们课程里用的是28BYJ-48,这是市面上最常见的5V步进电机。便宜、皮实、适合入门。我当年做第一个智能窗帘项目,用的就是它。

关键参数:

参数 值 说明
型号 28BYJ-48 28表示直径28mm
额定电压 5V DC 可以直接用Arduino的5V供电
步距角 5.625° 这是「半拍」模式下的角度
减速比 1:64 内部有齿轮减速,输出轴转一圈需要64×64个脉冲
相数 4相 内部有4个线圈

嗯,这里要注意。28BYJ-48内部自带了一个1:64的减速齿轮箱。什么意思呢?就是电机转子转64圈,输出轴才转1圈。所以实际控制的时候,要让输出轴转一圈,需要给 64(步距角圈数)× 64(减速比)= 4096 个脉冲。

我的经验:很多新手在这里算晕了。你只要记住:想让输出轴转90°,就是 4096 ÷ 4 = 1024 个脉冲。我一般会在代码里写一个函数,直接传角度进去,自动算脉冲数。

4.3 ULN2003 驱动板接线

步进电机不能直接接Arduino的IO口。为什么?因为电机线圈需要的电流比较大,Arduino的引脚撑死了输出20mA,根本带不动。这时候就需要驱动板。

ULN2003驱动板,本质上就是一个达林顿管阵列。它可以把Arduino的小信号放大成驱动电机的大电流。我见过有人直接用L298N去驱动28BYJ-48,其实没必要,大材小用。

接线方式:

28BYJ-48 电机  →  ULN2003 驱动板  →  Arduino
红线(VCC)    →  板子上的+号      →  5V
蓝线            →  IN4              →  D8
粉线            →  IN3              →  D9
黄线            →  IN2              →  D10
橙线            →  IN1              →  D11

避坑指南:我曾经有一次把电机的红线接到了Arduino的5V上,结果电机一转,Arduino就重启。后来才发现,电机启动瞬间电流能到200mA以上,直接把5V电压拉低了。正确的做法是:驱动板单独供电,或者用外部5V电源。Arduino的5V只给控制信号用。

4.4 正反转与角度控制

控制步进电机,其实就是控制脉冲的顺序。给线圈通电的顺序不同,电机转的方向就不同。

四相八拍控制时序:

// 正转脉冲序列
byte forward[8] = {
  0b0001,  // A相
  0b0011,  // A+B
  0b0010,  // B相
  0b0110,  // B+C
  0b0100,  // C相
  0b1100,  // C+D
  0b1000,  // D相
  0b1001   // D+A
};

// 反转就是把上面的顺序倒过来
byte backward[8] = {
  0b1001,
  0b1000,
  0b1100,
  0b0100,
  0b0110,
  0b0010,
  0b0011,
  0b0001
};

你看,正转和反转,其实就是把脉冲序列的顺序反过来。每次给一个脉冲,电机走一步。走完8个脉冲,就是一个完整的电气周期。

角度控制的核心代码:

void rotate(float angle, int direction) {
  // 计算需要的步数
  // 4096步 = 360°
  int steps = (angle / 360.0) * 4096;
  
  for(int i = 0; i < steps; i++) {
    // 根据方向选择脉冲序列
    if(direction == 1) {
      // 正转
      for(int j = 0; j < 8; j++) {
        digitalWrite(IN1, (forward[j] & 0x01));
        digitalWrite(IN2, (forward[j] & 0x02));
        digitalWrite(IN3, (forward[j] & 0x04));
        digitalWrite(IN4, (forward[j] & 0x08));
        delay(2);  // 速度控制
      }
    } else {
      // 反转
      for(int j = 0; j < 8; j++) {
        digitalWrite(IN1, (backward[j] & 0x01));
        digitalWrite(IN2, (backward[j] & 0x02));
        digitalWrite(IN3, (backward[j] & 0x04));
        digitalWrite(IN4, (backward[j] & 0x08));
        delay(2);
      }
    }
  }
}

实际应用:做窗帘控制时,我一般会先让电机走到限位开关位置,把这个位置记为「关」。然后根据窗帘的总行程,计算出「开」的位置需要多少步。比如窗帘总行程是1000步,那开一半就是500步。这样每次上电都不用校准,直接走步数就行。

4.5 本章知识体系

下面这张图,是我自己总结的步进电机控制逻辑。你看一遍,应该就能把整个流程串起来。

步进电机控制知识体系 Arduino 控制信号 ULN2003 驱动板 28BYJ-48 电机 脉冲序列控制 正转/反转 角度计算 限位保护 关键公式:角度 = 步数 × 步距角 ÷ 减速比 28BYJ-48:步距角5.625°,减速比1:64,一圈需4096步 经验:实际项目中建议用微步控制,减少震动和噪音

4.6 常见问题与调试

做步进电机控制,最容易出问题的就是电机不转或者乱转。我总结了几种情况:

  • 电机不转但发热:大概率是脉冲频率太高,电机跟不上。把delay(2)改成delay(5)试试。
  • 电机震动但不转:可能是某一线圈没接好,或者驱动板坏了。用万用表量一下各相电阻,正常应该在50Ω左右。
  • 电机转但方向反了:把正转和反转的脉冲序列互换就行,不用改硬件。
  • 电机转几圈就卡住:检查一下减速比设置。我遇到过有人把1:64的电机当1:16的来驱动,结果算出来的步数全错。

我的调试习惯:每次写步进电机代码,我都会先让电机转一圈,用记号笔在输出轴上做个标记。如果转完一圈标记回到原位,说明步数算对了。这个方法虽然土,但特别管用。

好了,这一章的内容就到这里。步进电机控制其实不难,关键是把脉冲、步距角、减速比这三个概念搞清楚。下一章我们会把电机装到窗帘轨道上,配合光敏传感器,做一个真正的智能窗帘。

可可精品资料库