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

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

概述

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

Arduino和ADXL345加速度计教程

ADXL345加速度计如何工作

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

ADXL345加速计如何工作亚博88下载

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

所以,如果我们有一个平放的加速度计,它的z轴向上,与重力相反,传感器的z轴输出将是1g。另一方面,X和Y的输出将为零,因为重力垂直于这些轴,完全不影响它们。

ADXL345 3轴加速器输出数据

如果我们把传感器倒过来,那么z轴输出将是- 1g。这意味着由于其重力方向,传感器的输出可以在-1g到+1g之间变化。

Adxl345 z轴输出

因此,根据这些数据和使用一些三角数学,我们可以计算出传感器所在的角度。

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

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

Arduino和ADXL345加速度计电路图

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

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

ADXL345加速计Arduino代码

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

/ * Arduino和Adxl345加速度计由Dejan,//www.kuaixg.com * / 亚搏手机版官方下载#include  //ire library  - 用于i2c Communication int ADXL345 = 0x53;// ADXL345传感器I2C地址浮动X_out, Y_out, Z_out;//输出void setup(){serial.begin(9600);//启动串口通信,在串口监视器上打印结果Wire.begin();//初始化Wire库//设置ADXL345在测量模式//开始与设备通信Wire.write(0x2D);// Access/ talk to POWER_CTL Register - 0x2D //启用测量Wire.write(8);//(8dec  - > 0000 1000二进制)位D3高度测量使能导线.endtransmission();延迟(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; Serial.print("Xa= "); Serial.print(X_out); Serial.print(" Ya= "); Serial.print(Y_out); Serial.print(" Za= "); Serial.println(Z_out); }

描述:所以首先我们需要包含Wire.h库,它用于I2C通信。如果你想了解更多关于I2C通信工作原理和如何使用Arduino你可以检查我的其他详细教程

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

Adxl345功率寄存器-使能测量模式

所以,使用beginTransmission()函数我们开始通信,然后利用写()函数我们告诉哪个寄存器访问,又使用写()函数我们设置了D3有些高,通过编写8在十进制数对应于设置D3高一些。

//在测量模式线上设置ADXL345.BegintRansmission(ADXL345);//开始与设备通信Wire.write(0x2D);// Access/ talk to POWER_CTL Register - 0x2D //启用测量Wire.write(8);//(8dec  - > 0000 1000二进制)位D3高度测量使能导线.endtransmission();

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

Adxl345加速计x y z数据寄存器

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

// ===读取加速计数据=== // Wire.beginTransmission(ADXL345);Wire.write (0 x32);//寄存器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的值。256lsb /g意味着每g有256个计数。

ADXL345灵敏度范围

根据不同的应用,我们可以选择合适的灵敏度。在这种情况下,对于跟踪方向,+-2g的灵敏度很好,但对于需要从突然运动、冲击等感知更高加速度的应用,我们可以使用DATA_FORMAT寄存器及其D1和D0位选择其他一些灵敏度范围。

Adxl345灵敏度范围寄存器和真值表

ADXL345 Acceleromter校准

然而,一旦我们读取数据,我们可以简单地将其打印在串行监视器上,以检查值是否如预期的那样。在我的例子中,我得到的值并不完全是它们应该得到的,特别是z轴有一个明显的0.1g的误差。

adxl345加速度计校准

为了解决这个问题,我们需要使用3个偏移校准寄存器来校准加速度计,下面是我们如何做到这一点。所以,我们需要将传感器平放,打印RAW值而不除以256。

Adxl345加速度计校准过程

从这里我们可以注意到输出是多少,在我的例子中,Z输出大约是283。这是正27的差值。现在我们需要将这个值除以4,这将给出我们需要写入z轴偏移寄存器的数字。如果我们现在上传代码,z轴输出将恰好是256,或1g。

//这段代码进入SETUP部分//偏移量校准// x轴线开始传输(ADXL345);Wire.write (0 x1e);// x轴偏移寄存器Wire.write(1);Wire.endTransmission ();延迟(10);/ /轴Wire.beginTransmission (ADXL345);Wire.write (0 x1f);// y轴偏移寄存器Wire.write(-2);Wire.endTransmission ();延迟(10); //Z-axis Wire.beginTransmission(ADXL345); Wire.write(0x20); // Z-axis offset register Wire.write(-7); Wire.endTransmission(); delay(10);

如果需要,我们应该用同样的方法校准另一个轴。顺便提醒一下,这个校准并不是永久写入寄存器的。我们需要在传感器每次通电时将这些值写入寄存器。

一旦我们完成了校准,我们现在可以使用这两个公式最终计算Roll和Pitch,或者绕x轴旋转和绕Y轴旋转的角度。

//计算滚转和俯仰(绕x轴旋转,绕y轴旋转)滚转= atan(Y_out / sqrt(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;

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

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

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

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

所以,我们使用相同的代码,通过串口发送滚动和Pitch值。这里是完整的Arduino代码:

/* Arduino and ADXL345 Accelerometer - 3D Visualization Example by Dejan, https://亚搏手机版官方下载www.kuaixg.com */ #include  // Wire library - used for I2C communication int ADXL345 = 0x53;// ADXL345传感器I2C地址浮动X_out, Y_out, Z_out;//输出float roll,pitch,rollF,pitchF=0;void setup() {Serial.begin(9600);//启动串口通信,在串口监视器上打印结果Wire.begin();//初始化Wire库//设置ADXL345在测量模式//开始与设备通信Wire.write(0x2D);// Access/ talk to POWER_CTL Register - 0x2D //启用测量Wire.write(8);// Bit D3 High for measuring enable (8dec -> 0000 1000 binary) 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 and ADXL345 Accelerometer - 3D Visualization Example by Dejan, https://亚搏手机版官方下载www.kuaixg.com */ import processing.serial.*;进口java.awt.event.KeyEvent;进口java.io.IOException;串行myPort;字符串数据= " ";浮动辊间距;void setup() {size (960, 640, P3D);myPort = new Serial(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对象将出现,它将跟踪加速度传感器的方向。我们可以注意到,这个物体实际上有点摇晃,那是因为加速度计不仅捕捉到了重力,还捕捉到了手部运动产生的小力。为了得到更平滑的结果,我们可以使用一个简单的Low-pass滤波器。在这里,我在Arduino代码中实现了这样一个过滤器,它获得了之前状态的94%,并添加了当前状态或角度的6%。

// Low-pass filter rollF = 0.94 * rollF + 0.06 * roll;pitchf = 0.94 * pitchf + 0.06 *间距;

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

为了做到这一点并改善我们的定位跟踪传感器的整体性能,我们实际上需要包括一个额外的传感器,一个陀螺仪,并将其数据与加速度计融合。

Adxl345加速度计和l3g4200d陀螺仪或mpu6050 6dof模块

所以,我们可以使用ADXL345加速度计结合一些陀螺仪传感器,或者使用MPU6050 IMU集成了三轴加速度计和三轴陀螺仪在一个芯片上。你可以在下一个视频中找到关于这个传感器的更详细的教程。

我希望你喜欢这个教程,并学到一些新的东西。欢迎在评论区提出任何问题,不要忘记查看我的Arduino项目的集合足彩网女欧洲杯

10的反应

  1. 吉姆雪利

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

    回复
  2. Diogo Santiago Sobral.

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

    回复
  3. 杨杰华

    一篇很有用,很容易理解的文章,预计使用GY-85 IMU添加卡尔曼滤波器来做动作识别。以及如何在excel中保存实际数据。

    回复
  4. 总长Shetti

    很有帮助。谢谢你!
    任何对校准感兴趣的人,请看下面的文档……
    AN-1077: ADXL345快速入门指南-模拟设备

    回复
    • 德扬

      谢谢!好检查我的NRF24L01教程,以及我的DIY RC发射器项目,你会发现更多的信息,你可以做到这一点在那里。

      回复

留下一个回复

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

推荐

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

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

推荐

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

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

推荐

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

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