Archive for the ‘小制作’ Category

四轴飞行器:出手报告

上周末在淘宝逛了两天街,买回来一大堆东西:
————————————————–
四轴飞行器机架;
朗宇2212电机kv980;
天行者20A电调;
L3G4200D 3轴数字陀螺仪;
ADXL345 数字三轴加速度传感器;
各种连接件和电容电阻们;
两块25C 2200mA锂电;
B6充电器;
Arduino Mega 1280;
蓝牙模块
————————————————-
目前考虑的方案是用Android手机做遥控器,通过蓝牙控制Arduino。
已经好多朋友指出蓝牙的稳定性不高,距离受限。对比另外几种方案:
1. 手机卡的方式(3G或GPRS)
据说超过400米左右的高度,手机基本就没有信号了。不过这个高度对四轴足够了,主要优点是基站遍地都是,通信服务比较稳定,3G的话还可以传输视频;缺点是价格偏高,耗电量比较大,开发较为复杂;
2. wifi模式
可以把手机的wifi作为路由,直接通信。距离应该也是几十米,如果携带电源+WIFI路由器的话,控制距离可以更远一点。优点是方便,便宜,数据带宽比较高;缺点是手机耗电比较大,开发难度暂时还不清楚;
3. 射频模式
传统的遥控模式,如果加上小型发射站和定向天线的话,可以达到几千米的高度。缺点是只能进行简单的信号传输,无法发送视频等。

总结的结论是:对于玩具级别的小四轴,任何方案都可以,哪个方便就用哪个。对于稍远距离的情况,则WIFI和3G都是不错的选择。对于玩航拍的大家伙,可能只能用射频遥控了(还有一种思路是携带GPS导航,事先设定好巡航路线,上天以后就自由发挥)

最终我还是打算先用蓝牙模块,原因很简单:我正好有一块蓝牙的小板子 :D

现在上班依然挺忙,估计我只能像蚂蚁搬家一样开工了,进展会比较慢,希望观众们不要打瞌睡啊。
这几天快递陆陆续续都到了,前天先把机架装好了,安了一个电机测试安装孔大小,其他的电机准备等调试之后再安装。先上些图:

四轴机架全部配件

四轴机架全部配件

组装好的架子

组装好的架子

安装的电机和旋翼

安装的电机和旋翼

换个角度看看

换个角度看看

自制激光传声器

来自老薛同学的又一次投稿

激光已经51岁了。去年,世界各地的人们一起庆祝了激光的50岁生日。有意思的是,当年它的发明者不知道这束神奇而危险的光能用来干吗,所以称它为:“a solution looking for a problem”;而五十年之后,我们的生活已经无法离开激光。

在基础科学领域,过去五十年里激光的应用也产生了十个诺贝尔奖(!)。在这篇文章里,我们要用激光制做一个无线传播声音的装置。虽不能凭此获诺贝尔奖,但也足以让我们开心一阵子了。

0:原理

二极管激光器(一般的激光笔里面就是一个二极管激光器)发光的强弱可以由加在它两端的电压决定。而电脑上耳机插孔里输出的,是一个随声波振荡的电压信号。如果我们把这个电压信号加到激光二极管两端,那么激光的强弱就会随声波信号振荡了。这就是我们的发射端。

我们可以把这个强弱振荡的激光信号转换成声音在远处播放出来,只需要先把它转换成电压信号,然后再送到音箱放大输出。我们可以用一个光敏二极管或者光敏电阻来做这个转换。这就是我们的接收端。

1:电路

发射端电路如下图所示。

发射端电路

发射端电路

变阻器(可选200千欧姆)设定激光器的基本工作电压,一般在2到4伏之间激光器都能发光,所以在输入声波电信号为零时,可以设定激光器两端的电压为3伏。这样声波信号就能使得激光器两端电压在3到4伏之间波动,从而控制激光亮度。注意,在把激光器连在电路中前,最好用万用表测量一下输出电压,以防过高烧毁激光二极管。

电路中对声波产生的电信号进行了放大,放大系数为两个电阻之比,51k/10k,所以为5.1倍。主要是因为我测量到从电脑耳机插孔出来的电压大概在0.2伏左右,为了防止它太小不足以调制激光强度而加上去的。

接收端电路图如下:

接收端电路

接收端电路

首先第一个运算放大器将光敏二极管产生的光电流(小于零点一毫安培)转换成电压,电阻取多大取决于光敏二极管能产生多大的电流。然后把这个电压信号放大五倍,输出到音箱插头。具体的各电阻取值可能随采用不同光敏二极管而稍有不同。只要用万用表测量最后输出的电压值,2伏左右即可。

2:实物照片

发射端如下图:

发射端实物图

发射端实物图

接收端如下图:

接收端实物图

接收端实物图

3:效果演示

利用激光传声方式播放Beyond的“真的爱你”:

参考老薛新浪播客视频

自制迈克尔逊激光干涉仪

这是一篇来自老薛同学的投稿

简介:老薛同学是在米国留学的物理学专业人士,据说是费米的门生,薛定谔的亲戚。 :D
也许有人觉得物理学专业非常枯燥,可是从老薛同学的生活看来,他们的日子过的相当有趣,在实验室玩遥控飞机,磁悬浮,激光等等,反正大家想象一下生活大爆炸里的各种情节就对了。

下面是老薛同学的正文,看来和我们IT工作者一样,物理学家们也喜欢从0开始编号

=====================惯例的昏割线===========================

0:什么是干涉?
1:什么是迈克尔逊干涉仪?
2:它有啥用?
3:自己怎么做一个便宜的?
4:自己怎么做一个更便宜的?

0:什么是干涉?

在物理学中,“干涉”指的是两束频率相同,相位固定的波,比如光波,声波,叠加在一起时发生的现象。实际上这种现象无处不在。比如下雨天路上彩虹色的油膜,就是太阳光在油膜上下两个表面之间发生的干涉。而雨滴打在池塘水面溅起的涟漪也会形成类似下图的干涉图样。

波的干涉

波的干涉

1:什么是迈克尔逊干涉仪?

迈克尔逊是一位跨世纪的波兰裔美国物理学家(1852-1931),他在19世纪末的时候发明了如下图所示的一种干涉仪。

迈克尔逊干涉仪

迈克尔逊干涉仪

上图中我们看到,红色的激光被分光镜分成两束(向上的那一束是反射光,向右的那一束是透射光),然后又被两面反射镜完全反射回来,分别被分光镜透射和反射,经凸透镜扩散,最后在观察面上形成干涉图样。

正是由于最终参与干涉的两束光线都来自初始的那束激光,它们具有相同的频率和固定的相位关系,所以才能形成稳定的干涉图样。下图是一架专业的迈克尔逊干涉仪形成的图样。

干涉仪形成的图样

干涉仪形成的图样

2:它有啥用?

迈克尔逊干涉仪产生的条纹是由两面反射镜到干涉平面的距离决定的。以上图为例,如果我们稍微移动一下其中的一面反射镜,就会看到上面的圆圈从中心“吐出来”或者“吃进去”。而这个“稍微移动”实际上很小,只需要移动激光波长的一半就可以“吐出”或“吃掉”一个圆圈。红色激光笔的波长大概在650纳米,也就是0.65微米。一根头发的直径大约90微米,所以只需要移动一根头发的千分之三就可以看到干涉图样很明显的变化。显而易见,它能用来测量精细的距离的变化,或者用来校对一个样品表面是否平整。

除此之外,它还能派上大用场,做为大科研项目的主力军。比如下面这个硕大的迈克尔逊干涉仪:

光干涉引力波观测台

光干涉引力波观测台

它叫做LIGO,是(light interferometer gravitational wave observatory) 的缩写,意思是光干涉引力波观测台。其中两面反射镜与分光镜的距离大概在3,4千米(世界上有好几家这样的观测台,每台的尺寸有所不同)。它也是用来测量距离的精细变化的。不过这里,距离的变化是由“引力波”引起的。爱因斯坦的理论说,两个硕大的天体在相互旋转的时候会引起它们周围的引力场周期性地变化,这种变化会像水波一样在宇宙中传播开来。而引力场的波动能改变空间的长度。如果这个波传到了地球,就会改变LIGO的两个反射镜与分光镜之间的距离,从而引起干涉条纹的变化。目前,实验还在进行中。

3:自己怎么做一个便宜的?

LIGO这个大号迈克尔逊干涉仪花费了4亿美元了,但是要做一个迷你版的却花不了30块人民币。下图就是这个迷你版的装置:

迷你版干涉仪

迷你版干涉仪

关键部分:反射镜和分光镜。

反射镜和分光镜

反射镜和分光镜

实验中,我偷了实验室价值大约3元人民币的液氮(小于一升),然后把它周围产生的水汽泼在光路上,就可以找出美丽的光线来,见下图:

雾气中的激光

雾气中的激光

(激光本身方向性很强是看不到的,但是在一定尺寸的粒子中,就会出现散射现象,显示出一条明亮的光路,这就是丁达尔现象)有一小段视频请看:

那么干涉图样怎么样呢?当两面反射镜反射的光不重叠时,见左图。当我们调节反射镜的角度,把这两块光斑重叠在一起时,见右图。

干涉图样

干涉图样

啊哈,这一点都不像开始展示的那种专业迈克尔逊干涉仪的干涉图样吧!那儿是一圈一圈的,这里是一块一块的。这是因为当两面反射镜接近完美地垂直,且分光镜接近完美地位于这个直角的一半的时候(45度),迈克尔逊干涉仪产生圆圈干涉图样,物理上叫做“等倾干涉”。两面反射镜成一定夹角,或者分光镜偏离了45度位置时,产生条纹状干涉图样,物理上叫做“等厚干涉”。要接近完美垂直,对仪器要求比较高,所以我们的山寨干涉仪只能产生条纹而不能产生圆圈了。

如果你做这个实验,你会发现,当两块光斑不重合的时候,它们各自是很稳定的。当形成干涉图样的时候(上面右图),图中的竖直方向的暗线会左右移动得比较厉害。这就是因为这些暗线的位置是由两面反射镜与分光镜之间的距离决定的。桌子轻微的抖动(头发直径的千分之三)就会引起这些暗线移动。所以迈克尔逊当年做实验的时候,是把他的干涉仪放在一大块大理石上,整块大理石又是浮在水银里的,用来减少仪器自身的振动。

4:自己怎么做一个更便宜的?

有朋友说,你这个干涉仪不好做啊,主要是那个反射镜镜座从哪儿弄?其实我还做了一个更便宜的,也几乎一样好用。见下图:

更加经济的版本1

更加经济的版本1

更加经济的版本2

更加经济的版本2

随便找一个成直角的东西,贴两面小镜子上去,找一块透明的玻璃片就可以做自己的激光干涉仪了。效果如何?见下图:

精简版的最终效果

精简版的最终效果

个人觉得,甚至比上面那个还要好一些。就是调节起来稍微麻烦一点。要让两束光重叠,需要小心地调节中间的分光镜的位置和角度,因为现在反射镜已经固定了。同样,这里竖直方向上的条纹也在左右移动着,反应出桌子在微小的抖动。因为绿光的波长比红光短,所以这架干涉仪的距离灵敏度比开始那个还要高一点。

集中回复关于下推式磁悬浮的一些问题

wlreg 等同学在PID平衡算法问了好多问题,那个页面的评论太长,已经找不到组织了,所以重开一个页面回答一些问题。

Q1、看了攻略和上面的评论,整个装置通上电后通过电位器先将接运放的传感器的输出调节为2.5V,然后再放浮子上去。霍尔传感器感应的气势是浮子的磁通吗?然后通过传感器的输出变化反应浮子的倾斜程度?(错了请指正呀,感谢的说。)
今天在图书馆居然被我找到一本关于PID控制器的书,对照了一下上面的符号和程序上的符号,大概理解了一些之前不懂的变量的意义,但是程序上还是有地方不懂,希望老男孩筒子指导一下吧。

A:气势这个词用的相当诡异,可能是因为wlreg同学刚喝了藿香正气水吧 :)
首先,电位器把输出调节到2V附近而不是2.5V附近,印象中那个东东输出的电压上限是3.7V,从读数上看最大值到750左右,我大概取了个中间值,对应的读数是400左右。
传感器感应的是浮子的磁通量的“变化量”,因为传感器垂直安装在线圈的中心高度,所以线圈中通电时对传感器基本没影响。而底座大磁环是不动的,所以传感器的读数变化基本都是由于浮子引起的。请注意这里浮子不会倾斜,只会水平移动!通过读数变化就可以知道浮子移动的方向。

—————————————————————

Q2:一开始的端口设置里,int rotatePin=3,rotatePin这个变量貌似一直都没有用过吧(只在上面程序注释里看见出现过)……

A:介位童鞋,你算是说对了,这个变量没有用。那它为啥会出现在代码里呢?其实在我的博客的某个角落里,写过企图给线圈加上旋转磁场,最后没有成功。所以这是一段没有删除干净的代码……嘿嘿,这个角落实在太角落了,以至于我也没有找到,汗

—————————————————————

Q3:Kp是比例系数,Kd是微分系数,这个程序采用的是增进式PID?那么setKd,和setKp这些系数都是实验慢慢调试出来的吗?如果我做的有些部件(磁铁的大小之类的)的和老男孩筒子列表里的有出入,那么这些值都要自己找了?

A: 没错,这些值都要自己找,但是也并非没有经验可循,建议先记录一段log到电脑上,然后把power值和传感器读数列出来对比,就可以估算出这些值了。推荐一个叫Origin的画图软件,可以画出图表对比。据说用excel也可以 :)

—————————————————————

Q4: 程序第82行,if(debug) tick=0;
这里debug不是设定为false吗?后面也貌似没有看见有更改过这个值,那么这一句实质上是永远不会运行的吧?

A: 当你需要调试的时候,把它改为true然后重新烧入板子。debug模式下不是为了悬浮的,而是为了拧那个电位器。
这个说来话长了:那两个电位器的螺丝孔很小,我需要两只手配合才能拧它。这样就不方便用万用表读数,我那个乱七八糟的洞洞板已经焊不下新的线头用来测量。所以你看到下面的几句:
    Serial.println(adjustValue1);   
    Serial.println(adjustValue2);   
    Serial.println(readValue1);   
    Serial.println(readValue2);  

这几行代码把读数打印到屏幕上,这样我就可以两只手调电阻,抬头看读数鸟。
另外顺便加了几行代码,用来判断线圈通电的方向是不是正确。

—————————————————————

Q5:程序第87行,if(tick2>=2;
这个是右移两位的意思吗?就是相当于除以4了,这个的意义何在呢?

A:读4次然后求平均嘛

—————————————————————

Q7、程序144行,if(debug)下面的括起来的真的会运行吗?

A:这个问题其实在Q4解释过了

—————————————————————

Q8: 程序第162行,delay(32000)
32000这个其实不用纠结的吧?但是总觉得很特殊的样子,为什么是这个设置……

A: 在PWM的秘密的两篇文章里,提到了改变PWM频率后,delay(n)的周期会产生变化,这里32000大约是0.5秒左右。对于我们这种老眼昏花的同志,再快就看不清了。

—————————————————————

Q9:程序第131行,Pid1.target = min(755, min(adjustValue1 + offset, Pid1.target));
755这个值是什么样来的呢?不是很明白的样子……

A:参见Q1,这个755应该是我调节时曾经见过的最大值。

————————————————————–

Q10: 额,之前那个问题也问错了,程序的PID应该是位置型的……
不过按照那个位置型PID的公式,貌似下面的这段就有点不解了
——————————————————
error = readValue1 – Pid1.target;
v = error – Pid1.preError;
Pid1.v = (Pid1.v * 6 + v) / 7;
Pid1.power = (int)error * Pid1.Kd + Pid1.v * Pid1.Kp;
——————————————————
按照公式,这里应该是
Pid1.power =Pid1.Kd*v+Pid1.Kp*(int)error
不是吗?

A: 这次真的满头大汗了,仔细看了一下,我好像确实是把kd和kp两个参数的含义搞错了。今天忙了一天,现在大脑还是一团浆糊,明天早上再看一眼确认。不过参数虽然含义弄错了,那些参数值是可用的,你把代码里所有的kd和kp互换一下吧 :)
另外,(int) 要放在最前面,是把结果取整用的。

——————————————————————————

Q11: 又有了一个新问题。仔细看了一下程序
第87行
———————————————–
if(tick2<50) {tick = 0;return;}
————————————————
按照我学的C语言的理解(只是入门级别,可能有错),这里有一个return语句,就是执行到这个return的话就会跳出函数体了,而这里正在执行的函数式loop函数,也就是说执行到这里,就跳出loop函数不往下执行了,按照开发板的运作,loop这个函数又会被从头开始执行。而程序的113行和119行也有一个return语句……
其实我想问的是,按我的理解这段if(tick==500)这段程序是用来检测端口的值用的……其实特意弄tick和tick2这两个变量以及return语句这样来检测端口的用途是什么呢……这段有些弄不懂意图……

A:你看这一段中间有一句:if(writeLog)。所以总体来说,tick1和tick2都是用来记录log用的,所以你不用太纠结于这段代码是什么意思。说实话我刚才看了一会儿也有点头昏眼花,恨不得把作者揪出来打一顿。仔细回想了一下,最早只有tick1,当循环500次以后,集中发送一次log(因为串口发数据很慢,会影响采样频率)。后来发现500次还不到1秒钟,这时候可能刚刚放上去还没平稳呢。所以加上了一个tick2,这个500次的循环执行50次以后,大概是30秒,这时候再发送最后的500个数据。
然后再看一下真正运行时的情况,这时候writeLog=false,这些代码基本都属于没有用的了,另外还有一些莫名其妙的tick2 = 0;  tick>500之类的,应该都是进化过程中的垃圾产物。

—————————————————————–

第一回遇到这么认真的读者。其实看代码重在领会精神,没必要理解每一行代码的作用。但是认真的同学也有认真的好处,钻研精神值得赞赏!尤其是那个kp和kd的参数,

其他页面的问题就回答到相应的留言下面了,那里评论没有那么长 :)

石墨静态磁悬浮的探索 – 这次成功了

昨天在网上淘的日本派通铅笔芯终于到了,因为担心买的型号不合适,所以买了0.5的2B和0.7的B和2B共三种。收到快递的时候简直是“欲火焚身”,迅速拿出一根做实验,果然悬浮成功了!

悬浮的铅笔芯

悬浮的铅笔芯

虽然这幅图看上去悬浮很平稳,事实上可能因为桌子不够水平,这个铅芯在磁铁面会非常快速的溜来溜去,有过徒手抓鱼经验的同学会有些体会。 :) 到了一定的位置,就会像荡秋千一样晃晃悠悠几下,然后停在那里。我猜想它应该是有类似碗装的磁场结构,让笔芯悬浮在碗底。只是这个碗沿比较低,哈口气都会让它溜出去(汗,圈妈:直接说盘状不就好了嘛)

看来之前没有成功果然是铅笔芯的问题,后来把三种都实验了一下,发现都可以悬浮。只是0.7的可能比较重,悬浮的高度更低。

虽然已经有很多照片证明石墨是可悬浮的,但是当真正亲手实验成功时,还是为自然的力量感到震撼!
这是另外一张照片:

常温下的静态磁悬浮
常温下的静态磁悬浮

事实上,在快递没有到之前,我没耐住寂寞,先跑到路边的文具店买了两盒。因为我知道国内假货多,所以去了两家文具店,买了不同牌子的两盒笔芯。好吧,事实证明小店买的,不仅不会悬浮,还能倒挂金钩。

下面这个是淘宝店对派通铅芯的描述:
【功能描述】:原装日本PENTEL派通铅芯适用于 所有0.7mm自动铅笔新型工艺配方,传统铅芯为粘土与石墨烧制而成,书写阻力大,不顺滑。且易折断。而派通铅芯为树脂与石墨压制而成,使铅芯的浓度与硬度达到了完美的结合比例,书写起来顺滑,无阻力感,字迹清楚。

这样说来,也许那两盒并不是假货,只是工艺不同吧,反正实验结果如下:

前三种都是日本派通铅笔芯

前三种都是日本派通铅笔芯

铅笔芯在磁铁表面悬浮的稳定性的讨论

关于不同长度铅笔芯在磁铁表面的稳定和位置,老薛写了两篇很精彩的解释,有兴趣的同学请过去围观:
铅笔芯在磁铁表面悬浮的稳定性的讨论(上)
铅笔芯在磁铁表面悬浮的稳定性的讨论(下)

悬浮稳定性的探索

悬浮稳定性的探索

抗磁性的原理

很多人在看到这个实验的时候,都觉得不相信:磁悬浮真的这么简单吗?进一步的问题就是:这是为什么呢?

事实上,任何物质都有抗磁性。它的本质是电磁感应定律的反映。外加磁场使电子轨道动量矩发生变化,从而产生了一个附加磁矩,磁矩的方向与外磁场方向相反。

这个解释貌似太专业了,看不懂没关系,回忆一下高中时候学的楞次定律也行:感应电流的磁场总是要阻碍引起感应电流的磁通量的变化。

啥?还是不好理解?那么请记住儿童不宜版定律:闭合回路的线圈,对变化磁性的反应是“插的时候不让插,拔的时候不让拔”

非常形象的楞次定律

非常形象的楞次定律

而原子中的电子们,对外加磁场表现出的就是这种抗磁性。从互动百科摘抄一段:

任何物体在磁场作用下,都会产生抗磁性效应。但因抗磁性很弱,若物体具有顺磁性或序磁性(见铁磁性)时,抗磁性就被掩盖了。因此,从原子结构来看,呈现抗磁性的物体是由具有满电子壳层结构的原子、离子或分子组成的,如惰性气体、食盐、水以及绝大多数有机化合物等。由于迈斯纳效应,超导体是理想的抗磁体(见超导电性)。实际上,自然界中绝大多数物体都是抗磁性的。抗磁磁化率与磁场和温度无关。但也有例外,如石墨、铋等。
指南针为什么不会向南极飞?

看到这个问题,我相信很多人跟我一样,第一反应就是“因为磁力不够大呀”。这个问题在老薛的博客里详细介绍了,很有意思。一个简单的论据就是,把磁铁放在泡沫上浮在水面,它马上就会旋转方向变成南北指向,但是却不会向南或者北移动。所以说,均匀的磁场只会对场中的磁铁产生扭矩,而不会产生水平的拉力。看到结论以后反过来看这个题目,好像变得很直观了。指南针实际上也是指北针,南极受力向北,北极受力向南,自然不会飞向任何一边。其实地球磁场也不是均匀的,南北半球的磁铁还是会受到微弱的牵引力,只是可以忽略而已。

为了验证这幅插图,我特地回顾了一下左手法则(又称安培定律):左手平展,大拇指与其余4指垂直,若磁力线垂直进入手心,4指指向电流方向,则大拇指所指方向为载流导线在外磁场中受力的方向。

顺便回顾一下右手法则,确定导体切割磁感线运动时在导体中产生的动生电流方向:伸开右手,使大拇指跟其余四个手指垂直并且都跟手掌在一个平面内,把右手放入磁场中,让磁感线垂直穿入手心,大拇指指向导体运动方向,则其余四指指向动生电流的方向。

好了,可以心满意足的睡觉去了 :D

石墨静态磁悬浮的探索 – 虽然没成功

之前介绍过有人用钕铁硼+铅笔芯可以实现静态的磁悬浮,因为石墨具有抗磁性。当时简单试了下没有成功,后来就没有再深究了,内心深处对这个实验一直持怀疑态度。直到前几天有一位叫做老薛的小朋友动手实验成功,有兴趣的同学可以去翻翻他的博客

这下老男孩坐不住了,老薛同学说了几点可能的原因:
1,把圆片形状的磁铁换为方块的,没有间隙可能漏磁较少;
2,磁铁不一定要大,小块的磁铁可能梯度更大
3,铅笔芯石墨含量越高越好

于是迅速淘了一小堆正方体小磁铁,兴致勃勃的准备见证奇迹,结果再次被打击了:
没有成功的静态磁悬浮

事实上,那根该死的铅笔芯不但没有浮起来,貌似还吸在了磁铁上。我把磁铁片翻过来,它居然还得意洋洋的挂在下面!

相比之下,老薛同学的实验照片如下:
老薛同学的结果

伤心之余,我查了下资料,在阿莫的论坛上找到了疑似答案。主要是国内的铅笔芯都是采用的石墨+粘土配方,而大部分粘土里都是含铁的。需要说明的是抗磁性一般都比磁性弱很多,所以不但不能悬浮,还会被吸住。
没办法,咱也不能因为这个就投诉国货,毕竟铅笔芯不是设计来玩悬浮的。

为啥老薛同学的笔芯可以呢?哈哈,因为他是在英国啊。说到这里,不得不对他们的实验室表示一下由衷的羡慕妒忌恨。他的导师居然和他一起玩磁悬浮,之前还在实验室里玩遥控飞机。唉,国内的导师们,已经被各种论文和指标压的喘不过气,你要是在实验室玩这个,非得被扔到楼下去不可 :D

下面是网上找来的图,可以看出磁铁大小和形状并不是关键原因,主要还是笔芯的问题:

最后,转一个国外某蛋疼到极致,同样也是敬业到极致的某同学的总结,试验了各个国家不同粗细和标号的铅笔芯的悬浮情况:
第一栏是笔芯粗细,国内一般只有0.5和0.7两种;第二栏是HB标号,B越大的越软,石墨含量越高(这次我还试了6B的铅笔芯,用小刀刮成片状,依然不成功);yes和no不解释;第四栏是产地。

其中来自德国的施德楼(Staedtler)铅笔标记了Very Good,这个牌子我一直很喜欢,可惜家里的都是圆珠笔。

Pentel Super Polymer,
0.35  HB YES Japan
0.35 B&2B YES Japan
0.5 B&2B YES Japan
0.5 HB YES Japan
0.5     F YES Japan
0.7  HB (1 box YES, 3 boxes NO) Japan
0.7 B YES Japan
0.9  2B YES 15/$1 at McGuckin, 2524 Arapahoe Ave., Boulder, CO
0.9 HB NO Japan
0.9 B NO Japan
Faber-Castell (1.4 B labeled Brazil)
http//www.faber-castell.de/
0.35   ? Germany
0.5 Super Polymer ? Germany
0.7  2B YES Germany
0.7   ? Germany
0.9   ? Germany
1.4  B,Super Polymer leads for their “E Motion Pencils” YES (very good) 6/$2.88 at Meninger 499 Broadway, Den, CO
2.0 B & 2B NO Germany
Staedtler (Marsmicro Polycarbon) Germany
http://www.staedtler.com
0.5   ? Germany
0.7   ? Germany
0.9 B & 2B YES (very good) No longer made.
0.9 HB YES (less than 2B & B) No longer made.
2.0 B & 2B NO Germany
Derwent
7.0 8B NO  
Stanford
0.5 HB YES Japan
0.9 HB (Sphere TM) NO Korea
Pilot (NEO-X)
0.7 HB YES Japan
MonAmi
0.7 HB NO Korea
School Time      
0.5 HB NO China
       

 

 

基于微分电路的上拉式磁悬浮

这是一个基于微分电路的上拉式磁悬浮。它不使用单片机,仅靠电路实现上拉式磁悬浮的平衡。而且作者把它做成了“便携式”,用一个透明文具盒+电池就装下了。可以随身携带,随时演示,简直就是工科宅男的泡妞利器!

原文的图片链接都已经失效了,还好我这里曾经下载保存过

废话不多说了,以下是原文攻略部分。

$$$$$$$$$$$$$$$$$$$$$华丽丽的昏鸽线$$$$$$$$$$$$$$$$$$$$

未组装阶段的通电悬浮图:

再来一张:

第三张

开始组装

它的心脏:比例微分控制电路

电路是由如下元件组成,一般家电维修处都能买到,其中运放,我用的是LM324 是因为我手头现有这个,其实用2 运放就行,线圈是自己饶的,漆包线挺贵的。

最终组装完成的视频:
http://www.56.com/u45/v_Mjk3NjY0NzQ.html

自制要点:被悬浮的必须是磁力强体积小的磁铁,推荐使用球形钕铁硼磁铁,非球形也行。漆包线很贵,线圈不必绕那么多圈,绕到我这个的一半就可以达到和我这个一样的磁场了,但是绕得越多,越省电. 两个可变电阻的阻值必须调试到合适才能悬浮且稳定. 霍尔元件的位置应该处于线圈中心。

霍尔元件在很多家电上都有用到,去家电维修部买就可以了,可以买3503,也可以买别的型号,但是要注意买输出线形量的,不是开关量的。

那么我就整体原理解释一下,如果你水平高,你可以做一个,如果水平不行,我解释了你起码能知道是怎么回事: 小球在空中受重力,当小球处于某个高度时,电路使重力和磁力平衡;当小球高于这个高度时,电路使线圈磁力小于重力,从而使小球有下落趋势;反之,低于这个高度,电路使线圈磁力增大,小球就有上升趋势.从而小球能在一定的扰动范围内保持平衡。

其实学过控制的人可以看出电路中还有微分控制,就是那个电容.其实这个电路没有微分控制也能工作,小球稳定性会稍差些.如果不懂控制,完全可以按你理解的不加电容来做.另外线圈挡板的铝板也起到类似于微分控制的作用,抑制震荡.

(本段系另一人回复,在帖中23楼,非作者叙述)
我说说我的理解:小球的轻微扰动会导致空间磁场变化,霍尔元件把这个变化感应成线性电位信号反馈。 两个500K 电阻的分压可以让运放输出有一个直流偏压, 防止三极管工作在截至区(调节静态工作点)。 200K 电位器的作用是调节霍尔元件信号的平衡位置, 500K 电位器的作用是调节控制电路的灵敏度(或者是调节前级放大倍数防止后面的放大电路饱和), 两级运放间RC滤波器是滤除纹波
让线圈的磁场更平稳。霍尔元件的反馈信号被两级运放和三极管放大了很多倍, 只要磁场一有扰动,就会驱动线圈电流变化让磁场趋于恒定。

23楼完全正解.
不过电容不是为了滤除波纹,而是微分控制,也就是根据小球的速度来改变线圈电流的大小. 如果不加电容,就只根据小球位置来改变了. 这种球形磁铁可以在淘宝上买到,搜“球形钕铁硼”即可,目前全国只此一家,所以是2元/个的“垄断价格”,不用球形的话,很多城市的卖电机的地方都有卖钕铁硼。

我又在土豆上传了一次视频:
http://www.tudou.com/programs/view/KT7KLCwYl2g/

(86 楼作者的总结)
“磁悬浮”现在已经变成家喻户晓的名词。但现在大家熟悉的磁悬浮都是利用磁场的斥力把铁磁体向上方托起,磁悬浮列车就属于这一种。可是你见过凌空悬着的“磁悬挂”吗?我设计制作了一个不算复杂的电子装置,就能演示这种不寻常的科学现象。

材 料
R1——R6均为1/4W碳膜电阻,R7、R8为1/4W微调电位器。
C1:1uF无极性电解电容。
IC1:四运算放大器集成块LM324。
VT1:9013。
霍尔元件:3503。霍尔元件被广泛用在家电上,电子市场或家电维修部都能买到,可以买3503,也可以用别的型号,但购买时须说明是线性输出的,错买了开关型的不能用。在电路图中没画出霍尔元件的接法,应该把有字的一端朝向自己,三个管脚从左到右依次接电源正极、接地、 接电路中的信号输入端。
悬浮小磁球为高强磁性的钕铁硼磁钢小球,普通磁铁的磁性不够,不能用。钕铁硼磁钢小球可以在淘宝网上购买(搜索“球形钕铁硼”),非球形的钕铁硼小磁钢也能用,就是演示的视觉效果差点。

制 作
1. 电路部分的元件不多,我自制时采取“空间连接”,各接点用电烙铁焊牢。如果不习惯,则把元器件焊在附上的印刷电路板上。
2. 制作电磁线圈。找一根内径8 毫米的塑料圆珠笔管,切割1.5 厘米长一段做为线圈芯管,用薄铝片(绝对不能用铁片)剪两块外径2 厘米的挡板,分别在中心部位钻一个与笔管内径一样大的孔,用AB 胶把两个档板粘牢在芯管两端。把长度为15 — 20 米、线径为0.2 毫米的漆包线密绕在这个骨架上。圈数绕得更多些就更省电,但是电磁力不会明显提高。
线圈做好后试验一下:接上大约5 伏直流电,在小磁球上方1 厘米之外应该能把它吸上来。最后在线圈芯管中心处插入一个霍尔元件,使霍尔元件上的平面与线圈挡板平行。在线圈端面前加一块铝片,铝片内形成的涡流能够使小磁球悬浮更加平稳,其作用类似于电容的微分控制。
3. 将包括5号电池夹(4节)和开关在内的各部分组装在一个长条形的半敞开盒子里,今后调节电位器就比较方便。

调试和演示
把磁钢小球放在线圈下5 毫米处。先把R8 调到最大,从正到负调节R7,直至小磁球离地为止。如果它一直不能离地,则应把线圈反接。
调小R8,使磁钢小球稳定;然后边观察边微调R7、R8,最终使小球能稳定悬空漂浮在线圈下1 厘米处。
在演示时,可以轻轻晃动装置,用纸、塑料瓶等从小球与线圈之间穿过,甚至用手指轻轻触碰小球,它都能保持悬浮状态。

(82 楼问) 不知道用这个线圈行不行.700 欧左右
作者:82 楼那位loonglog ,你的线圈太细了,圈数太多了。

(83 楼问) 晕.我的做好了就是在电磁铁下面乱跳.磁铁必须是球形的吗?
作者:83 楼的,不必,近似即可,例如圆柱也可。

盗梦陀螺攻略6- 陀螺制作(大结局)

之前的几篇磁悬浮攻略,引来了一位业内高手 — 老顽童同学。该同学提出了很多意见(虽然看不太懂,但是从众多的专业术语看来,应该是比较靠谱滴)。庆幸我之前已经把电路部分的攻略发完,不然都不好意思往下写了。圈圈妈说的对,电子这个行业我还没迈过门槛哪。有兴趣的同学可以去围观老顽童的飞轮电机计划

这篇攻略是盗梦陀螺的完结篇,好多人对这个金属质感的陀螺很有兴趣,希望了解它的材质和加工过程,下面就来揭晓谜底。

首先,原材料:三块钕铁硼磁铁,其中最大的是环形,另外一大一小两个圆片;一元硬币;一大一小两个乐高齿轮;一个乐高轴:

简单的大小排序组合,磁铁都在下面,乐高件都在上面,这样可以避免头重脚轻,用热胶粘上:

绕上铜丝,我的本意是弄成一个鼠笼,让它旋转的,最后没起作用:
铜丝绕成的“鼠笼”

在外面裹上纱布,这个是为了抹石膏方便,中空的结构可以让陀螺更轻。这个创意来源于10年前的一次骨折,北医三院的大夫教我的:
纱布

石膏来啦,广告贴,用医用石膏的最大好处是:不会被圈圈的保护者们赶出门去。
石膏这个东西很神奇,前一分钟还像豆浆一样稀,下一分钟就像牙膏似的,再一分钟就硬了:
牙医专用石膏

抹上石膏,好恶心的一大坨:
未经处理的陀螺

用小刀仔细刮平:
人肉加工,用小刀刮平

指甲油来啦,我选了古铜色,金属效果特别好。因为在家刷指甲油有味道,我带到公司刷的,顺便挑了一个手指头也测试了下。嗯,疑似有男士对我猛抛媚眼 :)
古铜色指甲油
注: 这个图是网上找的,不是我的手。

见证奇迹的时刻到了,看看最终成品:
最终的成品

注:这个有如熊掌的肉忽忽的手才是我的。

磁悬浮的攻略到此就结束了。最近很忙,因为圈圈的原因,也把电钻电烙铁之类的东西都收了,所以短期内不一定有新制作问世。有空的时候打算研究研究Android手机,Arduino板子和NXT的小功能,欢迎大家关注和讨论。顺便发个小广告,欢迎大家在新浪微薄上加我为好友:@动力老男孩

查看盗梦陀螺的其他几篇攻略点这里

盗梦陀螺攻略5- PID平衡算法

刚过完长假,继续发攻略来克服长假综合症。看到galiu同学带着女儿玩乐高,我突然非常高兴,哈哈,也许这就是若干年后的我啊! :)

进入正题,介绍提了多次的PID平衡算法。先从网上摘抄一段:

当今的自动控制技术都是基于反馈的概念。反馈理论的要素包括三个部分:测量、比较和执行。测量关心的变量,与期望值相比较,用这个误差纠正调节控制系统的响应。

这个理论和应用自动控制的关键是,做出正确的测量和比较后,如何才能更好地纠正系统。

在工程实际中,应用最为广泛的调节器控制规律为比例、积分、微分控制,简称PID控制,又称PID调节。它以其结构简单、稳定性好、工作可靠、调整方便而成为工业控制的主要技术之一。当被控对象的结构和参数不能完全掌握,或得不到精确的数学模型时,控制理论的其它技术难以采用时,系统控制器的结构和参数必须依靠经验和现场调试来确定,这时应用PID控制技术最为方便。即当我们不完全了解一个系统和被控对象,或不能通过有效的测量手段来获得系统参数时,最适合用PID控制技术。PID控制,实际中也有PI和PD控制。PID控制器就是根据系统的误差,利用比例、积分、微分计算出控制量进行控制的。

比例(P)控制
比例控制是一种最简单的控制方式。其控制器的输出与输入误差信号成比例关系。当仅有比例控制时系统输出存在稳态误差(Steady-state error)。

积分(I)控制
在积分控制中,控制器的输出与输入误差信号的积分成正比关系。对一个自动控制系统,如果在进入稳态后存在稳态误差,则称这个控制系统是有稳态误差的或简称有差系统(System with Steady-state Error)。为了消除稳态误差,在控制器中必须引入“积分项”。积分项对误差取决于时间的积分,随着时间的增加,积分项会增大。这样,即便误差很小,积分项也会随着时间的增加而加大,它推动控制器的输出增大使稳态误差进一步减小,直到等于零。因此,比例+积分(PI)控制器,可以使系统在进入稳态后无稳态误差。

微分(D)控制
在微分控制中,控制器的输出与输入误差信号的微分(即误差的变化率)成正比关系。自动控制系统在克服误差的调节过程中可能会出现振荡甚至失稳。其原因是由于存在有较大惯性组件(环节)或有滞后(delay)组件,具有抑制误差的作用,其变化总是落后于误差的变化。解决的办法是使抑制误差的作用的变化“超前”,即在误差接近零时,抑制误差的作用就应该是零。这就是说,在控制器中仅引入 “比例”项往往是不够的,比例项的作用仅是放大误差的幅值,而目前需要增加的是“微分项”,它能预测误差变化的趋势,这样,具有比例+微分的控制器,就能够提前使抑制误差的控制作用等于零,甚至为负值,从而避免了被控量的严重超调。所以对有较大惯性或滞后的被控对象,比例+微分(PD)控制器能改善系统在调节过程中的动态特性。

看概念可能有点晕,举个小小的例子也许能帮助理解。看下面的图:

假设我们想把一个小球稳定在一个光滑的坡顶,这显然是一个不平衡的系统,稍有扰动小球就会滚下来。假设恰好平衡的位置坐标是L,我们可以测量到小球的位置是x,那么怎么给小球施加f(x)的力反馈,让它能够平衡呢?

最直观的想法就是f(x) = Kp*(L-x),简单的说就是你在左边我就向右推,你在右边我就向左推,这就是比例因子P;

现在考虑两种情况,同样是在x位置,小球静止和小球具有速度V这两种情况。很明显,如果V>0,我们只需要施加更小的力,因为小球自身的惯性会让它运动向平衡位置。所以可以修正f(x) = Kp*(L-x) – Kd*V。因为速度一般不容易测量,我们常常用位置的变化Δx除以测量的时间差Δt来计算速度,所以这就是微分因子D;

情况继续发生变化,上面考虑的是斜坡静止的情况,如果这个变态的斜坡是移动的怎么办呢?(例如两轮平衡机器人实际上是可以运动的,对于静止的磁悬浮来说,不需要考虑这个参数)这时候我们需要不断的累加并平均x值,来计算平衡位置的L,这个就是积分因子I;

以上就是PID的简要介绍。说起来容易,真正调试的时候,最恼火的就是这几个参数到底是多少,办法只有一个:试,不断的试!

当然,试验也不要当老黄牛,累死都没人知道。我曾经试其中某个参数,从0.1开始,每次加0.01,差点试到崩溃。后来想了个办法,用串口把Arduino的读数发送到电脑,然后用软件分析结果,看到数据明显发现这个值偏小,发狠改到20,就这样成功了…..

当时的数据找不到了,发一段成功悬浮时的log吧,其中两种颜色分别代表两个方向的传感器读数(相当于x):

PID的测量值

从图上可以看出,平衡的位置具体在哪里,我们可能不一定能精确知道,但是通过合适的反馈系统,陀螺能够自动稳定到相应的位置上。参数不正确的情况下,这些点会越振越远,直到失控。

最后附上源代码,没有时间整理,可能有不少问题,有兴趣的同学凑合看吧 :)

//PINs setting
int adjust1Pin = 1;    //用来调节A的电位器
int adjust2Pin = 2;    //用来调节B的电位器
int read1Pin = 4;      //用来连接输入A传感器
int read2Pin = 3;      //用来连接输入B传感器
int i1Pin = 36;        //连接电机驱动板的I1接口
int i2Pin = 37;        //连接电机驱动板的I2接口
int i3Pin = 39;        //连接电机驱动板的I3接口
int i4Pin = 38;        //连接电机驱动板的I4接口
int power1Pin = 5;     //连接电机驱动板的EA接口
int power2Pin = 6;     //连接电机驱动板的EB接口
int rotatePin = 3;     //用来控制磁场旋转的PMW接口

boolean debug = false;
boolean writeLog = false;
double setKd1 = 0.55;
double setKd2 = 0.55;
double setKp = 22;
int offset = 70;
int delayMs = 1;
int tick = 0;
int myLog[3500];

//PID structure
typedef struct {
  double target;
  double aver;
  double Kp;
  double Kd;
  int preError;
  int power;
  boolean flag;
  double v;
} PID;

PID Pid1, Pid2;

void setup()
{
  pinMode(i1Pin, OUTPUT);     //I1和I2都是数字信号
  pinMode(i2Pin, OUTPUT);     //通过设置I1和I2来控制电流方向
  pinMode(i3Pin, OUTPUT);     //I1和I2都是数字信号
  pinMode(i4Pin, OUTPUT);     //通过设置I1和I2来控制电流方向
  pinMode(power1Pin, OUTPUT);  //按占空比方式输出的模拟信号
  pinMode(power2Pin, OUTPUT);  //按占空比方式输出的模拟信号
  pinMode(rotatePin, OUTPUT);  //按占空比方式输出的模拟信号

  //analogWrite(rotatePin, 128);

  Serial.begin(9600);          //设置波特率
  TCCR0B = 0x01;   // Timer 0: PWM 5 &  6 @ 16 kHz
  TCCR1B = 0x01;   // Timer 1: PWM 9 & 10 @ 32 kHz
  TCCR2B = 0x01;   // Timer 2: PWM 3 & 11 @ 32 kHz
  Pid1.Kp = setKp;
  Pid1.preError = 0;
  Pid1.Kd = setKd1;
  Pid1.power = 0;
  Pid1.flag = true;
  Pid1.target = 300;
  Pid1.aver = 0;
  Pid1.v = 0;
  Pid2.Kp = setKp;
  Pid2.preError = 0;
  Pid2.Kd = setKd2;
  Pid2.power = 0;
  Pid2.flag = true;
  Pid2.target = 300;
  Pid2.aver = 0;
  Pid2.v = 0;
  tick = 0;
}

int tick2 = 0;
//boolean rotateFlag = true;
void loop()
{
  //digitalWrite(rotatePin, rotateFlag);
  //rotateFlag = ! rotateFlag;
  //delay(16000);
  //return;

  if(debug) tick = 0;
  tick++;
  if(tick==500)
  {
    tick2++;
    if(tick2<50) {tick = 0;return;}
    tick2 = 0;
    if(writeLog)
    {
      for(int i=0;i<500;i++)
      {
        Serial.print(myLog[i*7 + 0]);
        Serial.print("  ");
        Serial.print(myLog[i*7 + 1]);
        Serial.print("  ");
        Serial.print(myLog[i*7 + 2]);
        Serial.print("  ");
        Serial.print(myLog[i*7 + 3]);
        Serial.print("  ");
        Serial.print(myLog[i*7 + 4]);
        Serial.print("  ");
        Serial.print(myLog[i*7 + 5]);
        Serial.print("  ");
        Serial.print(myLog[i*7 + 6]);
        Serial.println("  ");
      }
      Serial.println(Pid1.target);
      Serial.println(Pid1.preError);
      Serial.println(Pid2.target);
      Serial.println(Pid2.preError);
    }
    return;
  }
  else if(tick>500)
  {
    tick = 0;
    //delay(990000);
    return;
  };

  //=======第一组电位器和传感器========
  int readValue1 = 0;
  for(int i = 0; i < 4; i++) readValue1 += analogRead(read1Pin);
  readValue1 >>= 2;
  //readValue1 += (Pid1.flag ? 1 : -1) * Pid1.power / 17;
  int adjustValue1 = analogRead(adjust1Pin); //410 analogRead(adjust1Pin);
  Pid1.aver = Pid1.aver * 0.9995 + readValue1 * 0.0005;
  Pid1.target = Pid1.target + (Pid1.target - Pid1.aver) / 100.0;
  Pid1.target = max(0, max(adjustValue1 - offset, Pid1.target));
  Pid1.target = min(755, min(adjustValue1 + offset, Pid1.target));

  //=======第二组电位器和传感器=======
  int readValue2 = 0;
  for(int i = 0; i < 4; i++) readValue2 += analogRead(read2Pin);
  readValue2 >>= 2;
  //readValue2 += (Pid2.flag ? 1 : -1) * Pid2.power / 6;
  int adjustValue2 = analogRead(adjust2Pin); //240 analogRead(adjust2Pin);
  Pid2.aver = Pid2.aver * 0.9995 + readValue2 * 0.0005;
  Pid2.target = Pid2.target + (Pid2.target - Pid2.aver) / 1000.0;
  Pid2.target = max(0, max(adjustValue2 - offset, Pid2.target));
  Pid2.target = min(755, min(adjustValue2 + offset, Pid2.target));

  if(debug)
  {
    Serial.println(adjustValue1);
    Serial.println(adjustValue2);
    Serial.println(readValue1);
    Serial.println(readValue2);
    Pid1.flag = adjustValue1 > 512;
    Pid1.power = abs(adjustValue1 - 512) / 2;
    if(Pid1.power > 255) Pid1.power = 255;
    digitalWrite(i1Pin, Pid1.flag);
    digitalWrite(i2Pin, !Pid1.flag);
    analogWrite(power1Pin, Pid1.power);
    Pid2.flag = adjustValue2 > 512;
    Pid2.power = abs(adjustValue2 - 512) / 2;
    if(Pid2.power > 255) Pid2.power = 255;
    digitalWrite(i3Pin, Pid2.flag);
    digitalWrite(i4Pin, !Pid2.flag);
    analogWrite(power2Pin, Pid2.power);
    delay(32000);
    return;
  }

  //Calculate power values
  double v, error;
  error = readValue1 - Pid1.target;
  v = error - Pid1.preError;
  Pid1.v = (Pid1.v * 6 + v) / 7;
  Pid1.power = (int)error * Pid1.Kd + Pid1.v * Pid1.Kp;
  Pid1.flag = Pid1.power > 0;
  Pid1.power = abs(Pid1.power);
  if(Pid1.power>255) Pid1.power = 255;
  Pid1.preError = error;

  error = readValue2 - Pid2.target;
  v = error - Pid2.preError;
  Pid2.v = (Pid2.v * 6 + v) / 7;
  Pid2.power = (int)error * Pid2.Kd + Pid2.v * Pid2.Kp;
  Pid2.flag = Pid2.power < 0;
  Pid2.power = abs(Pid2.power);
  if(Pid2.power>255) Pid2.power = 255;
  Pid2.preError = error;

  //Write PMW to control the floa
  digitalWrite(i1Pin, Pid1.flag);
  digitalWrite(i2Pin, !Pid1.flag);
  analogWrite(power1Pin, Pid1.power);

  digitalWrite(i3Pin, Pid2.flag);
  digitalWrite(i4Pin, !Pid2.flag);
  analogWrite(power2Pin, Pid2.power);

  myLog[tick * 7 + 0] = tick;
  myLog[tick * 7 + 1] = (int)Pid1.target;
  myLog[tick * 7 + 2] = readValue1;
  myLog[tick * 7 + 3] = Pid1.power;
  myLog[tick * 7 + 4] = (int)Pid2.target;
  myLog[tick * 7 + 5] = readValue2;
  myLog[tick * 7 + 6] = Pid2.power;

  /*
  for(int i=0;i<8;i++)
  {
    digitalWrite(rotatePins[i] , 0);
    digitalWrite(rotatePins[(i + 1) % 8] ,1);
    delay(1);
  }
  digitalWrite(rotatePins[0] , 0);
  */

  delay(delayMs);
}

盗梦陀螺攻略4- 下推式磁悬浮电路

距上一篇攻略已经过了快一个月了。这个月生病一次,加班数次,其中还有带病加班的几天,过年前的日子真难过啊 :) 不过今年春节有10天假,强烈期待中。另外后天公司开年会,希望能抽个大奖,哈哈!

下面继续发磁悬浮的攻略。下推式其实原理和上拉式很相似,区别在于需要两组线圈才能维持浮子的平衡。下面是其中一组线圈的电路示意图:

下推式电路示意图

下推式电路示意图,点击看大图

这个电路和之前上拉式的完全一样,所以这次不需要额外的焊接工作,对比上篇博客的电路图,只是多了一些杜邦头的插针,便于连线:

上推式磁悬浮连线实物图

上推式磁悬浮连线实物图

之前制作小爱的时候,试验过Arduino的模拟输入输出数字输入输出,这里再简单复习下。

Android Mega一共有四种IO接口:模拟输入输出和数字输入输出。其中模拟输入标记为“ANALOG IN”,可以测量0~5V的电压,对应在代码中的读数范围是0~1023,示例代码如下:

int readValue1 = analogRead(read1Pin);

模拟输出实际上输出的是一串方波,通过高低电压的占空比来产生“平均电压”。在板上对应的标记是PWM,输出电压同样是0~5V,但是请注意设置的数值范围却是0~255。示例代码如下:

analogWrite(power1Pin, Pid1.power);

数字输入输出需要先设置管脚的模式,直接看示例代码吧,相信聪明的你肯定明白:

pinMode(Pin1, OUTPUT);     //设置为输出管脚
pinMode(Pin2, INPUT);      //设置为输入管脚
digitalWrite(Pin1, HIGH);  //输出高电压
int v = digitalRead(Pin2); //读取Pin2的电压,返回结果是0或1
anduino控制板

anduino控制板

其中0~53所有的接口都可以作为数字输入输出接口,而其中只有2~13可以用作PWM模拟输出。模拟输入的接口编号是0~15,和刚才的编号是互相独立的,不会冲突。对于盗梦陀螺来说,传感器和电位器的读数显然要用模拟输入,而线圈电流的控制也显然要用模拟输出。强烈建议把接线的编号集中写在程序的最前面,这样可以一目了然的看出是怎么接的线:

int adjust1Pin = 1;    //用来调节A方向的电位器
int adjust2Pin = 2;    //用来调节B方向的电位器
int read1Pin = 4;      //用来连接输入A传感器
int read2Pin = 3;      //用来连接输入B传感器
int i1Pin = 36;        //连接电机驱动板的I1接口
int i2Pin = 37;        //连接电机驱动板的I2接口
int i3Pin = 39;        //连接电机驱动板的I3接口
int i4Pin = 38;        //连接电机驱动板的I4接口
int power1Pin = 5;     //连接电机驱动板的EA接口
int power2Pin = 6;     //连接电机驱动板的EB接口

细心的朋友一定看到上面代码中,有I1到I4四个接口,我将会把它们设置成数字输出。这里再顺便介绍下L298N的用法。
L298N直接连接了20V的电源,通过板内取电的方式提供5V电压给电路使用。板上包含了对称的两组电流驱动电路,以I1,I2,EA为例:

I1=0;I2=1;  //输出正电压,EA范围0~255时,输出电压对应为0~+20V
I1=1;I2=0;  //输出负电压,EA范围0~255时,输出电压对应为0~-20V
I1=0;I2=0;  //输出电压均为0
I1=1;I2=1;  //输出电压均为0

我们可以用数字输出I1和I2控制线圈的电压方向,用模拟输出EA控制电压的大小。I3,I4和EB是完全一样的,这里就不多说啦。友情提醒一下,Arduino的地线,L298N的地线,还有焊接电路的地线,这些地线一定要都连在一起。

到这里电路硬件的部分就介绍完了,实际上,按照这个方式做好的版本是非常不稳定的。看下面的视频,就是最初的不稳定版本,可以看出振动的非常厉害:

后面会继续介绍如何让悬浮更稳定,主要是引入PID控制的概念,另外还需要提高Arduino的PWM方波频率。