【雕爷学编程】Arduino动手做(48)---GY-291 ADXL345 三轴模块6
37款传感器与模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止37种的。鉴于本人手头积累了一些传感器和执行器模块,依照实践出真知(一定要动手做)的理念,以学习和交流为目的,这里准备逐一动手试试多做实验,不管成功与否,都会记录下来——小小的进步或是搞不掂的问题,希望能够抛砖引玉。
【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
实验四十八:GY-291 ADXL345 数字三轴重力加速度倾斜度模块 IIC/SPI传输
【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); }
实验串口返回情况
打开Arduino IDE——工具——串口绘图器,查看实验波形
实验串口绘图器返回情况
【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——工具——串口绘图器,查看实验波形
实验串口绘图器返回情况
实验串口返回情况
【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; }
实验串口返回情况
打开Arduino IDE——工具——串口绘图器,查看实验波形
实验串口绘图器返回情况
程序十七:数据就绪中断在 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; }
实验串口返回情况
Arduino实验场景图