1. 简述

平时我们会遇到不同种类的电机,主要常见的是步进电机,无刷直流电机,有刷直流电机,其实这几种电机的工作原理类似,都是用电流产生磁场吸引电机里的转子旋转,这也就是为什么我们用一些电机驱动芯片(并不是所有的驱动)可以驱动一个步进电机或者两个直流电机。这篇博客主要是讲什么是步进电机以及如何驱动步进电机,如何设置定时器。如果大家对我的博客有任何疑问,欢迎大家和我讨论。

2. 所需的电子元件

  • Arduino
  • A4988 电机驱动
  • NEMA (17HS16-2004S1)步进电机
  • 电压源

电路图如下(摘自Pololu A4988,链接):

我搭出来的电路的模样:

3. 步进电机和电机驱动

3.1 datasheets

首先我们需要研究一下步进电机和它的驱动的datasheet。

3.1.1 步进电机的datasheet

我用第一张图给大家简单地讲解下步进电机是如何工作的:2A和2B是一条“导线”的两端,1A和1B是另外一条“导线”的两端,通过把这两条导线在电机内缠绕,会让他们在通电的时候各自产生磁场。磁场的方向根据洛伦兹法则可以得出,和电流的方向,绕线的方向有关。产生的磁场会吸引电机内部中心的转子旋转。通过两根导线交替产生不同方向的磁场,以此来吸引转子周而复始的旋转。更多的大家可以百度。

下面这张图是NEMA (17HS16-2004S1)的datasheet:

我们注意到在上图的电机datasheet里面额定电压是2V,额定电流是2A每个Phase,这个Phase指的就是上面提到的2A/2B或者是1A/1B的导线。我们应该如何理解这里的额定电压和电流?它们指的是:当我给2A和2B端或1A和1B端加上2V的电压,会有2A的电流流过导线,根据欧姆定律,我们得到导线两端的电阻是1欧(在datasheet上,Resistance/Phase那一行也写着1欧姆)。

所以我们可不可以认为交替地在2A/2B和1A/1B上加上2V的电压就可以让电机转动?答案是:是的。我们加的是额定电压,当然可以让电机转动。但问题是电机不会有足够的转速和扭矩,原因是根据法拉第电磁感应定律,除了我们电压所产生的电流外,还会有电磁感应产生的电流,而电磁感应的电流和电压所产生的电流是反向的,因此虽然我们在导线两端加上了额定电压,但是在最初的一段时间内,得到的电流会比额定电流少很多。如果电流不够大,那么产生的磁场是不够移动转子的。这时候我们想到的办法是:可以提高加在导线两端的打压来抵消由磁场产生的反向电流,而电机的驱动就是提高两端的电压,通常可以提高到额定电压的10倍,当然我们需要限制驱动芯片提供给电机的电流,这个我们后面会更详细地说。

3.1.2 步进电机驱动datasheet

市面上有很多步进电机的驱动,除了这次用的A4988,还有A3988,DRV8871等等。它们的工作方式也相似,都是1)在电机每个Phase两端加几倍于额定电压的电压值,2)控制每个Phase的最大电流,这样的步进电机驱动被称为chopper driver,就是说为了提供不超过某个上限电流,它会在特定的时间点停止为电机提供电压。如下图所示:

可以看到图中,当电流超过了上限值I,驱动就会停止提供电压,这时因为磁场作用,电流并不会瞬间为0,而是会逐渐减小(时间常数 = LR)。当电流小于上限值I,驱动又会重新提供电压。所以通过这种达到,既在电机每个Phase两端提供了高电压,又控制了电流。根据上面电机的datasheet中的AMP/PHASE,我们得到我们需要保证每个Phase的电流不超过2A。

下面我们来看看A4988的datasheet:
首先我们需要弄懂的是,Arduino应该如何让驱动开始驱动步进电机工作。如下图所示:

和第一张图对应,STEP需要输入脉冲信号(最上面RESET信号,我认为标识错了,因为STEP和下面的Phase1,Phase2都是正常工作时的样子)。电机驱动会控制电流输出,图中的Phase1和Phase2。有几点我们可以注意到,首先每次STEP的上升沿,是Phase1或者Phase2发生变化的地方,而且STEP在每个上升沿只会有一个Phase发生方向的改变。比如第二个上升沿,Phase 1的电流还是70.71%,而Phase 2的电流就从-70.71%改变到+70.71%,这里的正负号代表电流的方向,这个是和步进电机的机械结构相关的,比如我们不会把步进电机从0度直接到180度,而是会0度先到90度,再到180度。第二点,我们可以想到,如果想加快电机的转动速度,我们需要做的就是减少每个脉冲的宽度,当然这个脉冲的宽度会有最小值,最小值在于当我们设置了某个脉冲宽度,电机驱动在没有等到电机中的转子转到指定的位置的时候,就产生了下一次的脉冲,换句话说就是机械装置还没来得转到合适的地方,电信号就产生改变。第三点,Phase1和Phase2的电流可以有以下这四种组合,(Phase1, Phase2) = (+70.71%, +70.71%), (+70.71%, -70.71%), (-70.71%, -70.71%), (-70.71%, +70.71%),每一个组合代表了转子的一个旋转位置,从一个组合到下一个组合会使得转子从当前位置旋转到下一个位置。

现在我们知道我们需要PWM(脉冲方波)发送给驱动,这样驱动产生合适的电流控制电机了。下一步我们需要搞懂的是如何设置最大的电流上限,根据电机的datasheet,我们知道每个Phase的最大电流不可以超过2A。如下图截取自A4988 datasheet:

根据上面的截图,我们知道 Imax = Vref / (8 * Rs)。在pololu的A4988 的电路图如下图所以:

Rcs是68毫欧,Vref有一个连接一个滑动变阻器组成一个分压电路,所以我们需要用保证Vref 不高于1.088V即可。

具体方法大家可以百度,把滑动变阻器调节到合适的位置即可,比如参考这个链接。

4. 硬件定时器

现在我们来说说,Arduino如何产生PWM脉冲。嵌入式的定时器是非常有用的功能,很多东西都是在定时器的基础上搭起来的,比如说操作系统。Arduino使用的是Atmel328P芯片,大家可以下载Atmel328P的芯片手册,这款芯片上一共有三个定时器,两个8-bit timer,一个16-bit timer。我选择的是8-bit的TIMER2。想了解定时器的功能和寄存器功能的话,可以读一下atmel328p datasheet。我在这里主要和大家介绍下这个定时器不同的计数方式,参考TCCR2A里的WGM21和WGM20,TCCR2B里的WGM22。TIMER2可以控制两个GPIO来产生PWM输出,分别是OC2A和OC2B。

  • Normal Mode

第一种是正常工作的模式,这时8bit的计数寄存器会从0计数到255,然后返回0,重新计数。我设置计数器使用Normal mode,每62.5ns计数一次。每次compare match的时候就toggle OC2A和OC2B pin,OCR2A = 64, OCR2B = 192,所以当计数器计数到64时,会toggle OC2A pin,计数到192时,会toggle OC2B pin。

可以想象到,计数256次(62.5ns * 256 = 16us),OC2A和OC2B会toggle一次,而且OC2A和OC2B toggle的时间会相差128次计数,因为OCR2A和OCR2B相差了128。

产生的波形如下图,里面的黄色和蓝色的波形代表OC2A和OC2B pin上产生的电压,测量点A到测量点B是toggle两次的时间(16us*2 = 32us):

  • PWM, Phase Correct (Mode 1)

第二种计数模式是PWM Phase Correct模式。在计数方式上,它会从0计数到255,然后再从255到0。而它是PWM 模式的,和第一种的区别就在于,我们可以设置当计数到255和到compare match的时候OC2A, OC2B pin的电平高低,从而控制脉冲的宽度。

产生的波形如下图,OCR2A = OCR2B = 32,一个pin设置为compare match时设高电平,0xFF时设低电平;另外一个相反,compare match时低电平,0xFF时高电平。从测量点A到测量点B的时间应该是计数器从32->255->32,一共447*62.5us=27.9us。

  • CTC

第三种计数模式是CTC模式。这种模式的计数方式是从0到OCRA,再返回0,因此与第一种normal mode不同的是,这种模式可以到OCRA而不是0xff,换句话说是周期是可以调整的。如果是toggle pin的话,duty cycle一般是固定的50%(当然可以产生中断重新设置OCRA寄存器从而改变周期)。

产生的波形如下图,OCR2A = 64,OCR2B = 10,OC2A和OC2B都是toggle,所以当计数器counter等于64时,OC2A 会toggle然后计数器清零,当计数器counter等于10的时候,OC2B会toggle,但并不影响计数器继续计数。A 和B的周期都应该是(62.5*64 = 4us)

  • Fast PWM(Mode 3)

第四种是Fast PWM模式,且在0xFF清零。这种和第二种PWM, Phase Correct (Mode 1)非常相似,只不过计数方式是从0到255再返回0。

产生的波形如下图,OCR2A = OCR2B = 32,一个pin设置为compare match时设高电平,0xFF时设低电平;另外一个相反,compare match时低电平,0xFF时高电平。从测量点A到测量点B一共是一个周期,就是256*62.5 = 16us

  • PWM, Phase Correct (Mode 5) 和 Fast PWM(Mode 7)

第五种和第六种我放在一起,因为两种模式比较相似,这两种产生的波形的周期和duty cycle都可以非常方便地改变。
拿Fast PWM(Mode 7)举例来说,因为在计数器和OCRA一样的时候会清零,而且得决定在compare match和清零的时候发生什么事(参考WGM和COM bit),所以OCA pin是无法输出PWM波的(清零和compare match在一起)。我们通常把OCR2A和OCR2B配合只用,OCR2A决定周期,OCR2B决定duty cycle,OC2B pin产生所需要的PWM波形,比如说我要产生一个周期是8usec(62.5nsec128),duty cycle 25%(62.5nsec32),可以让OCR2A = 128, OCR2B = 32,然后设置在清零时置OC2B高电平,compare match时置低电平。

产生的波形如下图所示:

以上讲的所有类型的PWM设置的代码都在GitHub上,大家可以任意下载修改测试。GitHub Repo链接。

5. PWM驱动电机

到目前,我们已经知道硬件该如何连接,该如何设置最大电流,该如何设置Atmel328P的PWM。

我使用了Timer2 Fast PWM (Mode 7)来产生周期可变的PWM信号,这样可以方便地让电机开始时从最慢逐渐变快,在电机要停下来的时候从最快的速度逐渐变慢直到停止,这样可以增大电机的扭矩和稳定性。

整个控制步进电机的代码在GitHub上,链接

让电机动起来!Arduino驱动步进电机教程相关推荐

  1. arduino 步进电机驱动库_一文看懂arduino驱动uln2003操作步进电机的方法

    arduino驱动uln2003操作步进电机的方法 1.网上买的步进电机,很多接线顺序都不对.经过不懈努力查资料,终于找到了能用的接线方式: 电机上的12345针脚,对应着接线端子的42135. 2. ...

  2. arduino步进电机程序库_【MM32 eMiniBoard测评报告】+驱动步进电机

    1. 引言 先简单聊一下我与MM32的故事.在去年,我开始做BLDC的项目,于是开始学习了解各家的mcu及其解决方案.有幸获得了灵动微电子的MM32 SPIN系列开发板,给我的感觉是开发板做工精良,开 ...

  3. 【Proteus仿真】Arduino+uln2003驱动步进电机+单按键启保停正反转控制

    [Proteus仿真]Arduino+uln2003驱动步进电机+单按键启保停正反转控制 Proteus仿真 功能实现 采用外部中断来获取按键信息 程序代码 #define LED ( 13 )#de ...

  4. 【Proteus仿真】Arduino UNO利用Stepper库实现uln2003驱动步进电机转动

    [Proteus仿真]Arduino UNO利用Stepper库实现uln2003驱动步进电机转动 Proteus仿真 Proteus说明 Proteus软件里面的步进电机的步距角默认是90,和代码中 ...

  5. 【Proteus仿真】Arduino UNO+uln2003驱动步进电机+按键启保停正反转控制

    [Proteus仿真]Arduino UNO+uln2003驱动步进电机+按键启保停正反转控制 Proteus仿真演示 功能说明 正反转采用2和3 引脚外部中断,3和4引脚调节加减速. 示例程序代码 ...

  6. 【Proteus仿真】Arduino UNO+ uln2003驱动步进电机+按键启保停控制

    [Proteus仿真]Arduino UNO+ uln2003驱动步进电机+按键启保停控制 Proteus演示 功能说明 加减速采用外部中断引脚2和3实现调速控制,调速方位,110-250,也就是代码 ...

  7. 《Arduino直流电机控制教程》

    <Arduino直流电机控制教程> 在这个Arduino教程中,我们将学习如何使用Arduino控制直流电机.我们来看看控制直流电机的一些基本技术,并通过两个例子,学习如何使用L298N电 ...

  8. Arduino驱动L298N控制直流电机的正反转和调速

    Arduino驱动L298N控制直流电机的正反转和调速 一.前言 二.产品参数 三.驱动直流电机 三.接线图 四.程序 五.实验结果 总结 一.前言 本模块使用ST公司的L298N作为主驱动芯片,具有 ...

  9. arduino+A4889+步进电机

    内容 本篇文章主要是对步进电机相关原理介绍,并实现了arduino+A4899步进电机驱动对四二步进电机进行驱动. 材料清单 arduino nano(其他型号也可以).A4899.42步进电机.ar ...

  10. 【STM32篇】4988驱动步进电机

    本文介绍的步进电机驱动为毕设所用,学习时也借鉴了其他博主和商家的资料,介绍的都很详细.但对于刚入门的友友萌来说,可能还会存在的一些不解.而我就是被卡在驱动电源上.下文为我对4988驱动的一些理解,希望 ...

最新文章

  1. 介绍linux下Source Insight强大代码编辑器sublime_text_3
  2. Html篇-fieldset标签演示
  3. AJAX ||JQeury实现方式||原生的JS实现方式(了解)
  4. java thread 内存泄露_Java ThreadLocal 内存泄露问题分析及解决方法。
  5. 趣味编程:C#中Specification模式的实现
  6. yolov4 开发环境搭建_YOLOv4 的各种新实现、配置、测试、训练资源汇总
  7. server 2008中新建AD域控制器
  8. 自动化审批决策树助你面试更上一层楼
  9. C# Learning—Step By Step(9)
  10. Harmony OS — RoundProgressBar圆形进度条
  11. 详细介绍Access数据库注入
  12. 小米3g刷高格固件_小米路由器3g刷第三方固件遇到的一些坑
  13. sql server完全卸载
  14. win10+VS2013+OPENCV如何配置于仕琪人脸检测算法
  15. 通信中间件技术之DDS
  16. jquery实现点击图片放大功能
  17. Gitblit安装遇到的一些问题
  18. Acwing第 70 场周赛【未完结】
  19. 记一次greenplum集群数据库连接慢的问题定位
  20. 从蒙牛到小度,跨年晚会中的国民品牌变迁

热门文章

  1. 计算机cad比例尺1 150,CAD图纸里面 1:50 和:1:100和1:150三个比例分别怎么换算...
  2. 历久而新,我的新书《第二行代码》已出版!
  3. JQuery的选择器对控件ID含有特殊字符的解决方法
  4. 国内有哪些不错的计算机视觉团队?
  5. java c 日语一级,2017年职称日语C级考试语法知识强化题
  6. 美林投资时钟与大类资产配置
  7. 【win+黑苹果双系统②】黑苹果设置开机启动+wifi
  8. 三星固态Dell版的960g的sm863a硬盘
  9. 常见软件架构风格介绍
  10. 如何解决windows资源管理器已停止工作?两种方法教会你