【雕爷学编程】Arduino动手做(48)---GY-291 ADXL345 三轴模块2

37款传感器与模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止37种的。鉴于本人手头积累了一些传感器和执行器模块,依照实践出真知(一定要动手做)的理念,以学习和交流为目的,这里准备逐一动手试试多做实验,不管成功与否,都会记录下来——小小的进步或是搞不掂的问题,希望能够抛砖引玉。

【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
实验四十八:GY-291 ADXL345 数字三轴重力加速度倾斜度模块 IIC/SPI传输

知识点:加速度与三轴加速度传感器
一、加速度(acceleration)
1、加速度是物理学中的一个物理量,是一个向量,主要应用于经典物理当中,一般用字母a 表示,在国际单位制中的单位为米每二次方秒(m/s^{2})。加速度是速度向量对于时间的变化率,描述速度的方向和大小变化的快慢。加速度的图标见下图。

在经典力学中,牛顿第二定律说明了力和加速度成正比,这定律又称为「加速度定律」。假设施加于物体的净外力为零,则加速度为零,速度为常数,由于动量是质量与速度的乘积,所以动量守恒。在电动力学里,呈加速度运动的带电粒子会发射电磁辐射。


简单地说,速度描述了位置是如何变化的,而加速度描述了速度是如何变化的。这是两个层面的变化!比如,水平地向前扔出一个物体,起初它的速度朝向正前,然而由于重力它开始在向前的同时向下坠落,即其速度改变了。这里改变物体速度的主要是地球的重力引起的重力加速度。加速度是我们对任何速度变化的称呼。因为速度包含大小和方向,所以产生加速度只有两种方式:改变速度或者改变方向——或者两个都改变。

加速度具有向量性质,即需要用大小和方向同时描述一个加速度。在光滑水平面上向前运动的物体,如果向左或向右施以力,即给予了不同的加速度,则其速度会发生变化(包含了速率及方向),然而向左的加速度和向右的加速度显然引起了不同的效果。同样,施力的大小不同,引起的加速度不同,最终的结果也不一样,亦可以从向量的加成性来看。作为一个向量,加速度的叠加和分解分别遵循平行四边形法则和三角形法则。


具体而言,加速度描述的是速度随时间的变化率。需要注意的是,由于速度也是向量,因此加速度不为零的物体速度的大小(称之为速率)也不一定会发生变化,实际上,如果加速度保持与速度垂直,速度大小就一直不会改变,同时方向一直改变。这种情况在生活中最常见的是圆周运动,比如在被拴在一端固定的线的另一端的一个小物体在线保持绷直时做的运动,又比如带电粒子在仅受静磁场的劳仑兹力 F=qv x B时做的运动。


加速度是物体速度随时间的变化率,是矢量,具有大小量值和方向性(方向由+、-号代表)。加速度的大小等于单位时间内速度的改变量;加速度的方向与速度变化量ΔV方向始终相同。特别,在直线运动中,如果加速度的方向与速度相同,速度增加;加速度的方向与速度相反,速度减小。加速度等于速度对时间的一阶导数,等于位置坐标对时间的二阶导数。

如果你没有改变你的速度和方向,那么你就不可能产生加速度。因此,因为速度没有变化,一架以每小时800英里的速度沿直线匀速飞行的飞机的加速度为0,尽管这架飞机的速度非常快。当这架飞机降落并且迅速停下的时候它将会有加速度,因为它正在减速。或者你也可以这样想。在车里,你可以通过踩油门或者刹车来产生加速度,因为这会导致速度大小的变化。你也可以使用方向盘转弯来产生加速度,因为这会导致你的速度方向变化。这两者中的任何一个都会被认为是产生了加速度,因为他们都会导致速度的变化。

人们会想,“如果加速度是负值,那么物体就在减速,如果加速度是正值,那么物体就在加速,对吧?”错了。加速度为负值的物体可能在加速,加速度为正值的物体也可能在减速。为什么会这样呢?考虑到加速度是一个矢量,它指向与 速度变化 相同的方向。这意味着加速度的方向决定了速度应该加还是减去加速度。从数学上讲,负加速度意味着你应该从当前速度减去加速度,正加速度则表示你应该从当前速度加上加速度。如果速度一开始就是负值,那么从速度值中减去加速度可能会使物体的速度大小增加。

如果加速度与速度指向同一方向,则物体将加速。如果加速度与速度指向不同方向,物体将会减速。以下图为例,一辆车不小心开入了泥潭中—这会让车减速—或者追逐一个甜甜圈—会让车加速。假设右为正方向,车向右移动时速度为正值,车向左移动时速度为负值。如果车在加速,加速度指向速度相同方向;如果汽车减速加速度指向速度相反方向。另一种说法是,如果加速度与速度同号,物体将会加速。如果加速度与速度异号,物体将会减速。


三轴加速度传感器(Three-axis accelerometer)
加速度传感器有多种实现方式,主要可分为压电式、电容式及热感应式三种,按输入轴数目分类,有单轴、双轴和三轴加速度计。三轴加速度传感器是基于加速度的基本原理去实现工作,具有体积小和重量轻特点,可以测量空间加速度,能够全面准确反映物体的运动性质,在航空航天、机器人、汽车和医学等领域得到广泛的应用。下图为无人机中使用的三轴加速度传感器。

三轴加速度传感器的物理原理
加速度的感测基本原理相当简单,这类加速度计是利用特殊硅材料特质而设计出的可移动式结构,它的机械结构包括可移动的质量块与弹簧连接感测器的相对固定端,分别作为电容的两极。当外界因加速度而使得质量块与弹簧固定端发生相对位移时,两极间的电容量即会产生变化,透过特殊电路可将此变化量转换成相对应的输出讯号,进而得到相对加速度值。但是如果只有一个方向的加速度感测器,在应用方面来说相对较少,因此,为了适用于真实的 3D 世界,我们再进一步将其扩增立体三个方向,也就是三轴加速度感测器,因此其能检测 X、Y、Z 的加速度资料,并根据三轴资讯来判断当前的运动状态,进而推广出大量的应用端。

在空间飞行器的惯性测量系统、车辆船舶的倾斜测量、机器人的平衡姿态检测、肢体姿态检测等许多方面都需要测量物体的倾斜角。采用MEMS加速度传感器来测量倾斜角角度,具有体积小、质量轻、成本低、不影响被测物体的机械机构的特点。以电容式三轴加速度计的技术原理为例。电容式加速度计能够感测不同方向的加速度或振动等运动状况。其主要为利用硅的机械性质设计出的可移动机构,机构中主要包括两组硅梳齿,一组固定,另一组随即运动物体移动;前者相当于固定的电极,后者的功能则是可移动电极。当可移动的梳齿产生了位移,就会随之产生与位移成比例电容值的改变。三轴加速度传感器的好处就是在预先不知道物体运动方向的场合下,只有应用三维加速度传感器来检测加速度信号。三维加速度传感器具有体积小和重量轻特点,可以测量空间加速度,能够全面准确反映物体的运动性质。

三轴加速度传感器的几个应用
(1)车身安全、控制及导航系统中的应用
加速度传感器在进入消费电子市场之前,实际上已被广泛应用于汽车电子领域,主要集中在车身操控、安全系统和导航,典型的应用如汽车安全气囊、ABS防抱死刹车系统、电子稳定程序、电控悬挂系统等。车身安全越来越得到人们的重视,汽车中安全气囊的数量越来越多,相应对传感器的要求也越来越严格。整个气囊控制系统包括车身外的冲击传感器、安置于车门、车顶,和前后座等位置的加速度传感器、电子控制器,以及安全气囊等。电子控制器通常为16位或32位MCU,当车身受到撞击时,冲击传感器会在几微秒内将信号发送至该电子控制器。随后电子控制器会立即根据碰撞的强度、乘客数量及座椅/安全带的位置等参数,配合分布在整个车厢的传感器传回的数据进行计算和做出相应评估,并在最短的时间内通过电爆驱动器启动安全气囊保证乘客的生命安全。除了车身安全系统这类重要应用以外,加速度传感器在导航系统中的也在扮演重要角色。专家预测便携式导航设备(PND)将成为中国市场的热点,其主要利于GPS卫星信号实现定位。而当PND进入卫星信号接收不良的区域或环境中就会因失去信号而丧失导航功能。基于MEMS技术的三轴加速度传感器配合陀螺仪或电子罗盘等元件一起可创建方位推算系统,对GPS系统实现互补性应用。

(2)硬盘抗冲击防护
由于海量数据对存储方面的需求,硬盘和光驱等元器件被广泛应用到笔记本电脑、手机、数码相机/摄相机、便携式DVD机、PMP等设备中。便携式设备由于其应用场合的原因,经常会意外跌落或受到碰撞,而造成对内部元器件的巨大冲击。为了使设备以及其中数据免受损伤,越来越多的用户对便携式设备的抗冲击能力提出要求。一般便携式产品的跌落高度为1.2~1.3米,其在撞击大理石质地面时会受到约50KG的冲击力。虽然良好的缓冲设计可由设备外壳或PCB板来分解大部分冲击力,但硬盘等高速旋转的器件却在此类冲击下显得十分脆弱。如果在硬盘中内置3轴加速度传感器,当跌落发生时,系统会检测到加速的突然变化,并执行相应的自我保护操作,如关闭抗震性能差的电子或机械器件,从而避免其受损,或发生硬盘磁头损坏或刮伤盘片等可能造成数据永久丢失的情况。


(3)消费产品中的创新应用
三轴加速度传感器为传统消费及手持电子设备实现了革命性的创新空间。其可被安装在游戏机手柄上,作为用户动作采集器来感知其手臂前后、左右,和上下等的移动动作,并在游戏中转化为虚拟的场景动作如挥拳、挥球拍、跳跃、甩鱼竿等,把过去单纯的手指运动变成真正的肢体和身体的运动,实现比以往按键操作所不能实现的临场游戏感和参与感。


(4)姿态与动作识别
三轴加速度传感器的应用范围很广,除了文中提到的游戏动作操控外,还能用于手持设备的姿态识别和UI操作。例如借助3轴加速度传感器,手持设备可实现画面自动转向。iPod Touch就内建了此功能,设备显示的画面和信息会根据用户的动作而自动旋转。其通过内部传感器对重力向量的方向检测来确定设备处于水平或垂直状态,并自动调整显示状态,给用户带来方便。传感器对震动的感知性能也可将以前传统的按键动作变化为震动,用户可通过单次或多次震动来进行功能的选择,如曲目的选择、音量控制等。此外,该功能还可扩展至对用户界面元素的操控。如屏幕显示内容的上下左右等方向的浏览可通过倾斜手持设备来完成。

(5)趣味性扩展功能
三轴加速度传感器对用户操控动作的转变还可转化为许多趣味性的扩展功能上,如虚拟乐器、虚拟骰子游戏,以及“闪讯”(Wave Message)等。虚拟乐器内置的加速度传感器可检测用户对手持设备的挥动来控制乐器的节奏和音量等;骰子游戏也采用类似的原理,通过对挥动等动作的感知来控制虚拟骰子的旋转速度,并借助内部数学模型抽象的物理定律决定其停止的时间。

“闪讯”是一个更富有想象力的应用,用户可利用此功能在空中进行文字编辑。“闪讯”即让手持设备通过加速度传感器捕捉用户在空中模拟写字的快速动作,主要适合较暗的环境下使用。手持设备上会安装发光的LED,由于人眼视网膜的视觉暂留现象,其在空中挥动的动作会在其眼中留下短暂的连续画面,完成写字的所有动作笔顺。


ADXL345三轴加速度传感器模块实验所需硬件清单
8x8LED点阵屏模块X1
Arduino Uno开发板 X1
杜邦线 若干(备了9条)
LED发光二极管(蓝色)X1
IIC/I2C 1602 LCD液晶屏模块X1
ADXL345三轴加速度传感器模块X2
Proto Shield原型扩展板(带mini面包板)X1

传感器模块实验所需软件平台
代码编程 Arduino IDE (版本1.8.19)
仿真编程 Linkboy (版本V4.6.3)
图形编程 Mind+ (版本 V1.7.0 RC2.0)
以及编玩边学(线上平台https://ide.codepku.com/?type=Arduino)

 

搜索和安装“ADXL345”相关库
1、打开Arduino IDE——工具——管理库,搜索ADXL345

2、打开网页https://github.com/,搜索ADXL345

Arduino实验接线示意图

【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)

实验四十八:GY-291 ADXL345 数字三轴重力加速度倾斜度模块 IIC/SPI传输

程序一:在串口显示ADXL345的动态波形

Arduino实验开源代码

 

/*
  【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
  程序一:在串口显示ADXL345的动态波形
*/

#include <Wire.h>  // 线库 - 用于 I2C 通信
int ADXL345 = 0x53; // ADXL345传感器I2C地址
float X_out, Y_out, Z_out;  // 输出

void setup() {
  Serial.begin(9600); 
  Wire.begin(); // 启动 Wire 库
  Wire.beginTransmission(ADXL345); // 开始与设备通信
  Wire.write(0x2D); /// 访问/与 POWER_CTL 寄存器对话 - 0x2D
  // (8dec -> 0000 1000 binary) Bit D3 High 用于测量启用
  Wire.write(8); 
  Wire.endTransmission();
  delay(10);
}

void loop() {
  // === 读取加速度计数据 === //
  Wire.beginTransmission(ADXL345);
  Wire.write(0x32); // 从寄存器 0x​​32 (ACCEL_XOUT_H) 开始
  Wire.endTransmission(false);
  // 共读取 6 个寄存器,每个轴的值存储在 2 个寄存器中
  Wire.requestFrom(ADXL345, 6, true); 
  X_out = ( Wire.read()| Wire.read() << 8); // X轴值
  X_out = X_out/2; //将原始值除以2
  Y_out = ( Wire.read()| Wire.read() << 8); // Y轴值
  Y_out = Y_out/2;
  Z_out = ( Wire.read()| Wire.read() << 8); // Y轴值
  Z_out = Z_out/2; 
  Serial.print("Xa= ");
  Serial.print(X_out);
  delay(500);
  Serial.print("   Ya= ");
  Serial.print(Y_out);
  delay(500);
  Serial.print("   Za= ");
  Serial.println(Z_out);
  delay(500);
}

  

实验串口返回情况

打开Arduino IDE——工具——串口绘图器,查看实验波形

实验串口绘图器返回情况

【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)

实验四十八:GY-291 ADXL345 数字三轴重力加速度倾斜度模块 IIC/SPI传输

程序二:在串口显示ADXL345的动态波形之二

Arduino实验开源代码

 

/*
  【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
  程序二:在串口显示ADXL345的动态波形之二
  Arduino------ADXL345
  5V------------VCC
  GND-----------GND
  A4-----------SDA IIC 数据线
  A5-----------SCL IIC 时钟线
*/

#include <Wire.h>

#define DEVICE (0x53)  //ADXL345设备地址
#define TO_READ (6)    //我们每次要读取的字节数(每个轴两个字节)
byte buff[TO_READ] ;   //6字节缓冲区,用于保存从设备读取的数据

char str[512];   //字符串缓冲区,用于在将数据发送到串行端口之前对其进行转换
int regAddress = 0x32;  //ADXL345上的第一个轴加速度数据寄存器
int x, y, z;      //三轴加速度数据

double roll = 0.00, pitch = 0.00;  //Roll & Pitch 是绕 X 轴和 y 轴旋转的角度

void setup() {
  Wire.begin();    // 加入 i2c 总线(主机地址可选)
  Serial.begin(9600);  // 启动串口输出

  //开启ADXL345
  writeTo(DEVICE, 0x2D, 0);
  writeTo(DEVICE, 0x2D, 16);
  writeTo(DEVICE, 0x2D, 8);
}

void loop() {
  readFrom(DEVICE, regAddress, TO_READ, buff); //从ADXL345读取加速度数据

  //每个轴读数的分辨率为 10 位,即 2 个字节。最低有效字节优先!!
  //因此我们将两个字节转换为一个整数
  x = (((int)buff[1]) << 8) | buff[0];
  y = (((int)buff[3]) << 8) | buff[2];
  z = (((int)buff[5]) << 8) | buff[4];

  //我们将x y z值作为字符串发送到串口
  Serial.print("x,y,z的加速度信息为:");
  sprintf(str, "%d %d %d", x, y, z);
  Serial.print(str);
  Serial.write(10);

  //计算Roll & Pitch 
  RP_calculate();
  Serial.print("滚动:");
  Serial.println( roll );
  Serial.print("间距:");
  Serial.println( pitch );
  Serial.println("");
  //看来需要延迟才能不阻塞端口
  delay(500);
}

//将val写入设备上的地址寄存器
void writeTo(int device, byte address, byte val) {
  Wire.beginTransmission(device); //开始传输到设备
  Wire.write(address);        // 发送寄存器地址
  Wire.write(val);        // 发送要写入的值
  Wire.endTransmission(); //结束传输
}

//从设备上的地址寄存器开始读取num字节到buff数组
void readFrom(int device, byte address, int num, byte buff[]) {
  Wire.beginTransmission(device); //开始传输到设备
  Wire.write(address);        //发送要读取的地址
  Wire.endTransmission();     //结束传输

  Wire.beginTransmission(device); //开始传输到设备
  Wire.requestFrom(device, num);  // 从设备请求 6 个字节

  int i = 0;
  while (Wire.available()) //设备发送的数据可能少于请求的数据(异常)
  {
    buff[i] = Wire.read(); // 接收一个字节
    i++;
  }
  Wire.endTransmission(); //结束传输
}

//计算Roll&Pitch
void RP_calculate() {
  double x_Buff = float(x);
  double y_Buff = float(y);
  double z_Buff = float(z);

  roll = atan2(y_Buff , z_Buff) * 57.3;
  pitch = atan2((- x_Buff) , sqrt(y_Buff * y_Buff + z_Buff * z_Buff)) * 57.3;
}

  实验串口返回情况

 

实验串口绘图器返回情况

 

Arduino实验场景图

程序三:串口显示ADXL345的动态波形
实验开源仿真编程(Linkboy V4.63)

打开Linkboy——各种常用小工具——串口绘图器,查看实验波形

 

 

实验串口绘图器返回情况

 

posted @ 2023-07-20 11:21  行者花雕  阅读(364)  评论(0编辑  收藏  举报