丄帝De咗臂 发表于 2015-4-17 13:44:08

激光测距测高仪

本帖最后由 丄帝De咗臂 于 2015-4-17 15:37 编辑

做一个激光测距测高仪(原文地址http://blog.sina.com.cn/s/blog_6611ddcf0102vgxb.html)温州中学 谢作如 郑一粟做激光测距测高仪的想法源自一款用摄像头做为测量工具的App。这类App的测量原理是根据手机、平板的摄像头成像的比例关系,然后计算出测量距离和物体高度。比如iphone有款软件叫“光学测距仪”,运行界面如图所示。
iphone的光学测距仪在使用过程中,我发现这类App的操作其实还是比较麻烦,因为需要参照物。如果要测量某头顶某条梁的长度,或者屋顶离地面的高度,基于摄像头的测量软件几乎是无能为力了。那么,有没有其他的解决方案呢?于是,我就找学生一起研究,基于激光的测距测高仪就这样产生了。一、原理我们准备使用激光做为测量工具,并非使用反射时间来计算。接下来要用到数学知识了。如果要测量物体P到物体T的距离,我们可以用这样的办法:如图所示,在物体P处找两个点,如A、B,分别连接物体T的C点。这时,只要知道∠BAC(θ1)和∠ABC(θ2)的角度,以及AB线段的长度,就可以算出C点到AB的垂直距离L。
数学原理图1计算公式:好吧,只要能得到这两个夹角的准确角度,就可以计算出物体离测量仪器的距离了。然后,我们是否还可以利用这样的原理继续得到物体的高度或者长度呢?我们来看一个图吧。
数学原理图2如果在测量仪器上设置3个点。其中点1连接被测物体的一端A,点2和点3分别连接被测物体的另一段B。只要我们得到线段ab的长度,角度θ1、θ2和θ3的大小,便可以求出被测物的高度h以及测距仪器与被测物的水平距离x。那么连接测量仪器和被测物体的直线用什么来实现?毫无疑问,激光是最好的方案。因为激光具有定向发光、亮度极高的特点。只要把3个激光发射头安装在测量仪器上,手动调整其中两束激光在被测物体的一个端点上重叠,另一束激光则发射在物体的另一端点。只要能确保测量仪器和被测物体之间是平行的,就能计算出距离和高度。二、材料根据上面的原理,要制作一个这样的激光测距测高仪,大致需要如下材料:1.微控制器因为涉及到计算,就需要一个小型的中央处理器。因为我们仅仅为了做出一个模型,所以就选择了常见的Arduino。如果在意计算的精度,可以选择树莓派或者pcDuino之类的迷你电脑。2.角度传感器角度传感器的选择是最重要的,因为要获取精确的角度进行计算,牵一发而动全身,一点点的误差,经过计算放大后,误差就很可怕了。在淘宝上常见的角度传感器如图。
常见的角度传感器这种传感器的旋转角度最多只有300度,将5V电压均分每1度后,精度是相当低的。后来在淘宝上找到了多圈的精密角度传感器,才算初步解决了误差的问题。
多圈精密角度传感器3.液晶显示器计算结果应该要实时显示,所以仪器上需要液晶显示屏,或称LCD。因为仪器上仅仅需要显示几行字符,我选择了标准1602液晶显示屏,2行,每行显示16个字符。
液晶显示屏4.激光头激光头利用的是低功率的可视激光,常见的激光指示器有红光(655/635nm)、黄光(589/593nm)、绿光(532nm)、蓝光(473/445nm)和蓝紫光(405nm)等。一开始我把手头的电子教鞭拆了,后来发现淘宝上有现成的激光头卖,我们选择了一款5V的,直接使用Arduino输出的5V电流。需要注意的是,激光头很危险,绝对不用用肉眼去看,建议调试的时候先不要给激光头供电。
5V的激光头三、接线1.角度传感器的接线角度传感器接在Arduino的模拟口,如图。三个角度传感器分别用跳线接入Arduino控制板会显得很乱,我们使用了一块扩展板。
2.激光头的接线激光头的电源直接从Arduino的5V和Gnd上接出。3.显示屏的接线我们使用的LCD是IIC/TWI接口的,用四根线连接到Arduino扩展板的专用接口即可。
四、编程Arduino的代码比我们想象中简单,其核心代码如下。#include
#include
LiquidCrystal_I2C lcd(0x27,16,2);// set the LCD address to 0x27 for a 16 chars and 2 line display
int button = 13;
int sensor_1 = 0;
int sensor_2 = 1;
int sensor_3 = 2;
double Value_1,Value_2,Value_3;
double v_1=487,v_2=514,v_3=490;//默认位置的数值
double pi=3.14;
double d=2.5;//传感器距离
double x,y;
void setup()
{
lcd.init();                  
lcd.backlight();
lcd.print("please start measure!");
}

void loop()
{
Value_1 = analogRead(sensor_1);
Value_2 = analogRead(sensor_2);
Value_3 = analogRead(sensor_3);
lcd.clear();
lcd.print(Value_1);//输出参考值
Value_1 = ((v_1-Value_1)/3)*pi/180;
Value_2 = ((v_2-Value_2)/3)*pi/180;
Value_3 = (abs(v_3-Value_3)/3)*pi/180;
lcd.setCursor(0,1);
x=d / ( tan(Value_2) - tan(Value_1) );
y=x*( tan(Value_2) + tan(Value_3));
y=y+d;
lcd.print("|");
lcd.print(x);lcd.print("|");lcd.print(y);
delay(500);//输出距离和高度
}


最终的测试效果如图所示,显示屏上第一行数据是传感器的参考值,第二行数据分别是距离和高度,用“|”分开。
数据输出到显示屏比如想要测量的一堵墙的高度,我们先要将测量仪器保持垂直,一束激光束(激光点一)射向墙的一端,另外两束射向墙的另一端,按下按钮,Arduino就可以实时计算出,便可得到树的高度和人与树之间的距离了。五、包装为了看起来像个作品,我们使用雕刻机制作了激光头和角度传感器的连接件。当然,用3D打印机打印也是可以的,只是当时我们的创客空间还没有买3D打印机呢。
激光头和角度传感器的连接件再用雕刻机做一个底板,固定这些仪器。三个激光头排列在一起,看起来是不是很酷?旁边一条四线的接口是预留给接LCD用的。
整体效果再看看另一面的效果,虽然线有点多,但是并不是很乱。
接线效果这款仪器的使用步骤如下:1.连接电池,保持仪器呈垂直状态。2.打开电源,显示屏若未正常显示数字,请按下Arduino主板上的reset按钮;3.调节“下”、“中”激光,同时对准被测物体下端;4.调节“上”激光,对准被测物体上端;5.在显示屏上将显示X(测距仪与被测物之间的水平距离) 与Y(被测物两个端点之间的距离)。六、优化    正如一开始的担心,因为角度传感器的精度问题,测量距离稍微远一点的物体,误差就很大了。因为如果距离一远,角度传感器上的1度,对应的就是1、2米的距离。要解决这个问题,找精度很高的角度传感器也无济于事,因为调节激光头给角度传感器带来的旋转角度实在太小了。除非如下图一样,用齿轮组将激光头的旋转角度放大,然后给角度传感器。
旋转角度放大示意图因为自己动手做齿轮组,误差还是挺大,我们还试着拆了一个塑料的直流电机变速箱。但是这样一来,整个仪器的体积就要大很多。看来如何实现做工精细恰好是我们的短板啊。
塑料的直流电机变速箱我们还为这款仪器设计了一个外壳,如图所示。黑色是激光调节旋钮,红色按钮是开关。仅仅是设计,并没有真正生产哦。
外形设计当然,如果仅仅考虑演示用激光进行测距、测高的原理,我们也已经达到了探究的目的。其实这个作品原理还可以用于课堂教学。如果将角度传感器的数据接入电脑,使用S4A或者Scratch2.0之类的软件,教师可以直接使用这些数据进行教学或者验证一些数学原理,如三角函数、相似三角形等知识,肯定有助于学生的学习

hnyzcj 发表于 2015-4-17 16:18:45

赞一个老谢的作品。

丄帝De咗臂 发表于 2015-4-17 16:50:12

hnyzcj 发表于 2015-4-17 16:18
赞一个老谢的作品。

很早的一个作品,老谢还帮我在《中国信息技术教育》2014年11期上发表了一篇文章呢。
不过这一个是他把之前的作品做了改进:p

hnyzcj 发表于 2015-4-17 18:03:03

我知道,我看到过了,牛人。

大连林海 发表于 2015-4-17 20:05:25

这都是谢老师的高徒 佩服

丄帝De咗臂 发表于 2015-4-17 20:42:04

大连林海 发表于 2015-4-17 20:05
这都是谢老师的高徒 佩服

个子可以算不矮,180:victory:

20060606 发表于 2020-8-22 20:21:57

那个是童车的齿轮组,体积大,可以拆一个130减速电机
页: [1]
查看完整版本: 激光测距测高仪