Arduino系列测量器和数字精神级别项目

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

概述

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

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

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

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

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

进入第二个程序,我们再次必须按住按钮一段时间。在该程序中,我们可以通过采用两个垂直距离测量来测量方形区域。

Arduino方形区域测量

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

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

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

Arduino系列测量仪电路原理图

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

Arduino DIY数字范围测量和精神级电路原理图

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

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

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

定制设计PCB.

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

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

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

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

组装设备

尽管如此,在几天后,PCB已经到了。PCB的质量很大,一切都与设计完全相同。

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

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

Arduino系列测量器PCB设计

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

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

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

然后使用Forstner位I为电源开关,控制按钮和超声波传感器进行了开口。

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

一旦我有所有的碎片准备好,我用5分钟环氧树脂组装到情况。至于顶部,我插入和粘两个螺栓,通过它可以插入和固定顶部面板上的一些螺母。

Arduino系列测量器的丙烯酸盒

案件现在准备就绪,因此我继续焊接针头向LCD,因此我可以轻松地将其连接到PCB。我还向电源开关,按钮和电池连接器焊接销钉或跳线。

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

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

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

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

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

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

#include  // i2c通信库#include  //包括液晶库液晶LCD(7,6,5,4,3,2);//创建LCD对象。参数:( RS,ENABLE,D4,D5,D6,D7)CONST INT MPU = 0x68;// i2c地址的mpu6050加速度计#define trigpin 8 #define echopin 9 #define selectbutton 10 int16_t Acx,Acy,Acz;持续时间;浮动距离;int程序= 0;float d = 0;float d1 = 0;Float 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);//如果按下按钮-改变单位如果(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;

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

/转换单位(Inoneelect == 1){距离=距离;//从cm到cm的单位= "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";}

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

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

在这里,我们用扳机让传感器产生超声波。

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

然后使用回波引脚和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;// i2c地址的mpu6050加速度计#define trigpin 8 #define echopin 9 #define selectbutton 10 int16_t Acx,Acy,Acz;持续时间;浮动距离;int程序= 0;float d = 0;float 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.

    令人敬畏的项目
    我让它变得惊人,但我在Sprit水平上有问题,因为有时关闭,我切换到Sprit级别选项,但其他事情正在正常工作。

    回复
  3. Ajith.

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

    回复
    • 德扬Nedelkovski

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

      回复
  4. 穆罕默德Almazroey

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

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

    回复
  5. Alfonso.

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

    回复
  6. 二赞湖

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

    回复
  7. 狮子座罗斯曼

    你好,
    我试图为我的班级活动进行这个项目,我对材料有一些问题。
    PINS连接器是否带有PCB?或者我必须单独购买它们。

    回复
  8. 汤姆luken

    你好德詹
    很棒的项目,我做到了。没有建立的盒子,只是安装在PCB上的开关和超级胶粘一个9伏到背后。有一个问题,scematic显示r2要接地,但它在pcb上是死胡同,虽然工作得很好,r2的目的是什么,我应该把它接地吗?
    再次感谢一个伟大的项目

    回复
    • 德国

      嘿,谢谢!良好的R2用于分压器用于设置LCD的对比度。是的,它应该连接到GND。

      回复
  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打印机