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

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

概述

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

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

距离测量设备单元选择程序

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

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

为了进入第二个项目,我们需要再次按住按钮一段时间。在这个程序中,我们可以通过测量两个垂直距离来测量一个正方形的面积。

Arduino方形区域测量

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

Arduino DIY数字精神水平 - 角度冒充

使用按钮,我们可以在两个轴之间切换,或者我们可以测量俯仰或滚动。

Arduino系列测量仪电路原理图

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

Arduino DIY数字量程测量仪及水平仪电路原理图

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

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

必威外围提钱披露:这些是联盟链接。作为亚马逊助理,我从合格购买中获得。

定制设计PCB.

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

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

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

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

组装设备

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

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

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

Arduino系列测量器PCB设计

然后我插入并焊接了三个电阻。其中两个是用于LCD对比的分压器。1K电阻应放置在R1和R2的220欧姆。第三个是按钮的上拉电阻。

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

然后我必须在案例的顶部开放LCD,实际上是4mm勾选,因为它将适合LCD。所以首先,我用钻头制作了两个洞,然后通过它们插入钢锯。使用Hacksaw我大致开口,然后使用锉刀,我制成了细直线,使LCD能够紧密配合。

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

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

一旦我已经准备好所有的件,我用5分钟环氧树脂组装到案件。至于顶部,我插入并粘上了两个螺栓,通过这两个螺栓可以插入顶板,并在顶部使用一些螺母进行固定。

Arduino系列测量器的丙烯酸盒

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

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

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

就是这样,Arduino系列测量仪项目已经完成,但在此视频中留下的是解释程序的工作原理,因此让我们来看看Arduino代码。

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

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

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

#include< line .h> // I2C通信库#include< line .h> // I2C通信库#include< line .h> // I2C通信库//创建一个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程序= 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);}

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

switch (program){//不同程序之间的切换case 0: //选择测量lcd单位。setCursor (0,0);//设置将显示到LCD的后续文本的位置将显示LCD.print(“选择单位:”);lcd.setcursor(13,0);lcd.print(单位);lcd.print(“”);延迟(10);//如果按钮被按下-改变单位If (digitalRead(selectButton) == 0) {If (unitSelect == 0) {unit = "in";unitSelect = 1;} else if (unitSelect == 1){单位= "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;

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

/转换单位(Inoneelect == 1){距离=距离;// cm到cm单位= "cm";} else if (unitSelect == 2){距离=距离* 0.393701;// cm到in单位= "in";} else if (unitSelect == 3){距离=距离* 0.01;// cm到m单位= "m";} else if (unitSelect == 0){距离=距离* 0.0328;// cm到ft单位= "ft";}

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

//如果按钮延长,那么秒的一半 - 更改节目延迟(500);if (digitalRead(selectButton) == 0) {program = 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 digitalWrite(trigPin, LOW);//将trigPin设置为HIGH状态10微秒digitalWrite(trigPin, HIGH);delayMicroseconds (10);digitalWrite (trigPin、低);//读取echoPin,返回声波传播时间(毫秒)duration = pulseIn(echoPin, HIGH);//计算距离距离=持续时间* 0.034 / 2;//在cm //转换单位if (unitSelect == 1){距离=距离;// cm到cm单位= "cm";} else if (unitSelect == 2){距离=距离* 0.393701;// cm到in单位= "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; }

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

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

然后使用回波引脚和pulseIn()函数,我们测量波从传感器到物体并返回的持续时间。考虑到声速和传播时间,我们可以很容易地计算出距离。所以我们在LCD上打印测量的距离和一些文本,并使用“if”语句,如果我们按下按钮,我们打印或保存最后两个测量值。

接下来是计算我们使用类似方法的区域的程序。我们需要取两个垂直的测量值然后简单地将它们相乘以得到它们形成的正方形的面积。

case 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.

案例3://角度测量程序//读取加速度计数据线.BegintroAnsmission(MPU);Wire.write(0x3b);//以寄存器0x3b(Accel_XOUT_H)Wire.endTransmission(false)开始。wire.requestfrom(mpu,6,true);//读取6寄存器总,每个轴值存储在2寄存器acx = wie.read()<< 8 |wire.read();// x轴值acy = wire.read()<< 8 |wire.read();// y轴值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;

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

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

/ * DIY数字范围测量和精神级别由Dejan Nedelkovski,www.www.mfxpo.com * / #inclubet188官方网站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程序= 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项目中最好的一个。bet188me

    回复
  2. Arya Gajjar

    很棒的项目
    我做的非常棒,但是我在精灵关卡上有问题,因为有时当我切换到精灵关卡选项时,会关闭,但其他的东西运行得很好。

    回复
  3. Ajith

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

    回复
    • 德扬Nedelkovski

      可能会缩小突出,使用较小的显示器,如0.96“OLED,添加补偿,用于从壳体的背面测量,添加激光指针以了解您测量的ect的确切方向。

      回复
  4. 穆罕默德Almazroey

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

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

    回复
  5. Alfonso.

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

    回复
  6. 二赞湖

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

    回复
  7. 狮子座罗斯曼

    你好,
    我试图为我的班级活动进行这个项目,我对材料有一些问题。
    引脚连接器与PCB一起来吗?否则我就得分开买了。

    回复
  8. 汤姆luken

    你好德詹
    很棒的项目,我成功了。没有建立盒子,只是安装在PCB上的开关和超级粘一个9 v到后面。有一个问题,虽然示意图显示r2接地,但它死在pcb上…工作很好,尽管…r2的目的是什么,我应该把它接地吗?
    再次感谢这个伟大的项目

    回复
  9. 汤姆luken

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

    回复
  10. Alfonso.

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

    回复
  11. 马修

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

    回复
  12. 马修

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

    回复

发表评论

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

推荐

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

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

推荐

2019年初学者的8个最佳Arduino Starter Kits

8个最好的arduino初学者工具包

推荐

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

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