让电机动起来!Arduino驱动步进电机教程
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驱动步进电机教程相关推荐
- arduino 步进电机驱动库_一文看懂arduino驱动uln2003操作步进电机的方法
arduino驱动uln2003操作步进电机的方法 1.网上买的步进电机,很多接线顺序都不对.经过不懈努力查资料,终于找到了能用的接线方式: 电机上的12345针脚,对应着接线端子的42135. 2. ...
- arduino步进电机程序库_【MM32 eMiniBoard测评报告】+驱动步进电机
1. 引言 先简单聊一下我与MM32的故事.在去年,我开始做BLDC的项目,于是开始学习了解各家的mcu及其解决方案.有幸获得了灵动微电子的MM32 SPIN系列开发板,给我的感觉是开发板做工精良,开 ...
- 【Proteus仿真】Arduino+uln2003驱动步进电机+单按键启保停正反转控制
[Proteus仿真]Arduino+uln2003驱动步进电机+单按键启保停正反转控制 Proteus仿真 功能实现 采用外部中断来获取按键信息 程序代码 #define LED ( 13 )#de ...
- 【Proteus仿真】Arduino UNO利用Stepper库实现uln2003驱动步进电机转动
[Proteus仿真]Arduino UNO利用Stepper库实现uln2003驱动步进电机转动 Proteus仿真 Proteus说明 Proteus软件里面的步进电机的步距角默认是90,和代码中 ...
- 【Proteus仿真】Arduino UNO+uln2003驱动步进电机+按键启保停正反转控制
[Proteus仿真]Arduino UNO+uln2003驱动步进电机+按键启保停正反转控制 Proteus仿真演示 功能说明 正反转采用2和3 引脚外部中断,3和4引脚调节加减速. 示例程序代码 ...
- 【Proteus仿真】Arduino UNO+ uln2003驱动步进电机+按键启保停控制
[Proteus仿真]Arduino UNO+ uln2003驱动步进电机+按键启保停控制 Proteus演示 功能说明 加减速采用外部中断引脚2和3实现调速控制,调速方位,110-250,也就是代码 ...
- 《Arduino直流电机控制教程》
<Arduino直流电机控制教程> 在这个Arduino教程中,我们将学习如何使用Arduino控制直流电机.我们来看看控制直流电机的一些基本技术,并通过两个例子,学习如何使用L298N电 ...
- Arduino驱动L298N控制直流电机的正反转和调速
Arduino驱动L298N控制直流电机的正反转和调速 一.前言 二.产品参数 三.驱动直流电机 三.接线图 四.程序 五.实验结果 总结 一.前言 本模块使用ST公司的L298N作为主驱动芯片,具有 ...
- arduino+A4889+步进电机
内容 本篇文章主要是对步进电机相关原理介绍,并实现了arduino+A4899步进电机驱动对四二步进电机进行驱动. 材料清单 arduino nano(其他型号也可以).A4899.42步进电机.ar ...
- 【STM32篇】4988驱动步进电机
本文介绍的步进电机驱动为毕设所用,学习时也借鉴了其他博主和商家的资料,介绍的都很详细.但对于刚入门的友友萌来说,可能还会存在的一些不解.而我就是被卡在驱动电源上.下文为我对4988驱动的一些理解,希望 ...
最新文章
- 介绍linux下Source Insight强大代码编辑器sublime_text_3
- Html篇-fieldset标签演示
- AJAX ||JQeury实现方式||原生的JS实现方式(了解)
- java thread 内存泄露_Java ThreadLocal 内存泄露问题分析及解决方法。
- 趣味编程:C#中Specification模式的实现
- yolov4 开发环境搭建_YOLOv4 的各种新实现、配置、测试、训练资源汇总
- server 2008中新建AD域控制器
- 自动化审批决策树助你面试更上一层楼
- C# Learning—Step By Step(9)
- Harmony OS — RoundProgressBar圆形进度条
- 详细介绍Access数据库注入
- 小米3g刷高格固件_小米路由器3g刷第三方固件遇到的一些坑
- sql server完全卸载
- win10+VS2013+OPENCV如何配置于仕琪人脸检测算法
- 通信中间件技术之DDS
- jquery实现点击图片放大功能
- Gitblit安装遇到的一些问题
- Acwing第 70 场周赛【未完结】
- 记一次greenplum集群数据库连接慢的问题定位
- 从蒙牛到小度,跨年晚会中的国民品牌变迁
热门文章
- 计算机cad比例尺1 150,CAD图纸里面 1:50 和:1:100和1:150三个比例分别怎么换算...
- 历久而新,我的新书《第二行代码》已出版!
- JQuery的选择器对控件ID含有特殊字符的解决方法
- 国内有哪些不错的计算机视觉团队?
- java c 日语一级,2017年职称日语C级考试语法知识强化题
- 美林投资时钟与大类资产配置
- 【win+黑苹果双系统②】黑苹果设置开机启动+wifi
- 三星固态Dell版的960g的sm863a硬盘
- 常见软件架构风格介绍
- 如何解决windows资源管理器已停止工作?两种方法教会你