【NO.11】基于arduino的迈克尔逊干涉仪测量自动化装置

yangzq 于 2014-11-11 00:18 编辑



作品名称:基于arduino的迈克尔逊干涉仪测量自动化装置

参赛形式:小组参赛参赛组员:3人(杨振乾、张旭东、王子城)均为苦逼的南京大学物理系大二学生



作品简介:物理实验中的迈克尔逊干涉仪数条纹数的的眼都瞎了,为了减少人工劳动并提高实验精度,利用arduino对其进行改造。

我们利用光敏模块对条纹计数,利用L298驱动直流减速电机带动手轮,同时利用编码器测量角位移,换算成距离从而提高实验精度。

作品涉及到结构上的减震以及程序上的消抖,做起来比较坑爹,好在我们已经解决了问题通过了测试,目前实验误差提高到了1.4%比原先提高了5倍左右。

PS:一直在苦逼的考试,昨天终于考完了,睡了一大觉醒来发帖。









我们仨都是物理系的学生,做迈克尔逊实验要数1000条条纹,数的眼都瞎了而且还经常数错。。。(谁数谁知道),于是便设计搭建了这么一个自动化测量平台,减少我们的工作量,提高我们的实验精度。





先上个图



这就是我们改造好的的实验设备(比较难看大家就凑活一下吧







下面我就分开详细介绍一下这个项目





科普知识:不了解迈克尔逊干涉仪的同志们请戳下面的链接

http://baike.baidu.com/view/321080.htm?fr=aladdin





一、项目需用各种材料

1、Arduino Uno 1块 用于整体控制

2、L298电机驱动模块 1块 用于驱动直流电机

3、双轴直流减速电机 一台 用于整体传动

4、光敏模块 1块 用于识别条纹

5、直流电源 1个 用于给电机供电

6、AB相编码器 1个 用于测量转动角度

7、编码器轴联器 2个 用于连接减少震动

8、编码器支架 1个 用于固定编码器

9、自制连接套管 1个 用于连接

10、蓝牙模块 1个 用于手机控制

11、杜邦线胶水等



二、整体设计思想

整体的思想很是简单,就是由电脑发出指令给单片机而后单片机控制电机转动,双轴电机同时带动迈克尔逊干涉仪的手轮和AB相编码器转动,同时光敏模块测量条纹变化数目,再数出编码器测量的角度换算成距离实验就成功了!

下面是简易的一个电路图(第一次使用Fritzing不大会画





三、动力与联接部分

在转动的动力部分,我们采用了直流双轴减速电机,这个电机的特点是扭矩大,可以带动很沉重的迈克尔逊干涉仪,而且是双轴输出动力,可以直接连上编码器和干涉仪,不需要很复杂的传动装置,转的比较慢能给光敏模块足够的反应时间。

在联接迈克尔逊干涉仪的手轮时,我们采用了一个套管联接的方式,用套管套住手轮,一开始是用螺丝对顶宁死固定的,后来发现不牢固,就直接拿502粘了(大家慎用502啊,貌似那个套管现在还在上面,撬都撬不下来啊)。

由于迈克尔逊干涉仪是很精密的仪器,稍微的震动和抖动都会严重影响条纹,产生巨大的误差。一开始我们采用的刚性的链接,由于无法做到完全共轴,多以会产生一个周期性的抖动,会是条纹周期性的迷糊。后来我们采用了编码器轴联器解决了这一问题。编码器轴联器是一个像弹簧一样的东西,能减震,而且在不共轴的情况下也能传动。使用以后效果很好。





注意那俩银白色的铝的就是





由于电机有震动,实验室又不是减震光学平台,所以这些震动会对条纹的清晰度产生巨大影响!轴向的震动有轴联器吸收,而电机的震动在桌面的放大下会更厉害,桌面才是最大的影响。为了减震,我们使用了最常见的泡沫,而且垫了三层,效果出奇的好啊!!垫上以后敲电机都不影响条纹啊!!!





高端的泡沫减震台





四、编码器部分

我们采用的是600刻度的编码器,也是比较精密的仪器,由于它对角度很敏感,所以需要它的定子部分完全与电机定子部分固定。我们采用了一个支架(实际是步进电机支架改造的)然后用断锯条把支架与电机外壳用502粘上(注意上上张图片里的破锯条),这样的方式变废为宝,嘿嘿。AB相编码器的输出是两个方波,正转反转输出不同,采用网上最常用的中断方式即可使用。





五、光敏模块部分

我们采用的是最简单的光敏电阻模块。而且是数字式的输出。我们在光敏电阻上做了基本的遮光处理,能减少杂光的影响,而且测量的时候开着灯就行啦。



一开始我们是想测量光敏模块输出的0和1变化的次数而后除以2就是输出的条纹了,而且这样程序上也比较容易实现,但是在测试的时候却发现在我们肉眼只看到两条条纹但是单片机却认为已经数过了50条。我们把输出信号接到示波器上,发现了这个奇葩的抖动!!





输出信号并不是我们预想的方波,而是有剧烈的抖动!!!

于是,我们就改变了思路,在程序上解决这个问题。

在这里消抖的时候不能采用时间延迟的方式,因为这样会对编码器的计数产生巨大的影响带来巨大的误差!

我们是把测量跃变点改为测量平台期,即连续测出n个0或者连续的n个1才是认为达到了一个状态,状态改变两次视为测到一个条纹。实验中取n=300效果很好。





图中的红色部分视为平台期





六、控制部分

对电机的控制使用最常用的L298或者使用继电器也可以的,这个使用方法就不细讲了网上教程很多 蓝牙本质就是个无线的串口,这里只用从机模块。蓝牙的TX接uno的RX,蓝牙的RX接uno的TX,GND和VCC分别接GND和5V。用手机或带蓝牙的电脑可以实现无线控制。



七、代码

程序上设计了消除了回程差的功能。

[C] 纯文本查看 复制代码

int N = 20;          //条纹数
int num = 500; //为了消抖,连续读入高电平的数量
int state = 0; //当前探头的状态
int temp = 0; //读取的探头状态
int count = 0; //状态变化计数
int Pin_Light = 7; //光敏模块探头
int PinA = 2; //编码器的A相
int PinB = 3; //编码器的B相
int pinL = 14; //L298 IN1接口
int pinR = 15; //L298 IN2接口
int count_angle = 0; //编码器角度数值
void setup()
{
Serial.begin(9600); //设置通信波特率
pinMode(Pin_Light , INPUT);
digitalWrite(Pin_Light , HIGH); //设置光敏模块接口为输入并上拉
pinMode(PinA , INPUT);
pinMode(PinB , INPUT);
digitalWrite(PinA,HIGH);
digitalWrite(PinB,HIGH); //设置编码器AB两相的接口为输入并上拉
pinMode(pinL , OUTPUT);
pinMode(pinR , OUTPUT); //设置L298 IN1、IN2接口为输出
analogWrite(pinL , 0);
analogWrite(pinR , 255); //设置电机空转
state = digitalRead(Pin_Light);
return_trip();
analogWrite(pinR , 0); //消除回程差
state = digitalRead(Pin_Light); //读取当前状态
}
void return_trip ()
{
int i = 0;
while (i < num)
{
temp = digitalRead(Pin_Light);
if(temp == state)
{
i = 0;
continue;
}
else
{
++i;
}
}

}
//消除抖动的同时消回程差
void Light_mode ()
{
int i = 0;
while(i < num)
{
temp = digitalRead(Pin_Light);
if(temp != state)
{
++i;
}
else
{
break;
}
}
if(i == num)
{
state = temp;
++count;
}
}
//连续读到num个的状态与记录当前的状态不同才记录一次状态改变以消除模块在状态变化时的剧烈抖动
void add()
{
if (digitalRead(PinA) == LOW)
{
if (digitalRead(PinB) == LOW)
++count_angle;
}
}
//编码器正向旋转使角度计数加
void att()
{
if (digitalRead(PinB) == LOW)
{
if (digitalRead(PinA) == LOW)
--count_angle;
}
}
//编码器逆向旋转使角度计数减
void loop()
{
if(Serial.available())
{
char val=Serial.read();
if(val=='a')
N=1000;
else if(val=='b')
N=500;
else if(val == 'c')
N=100;
else if(val=='d')
N=50;
else if(val=='e')
N=10;
else if(val=='f')
N=5;
analogWrite(pinR , 255);
while(1)
{
attachInterrupt(0,add,FALLING);
attachInterrupt(1,att,FALLING);
//配合中断,使编码器正常工作
Light_mode();
if(count == 2*N)
{
analogWrite(pinR , 0);

Serial.print(&quot;Stripe Number=&quot;);
Serial.println(N);
Serial.print(&quot;Distance=&quot;);
Serial.print((float)(count_angle)*0.1/6.0);        //利用编码器的精度把角度换算成距离
Serial.println(&quot;um&quot;);
count=0;
count_angle=0;

break;
//通信输出测量结果

}
}
}
}



八、实验结果和后续开发以及可移植性
实验结果:我们做了最基本的测激光波长是实验,误差为1.4%比原本实验精度提高了5倍(关键是省力啊!不用人眼数了)。这也证实了我们这套装置的稳定性。
后续开发:在单片机上加入各种传感器就可以很方便的在迈克尔逊干涉仪上开发更多的功能进行更多的实验。如测温度湿度对空气折射率影响等等。
可移植性:这套设备可移植性很高,只要是测光有转动的仪器基本都可以移植,比如只有做很小的改动就能移植到分光计上。


九、过程图片
就当我们队的真相了





付上视频一个,视频中并未使用手机控制蓝牙

请大家多多支持啊!





这几天给它做了个壳子(线还是比较乱。。。凑活看看吧,过几天上高清大图),准备参加一个实际的仪器改进比赛,而且正在申请专利哦。



T恤还是很萌的~



最后请大家多多支持我们哦,你们的支持是我们苦逼学生最大的动力!!




via - arduino中文社区

标签: Arduino教程