超声波GPS。 概念模型
在开始这么长的航程之前,值得检查一下是否真的在膝盖上完成了所有操作。
本文的主题是:如何快速廉价地制作一个简单的超声波GPS。
所需设备清单
- HC-SR04 3个
- Arduino 1件
- 一卷电线。
概念图
图 1-设备的一般概念在房间的右上角安装了HC-SR04,它起着发射器的作用,在地面上,将接收器抬起,还有第三个,它对我们来说起接收器的作用。
所有这些都根据方案进行连接:
图 2-设备连接图当然,您可以通过USB将Arduino连接到计算机。
运作方式:
- 测量接收器到发射器的距离1
- 向接收器和发射器1发送有关距离测量开始的信号(将其拉动Trig支脚)。
- 等到接收器给我们长度为止。
- 对发射器2重复相同的操作。
- 计算接收器坐标。
回忆学校的几何形状
图 3-问题的几何表示根据此图,我们构成坐标计算公式:

A,F是发射器相对于接收器的高度;
C,E是通过测量从发射器到接收器的距离而获得的长度;
G是发射器之间的距离。
练习
在天花板下安装两个散热器,彼此之间要保持一定距离(3米),并将它们与散热器对准一点,围绕该散热器将形成您的工作区域。
将接收器安装在平坦的物体(例如一块板上)上,并用胶带将其包裹起来,以免在房间内产生不必要的超声波噪声。
根据上述方案连接所有设备。
这是用于发射器的紧固件和用于接收器的基材的外观:
图 4-模块类型程序
更详细地考虑代码的关键部分。
我们迫使发射器1和接收器通过将这些设备的Trig输入从低变高到10微秒再变回低来开始测量距离。
digitalWrite(trigPinRessiv, LOW); digitalWrite(trigPinTransmit1, LOW); delayMicroseconds(5); digitalWrite(trigPinRessiv, HIGH); digitalWrite(trigPinTransmit1, HIGH); delayMicroseconds(10); digitalWrite(trigPinRessiv, LOW); digitalWrite(trigPinTransmit1, LOW);
通常,这些设备本身会发出超声波信号,并等待其被某物反射并返回到它们。 但是我们在欺骗他们,在我们的例子中,一个发送而另一个接收,接收到的一个认为是他的信号,尽管这是来自另一设备的信号,并提供了到该另一设备的距离。
我们等到传感器开始告诉我们超声信号的飞行持续时间:
while (digitalRead(echoPinRessiv) == LOW);
记录信号的开始时间:
timeStartSignal = micros();
我们等到传感器停止告诉我们超声信号的传播时间:
while (digitalRead(echoPinRessiv) == HIGH);
我们写结束时间:
timeEndSignal = micros();
使用一个简单的公式,我们计算出发射器到接收器的距离:
lenC = ((timeEndSignal-timeStartSignal)/58.00)*10.00;
我们等到超声噪声在房间里消退:
delay(100);
值得注意的是,传感器通过将回波输出降低到低值一段持续时间与测量距离成正比来告诉我们该距离。
对第二个发射器重复相同的操作。
使用直角三角形上的规则,我们将得到的距离投影到地板平面上(图3)。
我们实现了从三维坐标到平面过渡的软件公式,公式如上所示:
lenB = sqrt((lenC*2.00)*(lenC*2.00) - lenA*lenA);
不幸的是,我们有错误,要删除它们,我想出了一个经验丰富的公式,将其删除,然后看看您得到了什么。
measurementError = 26.437 - 0.08*lenC/10; lenB = (lenB + measurementError*10)/10.00;
对传感器2重复相同的步骤。
我们计算平面上的坐标
找到角度Alpha:
alfa = acos(((lenG*lenG + lenD*lenD - lenB*lenB)*1.00) / ((2*lenE*lenG)*1.00));
自己找到坐标:
koord_X = lenE*cos(1.57-alfa); koord_Y = lenE*cos(alfa);
如果坐标值超出了可能,则将其替换为先前的值:
if((koord_X > 0) && (koord_X < 500) && (koord_Y > 0) && (koord_Y < 500)) { oldKoord_X = koord_X; oldKoord_Y = koord_Y; }else{ koord_X = oldKoord_X; koord_Y = oldKoord_Y; }
我们为6个坐标值创建一个缓冲区并不断移动它:
koord_X5 = koord_X4; koord_X4 = koord_X3; koord_X3 = koord_X2; koord_X2 = koord_X1; koord_X1 = koord_X; koord_Y5 = koord_Y4; koord_Y4 = koord_Y3; koord_Y3 = koord_Y2; koord_Y2 = koord_Y1; koord_Y1 = koord_Y;
我们获得最近6次测量的平均值:
averageKoord_X = (koord_X + koord_X1 + koord_X2 + koord_X3 + koord_X4 + koord_X5)/6; averageKoord_Y = (koord_Y + koord_Y1 + koord_Y2 + koord_Y3 + koord_Y4 + koord_Y5)/6;
将坐标发送到PC:
Serial.println(averageKoord_X); Serial.println(averageKoord_Y);
功能:
float asin(float c) float acos(float c) float atan(float c)
只需使用并使用=)
完整代码:
int trigPinRessiv = 8; int echoPinRessiv = 9; int trigPinTransmit1 = 2; int trigPinTransmit2 = 3; int i; long lenA = 2700;
因此,我们得到了最简单的超声波GPS系统,该系统每米范围内有一个仪表,视频显示了它们的工作原理。
轨迹的可视化在Matlab中完成,我将在下一篇文章中介绍如何进行相同的可视化。
在以后的文章中,我将更深入地考虑该系统的各个部分,并尝试对其进行改进。
我很高兴听到您对此主题的意见和反馈,该项目仍在进行中=)
项目页面受到以下来源的启发:
维基百科Habr“室内” GPS上的信息“精度为+ -2cm”