OneNET麒麟座应用开发之五:获取加速度传感器ADXL345数据

由于数据采集站基本都安装在野外或者楼顶,安装位置以及震动对检测数据的准确性有一定影响。所以想要有一个位置状态数据,正好发现麒麟作上有ADXL345,这样一个数字输出的加速度传感器。如图中红框所示:

1ADXL345概述

ADXL345是ADI公司推出的基于iMEMS技术的3轴、数字输出加速度传感器。该加速度传感器的特点如下:

  • 分辨率高。最高13位分辨率。
  • 量程可变。具有+/-2g,+/-4g,+/-8g,+/-16g可变的测量范围。
  • 灵敏度高。最高达3.9mg/LSB,能测量不到1.0°的倾斜角度变化。
  • 功耗低。 40~145uA 的超低功耗,待机模式只有 0.1uA。
  • 尺寸小。整个 IC 尺寸只有 3mm*5mm*1mm, LGA 封装。

ADXL支持标准的I2C或SPI数字接口,自带32级FIFO存储,并且内部有多种运动状态检测和灵活的中断方式等特性。ADXL345传感器的检测轴如下图所示:

当 ADXL345 沿检测轴正向加速时,它对正加速度进行检测。在检测重力时用户需要注意,当检测轴的方向与重力的方向相反时检测到的是正加速度。下图所示为输出响应与相对于重力的方向的关系:

2、硬件设计

ADXL345支持SPI 和I2C两种通信方式,麒麟座采用的I2C通讯方式,具体连接如下图所示:

对于任何不使用的引脚,没有内部上拉或下拉电阻,因此,CS引脚或ALT ADDRESS引脚悬空或不连接时,任何已知状态或默认状态不存在。使用I2C时, CS引脚必须连接至VDD I/O, ALT ADDRESS引脚必须连接至任一VDD I/O或接地。

ALT ADDRESS引脚处于高电平,器件的7位I2C地址是0x1D,随后为R / W位。这转化为0x3A写入,0x3B读取。通过ALT ADDRESS引脚(引脚12)接地,可以选择备用I2C地址0x53(随后为R / W位)。这转化为0xA6写入, 0xA7读取。

由于在麒麟座中,ALT ADDRESS引脚(引脚12)接地,所以地址为0x53,也就是0xA6写入, 0xA7读取。此外2个终端信号也引入了MCU。

3、软件设计

接下来我们开始软件方面的设计。因为麒麟座中ADXL345使用I2C接口与MCU通讯,并连接到了I2C2(PB10、PB11)端口,接下来我们将逐步实现这部分软件。

(1)I2C读写操作

因为ADXL345加速度传感器使用了标准的I2C通讯接口,所以我们来看一看I2C读写单个或多个子解释的报文格式(如下图)。

根据以上报文图示,并结合STM32F1的库函数我们封装读写字节操作的函数。封装发送命令和获取数据函数:

/*向ADXL345下发指令,指令格式均为1个字节*/

void WriteByteToADXL345(I2C_TypeDef* I2Cx,uint8_t deviceAddress,uint8_t command)

{

  uint16_t i2cTimeout=TimeoutPeriod;

  /*产生I2C起始信号*/

  I2C_GenerateSTART(I2C2, ENABLE);

  /*检测 EV5 事件并清除标志*/

  while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT))

  {

    if ((i2cTimeout--) == 0) return ;

  }

  /*发送ADXL345的地址*/

  I2C_Send7bitAddress(I2Cx,deviceAddress,I2C_Direction_Transmitter);

  i2cTimeout=TimeoutPeriod;

  /*检测 EV6 事件并清除标志*/

  while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))

  {

    if ((i2cTimeout--) == 0) return ;

  }

  /*下发操作命令*/

  I2C_SendData(I2Cx, command);

  i2cTimeout=TimeoutPeriod;

  /*检测 EV8 事件并清除标志*/

  while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED))

  {

    if ((i2cTimeout--) == 0) return ;

  }

  /* 产生I2C停止信号 */

  I2C_GenerateSTOP(I2Cx, ENABLE);

}

/*从ADXL345读取多个字节数据的值*/

void ReadBytesFromADXL345(I2C_TypeDef* I2Cx,uint8_t deviceAddress,uint8_t *pData,uint16_t bytesNum)

{

  uint16_t i2cTimeout=TimeoutPeriod;

  /*如果I2C总线忙,则等待一段时间*/

  while (I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY))

  {

    if ((i2cTimeout--) == 0) return ;

  }

  /* 产生 I2C 起始信号 */

  I2C_GenerateSTART(I2Cx, ENABLE);

  /*检测 EV5 事件并清除标志*/

  while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT))

  {

    if ((i2cTimeout--) == 0) return ;

  }

  /*发送ADXL345的地址*/

  I2C_Send7bitAddress(I2Cx,deviceAddress,I2C_Direction_Receiver);

  i2cTimeout=TimeoutPeriod;

  /*检测 EV6 事件并清除标志*/

  while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))

  {

    if ((i2cTimeout--) == 0) return ;

  }

  while(bytesNum)

  {

    if(bytesNum==1)

    {

      I2C_AcknowledgeConfig(I2Cx, DISABLE);//关闭应答

      I2C_GenerateSTOP(I2Cx, ENABLE);//停止信号

    }

    i2cTimeout=TimeoutPeriod;

    /*检测 EV7 事件并清除标志*/

    while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED))

    {

      if ((i2cTimeout--) == 0) return ;

    }

    /*通过 I2C,从设备中读取一个字节的数据 */

    *pData=I2C_ReceiveData(I2Cx);

    pData++;

    bytesNum--;

  }

  /*使能应答,方便下一次 I2C 传输*/

  I2C_AcknowledgeConfig(I2Cx, ENABLE);

}

2ADXL寄存器及操作

ADXL345传感器拥有29个用户可见的寄存器,如下图所示。但是我们不对其进行具体的介绍,在数据手册上有非常详细的说明。这些寄存器我们并不会全部使用,事实上通常我们只是用配置寄存器和部分数据寄存器。

在使用ADXL345读取我们想要的数居前,我们先使用相关寄存器对传感器进行必要的配置,以期获取我们想要得到的值。如下初始化配置过程:

void ADXL345_Init_Configuration(void)
{
    uint8_t devid = 0, val = 0;

    Delayus (300);

    ReadByteFromADXL345 (ADXL345_ADDRESS, 0x00, &devid);                //获取设备ID

       Delayus (300);

       val = 0x2B;

   WriteByteToADXL345 (ADXL345_ADDRESS, DATA_FORMAT_REG, &val);   //数据格式控制

       Delayus(50);

       val = 0x0A;

   WriteByteToADXL345 (ADXL345_ADDRESS, BW_RATE, &val);                //数据速率及功率模式控制

       Delayus(50);

       val = 0x28;

   WriteByteToADXL345 (ADXL345_ADDRESS, POWER_CTL, &val);           //上电特性控制

       Delayus(50);

       val = 0;

    WriteByteToADXL345 (ADXL345_ADDRESS, INT_ENABLE, &val);        //中断使能控制

       Delayus(50);

    WriteByteToADXL345 (ADXL345_ADDRESS, OFSX, &val);                      //X轴偏移

       Delayus(50);

    WriteByteToADXL345 (ADXL345_ADDRESS, OFSY, &val);                       //Y轴偏移

       Delayus(50);

    WriteByteToADXL345 (ADXL345_ADDRESS, OFSZ, &val);                       //Z轴偏移

       Delayus(500);
}

(3)ADXL345数据获取

接下来我们就可以读取数据了,获取和解析数据前我们先来了解一下数据的格式。分别在寄存器0x2C中进行速率控制,在寄存器0x31中进行数据格式控制。ADXL345的输出数据可以采用右对齐和左对齐两种方式。

数据右对齐方式:

数据左对齐方式:

此外,ADXL345通过VS = 2.5 V电源电压的测试且以其为额定电压;然而, VS可高至3.6 V或低至2.0 V。在麒麟座中解释使用的3.3VDC供源,偏移、灵敏度、噪声、自测和电源电流等参数随着电源电压变化而变化。随着电源电压的改变,静电力也发生细微变化,因此,偏移和灵敏度也有细微变化。在电源电压VS = 3.3 V下运行时, x轴和y轴偏移通常比VS = 2.5 V运行时高25 mg。在电源电压3.3 V下运行与在VS = 2.5V时比较, z轴偏移一般低20 mg。VS = 2.5V时, x轴和y轴的灵敏度为标称256 LSB/g(全分辨率或±2 g, 10位运行),而电源电压为3.3 V时,其灵敏度转换为265 LSB/g。 z轴灵敏度不受电源电压影响, 2.5 V时或3.3 V时都相同。可以用简单的线性插值来确定其他电源电压下的偏移和灵敏度的典型转换。

搞清楚了以上问题就可以读取正确的数据了:

void GetValue FromADXL345 (void)
{
      unsigned char devid = 0;
      unsigned char dataTemp[6];

    Delayus(200);

    ReadByteFromADXL345(ADXL345_ADDRESS, 0x00, &devid);                                     //读取设备ID

      Delayus(200);

      ReadBytes FromADXL345 (ADXL345_ADDRESS, 0x32, dataTemp, 6);                                   //获取原始数据(4mg/LSB)

      adxlInfo.incidence_X = (short)(dataTemp[0] + ((unsigned short)dataTemp[1] << 8));

    adxlInfo.incidence_Y = (short)(dataTemp[2] + ((unsigned short)dataTemp[3] << 8));

    adxlInfo.incidence_Z = (short)(dataTemp[4] + ((unsigned short)dataTemp[5] << 8));

      adxlInfo.incidence_Xf = (float)adxlInfo.incidence_X * 0.0039;          //换算为物理量值

      adxlInfo.incidence_Yf = (float)adxlInfo.incidence_Y * 0.0039;          //换算为物理量值

      adxlInfo.incidence_Zf = (float)adxlInfo.incidence_Z * 0.0039;           //换算为物理量值
}

至此软件编写完成。

4、结果验证

完成编写后,编译无误。我们查看最终的运行结果如何。首先我们登录到OneNET,并组态好设备和应用,然后下载程序重新上电,就可以看到Xg、Yg、Zg的数据以及上次我们读取的温湿度数据:

我们再看一下显示屏中显示的数据是什么样的。因显示精度不同有些差异,但基本是一致的。

至此,我们完成了ADXL345数据的获取以及上传到OneNET,在后续我们将继续各种OneNET以及麒麟座开发板的研究。OneNET真的是越用越有意思。

时间: 2024-10-10 12:14:32

OneNET麒麟座应用开发之五:获取加速度传感器ADXL345数据的相关文章

OneNET麒麟座应用开发之八:采集大气压力等环境参数

采集大气压力和温度也是核算大气标准状况下的各种数据的必须参数,为此我们必须知道压力和温度才能计算标准状况下的各种参数,于此我们需要一个既能检测压力也能检测温度的元件. 1.硬件概述 MS5837压力传感器是一种可用于电路板上,适用于检测10-1200mbar压力范围的传感器,灵敏度非常高,理论上能够检测到0.01mbar的压力变化,实际使用过程中测试并无明显的变化. (1)硬件连接 MS5837采用I2C总线通讯,与STM32的MCU可以实现I2C通讯.硬件连接方式如下: 我们发现OneNET麒

OneNET麒麟座应用开发之七:控制采样电机

气体采样采用主动抽取气体的方式保证充足而平稳的气流,所以我们采用气泵抽取气体来完成. 1.设计概述 客户对这部分要求能够设定电机的速度,但并不需要动态调节.对电机的控制有很多方式,我们采用比较简单的方式.我们采用定时器产生PWM舶来实现这一控制过程. 2.硬件连接 对电机的控制我们使用高级定时器TIM1产生PWM波来控制,对于OneNET麒麟座中TIM1的通道1.2.3以及他们的互补输出均已经引到了端子排J2-5(PA10).2-6(PA9).J2-7(PA8).J5-7(PA7).J3-2(P

OneNET麒麟座应用开发之十:空气质量数据监测站项目总结

大气质量数据监测站用于测试空气质量监测及数据采集,实现野外或者室内空气质量的检测. 1.项目概述 本项目是一个定制项目,要求采集大气的压力.温度.湿度.PM25.位置等数据并上传到指定的后台服务器.但有时候因为没有条件或因为各种原因不能联网,则采用本地保存的方式,本地保存我们决定使用SD卡来实现.除此外,为了实现显式需求,还需要配套一些东西来实现饮食的需求,如实时时钟记录,上传联网方式的选择等. 2.硬件设计 本项目涉及到的硬件并不复杂,我们对其中几个实用比较多的电路做一个说明.首先说一下串口通

Android加速度传感器

Android加速度传感器 效果图 手机平放桌面的两张截屏,数据一直在刷新 源码 下载地址(Android Studio工程):http://download.csdn.net/detail/q4878802/9065313 步骤 传感器使用步骤之前已经介绍过,地址:http://blog.csdn.net/q4878802/article/details/48112477 代码 package com.example.kongqw.kqwsensorforaccelerometerdemo;

玩转Android之加速度传感器的使用,模仿微信摇一摇

Android系统带的传感器有很多种,最常见的莫过于微信的摇一摇了,那么今天我们就来看看Anroid中传感器的使用,做一个类似于微信摇一摇的效果. OK ,废话不多说,我们就先来看看效果图吧: 当我摇动手机的时候这里的动画效果基本和微信上的动画效果一致,这里请大家自行脑补微信摇一摇画面. 那我们就动手吧. 1.布局文件 好,那我们先来看看布局文件吧,在布局文件的正中央是一个花的图片,上图大家看到的手机图片实际上是两张图片拼接在一起,将花的那张图片遮住了,当摇一摇的时候,这两张图片分别向上或者向下

OneNET麒麟座应用开发之二:串口读取PM25传感器数据

作为环境数据监测站首先要获取大气中可吸入颗粒物的数据.为了检测PM25数据,我们采用北京海联信为的HLPM025K3型号传感器,该传感器使用激光法测量PM25和PM10的数据. 该型传感器的检测对象如下: M2.5:测量空气中0.3-2.5微米颗粒物: PM10:测量空气中 0.3-10微米颗粒物. 该传感器采用的通讯协议如下: (1)波特率: 9600bit/S;数据位:8位;停止位:1位;校验位:无; (2)数据发送间隔时间为0.8-1.2S(秒) , (3)数据格式:7个字节,其中校验位=

六轴加速度传感器MPU6050官方DMP库到瑞萨RL78/G13的移植

2015年的电赛已经结束了.赛前接到器件清单的时候,看到带防护圈的多旋翼飞行器赫然在列,又给了一个瑞萨RL78/G13的MCU,于是自然联想到13年的电赛,觉得多半是拿RL78/G13做四旋翼的主控,虽然事后证实我的猜测是错的,但是在赛前我还是完成了相关代码的准备,这其中就包括了MPU6050的DMP库移植.在移植前我大概搜了一下,发现网上还没有相关的源代码.一起准备电赛的同学还买过一份RL78/G13的飞控代码,虽然也是使用MPU6050进行姿态获取,但是对MPU6050的读取并不是通过DMP

Android开发:Android设备传感器开发总结

本文中,笔者给大家分享一下Android中如何进行Android设备传感器开发. 转载请注明作者xiong_it和链接:http://blog.csdn.net/xiong_it/article/details/45917009 Android传感器开发基本流程 public class SensorActivity extends Activity implements SensorEventListener { private SensorManager mSensorManager; pr

博世传感器调试笔记(一)----加速度传感器BMA253

公司是bosch的代理商,最近一段时间一直在公司开发的传感器demo板上调试bosch sensor器件.涉及到的器件有7,8款,类型包括重力加速度.地磁.陀螺仪.温度.湿度.大气压力传感器等.在调试的过程中做了一些笔记,在此将其简单分享出来. BMA253是3轴12 bit加速度传感器,支持I2C/SPI两种通讯方式,其i2c设备地址0x18. 关键寄存器R0:CHIPID register ,值为 0xfa X轴加速度数据12bitr0x02:ACCD_X_LSB acc_x_lsb[3:0