Arduino 专题 - 蓝芽遥控车 之 心路历程
这次的专题,因为很多资料都是在很多专家高手的Blog查到的
所以决定效法他们来造福(?)他人
不过这并不是一篇纯知性的文章
前后夹杂了很多过程中的故事和心情,以整体来说比较像是一篇...呃......心得日记吧!
如果让你觉得故事有点跳来跳去......就体谅一下新手部落客吧><
段落连结>> 前情提要 Servo的改装 蓝芽连线 统整组装 测试影片看这里 漏掉的故事情节 心得
「同学们~ 我们这次微处理机要来做的 Arduino专题报告喔~ 你们可以自己做或是分组,但是一组最多2个人,加油吧!」
嗯...像我这种初阶级的 Arduino玩家,当然得找个伴carry我啊
才这么一想,就有个同学问我能不能跟我一组 (该同学以下称...嗯......Mr.L 好了)
噢...这下子有趣了 怎么说? 因为Mr.L 在班上是个人缘不好而这方面也不强的人,而我是少数对他比较好一点点的人 (仔细想想事实上也就真的那么一点点)
哎呀呀~该怎么办勒? 我应该婉拒他去找个跟我比较容易合作的人呢? 还是只因为同情他就答应他呢?
嗯...上次公训没跟他一组他一整个就很受伤的样子...如果我这次跟他一组,下次就有理由拒绝了。好吧!这次就先答应他好了
决定好组员之后,我们开始讨论要做什么
我一开始是想做一台遥控战车,这样马达就只要用 Arduino的 5V电压输出即可推动的伺服马达就好了,而且转弯什么的就跟真的战车一样很好解决,对一个WOT玩家几乎不构成问题
后来我也忘记为什么他会去找到一台「水陆两用车」...
好吧!如果都听我的感觉好像我是你的上司一样,这次就依你吧
于是,我们ㄉ专题题目: Arduino蓝芽水陆两用车
再来该讲讲我们究竟做了些什么了
首先,车子的轮子,我们使用方便控制的伺服马达(以下称Servo),而型号则选择较便宜的SG90
知道的人可能会问:「你们用一颗只能转180度的马达当轮子?!」
嗯...这问题很棒,我们的马达当然有经过改装,这也是我们第一阶段的工作
蛤?! 你问什么是伺服马达?! 呃...我的专题报告已经在PPT跟Word各打一次了.....
唉呀好啦简单说明
伺服马达又称为伺服机,属于直流马达
依其动作方式可分为两种,一为180度定位型(SG90属于此类),二为360度连续旋转型
共通点是利用脉波宽度调变(PWM)来控制转动角度或转速。
(不要问我PWM是什么,自己去查。不过会看这篇文章的人大部分都会知道吧)
用简单的程式和单晶片本身的5V输出即可控制,比传统马达来的容易许多
控制Servo的脉波周期一般为20mS
当脉宽为 1.5mS时(D = 7.5%) ,Servo定位在正中间 或是 停止转动
当脉宽大于1.5mS或小于1.5mS时(D > 7.5% or D < 7.5%) , Servo 会逆时针or顺时针旋转一个角度 或 逆时针or顺时针旋转
脉宽不可超过2.5mS或低于0.5mS(2.5% ≦ D ≦ 12.5%) 在极值时角度逆时针偏转约0°or180° 或 以最快速度旋转
脉宽越靠近极值,所偏转之角度越大 或 旋转速度越快
不过你还是得看你是要做什么,如果你是要做电风扇或是大台一点的车子,就不适合使用Servo
好,回归正题
首先这是一颗正常的Servo,要改装它,想也知道当然得把它拆解开
这就是把它底部螺丝松开拆解,把齿轮拿起来的样子
接下来,将 Servo的 Pin脚接上 Arduino,咖啡色的接GND 红色接VCC(5V) 然后黄色的接在讯号输出脚
利用 Arduino内建的Servo函式库程式码(以下称 code)将伺服马达的角度设定至90度:
-------
#include <Servo.h>
Servo myservo; //定义伺服马达
void setup()
{
Serial.begin(9600); //设定鲍率
myservo.attach(6); //设定输出脚位
}
void loop()
{
int d;
if(Serial.available())
{
d = Serial.parseInt();
Serial.println(d);
if(0 <= d && d <= 180)
{
myservo.write(d); //写入角度
}
}
}
-------
利用这个code,把序列埠监控视窗打开,输入0~180,Servo就会转至相对应的角度
所以输入90,让它转到90度,但是因为你把它拆开了,所以它可能会一直转不会停下来
所以要转动图中的那个旋钮(右边黄色那根),那是个可变电阻(以下称VR,Variablr Resister, 不是虚拟实境),要把它转到一个让Servo停下来的角度
建议可以插上那个最大颗的齿轮再转,这样不但比较好转,也不会因为手去碰它而影响了阻值 (经验谈XD
Servo 停下之后,利用快干或什么的,把可变电阻黏住、固定,让它再也不能转动,这部分就先告一个段落
再来是齿轮的部分 (如果你刚刚把它装上VR了记得拔下来时尽量去不要转到)
拆解之后你应该会注意到,VR的旋钮为了要固定大齿轮,所以它跟大齿轮的孔是半圆而不是圆的
除此之外,大齿轮底下还有两块突起来的小方块
所以你现在要做的,就是把大齿轮半圆的洞挖成圆的,并且除去小方块 (圆的大小以不卡住VR的转轴为原则)
最后,把所有的零件装回去,就......
Do Ra Mi So ~ 完成啦!!!!
现在输入数值后,它不会转到特定的角度,而是以不同速度往顺时针或逆时针方向不同旋转,而原本的90度则为停止
以 台中电子街 今华电子 的价格来说
180度的SG90 要80$ 而一颗360度的Servo我记得是320$还是360$
整整省下了约4~5倍的成本呀!
而如果你真的很不幸的在VR固定后发现 90度时仍会有些微的转动或是微小的马达震动,没能完全停止
这时候只要把输入的值加减个1~5,找到让它完全停止的值,在写code时记得输入的是该数值就可以了
可别像我一开始一样以为没救了就用了另外一个让我差点没崩溃的方法重新改造
另外一个方式是什么 因为很麻烦所以也不想讲了
参考资料:http://gsyan888.blogspot.tw/2016/01/diy-sg90-servo-360.html
(另一个方式:http://gsyan888.blogspot.tw/2014/12/diy-towerpro-sg90-servo-360.html 因为我拿到的Servo 里VR的脚是金属棒状而不是多芯线,让我除了焊接又多费了一番功夫想办法把它剪断)
(对不起我忘记我的Servo test code是从哪个网页找ㄉ了QAQ) (抱歉我那时忘记拍齿轮的照片 ㄎㄎ)
接下来是蓝芽连线的部分
我们当然是用最简单又可以发射接收改来改去的HC-05
(读者:Arduino 的蓝芽模组也不就05、06这两颗不然呢==?)
Arduino蓝芽模组的介绍网路上一堆 所以我就不再赘述了
这里要好好谢谢另一位好同学 Mr.T,这部分要是没有他凯瑞一波我大概就完了
至于连线的部分也是利用他推荐的 Bluetooth Terminal HC-05
幸好有这个,不然那个自己写坏的APP应该会把我弄到崩溃*2
下面的对话框是发送指令的地方,BTN 是指 Botten, 点进去可以设定输出指令,这样就不需要一直打字
而上面的黑色框框则是 Arduino回传的资料(序列埠的资料)
加入回传程式的优点就是 可以确定HC-05到底有没有收到资料 方便Debug
-------
#include <SoftwareSerial.h> // 引用程式库
SoftwareSerial BT(2,4); // TX, RX
int val = 0;
void setup()
{
Serial.begin(9600);
Serial.println("BT is ready!");
BT.begin(9600);
}
void loop()
{
if (Serial.available()) // 若收到「序列埠监控视窗」的资料,则送到蓝牙模组
{
val = Serial.read();
BT.write(val);
}
if (BT.available()) // 若收到蓝牙模组的资料,则送到「序列埠监控视窗」
{
val = BT.read();
Serial.print(val);
BT.write(val);
}
}
-------
(code感谢 Mr.T提供)
如果一直失败的话... 或许是你 RX TX 接反了
不然就让它冷却一下吧XD
问题都处理完了,接下来就该整体测试啦
因为遥控车是利用输入来决定移动方向
所以我的code 是利用 swich(in) 的方式在序列埠监控视窗输入指令控制伺服马达
一开始他接收到指令只能转动一点点,于是请教了高手 -- 刺猬
「不然用while回圈试试看吧!」
试来试去改来改去,却都还是行不通
(甚至一度因为把5V插成3.3V导致Servo不动还以为它们死了,跑去砸了500$买了自旋式Servo回来发现原来只是插错而且根本买回来还买错型号!!!根本超悲剧QAQ)
在某个我继续尝试的晚上,因为我家有睡前一起祷告的习惯,所以我想祷告完再来弄好了不然其他人想睡觉
回来之后,「嗯...这两颗Servo停止的数值是92...改一下好了」
改了之后,再试一次,输入! (转转转转转转转转~)
什么?!!!成功了?!!这...这不科学呀!!它...它成功了!这除了是神迹还是什么!我还没加回圈呀!!
来看看成功的影片吧
再来就要脱离面包版焊上900孔洞洞板啦
这部份决定交给咱们Mr.L 来做,为了省事(不放心就说啦),我简单画了一张布线图,所以他只需要完全的按图施工
隔了几天他把成品拍照给我看 问我这样是不是错了
因为之前他的问题我不是不会就是听不懂,所以我也没多看,就告诉他只要VCC、GND不要错,其他的只要是接到IO脚都好处理
结果后来看到成品...... 什么?!!你真的按照我的图把它焊在铜箔面?!!我画的是元件面而不是铜箔面呀!而且你Servo的脚位用母座是要怎么接!!!
(后来翻了一下对话纪录,噢...老天...我只能说我当初应该好好思考一下你的问题......虽然你的表达真的也不有问是没题......)
唉...这...反过来接也行不通......这...真的只能...重焊了......(阿不就好险你接Arduino的排针没有全部焊上去还拆得下来(呼~))
(拆下可用元件后的残骸)
最后,还是由我亲自操烙铁 (本来还觉得我好像把麻烦事都丢给你有点不好意思...)
结果一个不小心把HC-05的排针焊得太近了...... (这样...呃...应该...还行吧...?)
电路测试
YA~~ 大功告成!! (保险起见HC-05还是用杜邦线接好了)
至于测试花絮...算了吧我懒得弄了有人想看再说吧
成果程式码? 想要? 才不要给你哩~
只给你满满的 白~屏~
(读者:看到这么多黑条大概就知道只要反白...((作者:闭嘴((摀住
#include <SoftwareSerial.h> // 引用程式库
SoftwareSerial BT(2,4); // TX, RX
#include <Servo.h> // 引用程式库
Servo servoL; //定义Servo
Servo servoR;
int val = 0;
void setup()
{
Serial.begin(9600);
Serial.println("BT is ready!");
BT.begin(9600);
servoL.attach(12); //设定输出讯号脚位
servoR.attach(6);
servoL.write(91); //设定初始值
servoR.write(94);
}
void loop()
{
// 若收到「序列埠监控视窗」的资料,则送到蓝牙模组
if (Serial.available())
{
val = Serial.read();
BT.write(val);
}
// 若收到蓝牙模组的资料,则送到「序列埠监控视窗
if (BT.available())
{
val = BT.read();
Serial.print(val);
BT.write(val);
}
switch (val)
{
case'w': //往前
servoL.write(180);
servoR.write(50);
delay(3000); //因为蓝芽发送只能让Servo转动一个瞬间
break; //只好用delay让它往前QQ
case's': //后退
servoL.write(0);
servoR.write(115);
delay(2000);
break;
case'a': //右转
servoL.write(91);
servoR.write(50);
delay(1500);
break;
case'd': //左转
servoL.write(180);
servoR.write(91);
delay(1500);
break;
default:
servoL.write(91);
servoR.write(91);
}
Serial.write(val);
Serial.println(' '); //显示在序列埠视窗
}
在这里补充一点剧情
事实上在几次讨论后我觉得题目改成「多功能自走车」比较保险,避免做不出来的窘境
果然
你一定会发现我的标题和最后的成果完全没看到半滴水
因为真的最后只完成这样,其他的什么避障声控水陆两用通通都不要了
根本来不及也做不出来嘛QAQ
至少作业来得及交差了(呼~
等毕业专题再好好改善吧
在讨论的过程中,我们也遇到很~很多多的瓶颈
一开始,Mr.L 提出什么,我质疑什么
他单纯的认为:这样就好啦、用什么就好啦 的部分,我都觉得:可是你这样这个难道不会怎样吗、用这样那那个要怎么办
而他觉得:糟糕、惨了、该怎么办 的问题,对我来说却是:根本不比担心那个,就怎样怎样不就得了
光是如何防水这件事,他几乎每个方法都被我驳回,讨论到最后,我要他做好就好怎么做都随便了,因为我根本没有力气再思考那样倒底行不行得通了
因为这看似深不见底(夸饰)的代沟,导致很多次我对他的态度都很差
甚至有一次同学问到
「欸你们专题做的怎么样」 「喔 就剩蓝芽连线的部分啊」 「那他有在做事吗」 「喔哈哈 我觉得我比他还废欸w 他APP都写好了就等我...」 「那我怎么看你常常在凶他啊?」 「呃...因为他有些想法就很...」 「喔好 我懂我懂XD」
...好 我真的很抱歉有时候不小心就有点崩溃失控了(我真的有那么凶吗p.p)
(从最后一句也可以看出来他在班上可怜的处境了吧www)
不过他后来也跑来跟我说谢谢我愿意跟他同组 (真心希望没有下次了...)
这次的专题,不论是在专业、技术、或是人际关系
我都学到了很多
先讲讲技术层面好了
原本我的Servo测试是用从课本附的光碟里找到用脉宽控制的程式
后来才发现原来Arduino里有内建的Servo函式库,可以再省去一些小复杂的地方
也学会了控制蓝芽模组的方法(接收而已,主动发送还不会 www)
对 威力导演 的使用也更熟悉了一点 (有看成果影片就会懂)
人际关系和生活的部分呢~ (本文精华(?))
千万不要做个烂好人
虽然有个愿意帮助人、怜悯人的心很值得赞赏,但是在伸出援手之前,还是得先衡量一下自己的能力。不然很可能不但没帮到忙,还把自己给拖垮了
时间一定要安排好
这真是太重要了。不要把事情都拖到最后才处理,应该要把事情一个阶段一个阶段的分配好。不然拖到最后不但会把自己弄得一团乱,甚至可能连成果都交不出来
不要越级打怪
设立一个自己能力范围内的目标,才不会做得非常辛苦最后还失败觉得自己糟糕透顶。做个简单一点的,不但轻松快乐又有成就感不是很好吗(当然也要有点程度可以看啦!不是说随便找个菜鸟等级的东西敷衍了事)
然~后...
分组还是要找个志同道合好沟通的组员,而且动作要快,这样有办法说:不好意思 我已经跟谁谁谁一组了
成绩通常大于人情,有时候该坚持的就别妥协吧
平时就要跟那些成绩很好的同学打好交情,分组或需要时才有人可以求carry
做事要有B计划
嗯...大概就这样了吧!
好~了! 这次的心得分享就到这里
谢谢大家\(^_^)/
有任何的建议或是问题 欢迎在下方留言 我会尽快回复您喔^_^
昨天专题发表完 下星期就要段考了
我很高兴我还可以花两个晚上把这篇文章写完