带好盈程序的电子调速器控制
由 动力老男孩 发表于 2012/03/12 22:52:44最近制作四轴飞行器陷入困境,用手抓住它左右摇晃,能够感受到螺旋桨明显的阻力。但是PID参数调节的结果,要么就是飞行器剧烈摇摆失控,要么就是起飞后向一侧斜飞,很难达到一个较为稳定的状态。
应朋友们的建议,先陆陆续续写一些攻略和步骤。一来可以相当于做好笔记,二来也可以请大家帮忙查找原因,出谋划策。
前面几篇提到了目前控制电机的一些问题,正好在这里介绍下我控制电机的方式。
电机
首先,航模的电机一般都是无刷电机,这种高速的无刷电机不像直流电机那样,接上一定电压就可以旋转,一般需要在多个电源线中输入周期性的交流电。例如我买的电机就是下面这样的:
它有三根输入电源线,如果用单片机直接输出交变的电信号给它,因为单片机输出功率太低,是转不动的。
如果把单片机的输出经过电流放大电路,例如L298N,事实上很多步进电机就是这样控制的。它的问题在于一个单片机只能控制几个电机,并且很难再做其他的计算了。
电调
由于上面的原因,我们必须采用专门控制电机转速的设备,就叫做电调(全称电子调速器,英文electronic speed controller ,简称ESC)。它的作用就是接受单片机的PWM指令,并且生成成无刷电机需要的高频交流电。
大家可以看到电调有很多线,其中两根粗线连接的是电源的正负极;三根输出线分别连电机的三根输入线(如果需要电机反转,任意对换两根接线即可);另外还有三根细线,分别是单片机接地,5V输出电源和PWM信号线。
根据航模标准,PWM信号线的频率应该是50Hz,对应的每个周期总时长是20ms。经过我的实测,基本上超过55Hz以后就不转了。
在这个20ms的周期中,高电平的持续时间应该在0.92ms到2.120ms之间,分别对应电机的最低转速和最高转速。
我曾经在想为什么只给转速控制留了这么小的PWM范围?如果是按Arduino系统PWM输出的话,用0~255来输出20ms之间的PWM值,有效控制转速的值范围大约只有pwm=(20~40)之间。后来大概明白了,这是为了给单片机节约宝贵的CPU资源,这样才可以在剩余的18ms中处理其他事务。
好盈程序
看电调的说明书,它有很多功能。比如设置电池的特性,设置刹车特性,设置最大转速等等。这些功能都可以通过遥控器进行设置,其中大部分功能我们使用默认值就可以,只有初始化一项是必须做的。
具体的设置方法是,把油门推到最大(2.12ms),这时候电调就会滴滴几声提醒你进入设置模式,然后就可以把油门迅速拉到最低(0.92ms)保持一会儿之后,电调就可以初始化成功了。
新手可能会有和我一样的疑问:把油门推到最大的时候,会不会电机突然暴走起来?
所以这里需要强调的是,电调的使用一定要按照说明书操作。单片机通电的时候,需要立刻给电调输出最低油门的PWM值(0.92ms),经过我的实验,0.85或0.95也没有太大关系。再低的话就会滴滴滴的报警,告诉你没有初始化成功;再高的话(0.95到2.1之间)只会有一声警报,但是无法正常转动;再再高到最高油门值(2.12ms)的时候,就会提醒你进入设置模式。
这样做是安全的,如果你不慎把遥控器留到了高位,这时候给电机通电,不至于突然上升到非常高的转速。前几天我企图修改PWM的时候,发生了一次这样的失误,手机控制的参数一下子升到最大,螺旋桨的风力大到手几乎抓不住,真是吓的屁滚尿流……
初始化和调速
之前有提到过用电脑通过串口通信控制电机,这里也是类似,在PC上写一段小程序,可以输出0~200之间的一个整数到Arduino。
在Arduino上,分别把0对应到0.9ms的高电平;200对应到2.1ms的高电平。
void loop() { long t0 = micros(); //记录进入loop的时间 while(Serial.available()) { // 这里是获取控制指令 pushData(Serial.read()); } //ctrlPower从串口读取,0~200分别对应高电平脉宽0.9ms~2.1ms double len = 1000 * (0.9 + ctrlPower * (2.1 - 0.9) / 200.0)); // 输出高电平 for(int i = 0; i < 4; i++) digitalWrite(motorPins[i], HIGH); // 延时len毫秒 delayMicroseconds(len); // 输出低电平 for(int i = 0; i < 4; i++) digitalWrite(motorPins[i], LOW); // 等待一段时间,形成20ms的周期 delayMicroseconds(t0 + 20000 - micros()); }
其中ctrlPower就是从PC端读取的那个控制值。新电机和电调买回来,把4个装到一起,然后从这个程序统一进行初始化和控制转速。强烈建议第一次玩电机的朋友,先不要装上螺旋桨,应该等调试胸有成竹之后再安装。
飞控板做减震处理,拿橡皮筋勾着,试试?
你可以试试bangbang控制,一般这种程度的模型比较适合这样控制。PID反而不容易调的很稳定,经常可能过调,
动力哥,你文中提到的“这些功能都可以通过遥控器进行设置,其中大部分功能我们使用默认值就可以,只有初始化一项是必须做的。”
指的是什么控制器?另外能在Ardunio上写CODE代替控制器来初始化电调吗?
也就是能用ardunio来模拟你文中的“把油门推到最大(2.12ms),这时候电调就会滴滴几声提醒你进入设置模式,然后就可以把油门迅速拉到最低(0.92ms)保持一会儿之后,电调就可以初始化成功了”
对,就是可以从Arduino来把油门推倒最大。我的意思是,你最终只要能输出高电平在0.92~2.12ms之间的PWM就可以
不好意思,动力哥,打扰了,只是项目在快结束的时候出现了问题,很着急。怕挂了,毕不了业,所以才想加你QQ的。
我用示波器测了下,我用PPM控制也是测出来无刷电机确实是在0.9ms的时候启动,这是正常的电机启动。但是我的现在的问题是我其中一个电机现在要1.1ms才启动(因为要调试PID的参数,所以我经常把它加到2.12ms)我看了说明书,和查了一些网上的资料,猜想是不是该电机进入了安全模式?或者这种0.9到2.12的这种1.22ms区间会移动?比如移到1.1到2.32ms?
这个问题现在很纠结。
这个不用纠结啦,电机的特性不是那么线性的,虽然期望的是0.9ms时启动,但是很多都要到推后的。我的电机大概在1.2ms左右陆陆续续起来,应该没关系的
有个说法是电调会把启动时的脉宽当作最低速度,但是我实验看不是这样,启动脉宽不对的话,直接就报警了
可是,我说的两种启动时间(0.9ms和1.1ms)在同样的PID参数效果确不一样。也就是说,我在0.9ms下能达到理想响应曲线的P,I,D在1.1ms
下就失效了。而且过了一段时间后1.1ms启动的电机又会返回到0.9ms启动。这可怎么办?而且我发现COM口在第二次运行的开始会出现一些乱码,我想这是不是因为ESC有记忆功能?
jacob1990 同学,从网上的文档看,ESC确实有记忆功能。
我印象中,它会把上电时的脉宽作为最低转速点(当然脉宽不能离0.9ms太远)。
具体的文章可以看这篇:
http://zhidao.baidu.com/question/247364848.html
注意看这句话:
———————————-
所以,你要做的是,把脉宽放在1ms,然后给电调上电,把0速度对应的脉宽值降下来,然后5us一个步进量调速度,最大加到2ms就不要再提高了。
———————————-
也就是说,电调不是总把0.9ms作为最低转速的,而是看上电时的脉宽。
假如你的单片机上电和电调上电是同时的,那么单片机在开始的时候可能会做一些操作,例如初始化传感器等等,可能就会造成电调的初始脉宽稍大
今天有点生病,等会儿准备坚持做个小实验就去睡了
另外,动力哥,因为我的毕设截止时间快到,还有些地方没想通,请问能不能加个QQ,这样子,能方便很多,我保证绝不会没事骚扰您。
QQ:522040987
兄弟,这是老哥哥们摆弄爱好的地方,意义在于实现自己的梦想,毕业设计主要是对自己学校所学东西的一个综合运用,照抄或者拿来主义欠妥阿,纯属友情提示,再有啥想法咱们私下聊,别坏了动力哥的宝地。QQ:227704
多谢SSS_SXS兄弟帮我圆了场,现在不是学生时代了,上班的时候肯定不能用QQ,不然太影响工作。
晚上回家就一点儿时间,做点事情,回复下评论就该睡觉了。
arduino飞控可以参考下mwc嘛,可以在已有基础上开发更高级功能,没必要重新造轮子啊
之前有看过一阵子mwc,说实话里面很多代码不太理解。所以先自己玩玩,加深下理解
动力兄,还是围绕你不能试飞成功的话题考虑,我始终还是觉得PID公式运用上出了问题,侧飞的话,是不是因为在改参数的时候,飞行器就开始侧倾了?按照理论解释,因为你是乘上这个参数做积分的,而不是和这参数一起做积分的,所以修改瞬间会有一阵很大干扰在(所谓”风”),建议把PID代码发出来看一下
其实Arduino的PWM应该可以异步的。
大哥,我有个问题,我DIY的是四个螺旋桨的飞行器,这样就有4个ESC,就是要4个PWM值。
我的问题是,如果是这样我这接把这4个ESC接到MicroC上的PWM OUTPUT就可以了,还是一定要接个PPM ENCODER进行转化。
如果是后者,,,我真不知道接线是如何的。
我发现你的下一章就是更新。。。多路啊,,,期待
这个电调可以自己做吧,芯片BTS7960,重量可以再轻点,呵呵
多谢建议,请教一个非常外行的问题:比如我大概知道一个功能方面的需求,该去什么地方找合适的芯片和型号呢?
比如这个电调,我只想到去百度搜场效应管,明显是不得要领,而你是怎么能知道该用BTS7960呢?
动力哥,请教个问题,avr 2560虽然有11路pwm,想做8路的ppm遥控器。但是貌似频率不容易改到50hz啊,255对应20ms也有点粗糙啊。麻烦动力哥详细介绍下配置的细节。用增强单片机定时器模拟倒是还可以,就是有点抖。
那部分是我说错了,arduino的pwm是490Hz,对应的周期约等于2ms,其实还算不错啦
楼主你好,我想用电脑串口和安卓串口控制无刷电机或者电调,请问有没有什么方法?我扣扣771839939,跪求解答
这个貌似有点儿难,串口通信协议是固定的,不能随意的发送01数据。
不过你也许可以用一个usb小板子接在手机上,通过这个小板子跟设备通信。具体的细节我就不清楚了
pushData();
motorPins[i]
micros()
你好,我刚刚入手,arduino还有无刷电机,正在尝试,看到了你的代码,我想问下上面这三个函数的源码是啥?多谢了,或者你能把,setup()函数,以及全部的代码贴出来吗?谢谢了