Arduino开发板实验四:步进电机控制
由 动力老男孩 发表于 2010/08/08 23:07:54上周总算做成了点事,其实很简单,就是用Arduino实现了步进电机的正转和反转。因为总是很忙,所以拖到现在才有时间补上攻略。感慨一下,IT民工真辛苦啊,有位同事的昵称已经改成 “还是古代好,切掉小JJ就可以当公务员了”。 好吧,祝这位朋友心想事成,我还是坚持当民工好了
在步进电机实验前,从网上找到了一个关于步进电机驱动的文档,使用的是L298N的驱动芯片。这个文档里面有些错误,导致我浪费了大量时间。也许不同的电机和芯片版本也许有区别吧,请大家慎重使用。先借用一下原理图:
其中IN1~IN4以及ENA,ENB在之前的一篇关于直流电机驱动中有介绍过,分别对应输入的六个管脚。这个图里有两处错误,首先可以看到有两个ENA,其中一个应该是ENB;另外这两个EN都是接地的,但是经我实验看来,应该接+5V的电压才对。
所以正确的原理图应该是这样的:
下面是对应的接线图:
接线之后按照说明书里的时序图写了一段程序,呼呼,一次就通过了电机的正转实验。可是在企图实现反转的时候,总是不成功。在焦头烂额之后,终于开始怀疑文档是否正确。事实证明,大家做任何事情都要相信伟大的党而不是万恶的“文档”,下面是错误的反转时序图和经我验证可行的时序图:
基于以上时序图,我写了一段代码,让步进电机实现下面的动作:
正转一圈 -> 暂停1秒钟 -> 反转一圈 -> 暂停一秒钟 ->循环
代码如下:
int LeftI1 = 28; //连接电机驱动板的I1接口 int LeftI2 = 22; //连接电机驱动板的I2接口 int LeftEA = 8; //连接电机驱动板的EA接口 int RightI1 = 36; //连接电机驱动板的I1接口 int RightI2 = 42; //连接电机驱动板的I2接口 int RightEB = 6; //连接电机驱动板的EB接口 int StepCount = 0; int StepDelayTime=1500; void setup() { pinMode(LeftI1, OUTPUT); //I1和I2都是数字信号 pinMode(LeftI2, OUTPUT); //通过设置I1和I2来控制电机旋转方向 pinMode(LeftEA, OUTPUT); //按占空比方式输出的模拟信号 pinMode(RightI1, OUTPUT); //I1和I2都是数字信号 pinMode(RightI2, OUTPUT); //通过设置I1和I2来控制电机旋转方向 pinMode(RightEB, OUTPUT); //按占空比方式输出的模拟信号 Serial.begin(9600); //设置波特率 } void ForwardInit() { digitalWrite(LeftEA, HIGH); digitalWrite(RightEB,HIGH ); digitalWrite(LeftI1, LOW); digitalWrite(LeftI2,HIGH ); digitalWrite(RightI1,HIGH); digitalWrite(RightI2, HIGH); StepCount=0; } void BackwardInit() { digitalWrite(LeftEA, HIGH); digitalWrite(RightEB,HIGH ); digitalWrite(LeftI1, LOW); digitalWrite(LeftI2,LOW ); digitalWrite(RightI1,LOW); digitalWrite(RightI2, HIGH); StepCount=0; } void ForwardOneStep() { delayMicroseconds(StepDelayTime); switch(StepCount) { case 0: digitalWrite(RightI2,LOW); digitalWrite(LeftI1,HIGH); break; case 1: digitalWrite(RightI1,LOW); digitalWrite(RightI2,HIGH); break; case 2: digitalWrite(LeftI2,LOW); digitalWrite(RightI1,HIGH); break; case 3: digitalWrite(LeftI1,LOW); digitalWrite(LeftI2,HIGH); break; } StepCount=(StepCount + 1) % 4; } void BackwardOneStep() { delayMicroseconds(StepDelayTime); switch(StepCount) { case 0: digitalWrite(RightI2,LOW); digitalWrite(LeftI1,HIGH); break; case 1: digitalWrite(LeftI1,LOW); digitalWrite(LeftI2,HIGH); break; case 2: digitalWrite(LeftI2,LOW); digitalWrite(RightI1,HIGH); break; case 3: digitalWrite(RightI1,LOW); digitalWrite(RightI2,HIGH); break; } StepCount=(StepCount + 1) % 4; } void loop() { while(1) { ForwardInit(); for(int i=0;i<200;i++) { ForwardOneStep(); } delay(1000); BackwardInit(); for(int i=0;i<200;i++) { BackwardOneStep(); } delay(1000); } }
除了实现了动作之外,我还搭车实验了下面几件事情:
1,步进电机的转角相当精确,我捆了根电线当指针,反复转了几百圈之后,指针的位置几乎没有变化
2,扭矩还挺大,我选用的是标称扭矩是3.4Kg.cm的步进电机,用铅酸蓄电池供电,旋转时我用爪子完全不能把它捏住(NXT的电机貌似没有这么强劲)。
3,经我测试,每个脉冲之间的间距最好大于1500μs(1.5ms),如果间距太小的话,就会出现失步的情况。
思考问题:基本上来说,每个步进电机都需要一个驱动板(L298N)和一个控制板(Arduino或其它单片机)。如果需要控制多个电机的话(小爱也许会有20多个关节),买这么多板子成本就太高了。实际上,每个脉冲间距之间有1500微秒的空闲时间,对CPU来说简直是漫漫长夜。所以我觉得可以用类似于操作系统多任务的思想来生成时序,充分利用脉冲间距之间的剩余价值,这样就可以只用一块Arduino实验板来控制多个电机了。
呵呵,又想多了,等下周有空再试试吧!
又是一技术牛人。膜拜
hi,博客又更新了呢,呵呵,顺便想请教下建bolg的话购买虚拟主机能给个建议吗,比如这个博客,谢谢啦~
呵呵,虚拟主机用的是这个,不做广告,仅供参考:)
http://www.godaddy.com/
啊,我也是在上面申请的域名,空间现在正在找呢,发现好多人说godaddy可能被封ip,那样的话就又要买个独立ip了的,谢谢博主了
嗯,空间+独立IP一起买好像有优惠,另外搜一搜优惠码
能省不少钱呢
真实牛人,能折腾。 佩服
话说。。你博客的名字一直就这么XE吗?
———-
笑话不需要分类,只需要全文订阅。。
好厉害
支持下
偶头一次来,
偶就支持一下,
偶其实应该说我。
这么专业的东西
基本上很难看明白
有些东西很难超越的哈!
Arduino多个步进电机的控制可以实现阿,我都做出来拉,可以控制它的速度,还有脉冲个数阿。
你是怎么做的呢,如果Arduino支持多线程的话就方便了
但是没有查到相关的资料
我的想法是做一个Timer对象来模拟多线程
这样可以控制多个电机,并分别控制它们的转速
我有办法让它控制多个电机,在循环语句中加N++,用条件语句判断N等于多少了发个脉冲,几个电机几个IF,速度要求快的电机N值可小,N值大就会变慢。
没错,这样可以控制多个电机
其实这个相当于是模拟了多个线程
但是我觉得这个方法还需要再优化
因为这种方式下,一块Arduino板只能用来控制(多个)电机
没法做别的事情
不知道能不能用控制电机的闲余时间做点其他的逻辑
你好!请问下,我想闭环控制直线电机的运动,就是用位移传感器测直线电机的位移,然后将传感器采到的信号给开发板,开发板根据自己写的算法计算出输出信号,然后在将输出的信号(电压信号)传给电机,驱动电机运动。
您觉得我用开发板可以实现吗?有合适的开发板可以推荐下吗?
就arduino就可以,传感器输入0~5V的电压给开发板,对应到0~1024的读数
对于简单的算法来说和硬件关联不大,毕竟是在ARDUINO的处理能力以内(毕竟ARDUINO等单片机擅长的就是控制和采集)
建议好好的看语言和算法,吃透了就很简单
也就是说用ARDUINO可以实现直线电机的闭环运动控制吗?
你好,拜读了您的大作。我想用一个arduino控制4个不同的步进电机(4个独立的,不需要相互配合工作),用什么办法比较好呢?
试试arduino的servo库
请问下,我是新手,我正在用arduino UNO和L298N控制一个步进电机。因为是新手,查了很多的网上资料,对于实现步进电机的预想功能感到很迷茫,希望能够指教一下。
我的步进电机需要 1、通过改变频率控制步进电机的速度(pwm指令输出吧,但是具体不知道怎么操作) 2、改变脉冲的个数控制步进电机的行程 3、要实现步进电机某项功能的循环输出(猜想是不是用while指令啊,不是很会用)
奇怪,你得思路是正确的啊,你会不会是不巧买到了一个坏板子?
你好,看了你的文章我受益匪浅。我准备在做一个遥控智能小车(比市面上的遥控车大点)。控制板子是用arduino uno,电机驱动板子是l298n,不知道选多大转矩的电机和相应的蓄电池供电,希望你能帮我出出注意!谢谢啦!
市面上的普通遥控小车,就是用的直径20mm到30mm左右的有刷直流电机
这种电机转速比较快,所以一般要通过齿轮组来减速
电池就用那种一节一节的充电锂电池组合起来就可以
楼主按照上面的接线,用uno+298,通电后像堵转现象,不知道啥问题,out1,2是不是应该接motor1??
EN称为使能端,其特点是高电平有效,低电平是相当于将逻辑器件置于高阻态,可以视为将这个逻辑器件从图中移走,不影响其他部分器件的工作。由于驱动板的图中,EN并没有取反,所以还是高电平有效。这就是,这个驱动板中EN要接高电平的原因。
freshman才看到,首发。就全当是为了积极参与讨论吧。
你好,拜读了您的作品。我想用一个arduino控制3个不同的步进电机(4个步进电机需要相互配合工作),用什么办法比较好呢?
你好,拜读了您的作品。我想用一个arduino控制3个不同的步进电机(3个步进电机需要相互配合工作),用什么办法比较好呢?
arduino可以控制3个步进电机,但是功率不够,需要额外的步进电机驱动器
您好,您是说用arduino uno就可以吗
一个电机需要4个脚,所以有12个脚的arduino都可以
你好,我是一个新手,目前是做一个小项目,可是完全不懂。就是通过光电感应器感应到没有物料的存在则步进电机正转,有物料则停止运动。
1、需要的设备:两个按钮(启动与急停)、光电感应器、Arduino UNO(微控制器)、Arduino L298N
2、问题:我选的设备是否正确?
按钮就是数字输入,光电感应属于模拟量输入,而步进电机属于数字输出?
就这两方面的问题,麻烦回复下,谢谢。
请问loop循环中200怎么算出来的呢