Arduino测距仪和数字水平仪项目

在本教程中,我们将学习如何制作Arduino系列测量器和数字精神级别。您可以观看以下视频或阅读下面的书面教程。

概述

该装置具有超声波传感器,用于测量与最近物体的距离,用于测量相对于地面的角度的加速度计,用于显示结果的LCD显示器和所有组件的定制设计的PCB。

我们可以只需单个按钮操作设备。一旦我们为设备供电,我们需要选择测量单位。

距离测量装置单元选择程序

按下按钮,我们可以通过单位切换,如果我们按住按钮,我们将进入第一个程序。在这里,我们可以测量距离并具有存储最后两次测量的能力。

Arduino系列测量仪 - 到最近物体的距离

为了进入第二个程序,我们还是要按住按钮一会儿。在这个程序中,我们可以通过测量两个垂直的距离来测量一个正方形的面积。

Arduino正方形面积测量

下一个程序是数字精神级别,在这里我们可以测量与地面的角度。

Arduino DIY数字水平仪角度测量

使用按钮,我们可以在两个轴之间切换,或者我们可以测量Pitch或Roll。

Arduino测距仪电路原理图

这是这个Arduino项目的电路原理图。

Arduino DIY数字测距仪和电平电路原理图

请注意,我已经有详细的教程,每个模块如何运行,并且您可以在以下链接上查看:超声波传感器教程液晶教程MEMS加速度计教程

您可以从下面的链接获取此项目所需的组件:

yaboAG娱乐城披露:这些是联盟链接。作为亚马逊助理,我从合格购买中获得。

定制设计PCB.

根据电路原理图,我们需要设计自定义PCB,我用了这一点EasyEDA免费在线电路设计软件。

完成此处的设计后,我们只需导出用于制造PCB的格柏文件。你可以检查此项目的Easyeda项目文件

然后我们可以从JLCPCB订购我们的PCB它实际上是这个项目的赞助商。

在这里,我们可以简单地拖放Gerber文件。一旦上传,我们可以在Gerber Viewer中查看我们的PCB。如果一切都正确,那么我们可以继续,选择我们为PCB的属性,然后我们可以以合理的价格订购我们的PCB。请注意,如果它是jlcpcb的第一个订单,您只需2美元即可获得10台PCB即可。

组装设备

然而,几天后,多氯联苯就到了。pcb的质量是伟大的,一切都是完全相同的设计。

定制PCB设计-数字距离和角度计

好的,现在我们可以开始为这个项目组装电子产品。yabo7. com我开始焊接PCB上的PIN标头。通过这种方式,我们可以在需要时轻松连接和断开组件。

Arduino系列测量器PCB设计

然后我插入和焊接三个电阻。其中两个是用于液晶显示对比度的分压器。1k电阻应置于R1, 220欧姆置于R2。第三个是按钮的上拉电阻。

接下来我继续进行设备的情况。我决定使用透明丙烯酸,因为我希望所有电子元件的美容都可以看到。yabo7. com我从一个旧项目中有了5毫米的蜱丙烯酸,我用一个圆形的圆形来切割它。

然后我必须在表壳的顶部为液晶屏开一个口,实际上是4毫米的刻度,因为它更适合液晶屏。所以我先用钻头钻了两个孔,然后用钢锯把它们锯穿。用钢锯我粗略地做了一个开口,然后用锉刀我做了很好的直线,这样液晶显示器可以紧紧地配合。

然后使用forstner钻头,我做了电源开关,控制按钮和超声波传感器的开口。

用福尔斯特纳漂流丙烯酸碎片

一旦我准备好所有碎片,我用5分钟的环氧树生来装配案件。至于顶部,我插入并胶合了两根螺栓,顶板可以在其顶部上使用一些螺母插入和固定。

Arduino系列测量器的丙烯酸盒

现在的情况是准备好了,所以我继续焊接引脚头到LCD,所以我可以很容易地把它连接到PCB。我还焊接了插头头或跳线到电源开关,按钮和电池连接器。

Findy,我有一切准备好装配设备。我开始使用在PCB上插入超声波传感器,然后通过侧面板上的孔。接下来是Arduino板,加速度计模块以及电池连接器。

在顶部面板上,我固定了LCD,电源开关和按钮,然后将它们连接到PCB。最后我将9V电池插入连接器并用螺母固定顶部面板。

就这样,Arduino测距仪项目完成了这个视频剩下的是解释程序是如何工作的,让我们看一下Arduino代码。

Arduino系列测量器和数字精神级源代码

由于代码更长,因此为了更好地理解,我将在每个部分的描述中发布程序的源代码。并且在本文的末尾,我将发布完整的源代码。

所以首先我们需要包括用于加速度计I2C通信的Wire.h库,以及用于控制LCD的LiquidCrystal.h库。然后我们需要定义液晶,I2C地址的MPU6050加速度计模块,超声波传感器引脚,以及下面的程序所需的一些变量。

#include // I2C通信库#include< LiquidCrystal.h> //包括LiquidCrystal library液晶(7,6,5,4,3,2);//创建一个LCD对象。参数:(rs, enable, d4, d5, d6, d7) const int MPU = 0x68;// MPU6050加速度计的I2C地址#define trigPin 8 #define echoPin 9 #define selectButton 10 int16_t AcX, AcY, AcZ;长时间;浮动的距离;Int program = 0;浮点数d = 0;浮点数d1 = 0;浮点数d2 = 0; float area = 0; int axis = 0; int angle = 0; int unitSelect = 0; String unit = "cm";

在设置部分,我们需要初始化加速度计的I2C接口和液晶显示,以及定义超声波传感器触发和回波引脚的引脚模式,以及按钮引脚。

void setup(){// initialize接口到mpu6050 wire.begin();Wire.Begintroansmission(MPU);Wire.write(0x6b);Wire.write(0);wire.endtransmission(true);LCD.BEGIN(16,2);//初始化LCD屏幕Pinmode(Trigpin,输出)的接口;Pinmode(echopin,输入);PinMode(SelectButton,Input_Pullup);}

在主循环部分,我们有一个switch语句,通过它我们可以在设备的不同程序之间切换。在第一个,或者案例编号0中,我们选择测量单位。使用LCD .print()函数,我们将文本打印在LCD上,并使用if语句切换到四个测量单元。

切换(程序){//在不同程序之间切换案例0://选择测量单位LCD.SetCursor(0,0);//设置将显示到LCD的后续文本的位置将显示LCD.print(“选择单位:”);lcd.setCursor(13,0);lcd.print(单位);lcd.print(“”);延迟(10);//如果按下按钮 - 如果(DigitalRead(SelectButton)== 0){If(InoneLect == 0){Unit =“In”;inononelect = 1;}如果(Inoneelect == 1){单位=“m”;inononelect = 2; } else if (unitSelect == 2) { unit = "ft"; unitSelect = 3; } else if (unitSelect == 3) { unit = "cm"; unitSelect = 0; } // If button is held longer then half a second - change program delay(500); if (digitalRead(selectButton) == 0) { program = 1; lcd.clear(); delay(500); } } break;

我们应该注意到,InnesElect变量在GetDistance()Cunstom函数中采取了操作,其中它实际上告诉我们应该转换我们来自超声波传感器的基本CM单元。

/转换单位(Inoneelect == 1){距离=距离;// cm到cm单位=“cm”;}如果(Inoneelect == 2){距离=距离* 0.393701;// cm到单位=“in”;}如果(InoneLect == 3){距离=距离* 0.01;// cm到m单位=“m”;}如果(Inoneelect == 0){距离=距离* 0.0328;// cm到ft单位=“ft”;}

为了选择测量单位并进入设备的第一个程序,我们只需按住更长的按钮超过半秒。

//如果按钮延长,那么秒的一半 - 更改节目延迟(500);if(DigitalRead(SelectButton)== 0){程序= 1;lcd.clear ();延迟(500);}}打破;

在第1种情况中,或者在距离测量程序中,我们首先使用getDistance()自定义函数获取到最近对象的距离。

案例1://距离测量程序距离= getDistance();//到最近对象lcd.setcursor的距离(0,0);lcd.print(“dist:”);lcd.print(距离);//从传感器LCD.Print(“”)中打印距离值;lcd.setCursor(14,0);lcd.print(单位);延迟(10);lcd.setcursor(0,1);lcd.print(“D:”); lcd.setCursor(8, 1); lcd.print("d:"); delay(200); // Save distance 1 if (digitalRead(selectButton) == 0) { if (d == 0) { lcd.setCursor(0, 1); lcd.print("d: "); lcd.setCursor(2, 1); lcd.print(distance); d = 1; delay(100); } // Save distance 2 else if (d == 1) { lcd.setCursor(8, 1); lcd.print("d: "); lcd.setCursor(10, 1); lcd.print(distance); d = 0; delay(100); } // If button is held longer then half sencond change program delay(500); if (digitalRead(selectButton) == 0) { program = 2; d = 0; lcd.clear(); delay(500); } } break;

让我们看看这个函数是如何工作的。

// ===== getdistance  - 自定义函数float getdistance(){//清除Trigpin DigiteWrite(Trigpin,低);//在高状态上设置TRIGPIN 10微秒数号(TRIGPIN,高);Delaymicroseconds(10);DigitalWrite(Trigpin,低);//读取echopin,返回微秒持续时间的声波行程时间=脉冲素(echopin,高);//计算距离距离=持续时间* 0.034 / 2;//距离cm //如果(inononelect == 1){距离=距离转换为单位;// cm到cm单位=“cm”;}如果(Inoneelect == 2){距离=距离* 0.393701;// cm到单位=“in”; } else if (unitSelect == 3) { distance = distance * 0.01; // cm to m unit = "m"; } else if (unitSelect == 0) { distance = distance * 0.0328; // cm to ft unit = "ft"; } return distance; }

这里使用触发器引脚,我们告诉传感器以产生超声波声波。

数字范围测量器 - 超声波传感器工作原理

然后使用回声引脚和脉冲素()函数我们测量从传感器行进到物体和背部的持续时间。考虑到声音的速度和旅行时间我们很容易计算距离。因此,我们将测量的距离与LCD上的一些文本一起打印,并使用“if”语句,如果我们按下按钮,我们打印或保存最后两次测量。

接下来是我们使用类似方法计算面积的程序。我们需要做两个垂直的测量,然后把它们相乘就能得到它们组成的正方形的面积。

案例2://区域测量程序距离= getDistance();lcd.setCursor(0,0);lcd.print(“地区:”);lcd.print(地区);//从两次测量的计算区域LCD.SetCursor(12,0)打印;lcd.print(单位);//打印所选单元和方形标志LCD.Print(“^ 2”);延迟(200);if(d == 0){lcd.setcursor(0,1);lcd.print(“D1:”); lcd.setCursor(3, 1); lcd.print(distance); delay(200); } else if (d == 1) { lcd.setCursor(9, 1); lcd.print("d2: "); lcd.setCursor(12, 1); lcd.print(distance); delay(200); } else if (d == 2) { lcd.setCursor(6, 0); lcd.print(area); delay(200); } // Save distance 1 if (digitalRead(selectButton) == 0) { if (d == 0) { lcd.setCursor(0, 1); lcd.print("d1: "); lcd.setCursor(3, 1); lcd.print(distance); d = 1; d1 = distance; delay(100); } // Save distance 2 else if (d == 1) { lcd.setCursor(9, 1); lcd.print("d2: "); lcd.setCursor(12, 1); lcd.print(distance); d = 2; d2 = distance; area = d1 * d2; // Calculate the area delay(100); } else if (d == 2) { lcd.clear(); d = 0; area = 0; delay(100); } // If button is held longer then half sencond change program delay(500); if (digitalRead(selectButton) == 0) { program = 3; d = 0; lcd.clear(); delay(500); } } break;

最后一个情况,是角度测量程序。Here we need to read the accelerometer data which is actually the strength of the Earth’s gravitational field in three different axes, X,Y, and Z. The value of each axis is stored in 2 registers, so we need to read total of 6 registers and combine them in order to get the right value.

case 3: //角度测量程序//读取加速度计数据Wire.beginTransmission(MPU);Wire.write (0 x3b);//寄存器0x3B (ACCEL_XOUT_H) Wire.endTransmission(false);wire.requestfrom(mpu,6,true);//总共读取6个寄存器,每个轴的值存储在2个寄存器中AcX = Wire.read() << 8 | Wire.read();// x轴值AcY = Wire.read() << 8 | Wire.read();// y轴值AcZ = Wire.read() << 8 | Wire.read();// z轴值if (axis == 0){//计算俯仰角(绕y轴旋转)角度= atan(-1 * AcX / sqrt(pow(AcY, 2) + pow(AcZ, 2)) * 180 / PI;lcd.setCursor(0,0);lcd.print(“音高”); } else if (axis == 1) { // Calculating the Roll angle (rotation around X-axis) angle = atan(-1 * AcY / sqrt(pow(AcX, 2) + pow(AcZ, 2))) * 180 / PI; lcd.setCursor(0, 0); lcd.print("Roll "); } lcd.setCursor(0, 1); lcd.print("Angle: "); lcd.print(abs(angle)); lcd.print(" "); lcd.setCursor(10, 1); lcd.print("deg"); delay(200); // Change axis if (digitalRead(selectButton) == 0) { if (axis == 0) { axis = 1; delay(100); } // Save distance 2 else if (axis == 1) { axis = 0; delay(100); } // If button is held longer then half sencond change program delay(500); if (digitalRead(selectButton) == 0) { program = 0; lcd.clear(); delay(500); } } break;

一旦我们有加速度计的x,y和z值,我们可以使用两个方程来计算俯仰角或围绕y轴的旋转,或围绕x轴旋转,或围绕x轴旋转。您可以在飞思卡尔半导体应用笔记上找到有关这些方程的更多详细信息,使用三轴加速度计倾斜感应.在此之后,我们将值和一些文本一起打印在LCD上,通过按下按钮,我们改变我们在LCD上显示的内容,无论是俯仰角度还是滚动角度。

以下是此Arduino系列测量仪和精神级别项目的完整源代码:

/ * DIY数字范围测量和精神级别由Dejan Nedelkovski,www.www.kuaixg.com * / #inclu亚搏手机版官方下载de  // I2c通信库#include  //包括液晶库液晶LCD(7,6,5,4,3,2);//创建一个LCD对象。参数:(rs, enable, d4, d5, d6, d7) const int MPU = 0x68;// MPU6050加速度计的I2C地址#define trigPin 8 #define echoPin 9 #define selectButton 10 int16_t AcX, AcY, AcZ;长时间;浮动的距离;Int program = 0;浮点数d = 0;浮点数d1 = 0; float d2 = 0; float area = 0; int axis = 0; int angle = 0; int unitSelect = 0; String unit = "cm"; void setup() { // Initialize interface to the MPU6050 Wire.begin(); Wire.beginTransmission(MPU); Wire.write(0x6B); Wire.write(0); Wire.endTransmission(true); lcd.begin(16, 2); // Initializes the interface to the LCD screen pinMode(trigPin, OUTPUT); pinMode(echoPin, INPUT); pinMode(selectButton, INPUT_PULLUP); } void loop() { switch (program) { // Switch between different programs case 0: // Select unit of measurement lcd.setCursor(0, 0); // Sets the location at which subsequent text written to the LCD will be displayed lcd.print("Select Unit: "); lcd.setCursor(13, 0); lcd.print(unit); lcd.print(" "); delay(10); // If button is pressed - change unit if (digitalRead(selectButton) == 0) { if (unitSelect == 0) { unit = "in"; unitSelect = 1; } else if (unitSelect == 1) { unit = "m"; unitSelect = 2; } else if (unitSelect == 2) { unit = "ft"; unitSelect = 3; } else if (unitSelect == 3) { unit = "cm"; unitSelect = 0; } // If button is held longer then half a second - change program delay(500); if (digitalRead(selectButton) == 0) { program = 1; lcd.clear(); delay(500); } } break; case 1: // Distance measuring program distance = getDistance(); // Distance to the nearest object lcd.setCursor(0, 0); lcd.print("Dist: "); lcd.print(distance); // Prints the distance value from the sensor lcd.print(" "); lcd.setCursor(14, 0); lcd.print(unit); delay(10); lcd.setCursor(0, 1); lcd.print("d:"); lcd.setCursor(8, 1); lcd.print("d:"); delay(200); // Save distance 1 if (digitalRead(selectButton) == 0) { if (d == 0) { lcd.setCursor(0, 1); lcd.print("d: "); lcd.setCursor(2, 1); lcd.print(distance); d = 1; delay(100); } // Save distance 2 else if (d == 1) { lcd.setCursor(8, 1); lcd.print("d: "); lcd.setCursor(10, 1); lcd.print(distance); d = 0; delay(100); } // If button is held longer then half sencond change program delay(500); if (digitalRead(selectButton) == 0) { program = 2; d = 0; lcd.clear(); delay(500); } } break; case 2: // Area measuring program distance = getDistance(); lcd.setCursor(0, 0); lcd.print("Area: "); lcd.print(area); // Prints the calculated area from the two measurements lcd.setCursor(12, 0); lcd.print(unit); // Prints the selected unit and the square sign below lcd.print("^2"); delay(200); if ( d == 0) { lcd.setCursor(0, 1); lcd.print("d1: "); lcd.setCursor(3, 1); lcd.print(distance); delay(200); } else if (d == 1) { lcd.setCursor(9, 1); lcd.print("d2: "); lcd.setCursor(12, 1); lcd.print(distance); delay(200); } else if (d == 2) { lcd.setCursor(6, 0); lcd.print(area); delay(200); } // Save distance 1 if (digitalRead(selectButton) == 0) { if (d == 0) { lcd.setCursor(0, 1); lcd.print("d1: "); lcd.setCursor(3, 1); lcd.print(distance); d = 1; d1 = distance; delay(100); } // Save distance 2 else if (d == 1) { lcd.setCursor(9, 1); lcd.print("d2: "); lcd.setCursor(12, 1); lcd.print(distance); d = 2; d2 = distance; area = d1 * d2; // Calculate the area delay(100); } else if (d == 2) { lcd.clear(); d = 0; area = 0; delay(100); } // If button is held longer then half sencond change program delay(500); if (digitalRead(selectButton) == 0) { program = 3; d = 0; lcd.clear(); delay(500); } } break; case 3: // Angle measuring program // Read the accelerometer data Wire.beginTransmission(MPU); Wire.write(0x3B); // Start with register 0x3B (ACCEL_XOUT_H) Wire.endTransmission(false); Wire.requestFrom(MPU, 6, true); // Read 6 registers total, each axis value is stored in 2 registers AcX = Wire.read() << 8 | Wire.read(); // X-axis value AcY = Wire.read() << 8 | Wire.read(); // Y-axis value AcZ = Wire.read() << 8 | Wire.read(); // Z-axis value if ( axis == 0) { // Calculating the Pitch angle (rotation around Y-axis) angle = atan(-1 * AcX / sqrt(pow(AcY, 2) + pow(AcZ, 2))) * 180 / PI; lcd.setCursor(0, 0); lcd.print("Pitch"); } else if (axis == 1) { // Calculating the Roll angle (rotation around X-axis) angle = atan(-1 * AcY / sqrt(pow(AcX, 2) + pow(AcZ, 2))) * 180 / PI; lcd.setCursor(0, 0); lcd.print("Roll "); } lcd.setCursor(0, 1); lcd.print("Angle: "); lcd.print(abs(angle)); lcd.print(" "); lcd.setCursor(10, 1); lcd.print("deg"); delay(200); // Change axis if (digitalRead(selectButton) == 0) { if (axis == 0) { axis = 1; delay(100); } // Save distance 2 else if (axis == 1) { axis = 0; delay(100); } // If button is held longer then half sencond change program delay(500); if (digitalRead(selectButton) == 0) { program = 0; lcd.clear(); delay(500); } } break; } } //===== getDistance - Custom Function float getDistance() { // Clears the trigPin digitalWrite(trigPin, LOW); // Sets the trigPin on HIGH state for 10 micro seconds digitalWrite(trigPin, HIGH); delayMicroseconds(10); digitalWrite(trigPin, LOW); // Reads the echoPin, returns the sound wave travel time in microseconds duration = pulseIn(echoPin, HIGH); // Calculating the distance distance = duration * 0.034 / 2; // distance in cm // Converting the units if (unitSelect == 1) { distance = distance; // cm to cm unit = "cm"; } else if (unitSelect == 2) { distance = distance * 0.393701; // cm to in unit = "in"; } else if (unitSelect == 3) { distance = distance * 0.01; // cm to m unit = "m"; } else if (unitSelect == 0) { distance = distance * 0.0328; // cm to ft unit = "ft"; } return distance; }

所以这就是全部,我希望你喜欢这个Arduino项目并学会了新的东西。随意询问以下意见部分中的任何问题。

19回应

  1. Pranav Desai.

    太酷了!
    一个有趣的项目!
    我要成功了!
    感谢您的辛勤工作,建立了这个网站。这是我发现的Arduino项目中最好的一个。足彩网女欧洲杯

    回复
  2. Arya Gajjar

    很棒的项目
    我做的非常棒,但我在精神级别上有问题,因为有时我切换到精神级别选项时关闭了,但其他东西工作得很好。

    回复
  3. Ajith

    我们对我们可以添加到现有项目的额外建议是否有任何建议?

    回复
  4. 穆罕默德Almazroey.

    你好。感谢您所做的惊人项目。我做了这个项目,但我有问题,我需要你的帮助。

    完成所有连接并上传代码后,项目将工作,但在循环中。我无法控制它。希望你能提供帮助。谢谢你。

    回复
  5. Alfonso.

    早上好。
    导出文件时,DRC错误检测器检测到2个错误:
    1轨道从传感器三角到D8。
    从echo到D9的2声道呼叫pado。
    安装时会造成麻烦吗?
    谢谢

    回复
  6. 二赞湖

    先生,你好,
    如果我可以使用Arduino Uno而不是Arduino Nano,请您能建议。

    回复
  7. 狮子座罗斯曼

    你好,
    我试图为我的课堂活动做这个项目,我有一些关于材料的问题。
    线路板上有引脚连接器吗?否则我就得分开买了。

    回复
  8. 汤乌肯

    你好德詹
    伟大的项目......我做了它的工作。没有建造盒子,刚刚将开关安装在PCB上并超级胶合到后面。虽然一个问题,Scematic表明R 2去了地面,但它死于PCB ......工作正常......虽然...... R 2的目的是什么?
    再次感谢这个伟大的项目

    回复
  9. 汤乌肯

    干草德国
    真的很棒的项目,谢谢。我做了它的工作......我没有建造盒子(我懒惰)只是把开关放在电路板上并胶合到后背......但是r2的原理图转到了地面,但pcb死了,应该连接R2结束地面?它现在运作,但我不喜欢违反你的原理
    再次,伟大的项目,,工作正常
    问候
    汤姆

    回复
  10. Alfonso.

    您好,是否有任何模板制作外壳,或3D设计打印?
    提前致谢

    回复
  11. 马修

    嗨,绝对getft projekts。我想和我的学生在学校一起这样做。R3电阻的欧姆是什么?谢谢

    回复
  12. 马修

    陀螺仪的角度对测量很重要吗?陀螺仪的引脚在焊接后不完全是90度。

    回复

留下一个回复

您的电子邮件地址不会被公开。

推荐

2019年面向初学者和爱好者的最佳入门级示波器

为初学者和爱好者最好的示波器

推荐

2019年针对初学者的8个最佳Arduino入门工具包

初学者的8个最佳Arduino Starter Kits

推荐

最佳3D打印机初学者和爱好者- 3D打印

最好的3d打印机初学者和爱好者