找回密码
 立即注册→加入我们

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 3214|回复: 0

【步进电机】一次失败的尝试:我想让步进电机在转动的时候不发出声音,不产生振动

[复制链接]

1109

主题

1649

回帖

7万

积分

用户组: 管理员

一只技术宅

UID
1
精华
244
威望
743 点
宅币
24180 个
贡献
46222 次
宅之契约
0 份
在线时间
2294 小时
注册时间
2014-1-26
发表于 2018-11-24 22:15:54 | 显示全部楼层 |阅读模式

欢迎访问技术宅的结界,请注册或者登录吧。

您需要 登录 才可以下载或查看,没有账号?立即注册→加入我们

×
步进电机,顾名思义,就是一步一步前进的电机。因为你可以控制它的步数,你的系统可以通过让它走特定的步数来预计它转动的位置。3D打印机里面有很多步进电机,它们可以较为准确地控制喷头的位置和底座的高度,或者底座的位置和喷头的高度等。

然而这种控制系统依然是一种开环系统。你用手掰一下喷头让它稍微偏离一下它正在打印的东西,你就看着它像模像样地吐屎了。因为控制器只知道自己控制了步进电机转几圈,却不知道步进电机是不是真的转了那么多圈,或者是不是处在正确的角度上。

不过这些都与我现在要说的主题无关。我要做的尝试是:我想通过PWM调制,来让步进电机能够较为平缓地从一步走到下一步。这样我可以以此实现振动抑制,或者降低噪声等。

我用的步进电机有两个,一个是我在AKIBA买到的PM050、2相6线的“大铁块”,另一个是28BYJ-48

IMG_1172.png

IMG_1173.png

其中这个28BYJ-48是带了一个附赠的ULN2003步进电机驱动板(其实这个ULN2003就是一个有8个基极和8个发射极的“8联三极管”)。而我买的PM050步进电机则没有送步进电机驱动板。于是我自己用4个S8050三极管,焊了一个。

s8050.png

其中5线的步进电机它是这样的:

5wire.png
(没错。红色是接地。你有意见吗?)

而6线的步进电机则是这样的:

6wire.png
(把两个接地接起来后,它们之间的差异也就是颜色不同罢了)

我的这两个电机都是2相电机,用一个最直观的图来描述就是这样的:

6wire.GIF

也就是只要按照顺序依次给它的4个电磁铁通电(实际不是这样的设计,但逻辑是这样的)转子就能转起来了。这也是步进电机名字的由来——它是一步步前进的。

a-Full-step-operation-and-b-half-step-operation-for-a-two-phase-stepping-motor.png

然而每次你让它前进一步,整个步进电机都会抖动一下,咯噔一声。不管步进电机的静音设计怎么样,这个声音是少不了的。

尽管如此,依然存在一个叫“Microstepping”的黑科技。也就是微调每个“电磁铁”的电流大小,从而让步进电机能平缓前进。

用图像来描述的话,就是要想办法让它像下图的曲线一样进行。让转子平缓地从一个“电磁铁”转向另一个“电磁铁”。

ms.png

然后这有两种方式实现。一种是DAC方式,平缓增加电流强度,弄出个这样的波形。另一种则是PWM方式——我控制的不是电流的强弱,而是电流的有无,以及持续的长短——如下图。

PWM-signal-generation-with-a-sinusoidal-reference-a-Two-level-PWM-b-Three-level.png

我可以把每个PWM周期的长度弄得很短,把频率弄得很高,然后再调整每个周期内的高电平长度。我用这种方式控制LED灯的时候,只要频率足够高,这LED灯看起来的明暗度就是可以被控制的。所以相同的道理是否可以被用到步进电机里面去呢?

其实经过我的尝试,并不成功。一方面,过短的脉冲其实并不能让转子稍微动一下——而脉冲到达一定阈值后转子就直接跳到了下一格,不会回来了——步进电机依然还是一步步走的。另一方面,我发现这样弄的话,步进电机的扭矩会变得更低,除非达到足够高的转速。

也就是说,最终的试验结果是——除了让步进电机转速更慢、力更弱以外,没有别的影响——噪音依然该有还得有,不仅如此,而且如果你的PWM频率不够高的话,你是能听到你的PWM发出的噪声的。等同于多加了个噪声。

不过这次尝试也并不完全失败——至少软件层面我做出了一个整数查表法的128个单位是一个周期的sin波形函数。源码可以放出来以后备用。
  1. const int sin_max = 65536;
  2. const int sin_period = 128;

  3. int sin_128(int x)
  4. {
  5.         const int quarter_sin[33] =
  6.         {
  7.                 0, 3215, 6423, 9616, 12785, 15923, 19024, 22078,
  8.                 25079, 28020, 30893, 33692, 36409, 39039, 41575, 44011,
  9.                 46340, 48558, 50660, 52639, 54491, 56212, 57797, 59243,
  10.                 60547, 61705, 62714, 63571, 64276, 64826, 65220, 65457,
  11.                 65536
  12.         };
  13.         x %= 128;
  14.         if(x < 33) return quarter_sin[x];
  15.         if(x < 64) return quarter_sin[64 - x];
  16.         return -sin_128(x - 64);
  17. }

  18. int cos_128(int x)
  19. {
  20.         return sin_128(x + 32);
  21. }
复制代码
回复

使用道具 举报

QQ|Archiver|小黑屋|技术宅的结界 ( 滇ICP备16008837号 )|网站地图

GMT+8, 2024-3-28 21:43 , Processed in 0.042619 second(s), 34 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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