目录

  • 有用的链接
  • 1. ADXL345加速度计的工作原理
    • 1.1 工作原理
    • 1.2 如何使用Arduino读取ADXL345加速度计数据
      • 1.2.1 电路图
      • 1.2.2 ADXL345加速度计的Arduino代码
      • 1.2.3 代码描述
  • 2. ADXL345加速器校准
  • 3. Arduino和ADXL345加速度计方向跟踪 - 三维可视化
    • 3.1 Arduino代码
    • 3.2 Processing代码
    • 3.3 代码描述
  • 附:Arduino开发板使用MPU6050加速度计和陀螺仪的方法

本文转载自:一板网https://www.yiboard.com/thread-1213-1-1.html
国外的网址:https://howtomechatronics.com,网站中的地址是:https://howtomechatronics.com/tutorials/arduino/how-to-track-orientation-with-arduino-and-adxl345-accelerometer/
本文是原文转载,目的是为了在学习的过程中,不断修改并补充自己的内容,如果有侵权请联系我,将尽快改正。

参考:

  1. 编程和校准ADXL345 数字加速度计)
  2. ADXL345: 如何校准
  3. ADXL345:新增自动加速度计校准
    在本篇文章中,我们将学习如何使用Arduino开发板和ADXL345加速计传感器测量角度和跟踪方向。首先,我们将介绍传感器是如何工作以及如何从中读取数据,然后使用Processing开发环境,对加速度计方向进行3D可视化。

有用的链接

1.寻找IIC设备地址的代码
https://blog.csdn.net/acktomas/article/details/101419690

1. ADXL345加速度计的工作原理

  1. ADXL345传感器芯片的三轴加速度测量轴向定义如下图:

  2. 下图举例了ADXL345传感器以各种不同方式静置时传感器的理想输出值(实际中由于器件偏差,尤其是Z轴很难保证输出纯正的±1g):

知道了这一点,您可以计算传感器读数的校正输出。
首先,让我们来看看ADXL345传感器的工作原理。这是一个3轴加速度计,可以测量静态和动态加速度力。地球重力是静力的典型例子,而动态力可以由振动、运动等引起。

1.1 工作原理

加速度的测量单位是米每二次方秒(m/s2)。但是,加速计传感器通常以“g”或重力表示测量值。一个“g”是地球重力的值,它等于每平方秒9.8米。

因此,如果我们将加速度计平放,其Z轴朝上,与重力相反,则传感器的Z轴输出将为1g。另一方面,X和Y输出将为零,因为重力垂直于这些轴并且根本不影响它们。

ADXL345 3轴加速器输出数据

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

adxl345 z轴输出

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

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

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

1.2.1 电路图

Arduino和ADXL345加速度计电路图

1.2.2 ADXL345加速度计的Arduino代码

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

/*Arduino and ADXL345 Accelerometer Tutorialby Dejan, https://howtomechatronics.com
*/
#include <Wire.h>  // Wire library - used for I2C communication
int ADXL345 = 0x53; // The ADXL345 sensor I2C address
float X_out, Y_out, Z_out;  // Outputs
void setup() {Serial.begin(9600); // Initiate serial communication for printing the results on the Serial monitorWire.begin(); // Initiate the Wire library// Set ADXL345 in measuring modeWire.beginTransmission(ADXL345); // Start communicating with the deviceWire.write(0x2D); // Access/ talk to POWER_CTL Register - 0x2D// Enable measurementWire.write(8); // (8dec -> 0000 1000 binary) Bit D3 High for measuring enableWire.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 registersX_out = ( Wire.read()| Wire.read() << 8); // X-axis valueX_out = X_out/256; //For a range of +-2g, we need to divide the raw values by 256, according to the datasheetY_out = ( Wire.read()| Wire.read() << 8); // Y-axis valueY_out = Y_out/256;Z_out = ( Wire.read()| Wire.read() << 8); // Z-axis valueZ_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);
}

1.2.3 代码描述

  1. 我们需要包含用于I2C通信的Wire.h库。每个使用I2C通信的器件都有一个唯一的I2C地址,该地址可以在传感器的数据手册中找到(ADXL345数据手册)。因此,我们定义了三个输出的地址和变量之后,首先在setup函数部分中,我们需要初始化wire库,然后将加速度计设置为测量模式。为了实现这一点,如果我们再次查看数据手册,可以看到需要将POWER_CTL寄存器的位D3置为高电平。


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

  1. 使用beginTransmission()函数,我们开始通信,然后使用write()函数,我们告诉要访问哪个寄存器,再次使用write()函数,将D3位设置为HIGH,通过写入十进制的数字8,对应于将D3位设置为HIGH。
// Set ADXL345 in measuring modeWire.beginTransmission(ADXL345); // Start communicating with the deviceWire.write(0x2D); // Access/ talk to POWER_CTL Register - 0x2D// Enable measurementWire.write(8); // (8dec -> 0000 1000 binary) Bit D3 High for measuring enableWire.endTransmission();

现在我们在loop()函数部分中读取传感器的数据。每个轴的数据存储在两个字节或寄存器中。我们可以从数据手册中看到这些寄存器的地址。

adxl345加速器x y z数据寄存器

  1. 为了全部读取它们,我们从第一个寄存器开始,并使用requestFrom()函数,我们要求读取6个寄存器。然后使用read()函数,我们从每个寄存器读取数据,并且由于输出是两个补码,我们将它们适当地组合以获得正确的值。
// === 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 registersX_out = ( Wire.read()| Wire.read() << 8); // X-axis valueX_out = X_out/256; //For a range of +-2g, we need to divide the raw values by 256, according to the datasheetY_out = ( Wire.read()| Wire.read() << 8); // Y-axis valueY_out = Y_out/256;Z_out = ( Wire.read()| Wire.read() << 8); // Z-axis valueZ_out = Z_out/256;

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


adxl345灵敏度范围

  1. 根据应用,我们可以选择适当的灵敏度。在本例中,对于跟踪方向,±2g灵敏度很好,但对于需要从突然移动、冲击等感知更高加速力的应用,我们可以使用DATA_FORMAT寄存器和它的D1和D0位选择一些其他灵敏度范围。


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

2. ADXL345加速器校准

然而,一旦我们读取数据,我们可以简单地在串行监视器上打印它以检查值是否符合预期。本例中,我得到的值并不完全正确,特别是Z轴有0.1g的明显误差。


adxl345加速度计校准

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


adxl345加速度计校准过程

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

ADXL345需要通过放在绝对水平的位置,进行校准。涉及到校准的寄存器包括(0X1E,0X1F,0X20)。校准寄存器比例因子为15.6mg/LSB,也就是说0X7F代表2G;这个寄存器的数值会自动加到加速度值中。
加速度传感器内含MEMS机械结构,这个器件组装到PCB上之后,由于安装等各种原因,可能导致并非绝对精准,从而需要进行数据校准。通常校准时,Z轴为1G, X,Y为0G。校准时,通常采用默认的100Hz采样率连续采样10个样板(也就是对应于0.1秒采样时间),测量的值为X,Y,Z的偏移量,分别对应X,Y在0G, Z在1G的情况。
偏移寄存器的数值是用加法 计算的。因此,如果水平位置原始值为负值,则偏移寄存器数值为正,如果水平位置原始值为正,则偏移寄存器数值为负(用反码表示,反码中0XFF表示-1)
例如:水平放置时,X读数-5,y读数2, Z读数270;这时,正常值应该是0,0,255,因此需要把偏移量设置为5, -2, -15。但是这里注意了,ADXL345默认13位分辨率,16G量程时,1 LSB为1/256 = 3.9mg/LSB。
由于== 偏移寄存器为15.6mg/LSB,所以偏移寄存器写1个LSB,相当于偏移了4个LSB,所以偏移寄存器的值,需要除以4==。所以实际偏移量应该为5/4=1, -2/4=0, -15/4=-4, 其中负数用反码表示,所以为1, 0 , FC, 分别写入off_x, off_y和off_z即可。

// This code goes in the SETUP section
// Off-set Calibration//X-axisWire.beginTransmission(ADXL345);Wire.write(0x1E);  // X-axis offset registerWire.write(1);Wire.endTransmission();delay(10);//Y-axisWire.beginTransmission(ADXL345);Wire.write(0x1F); // Y-axis offset registerWire.write(-2);Wire.endTransmission();delay(10);//Z-axisWire.beginTransmission(ADXL345);Wire.write(0x20); // Z-axis offset registerWire.write(-7);Wire.endTransmission();delay(10);

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

完成校准后,我们现在可以使用这两个公式计算出滚动和俯仰,或绕X轴旋转和围绕Y轴旋转的度数。
(传感器的X轴与自然界的X轴夹角)yaw=arctan⁡accy2+accz2accx×180PI.(传感器的Y轴与自然界的Y轴夹角)roll=arctan⁡accx2+accz2accy×180PI.(传感器的Z轴与自然界的Z轴夹角)pitch=arctan⁡accx2+accy2accz×180PI.(传感器的X轴与自然界的X轴夹角)yaw = \arctan{\frac{\sqrt{acc_y^2+acc_z^2}}{acc_x}} \times \frac{180}{PI} \\.\\ (传感器的Y轴与自然界的Y轴夹角)roll = \arctan{\frac{\sqrt{acc_x^2+acc_z^2}}{acc_y}} \times \frac{180}{PI} \\.\\ (传感器的Z轴与自然界的Z轴夹角)pitch = \arctan{\frac{\sqrt{acc_x^2+acc_y^2}}{acc_z}} \times \frac{180}{PI}\\.\\ (传感器的X轴与自然界的X轴夹角)yaw=arctanaccx​accy2​+accz2​​​×PI180​.(传感器的Y轴与自然界的Y轴夹角)roll=arctanaccy​accx2​+accz2​​​×PI180​.(传感器的Z轴与自然界的Z轴夹角)pitch=arctanaccz​accx2​+accy2​​​×PI180​.

// 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;

有关这些公式如何工作的更多详细信息,请查看此飞思卡尔半导体应用说明:https://www.nxp.com/files-static/sensors/doc/app_note/AN3461.pdf。

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

好吧,让我们现在制作加速度计3D可视化示例。

Arduino和ADXL345加速度计方向跟踪 - 三维可视化

3.1 Arduino代码

因此,我们使用相同的代码,通过串口发送Roll和Pitch值。 以下是完整的Arduino代码:

/*Arduino and ADXL345 Accelerometer - 3D Visualization Exampleby Dejan, https://howtomechatronics.com
*/
#include <Wire.h>  // Wire library - used for I2C communication
int ADXL345 = 0x53; // The ADXL345 sensor I2C address
float X_out, Y_out, Z_out;  // Outputs
float roll,pitch,rollF,pitchF=0;
void setup() {Serial.begin(9600); // Initiate serial communication for printing the results on the Serial monitorWire.begin(); // Initiate the Wire library// Set ADXL345 in measuring modeWire.beginTransmission(ADXL345); // Start communicating with the deviceWire.write(0x2D); // Access/ talk to POWER_CTL Register - 0x2D// Enable measurementWire.write(8); // Bit D3 High for measuring enable (8dec -> 0000 1000 binary)Wire.endTransmission();delay(10);//Off-set Calibration//X-axisWire.beginTransmission(ADXL345);Wire.write(0x1E);Wire.write(1);Wire.endTransmission();delay(10);//Y-axisWire.beginTransmission(ADXL345);Wire.write(0x1F);Wire.write(-2);Wire.endTransmission();delay(10);//Z-axisWire.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 registersX_out = ( Wire.read() | Wire.read() << 8); // X-axis valueX_out = X_out / 256; //For a range of +-2g, we need to divide the raw values by 256, according to the datasheetY_out = ( Wire.read() | Wire.read() << 8); // Y-axis valueY_out = Y_out / 256;Z_out = ( Wire.read() | Wire.read() << 8); // Z-axis valueZ_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 filterrollF = 0.94 * rollF + 0.06 * roll;pitchF = 0.94 * pitchF + 0.06 * pitch;Serial.print(rollF);Serial.print("/");Serial.println(pitchF);
}

3.2 Processing代码

现在在Processing开发环境中,我们需要接收这些值并使用它们来旋转我们将创建的3D对象。 这是完整的Processing代码:

/*Arduino and ADXL345 Accelerometer - 3D Visualization Exampleby Dejan, https://howtomechatronics.com
*/
import processing.serial.*;
import java.awt.event.KeyEvent;
import java.io.IOException;
Serial myPort;
String data="";
float roll, pitch;
void setup() {size (960, 640, P3D);myPort = new Serial(this, "COM8", 9600); // starts the serial communicationmyPort.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 objectrotateX(radians(roll));rotateZ(radians(-pitch));// 3D 0bjecttextSize(30);  fill(0, 76, 153);box (386, 40, 200); // Draw boxtextSize(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 degreesroll = float(items[0]);pitch = float(items[1]);}}
}

3.3 代码描述

在这里,我们需要包括串行库,定义串口和波特率,这需要与上传的Arduino草图的波特率相匹配。然后我们读取输入数据并将其放入相应的roll和pitch变量中。在主draw循环中,我们使用这些值来旋转3D对象,本例中是一个具有特定颜色和文本的简单框。

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

// Low-pass filterrollF = 0.94 * rollF + 0.06 * roll;pitchF = 0.94 * pitchF + 0.06 * pitch;

使用此过滤器,我们可以注意到对象现在移动得更顺畅,但也有副作用,响应速度较慢。我们还可以注意到我们确实Yaw,或绕Z轴的旋转值。仅使用3轴加速度计数据,我们无法计算偏航。

为了实现这一目标并提高定向跟踪传感器的整体性能,我们实际上需要包括一个额外的传感器,一个陀螺仪,并将其数据与加速度计融合。


adxl345加速度计和l3g4200d gyrscope或mpu6050 6dof模块

因此,我们可以将ADXL345加速度计与一些陀螺仪传感器结合使用,或者使用MPU6050 IMU,它将3轴加速度计和3轴陀螺仪集成在一个芯片上。我希望你喜欢这篇文章并学到新的东西。

附:Arduino开发板使用MPU6050加速度计和陀螺仪的方法

网址:https://www.yiboard.com/thread-1212-1-1.html

如何使用Arduino开发板和ADXL345加速度计跟踪方向相关推荐

  1. 传感器i2c与arduino连接_如何在两个Arduino开发板之间使用I2C总线进行通信

    在之前的文章中,我们介绍了Arduino之间的SPI通信.今天我们将学习另一种串行通信协议:I2C(内部集成电路).比较I2C和SPI,I2C只有两条线,而SPI使用四条,I2C可以有多个主机和从机, ...

  2. Arduino 开发板介绍及对比

    一.UNO/UNO r3 Arduino / Genuino Uno是基于ATmega328P的单片机开发板.它有14个数字输入/输出引脚(其中6个可用作PWM输出),6个模拟输入脚,16 MHz晶振 ...

  3. arduino串口监视器显示nan_使用Arduino开发板制作摩尔斯电码生成器

    摩尔斯电码是一种通信系统,用于在两个不同持续时间的信号中编码任何字符,称为点和虚线.摩尔斯电码由Samuel F.B开发.并进一步用于电报传输秘密信息.它在第二次世界大战时最常用.摩尔斯电码可以通过点 ...

  4. Arduino开发板制作

    Arduino UNO 介绍 ,Arduino开发板制作 教程: Arduino制作 Arduino UNO 图 Arduino是什么 Arduino是一款便捷灵活.方便上手的开源电子原型平台.包含硬 ...

  5. 四针角oled屏连接arduino_使用Arduino开发板连接OLED显示屏制作一款智能手表

    我们大多数人都比较熟悉1602点阵液晶显示屏,它在许多项目中用于向用户显示一些信息.但是这些LCD显示器在他们能做的事情上有很多限制.在本篇文章中,我们将使用OLED显示Android智能手机的一些基 ...

  6. arduino编程时加{}报错_使用Arduino开发板时最常见的10个错误

    作为Arduino开发板的初学者,对于没有电子背景的人来说非常具有挑战性,你会遇到很多错误,其中一些可能有简单的解决方案,但可能需要几天的时间来解决.因此,为了使事情变得更容易,我制作了一个包含10个 ...

  7. arduino loar_如何使用Arduino开发板制作函数生成器(波形发生器)

    对于喜欢偶尔鼓捣电子产品的工程师来说,他们都希望能有自己的实验室.万用表.钳形表.示波器.LCR表.函数发生器.双模电源和自动变压器都是实验室的基本配置.虽然所有这些都可以购买,但我们也可以轻松地自行 ...

  8. 如何使用Arduino开发板读/写SD卡模块的数据

    存储数据是每个项目最重要的部分之一.根据数据类型和大小,有几种方法可以存储数据. SD和micro SD卡是存储设备中最实用的一种,用于移动电话.小型机等设备.在本篇文章中,您将学习如何在Arduin ...

  9. 认识 Arduino 开发板

    Arduino 是源自意大利的一个开放源代码的硬件项目平台,该平台包括一块具备简单 I/O 功能的电路板以及一套程序开发环境软件.     Arduino 真正腾飞的原因是其能够实现将模拟输入转换为数 ...

  10. 基于Arduino开发板的文本转语音(TTS)转换器

    文本转语音(TTS系统)能够将普通文本转换为语音.这种技术使系统能够用人声说出文本.有许多文本转语音转换的例子,例如公共交通公告.客户服务电话.智能手机中的语音助手或一些机器的导航菜单.您甚至可以在M ...

最新文章

  1. 关于sharepoint
  2. 动态显示时采色改为单帧采色
  3. aliyun 阿里云Maven仓库地址 不管是自建私服还是maven构建 必备 结束了几kb的历史
  4. linux 端口打不开,在线等!!为什么telnet的23端口就是打不开啊
  5. 因为我们还很穷,所以世界杯氛围差
  6. 阿里忘禅:蚂蚁集团分布式注册中心建设分享
  7. Bootstrap3 面板 .panel 容器
  8. oracle raw类型 索引,为什么RAW数据类型可以建立索引,但是不走索引
  9. 一段可自动点击运行代码(只偷偷的点一次)
  10. 开源软件 Cachet 被曝RCE漏洞
  11. seaborn—seaborn.boxplot绘制箱型图
  12. 批处理只执行第一句,其他的不被执行,怎么办?
  13. 青海干部网络学院 自动学习网站
  14. java与模式.pdf_Java与模式(清晰书签版)PDF文档
  15. 邮件抄送(CC)和秘密抄送(BCC)
  16. Word和WPS中引入Mathtype的常见问题
  17. 机器学习的所有资源链接和经验教训(五)ML技术讲座
  18. 魔兽任务分类及游戏任务系统设计启示
  19. java基础(部分)
  20. 计算机二级考试模拟软件 操作流程

热门文章

  1. 尚硅谷大数据技术之 Flink-CDC(转)
  2. 深入浅出Dubbo剖析出视频教程了!!!
  3. 黑马程序员视频加源码
  4. 理解int的存储方式以及二进制编辑器的使用
  5. 你不知道的华为交换机22个实用技巧
  6. SQL语句的执行计划
  7. 区块链零知识证明:Zcash 基础知识普及帖,Zcash 技术分析
  8. 关于win10系统常用的c盘清理技巧
  9. JAVA常用算法手册 第3版 pdf
  10. Java实现常用的三种加密算法详解