回到首页 返回首页
回到顶部 回到顶部
返回上一页 返回上一页

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

头像 驴友花雕 2023.07.20 29 1

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

 

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

6.3-01.jpg

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

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

程序十四:测量 ADXL345 的俯仰角和滚动角与校正角度法的对比

Arduino实验开源代码


 

代码
/*
  【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
  程序十四:测量 ADXL345 的俯仰角和滚动角与校正角度法的对比
*/

#include<Wire.h>
#include<ADXL345_WE.h>

#define ADXL345_I2CADDR 0x53 // 如果 SDO = HIGH,则为 0x1D

/* 有几种方法可以创建您的 ADXL345 对象:
   ADXL345_WE myAcc = ADXL345_WE()                -> uses Wire / I2C Address = 0x53
   ADXL345_WE myAcc = ADXL345_WE(ADXL345_I2CADDR) -> uses Wire / ADXL345_I2CADDR
   ADXL345_WE myAcc = ADXL345_WE(&wire2)          -> uses the TwoWire object wire2 / ADXL345_I2CADDR
   ADXL345_WE myAcc = ADXL345_WE(&wire2, ADXL345_I2CADDR) -> all together
*/
ADXL345_WE myAcc = ADXL345_WE(ADXL345_I2CADDR);

void setup() {
  Wire.begin();
  Serial.begin(9600);

  Serial.println("ADXL345 程序 - 俯仰和横滚与校正角度");
  Serial.println();

  if (!myAcc.init()) {
    Serial.println("ADXL345 未连接!");
  }

  /* 添加您使用 ADXL345_calibration.ino 找到的最小和最大原始值。
      顺序是:setCorrFactors(min x, max x, min y, max y, min z, max z)。
      setCorrFactors 校准斜率并假设零点
      是(最小+最大)/2。您必须将 setCorrFactors 函数添加到所有草图
      您想在其中使用它。
  */

  myAcc.setCorrFactors(-295.0, 255.0, -283.0, 264.0, -262.0, 265.0);

  /* 在下一步中,角度的偏移被校正以获得相当精确的校正
      角度 x 和 y 高达 ~60°。额外的 offsetCorrection 仅用于校正
      角度测量,不适用于俯仰和滚动。该过程只是确保从 0° 开始。
  */

  Serial.println("将您的 ADXL345 平放,不要移动它");
  delay(2000);

  myAcc.measureAngleOffsets();
  Serial.println("....完成");

  /* 选择数据速率                  Hz
      ADXL345_DATA_RATE_3200    3200
      ADXL345_DATA_RATE_1600    1600
      ADXL345_DATA_RATE_800      800
      ADXL345_DATA_RATE_400      400
      ADXL345_DATA_RATE_200      200
      ADXL345_DATA_RATE_100      100
      ADXL345_DATA_RATE_50        50
      ADXL345_DATA_RATE_25        25
      ADXL345_DATA_RATE_12_5      12.5
      ADXL345_DATA_RATE_6_25       6.25
      ADXL345_DATA_RATE_3_13       3.13
      ADXL345_DATA_RATE_1_56       1.56
      ADXL345_DATA_RATE_0_78       0.78
      ADXL345_DATA_RATE_0_39       0.39
      ADXL345_DATA_RATE_0_20       0.20
      ADXL345_DATA_RATE_0_10       0.10
  */
  myAcc.setDataRate(ADXL345_DATA_RATE_50);

  Serial.print("数据速率:");
  Serial.print(myAcc.getDataRateAsString());

  /* 选择测量范围
      ADXL345_RANGE_16G    16g
      ADXL345_RANGE_8G      8g
      ADXL345_RANGE_4G      4g
      ADXL345_RANGE_2G      2g
  */
  myAcc.setRange(ADXL345_RANGE_2G);
  Serial.print("/g 范围:");
  Serial.println(myAcc.getRangeAsString());
  Serial.println();
}

void loop() {
  //xyzFloat g = myAcc.getGValues();
  xyzFloat corrAngles = myAcc.getCorrAngles();

  /* 修正后的角度使用修正后的原始数据和额外的角度
      抵消。该方法为 x/y 提供了相当精确的值
      角度向上 60°。
  */

  Serial.print("角度 x = ");
  Serial.print(corrAngles.x);
  Serial.print("  |  角度 y = ");
  Serial.print(corrAngles.y);
  Serial.print("  |  角度 z = ");
  Serial.println(corrAngles.z);

  /* 俯仰和横滚使用更正的坡度,但没有额外的偏移。
      所有轴都被考虑用于计算。
  */

  float pitch = myAcc.getPitch();
  float roll  = myAcc.getRoll();

  Serial.print("俯仰 ="); //将x轴的倾斜角度称为“俯仰”
  Serial.print(pitch);

  Serial.print("  | 滚动 = ");//将y轴的倾斜角度称为“滚动”
  Serial.println(roll);

  Serial.println();

  delay(1000);
}

实验串口返回情况

 

6.3-57.jpg

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

6.3-58.jpg

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

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

程序十五:将ADXL345置于休眠状态,并唤醒它

Arduino实验开源代码


 

代码
/*
  【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
  程序十五:将ADXL345置于休眠状态,并唤醒它
*/

#include<Wire.h>
#include<ADXL345_WE.h>
#define ADXL345_I2CADDR 0x53

/* 有几种方法可以创建您的 ADXL345 对象:
 * ADXL345_WE myAcc = ADXL345_WE()                -> uses Wire / I2C Address = 0x53
 * ADXL345_WE myAcc = ADXL345_WE(ADXL345_I2CADDR) -> uses Wire / ADXL345_I2CADDR
 * ADXL345_WE myAcc = ADXL345_WE(&wire2)          -> uses the TwoWire object wire2 / ADXL345_I2CADDR
 * ADXL345_WE myAcc = ADXL345_WE(&wire2, ADXL345_I2CADDR) -> all together
 */
ADXL345_WE myAcc = ADXL345_WE(ADXL345_I2CADDR);

void setup(){
  Wire.begin();
  Serial.begin(9600);
  Serial.println("ADXL345实验程序 - 睡眠");
  Serial.println();
  if(!myAcc.init()){
    Serial.println("ADXL345 未连接!");
  }
  myAcc.setDataRate(ADXL345_DATA_RATE_50);
  myAcc.setRange(ADXL345_RANGE_2G);
}

void loop(){
  myAcc.setSleep(true, ADXL345_WUP_FQ_1);
  Serial.println("在睡眠模式下测量:");
  doMeasurements();
  
  myAcc.setSleep(false);
  Serial.println("正常模式下测量:");
  doMeasurements();
}
  
void doMeasurements(){
  for(int i=0; i<10; i++){
    xyzFloat g = myAcc.getGValues();
    
    Serial.print("g-x   = ");
    Serial.print(g.x);
    Serial.print("  |  g-y   = ");
    Serial.print(g.y);
    Serial.print("  |  g-z   = ");
    Serial.println(g.z);
    
    delay(60);
  }
}

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

6.3-60.jpg

实验串口返回情况

 

6.3-59.jpg

【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
实验四十八:GY-291 ADXL345 数字三轴重力加速度倾斜度模块 IIC/SPI传输
程序十六:ADXL345自由落体中断(激活并分配给 INT2)

(1)ADXL345的中断特性
有关中断功能的一般信息
ADXL345区分了八个中断:
(a)溢出:当未读数据被覆盖时触发,即当数据速率大于数据检索的频率时。
水印:如果FIFO缓冲器中的测量值数量与FIFO控制寄存器中定义的值相对应(稍后会更清晰)。
(b)自由落体:当所有轴上的加速度值在一段时间内低于某个值时,就会触发该值。
(c)不活动:在指定时间内超过指定轴上的加速度限制时。
(d)活动:当指定轴上的加速度超过极限时。
(e)单点:超过特定限制的最大持续时间的加速度。
(f)双击:两个峰值,两者都满足单点条件,并且它们之间也有一定的时间间隔。
(g)数据就绪:存在未读数据。
(h)使用函数:激活中断。第一个参数是中断类型,第二个参数是确定中断输出的引脚。setInterrupt(type, pin1/pin2)
请务必注意,“溢出”、“水印”和“数据就绪”的中断始终处于启用状态。因此,您无法禁用它们,只需更改输出引脚即可。默认值为 INT1。您必须先激活所有其他中断。您可以使用 停用它们。deleteInterrupt(type)
在中断寄存器中,在中断的情况下,存储中断类型。读取此寄存器将删除中断,以便可以触发新的中断。其函数为 。它将中断类型作为字节返回。如何“翻译”这可以在库文件ADXL345_WE.h中找到。或者,您可以检查特定类型。readAndClearInterrupts()checkInterrupt(source, type)
还有另一个通用功能,即.这将设置中断引脚是低电平有效还是高电平有效(默认)。setInterruptPolarity(polarity)


Arduino实验开源代码
 

代码
/*
  【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
  程序十六:ADXL345自由落体中断(激活并分配给 INT2)
*/

#include<Wire.h>
#include<ADXL345_WE.h>
#define ADXL345_I2CADDR 0x53

const int int2Pin = 2;
volatile bool freeFall = false;
/* 有几种方法可以创建您的 ADXL345 对象:
   ADXL345_WE myAcc = ADXL345_WE()                -> uses Wire / I2C Address = 0x53
   ADXL345_WE myAcc = ADXL345_WE(ADXL345_I2CADDR) -> uses Wire / ADXL345_I2CADDR
   ADXL345_WE myAcc = ADXL345_WE(&wire2)          -> uses the TwoWire object wire2 / ADXL345_I2CADDR
   ADXL345_WE myAcc = ADXL345_WE(&wire2, ADXL345_I2CADDR) -> all together
*/
ADXL345_WE myAcc = ADXL345_WE(ADXL345_I2CADDR);

void setup() {
  Wire.begin();
  Serial.begin(9600);
  pinMode(int2Pin, INPUT);
  Serial.println("ADXL345_Sketch - ADXL345实验程序 - 自由落体中断");
  Serial.println();
  if (!myAcc.init()) {
    Serial.println("ADXL345 未连接!");
  }
  /* 插入测试的数据并取消注释以获得更精确的结果 */
  myAcc.setCorrFactors(-295.0, 255.0, -283.0, 264.0, -262.0, 265.0);
  myAcc.setDataRate(ADXL345_DATA_RATE_25);
  myAcc.setRange(ADXL345_RANGE_2G);

  /* setFreeFallThresholds函数的参数为​​:
       -g 阈值——不要选择太低的参数。 0.3 - 0.6 克就可以了。
       - 以毫秒为单位的时间阈值,最大值为 1275。推荐为 100 - 350;
      如果时间阈值太低,则可以将振动检测为自由落体。
  */
  myAcc.setFreeFallThresholds(0.4, 100);

  /* 你可以选择以下中断:
       Variable name:             Triggered, if:
      ADXL345_OVERRUN      -   new data replaces unread data
      ADXL345_WATERMARK    -   the number of samples in FIFO equals the number defined in FIFO_CTL
      ADXL345_FREEFALL     -   acceleration values of all axes are below the threshold defined in THRESH_FF
      ADXL345_INACTIVITY   -   acc. value of all included axes are < THRESH_INACT for period > TIME_INACT
      ADXL345_ACTIVITY     -   acc. value of included axes are > THRESH_ACT
      ADXL345_DOUBLE_TAP   -   double tap detected on one incl. axis and various defined conditions are met
      ADXL345_SINGLE_TAP   -   single tap detected on one incl. axis and various defined conditions are met
      ADXL345_DATA_READY   -   new data available
      Assign the interrupts to INT1 (INT_PIN_1) or INT2 (INT_PIN_2). Data ready, watermark and overrun are
      always enabled. You can only change the assignment of these which is INT1 by default.
      You can delete interrupts with deleteInterrupt(type);
  */
  myAcc.setInterrupt(ADXL345_FREEFALL, INT_PIN_2);

  attachInterrupt(digitalPinToInterrupt(int2Pin), freeFallISR, RISING);
  freeFall = false;
}

void loop() {
  xyzFloat raw = myAcc.getRawValues();
  xyzFloat g = myAcc.getGValues();

  Serial.print("Raw-x = ");
  Serial.print(raw.x);
  Serial.print("  |  Raw-y = ");
  Serial.print(raw.y);
  Serial.print("  |  Raw-z = ");
  Serial.println(raw.z);
  Serial.print("g-x   = ");
  Serial.print(g.x);
  Serial.print("  |  g-y   = ");
  Serial.print(g.y);
  Serial.print("  |  g-z   = ");
  Serial.println(g.z);
  Serial.println();

  if (freeFall == true) {
    Serial.println("Aaaaaaaaah!!!!! - 我是 faaaaallllling!");
    delay(1000);
    freeFall = false;
    /* 通过读取中断寄存器清除中断 */
    myAcc.readAndClearInterrupts();

    /* 如果您还期望其他中断,您可以检查类型。对于此评论的上一行,
        并替换为以下四行:*/
    //byte intType = myAcc.readAndClearInterrupts();
    //if(myAcc.checkInterrupt(intType, ADXL345_FREEFALL)){
    //  Serial.println("FREEFALL confirmed");
    //}
  }
  delay(500);
}

void freeFallISR() {
  freeFall = true;
}

实验串口返回情况

 

6.3-61.jpg

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

6.3-62.jpg

程序十七:数据就绪中断在 Arduino 引脚 2 上触发中断(分配给 INT2)
Arduino参考开源代码
 

代码
/*
  【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
  程序十七:数据就绪中断在 Arduino 引脚 2 上触发中断(分配给 INT2)
*/

#include<Wire.h>
#include<ADXL345_WE.h>
#define ADXL345_I2CADDR 0x53
const int int2Pin = 2;  // 中断引脚
volatile bool dataReady = false;
/* 有几种方法可以创建ADXL345对象:
   ADXL345_WE myAcc = ADXL345_WE()                -> uses Wire / I2C Address = 0x53
   ADXL345_WE myAcc = ADXL345_WE(ADXL345_I2CADDR) -> uses Wire / ADXL345_I2CADDR
   ADXL345_WE myAcc = ADXL345_WE(&wire2)          -> uses the TwoWire object wire2 / ADXL345_I2CADDR
   ADXL345_WE myAcc = ADXL345_WE(&wire2, ADXL345_I2CADDR) -> all together
*/
ADXL345_WE myAcc = ADXL345_WE(ADXL345_I2CADDR);

void setup() {
  Wire.begin();
  Serial.begin(9600);
  pinMode(int2Pin, INPUT);
  Serial.println("ADXL345实验程序 - 数据就绪中断");
  Serial.println();
  if (!myAcc.init()) {
    Serial.println("ADXL345 未连接!");
  }
  myAcc.setDataRate(ADXL345_DATA_RATE_0_20);
  myAcc.setRange(ADXL345_RANGE_2G);

  attachInterrupt(digitalPinToInterrupt(int2Pin), dataReadyISR, RISING);
  /* 默认中断引脚极性为高电平有效。如果您愿意,请更改 */
  // myAcc.setInterruptPolarity(ADXL345_ACT_LOW);
  myAcc.setInterrupt(ADXL345_DATA_READY, INT_PIN_2);
}
/* 在以下循环中,INT2 上只能出现一种中断类型。
  如果您期望有更多的候选人,您可以检查如下:
  uint8_t intType = myAcc.readAndClearInterrupts();
  if(myAcc.checkInterrupt(intType, ADXL345_DATA_READY)){
  Serial.println(“DATA READY CONFIRMED”);
        }
*/

void loop() {
  // 你看这里是无延迟控制输出速率
  if (dataReady == true) {
    xyzFloat g = myAcc.getGValues();

    Serial.print("g-x   = ");
    Serial.print(g.x);
    Serial.print("  |  g-y   = ");
    Serial.print(g.y);
    Serial.print("  |  g-z   = ");
    Serial.println(g.z);

    dataReady = false;
  }
}

void dataReadyISR() {
  dataReady = true;
}

实验串口返回情况

 

6.3-64.jpg

Arduino实验场景图

 

6.3-63.jpg

评论

user-avatar
  • hacker_

    hacker_2023.08.12

    666

    0
    icon 他的勋章
      展开更多