如何跟踪Arduino和ADXL345加速度计的方向

在本教程中,我们将学习如何使用Arduino和ADXL345加速度计传感器测量角度和跟踪方向。你可以观看下面的视频或阅读下面的书面教程了解更多细节。

概述

首先,我将解释传感器如何工作以及如何从中读取数据,然后使用处理开发环境,我们将进行加速度计方向的3D可视化。

Arduino和ADXL345加速度计教程

Adxl345加速度计如何工作

首先,让我们来看看ADXL345传感器的工作原理。这是一个3轴加速度计,可以测量加速度的静态和动态力。地球重力是静态力的典型例子,而动态力可以由振动,运动等引起。

ADXL345加速器如何运作betway

加速度单位为每秒平方(M / S ^ 2)。然而,加速度计传感器通常表达“G”或重力的测量。一个“g”是地球重力的值,其等于每秒平方9.8米。

因此,如果我们有一个加速度计定位平板,其z轴向上指向,与重力相反,传感器的z轴输出将是1g。另一方面,x和y输出为零,因为重力力垂直于这些轴并且根本不会影响它们。

ADXL345 3轴加速器输出数据

如果我们将传感器倒置,则z轴输出将为-1g。这意味着传感器的输出由于其对重力而导致的导致可以从-1g到+ 1g变化。

ADXL345 Z轴输出

因此,根据该数据并使用一些三角仪数学,我们可以计算传感器定位的角度。

如何读取ADXL345加速度计数据Arduino

好的,现在让我们看看我们如何使用Arduino读取ADXL345加速度计数据。该传感器使用I2C协议进行与Arduino通信,因此我们只需要两根电线来连接它,加上两根电线供电。

Arduino和ADXL345加速度计电路图

你可以从下面的链接获得这个Arduino教程所需的组件:

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

ADXL345加速度计Arduino代码

这是读取ADXL345加速度计数据的Arduino代码。

/ * Arduino和Adxl345加速度计由Dejan,//www.mfxpo.com * / bet188官方网站#include  //ire library  - 用于i2c Communication int ADXL345 = 0x53;// ADXL345传感器I2C地址float x_out,y_out,z_out;//输出void setup(){serial.begin(9600);//启动串行通信以在串行监视器线上打印结果.Begin();//在测量模式Wire.BegIntroAnsmission(ADXL345)中启动电线库//设置ADXL345;//开始与设备线路通信.WRITE(0x2D);//访问/与power_ctl寄存器 -  0x2d //启用测量线.write(8);//(8dec  - > 0000 1000二进制)位D3高度测量使能导线.endtransmission();延迟(10);void循环(){// ===读取加速器数据=== // wire.begintroansmission(adxl345); Wire.write(0x32); // Start with register 0x32 (ACCEL_XOUT_H) Wire.endTransmission(false); Wire.requestFrom(ADXL345, 6, true); // Read 6 registers total, each axis value is stored in 2 registers X_out = ( Wire.read()| Wire.read() << 8); // X-axis value X_out = X_out/256; //For a range of +-2g, we need to divide the raw values by 256, according to the datasheet Y_out = ( Wire.read()| Wire.read() << 8); // Y-axis value Y_out = Y_out/256; Z_out = ( Wire.read()| Wire.read() << 8); // Z-axis value Z_out = Z_out/256; Serial.print("Xa= "); Serial.print(X_out); Serial.print(" Ya= "); Serial.print(Y_out); Serial.print(" Za= "); Serial.println(Z_out); }

描述:因此,首先,我们需要包括用于I2C通信的Wire.h库。如果您想了解如何使用I2C通信的工作以及如何使用Arduino使用它,您可以查看我的其他详细的教程

使用I2C通信的每个设备都具有唯一的I2C地址,并且可以在传感器的数据表中找到此地址(ADXL345数据表)。因此,一旦我们在设置部分中定义了三个输出的地址和变量,首先,我们需要初始化线路库,然后在测量模式下设置加速度计。为了做到这一点,如果我们再次查看数据表,我们可以看到我们需要设置POWER_CTL寄存器高的位D3。

ADXL345电源寄存器 - 启用测量模式

因此,使用BegintRansmission()函数我们开始通信,然后使用Write()函数我们告诉我们要访问的寄存器,并再次使用Write()函数我们将D3位高,通过写入第8号十进制对应于设置位D3高电平。

//在测量模式线上设置ADXL345.BegintRansmission(ADXL345);//开始与设备线路通信.WRITE(0x2D);//访问/与power_ctl寄存器 -  0x2d //启用测量线.write(8);//(8dec  - > 0000 1000二进制)位D3高度测量使能导线.endtransmission();

在循环部分时,我们现在从传感器读取数据。每个轴的数据存储在两个字节或寄存器中。我们可以从数据表中看到这些寄存器的地址。

ADXL345 Acceleromter X Y Z数据寄存器

为了阅读所有,我们从第一个寄存器开始,并且使用RequestionFrom()函数我们要求阅读6寄存器。然后使用read()函数,我们从每个寄存器读取数据,因为输出是twos补充我们,我们将它们适当地组合以获得正确的值。

// ===读取Acceleromter Data === // Wire.BegintRansmission(ADXL345);Wire.write(0x32);//从寄存器0x32(Accel_XOUT_H)Wire.endTransmission(false)开始;Wire.RequestFrom(ADXL345,6,True);//读取6个寄存器总,每个轴值存储在2寄存器x_out =(wire.read()| wire.read()<< 8);// x轴值x_out = x_out / 256;//范围为+ -2g,我们需要将原始值除以256,根据数据表y_out =(wire.read()| wire.read()<< 8);// y轴值y_out = y_out / 256;z_out =(wire.read()| wire.read()<< 8);// z轴值z_out = z_out / 256;

来自传感器的输出值实际上取决于所选择的灵敏度,可以从+ - 2g到+ -16g变化。默认的灵敏度是+ -2g,这就是为什么我们需要将输出划分为256,以便从-1到+ 1g获取值。256 LSB / g意味着我们每g有256个计数。

ADXL345灵敏度范围

根据应用程序,我们可以选择适当的灵敏度。在这种情况下,对于跟踪方向,+ -2g灵敏度很好,但是对于我们需要感知从突然移动,冲击等更高的加速力的应用程序,我们可以使用DATA_FORMAT寄存器选择一些其他灵敏度范围它的d1和d0位。

ADXL345敏感度范围寄存器和真理表

ADXL345加速器校准

尽管如此,一旦我们阅读数据,我们就可以简单地将其打印在串行监视器上以检查值是否按预期。在我的情况下,我得到的价值观并不完全像它们,尤其是具有0.1g的明显误差的z轴。

ADXL345加速度计校准

要解决此问题,我们需要使用3个偏移校准寄存器校准加速度计,这是我们如何做到的。因此,我们需要将传感器平整定位,并在不将它们划分256的情况下打印原始值。

ADXL345加速度计校准过程

从现在开始,我们可以注意到输出关闭,在我的情况下,z输出大约为283.这与正面的27个差异。现在我们需要将此值划分为4,这将提供我们需要写入z轴偏移寄存器的数字。如果我们现在上传代码,Z轴输出将是256,或者1g。

//此代码进入设置部分// off-set校准// X轴Wire.BegintRansmission(ADXL345);Wire.write(0x1e);// X轴偏移寄存器线.WRITE(1);wire.endtransmission();延迟(10);// y轴线.Begintroansmission(ADXL345);Wire.write(0x1f);// y轴偏移寄存器线.write(-2);wire.endtransmission();延迟(10); //Z-axis Wire.beginTransmission(ADXL345); Wire.write(0x20); // Z-axis offset register Wire.write(-7); Wire.endTransmission(); delay(10);

如果需要,我们应该使用相同的方法校准另一个轴。并且只需快点注意,此校准不会永久写入寄存器。我们需要将这些值写入传感器的每个电源的寄存器。

一旦我们完成了标定,我们现在可以最终计算横摇和俯仰,或绕x轴旋转和绕Y轴旋转的角度,使用这两个公式。

// Roll = atan(Y_out / sqrt(pow(X_out, 2) + pow(Z_out, 2))) * 180 / PI;if (pow(Y_out, 2) + pow(Z_out, 2)) * 180 / PI;

有关更多详细信息,这些公式如何工作,您可以查看此功能飞思卡尔半导体应用笔记

Arduino和ADXL345加速度计取向跟踪 - 3D可视化

好的,让我们立即制作加速度计3D可视化示例。

Arduino和ADXL345加速度计方向跟踪- 3D可视化

因此,我们使用相同的代码,通过串行端口发送卷和俯仰值。这是完整的Arduino代码:

/ * Arduino和ADXL345加速度计 -  Dejan,//www.mfxpo.com * / #include  //ire wircult  - 用于i2c通信int adxl345 = 0x53;// ADXL345传感器I2C地址float x_out,y_out,z_out;//输出浮动辊,间距,rollf,pitchf = 0;void setup(){serial.begin(9600);//启动串行通信以在串行监视器线上打印结果.Begin();//在测量模式Wire.BegIntroAnsmission(ADXL345)中启动电线库//设置ADXL345;//开始与设备线路通信.WRITE(0x2D);//访问/与power_ctl寄存器 -  0x2d //启用测量线.write(8);//位D3高测量使能(8dec  - > 0000 1000二进制)wire.endtransmission();延迟(10); //Off-set Calibration //X-axis Wire.beginTransmission(ADXL345); Wire.write(0x1E); Wire.write(1); Wire.endTransmission(); delay(10); //Y-axis Wire.beginTransmission(ADXL345); Wire.write(0x1F); Wire.write(-2); Wire.endTransmission(); delay(10); //Z-axis Wire.beginTransmission(ADXL345); Wire.write(0x20); Wire.write(-9); Wire.endTransmission(); delay(10); } void loop() { // === Read acceleromter data === // Wire.beginTransmission(ADXL345); Wire.write(0x32); // Start with register 0x32 (ACCEL_XOUT_H) Wire.endTransmission(false); Wire.requestFrom(ADXL345, 6, true); // Read 6 registers total, each axis value is stored in 2 registers X_out = ( Wire.read() | Wire.read() << 8); // X-axis value X_out = X_out / 256; //For a range of +-2g, we need to divide the raw values by 256, according to the datasheet Y_out = ( Wire.read() | Wire.read() << 8); // Y-axis value Y_out = Y_out / 256; Z_out = ( Wire.read() | Wire.read() << 8); // Z-axis value Z_out = Z_out / 256; // Calculate Roll and Pitch (rotation around X-axis, rotation around Y-axis) roll = atan(Y_out / sqrt(pow(X_out, 2) + pow(Z_out, 2))) * 180 / PI; pitch = atan(-1 * X_out / sqrt(pow(Y_out, 2) + pow(Z_out, 2))) * 180 / PI; // Low-pass filter rollF = 0.94 * rollF + 0.06 * roll; pitchF = 0.94 * pitchF + 0.06 * pitch; Serial.print(rollF); Serial.print("/"); Serial.println(pitchF); }

现在在这一点处理开发环境我们需要接收这些值并使用它们旋转我们将创建的3D对象。以下是完整的处理代码:

/* Arduino和ADXL345加速计- 3D可视化实例,Dejan, //www.mfxpo.com */ import procbet188官方网站essing.serial.*;进口java.awt.event.KeyEvent;进口java.io.IOException;串行myPort;字符串数据= " ";浮动辊间距;void setup() {size (960, 640, P3D);myPort = new串行(this, "COM8", 9600);//启动串行通信myPort.bufferUntil('\n');} void draw() {translate(width/2, height/ 2,0); background(33); textSize(22); text("Roll: " + int(roll) + " Pitch: " + int(pitch), -100, 265); // Rotate the object rotateX(radians(roll)); rotateZ(radians(-pitch)); // 3D 0bject textSize(30); fill(0, 76, 153); box (386, 40, 200); // Draw box textSize(25); fill(255, 255, 255); text("www.HowToMechatronics.com", -183, 10, 101); //delay(10); //println("ypr:\t" + angleX + "\t" + angleY); // Print the values to check whether we are getting proper values } // Read data from the Serial Port void serialEvent (Serial myPort) { // reads the data from the Serial Port up to the character '.' and puts it into the String variable "data". data = myPort.readStringUntil('\n'); // if you got any bytes other than the linefeed: if (data != null) { data = trim(data); // split the string at "/" String items[] = split(data, '/'); if (items.length > 1) { //--- Roll,Pitch in degrees roll = float(items[0]); pitch = float(items[1]); } } }

描述:因此,在这里,我们需要包含串行库,定义串行端口和需要与上传的Arduino草图的波特率匹配的波特率。然后我们读取传入的数据,并将其放入适当的横摇和俯仰变量中。在主绘制循环中,我们使用这些值来旋转3D对象,在这个例子中,这是一个带有特定颜色和文本的简单框。

如果我们运行草图,将出现3D对象,它将跟踪加速度计传感器的方向。我们可以在这里注意到该目的实际上有点摇晃,这是因为加速度计不仅捕获了引力,而且也是由我们手动的运动产生的小力。为了得到更平滑的结果,我们可以使用简单的低通滤波器。这里我在Arduino代码中实现了这样的滤波器,其占先前状态的94%并增加了当前状态或角度的6%。

//低通滤波器rollf = 0.94 * rollf + 0.06 *卷;pitchf = 0.94 * pitchf + 0.06 *间距;

有了这个过滤器,我们可以注意到对象现在移动得更平滑了,但也有一个副作用,那就是响应速度变慢了。我们还可以注意到,我们错过了偏航,或绕z轴的旋转。仅使用三轴加速度计的数据我们无法计算偏航。

为此,提高我们定向跟踪传感器的整体性能,我们实际上需要包括附加传感器,陀螺仪和熔断器与加速度计。

ADXL345加速度计和L3G4200D GyrScope或MPU6050 6DOF模块

因此,我们既可以使用ADXL345加速度计结合一些陀螺仪传感器,也可以使用具有3轴加速度计和3轴陀螺仪的MPU6050 IMU,集成在单个芯片上。在我的下一个视频中,您可以在此传感器上找到更详细的教程。

我希望您喜欢本教程并学到了一些新东西。请在下面的评论部分提出任何问题,不要忘记检查我的Arduino项目的收集bet188me

10的反应

  1. 吉姆雪利

    ADXL非常专业和信息丰富。我希望看到使用ADXL并控制ADXL输出时控制伺服和/或步进器的解释。例如如果ADXL左转,则伺服/步进将旋转右键以补偿。谢谢,保持良好的工作。

    回复
  2. Diogo Santiago Sobral.

    一篇很酷的文章。我学到了很多如何在arduino中生成方向的数据。我唯一不明白的是如何在3D显示器上再现实时数据。需要下载其他软件或代码自己做资源的输入吗?

    回复
  3. 杨杰华

    一个非常有用的文章,非常易于理解,预计将使用GY-85 IMU添加Kalman滤波器来执行动作识别。如何保存Excel中的真实数据。

    回复
  4. Prithviraj Shetti.

    很有帮助。谢谢你。
    对于更多校准感兴趣的人,请遵循此文档...
    AN-1077:ADXL345快速入门指南 - 模拟设备

    回复
  5. 1月

    很好的文章,只是一个问题;我如何通过无线电波取出生成的数据并发送它?

    回复
    • 德国

      谢谢!嗯,请检查我的NRF24L01教程,以及我的DIY RC发射器项目,您可以找到更多信息您可以在那里做的。

      回复

发表评论

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

推荐的

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

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

推荐的

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

初学者的8个最佳Arduino Starter Kits

推荐的

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

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