大一到大二的暑假里,刚学了51单片机一些比较基础的操作,而自己又一直很不满市面上出售舵机的造型一类的问题,从那时萌生了想自己设计一个舵机系统的想法,跌跌撞撞碰了好些坑,大二上又被各种烦心事打扰,因疫情延长的假期反成了大学一年半里最为清净的时光,也便是在这个假期里有时间捡起自己曾经挖的坑好好填补填补,这里想就自己设计舵机系统的一点经验和大家分享下。
首先是第一个问题,舵机,是什么?笔者在大一也是花了好久才搞分清伺服电机,步进电机,数字舵机,模拟舵机这许许多多词汇。
首先第一点,舵机是一种伺服电机,“伺服”一词指被驯服,即这个电机听从信号运动。在诸多伺服电机中的舵机通常由直流电机、减速齿轮组、传感器和控制电路四个部分组成,在如今人们的生活中有诸多应用场合。
我们分析舵机的四个部分
直流电机,也就是平常遥控车上用的小马达啊之类的,通上电它就会一直转啊转。
减速齿轮组,通常小型直流电机转速快,转矩小,通过减速齿轮组可以降低转速,有效提高转矩。
传感器,即检测舵机转角的传感器,常用有电位计(就是旋转变阻器)。当然还有磁编码器,不过那个比较贵。个人觉得光栅式更适合测速。
控制系统,个人觉得控制系统主要分为电源系统,主控芯片,电机驱动三部分。
之前提到的模拟舵机和数字舵机的区别在这里,模拟舵机用比较器判断目标角度和实际角度的差别,而数字电路通过单片机读角度再控制直流电机运动。
随便拆开一个舵机就会发现,减速齿轮组末端插着个电位计,电位计连到控制芯片上去,控制芯片在连到电机驱动芯片上,驱动芯片提供更稳定的驱动电压促使直流电机运转。当实际角度产生电压值高于目标电压值,电机反转,反之亦然。
根据这些资料总结,我们如果想自己设计舵机的话我们需要
1.减速电机
2.电位计
3.单片机
4.电机驱动
5.稳压电路
根据这些,我决定,设计一款通用的串口总线舵机控制器,任何直流电机套个电位计就能跑。
问:做这个系统需要用PID算法吗
答:不需要
我知道不少大三学过自动控制的学长学姐们都会觉得这个问题很好笑。。但这个问题最一开始确实折腾我不少时间,毕竟都说数字舵机优于模拟舵机运行更平滑啊之类的,肯定是有什么好算法。
这里算这一笔账,比如笔者用的是JGA1024-N20电机,12V供电,空载转速120rpm/min,电位计RDC503013A,角度333°,单片机10位ADC也就是最大值才1024。考虑到电位计转动0.3252°才让电压值上升1,而电机转0.45166ms才让电位计转动0.3252°,而据说ADC最快每秒可以做30万次。。。
所以算到最后决定每300us做次ADC,接着估算电机此时电位计表示数与目标值差距,最后做电机运动判定
此外一定要估一下ADC置信区间,各种原因,测得电压值会飘的很厉害,在置信区间内的电机最好静止,不然会抖得很厉害。
笔者选材如下
电机 | JGA1024-N20 12V 120rpm/min |
电机驱动 | L9110s |
电位计 | RDC503013A |
控制芯片 | STC15W408AS |
供大家参考,某宝都有售
稳压部分还没做,因为我不会做
其中单片机程序部分可能是花费最多的部分,我有的学长在之前选用的是arduino上的主控芯片,但最一开始我错误地估计了这个系统的难度,用的是宏晶公司STC15W系列芯片。
当时第一次用的是STC15W201S。看中的是sop-8封装,但是只能用比较器做ADC运算,不是很方便。
后来改用用STC15W408AS这款,有如下优点
1.价格低,封装sop-16体积小
2.8KSRAM字节够我瞎写程序的
3.8路A/D做电压测量很方便
4.1T高速运行(事实上就这样后边发现有时候还是不够算)
做的系统是仿照一家公司的串口总线舵机思路去做的,通过串口通讯的方式来和舵机沟通。
然后因为觉得这么多资源就控制一个电机太可惜了。。
所以设计了个四路舵机控制器,想尝试下用一个芯片控制4个电机,实现串口通讯主从机控制,电机可以从定速和定位两种模式切换。
这里想聊聊51单片机系统搭建的问题。
总觉得宏晶公司有想把51做成32的意思,他们为STC系列单片机设计了许多库函数(在他们的编译器里能翻到)。笔者之前自己瞎写系统,崩的不行。
51单片机虽是单片机,程序还是要有条理地写的。
首先第一步理清单片机有哪些资源,规划好系统结构,通过参数或仿真计算好每个流程需要花的大致时间,确定系统可行性。
之后打好串口系统,没有稳定的串口系统单片机程序出了什么问题自己都猜不着,有了串口便可以及时调控。当然有人说单片机仿真也可,但是仿真总是解决不了现实生活中出的问题。串口系统个人建议设置中断最高优先级
有了稳定的串口系统便可以着手时钟系统,确定单片机的毫秒时间和自己的秒表差不多,再开始提速到自己需要的速度看会不会影响自己的串口系统。
有了稳定的串口和时钟,其他问题也会好很多,之后便是添加自己各种函数的时候啦。
像笔者做的这个舵机流程大致如下
调串口
调定时器
定时器加ADC(发现速度不够所以稍微调整了一下ADC速度)
调电机驱动引脚
定时器加电机控制
调指令系统
目前电机只能说能转,但是精度还差得远,参数还得慢慢调。
大概就是这么个感觉,感觉还不错哈哈。
指令部分也是花了不少功夫,最后定这样的
字节一
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
舵机ID | 电机 |模式| 低二位
字节二
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
高八位
工作方式0 | 工作方式1 |
---|---|
(定位) 此后主机将发送目标值(0-高8,1-低2),从机也会反馈当前位置 高8位放ADC_RES,低2位在ADC_RESL的低2位 | (匀速转) 此后主机将发送目标转速,从机也会反馈转速 |
当然还有ID修改问题,正在设计中。
附:当时设计的时候还想到一个很有趣的控制方法,老早以前控制电机正反转都是靠两根pwm控制的,实际上一根pwm一根普通线也能完成这种任务滴!
之后还会向系统里增加定速转动模式,可能会用到,先码在这记一下。
之后还会试着做一下电路板的设计,届时再做分享。
2021/06/24
一年前忘记发代码地址了
请看github
https://github.com/hhq-123/servo-motor-N20