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

1、ADXL345概述
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--) == ) return ;
}
/*发送ADXL345的地址*/
I2C_Send7bitAddress(I2Cx,deviceAddress,I2C_Direction_Transmitter);
i2cTimeout=TimeoutPeriod;
/*检测 EV6 事件并清除标志*/
while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
{
if ((i2cTimeout--) == ) return ;
}
/*下发操作命令*/
I2C_SendData(I2Cx, command);
i2cTimeout=TimeoutPeriod;
/*检测 EV8 事件并清除标志*/
while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
{
if ((i2cTimeout--) == ) 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--) == ) return ;
}
/* 产生 I2C 起始信号 */
I2C_GenerateSTART(I2Cx, ENABLE);
/*检测 EV5 事件并清除标志*/
while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT))
{
if ((i2cTimeout--) == ) return ;
}
/*发送ADXL345的地址*/
I2C_Send7bitAddress(I2Cx,deviceAddress,I2C_Direction_Receiver);
i2cTimeout=TimeoutPeriod;
/*检测 EV6 事件并清除标志*/
while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))
{
if ((i2cTimeout--) == ) return ;
}
while(bytesNum)
{
if(bytesNum==)
{
I2C_AcknowledgeConfig(I2Cx, DISABLE);//关闭应答
I2C_GenerateSTOP(I2Cx, ENABLE);//停止信号
}
i2cTimeout=TimeoutPeriod;
/*检测 EV7 事件并清除标志*/
while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED))
{
if ((i2cTimeout--) == ) return ;
}
/*通过 I2C,从设备中读取一个字节的数据 */
*pData=I2C_ReceiveData(I2Cx);
pData++;
bytesNum--;
}
/*使能应答,方便下一次 I2C 传输*/
I2C_AcknowledgeConfig(I2Cx, ENABLE);
}
(2)ADXL寄存器及操作
ADXL345传感器拥有29个用户可见的寄存器,如下图所示。但是我们不对其进行具体的介绍,在数据手册上有非常详细的说明。这些寄存器我们并不会全部使用,事实上通常我们只是用配置寄存器和部分数据寄存器。

在使用ADXL345读取我们想要的数居前,我们先使用相关寄存器对传感器进行必要的配置,以期获取我们想要得到的值。如下初始化配置过程:
void ADXL345_Init_Configuration(void)
{
uint8_t devid = , val = ; Delayus (); ReadByteFromADXL345 (ADXL345_ADDRESS, 0x00, &devid); //获取设备ID Delayus (); val = 0x2B; WriteByteToADXL345 (ADXL345_ADDRESS, DATA_FORMAT_REG, &val); //数据格式控制 Delayus(); val = 0x0A; WriteByteToADXL345 (ADXL345_ADDRESS, BW_RATE, &val); //数据速率及功率模式控制 Delayus(); val = 0x28; WriteByteToADXL345 (ADXL345_ADDRESS, POWER_CTL, &val); //上电特性控制 Delayus(); val = ; WriteByteToADXL345 (ADXL345_ADDRESS, INT_ENABLE, &val); //中断使能控制 Delayus(); WriteByteToADXL345 (ADXL345_ADDRESS, OFSX, &val); //X轴偏移 Delayus(); WriteByteToADXL345 (ADXL345_ADDRESS, OFSY, &val); //Y轴偏移 Delayus(); WriteByteToADXL345 (ADXL345_ADDRESS, OFSZ, &val); //Z轴偏移 Delayus();
}
(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 = ;
unsigned char dataTemp[]; Delayus(); ReadByteFromADXL345(ADXL345_ADDRESS, 0x00, &devid); //读取设备ID Delayus(); ReadBytes FromADXL345 (ADXL345_ADDRESS, 0x32, dataTemp, ); //获取原始数据(4mg/LSB) adxlInfo.incidence_X = (short)(dataTemp[] + ((unsigned short)dataTemp[] << )); adxlInfo.incidence_Y = (short)(dataTemp[] + ((unsigned short)dataTemp[] << )); adxlInfo.incidence_Z = (short)(dataTemp[] + ((unsigned short)dataTemp[] << )); 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真的是越用越有意思。
OneNET麒麟座应用开发之五:获取加速度传感器ADXL345数据的更多相关文章
- OneNET麒麟座应用开发之四:数据上传测试
已经测试过OneNET麒麟座开发板了,这次来尝试与OneNET的连接和数据上传.这也是我们测试这块开发办的主要原因,因为在十几种我们有这种将分散的采集点数据上传到后台的需求. 先看看麒麟座这块开发板, ...
- OneNET麒麟座应用开发之八:采集大气压力等环境参数
采集大气压力和温度也是核算大气标准状况下的各种数据的必须参数,为此我们必须知道压力和温度才能计算标准状况下的各种参数,于此我们需要一个既能检测压力也能检测温度的元件. 1.硬件概述 MS5837压力传 ...
- OneNET麒麟座应用开发之六:与气体质量流量控制器通讯
气体质量流量控制器,简称MFC,通常用于在各种检测中,计量气体的流量.在我们的大气环境数据采集站中,要让气流保持稳定,这样才能准确的获取PM25的数据. 我们采用的气体质量流量控制器具备串口通讯功能, ...
- OneNET麒麟座应用开发之一:初识OneNET麒麟座
今天收到了OneNET麒麟座开发板.能得到使用的机会只能说是幸运的.首先上一张靓照: 板子使用的MCU是STM32F103RET6,带有GSM摸块和Wifi摸块可以联网.带有显示屏接口和I2C接口以及 ...
- 实践案例丨利用小熊派开发板获取土壤湿度传感器的ADC值
摘要:一文带你用小熊派开发板动手做土壤湿度传感器. 一.实验准备 1.实验环境 一块stm32开发板(推荐使用小熊派),以及数据线 已经安装STM32CubeMX 已经安装KeilMDK,并导入stm ...
- OneNET麒麟座应用开发之七:控制采样电机
气体采样采用主动抽取气体的方式保证充足而平稳的气流,所以我们采用气泵抽取气体来完成. 1.设计概述 客户对这部分要求能够设定电机的速度,但并不需要动态调节.对电机的控制有很多方式,我们采用比较简单的方 ...
- OneNET麒麟座应用开发之三:获取温湿度数据
对于大气环境监测来说温湿度也是重要的指标.原本计划使用SHT15来采集温湿度数据,不过在OneNET麒麟开发板上,我们发现已经集成有SHT20温湿度传感器,于是我们就使用它了.如下图的红框处: 我们还 ...
- OneNET麒麟座应用开发之十:空气质量数据监测站项目总结
大气质量数据监测站用于测试空气质量监测及数据采集,实现野外或者室内空气质量的检测. 1.项目概述 本项目是一个定制项目,要求采集大气的压力.温度.湿度.PM25.位置等数据并上传到指定的后台服务器.但 ...
- 微信小程序云开发-数据库-获取用户添加的数据到数据库
一.列表页面新增[添加商品]按钮 在列表页增加[添加商品]按钮,按钮绑定事件toAdd(),用户点击该按钮跳转到添加商品页面. 在js文件中写toAdd()函数,作用是点击[添加商品]按钮,跳转到[添 ...
随机推荐
- 外显子分析弹错解决方案:Invalid command line: Cannot process the provided BAM/CRAM file(s) because they were not indexed.
出现这种问题说明bam/cram文件没有进行index. Samtool能解决这个问题,以bam文件为例,输入以下命令行即可解决问题: /path/to/your/samtools index fil ...
- JavaSE学习总结(四)——Java面向对象十分钟入门
面向对象编程(Object Oriented Programming,OOP)是一种计算机模拟人类的自然思维方式的编程架构技术,解决了传统结构化开发方法中客观世界描述工具与软件结构的不一致性问题.Ja ...
- centos7环境下开启指定端口
参考原博:https://www.cnblogs.com/eaglezb/p/6073739.html 查看已经开放的端口: firewall-cmd --list-ports 开启端口 firewa ...
- 常用的一些js方法
<input type="text" name="number" onkeyup="floatNum(this)"/> // 数 ...
- POJ 2127 Greatest Common Increasing Subsequence
You are given two sequences of integer numbers. Write a program to determine their common increasing ...
- android measure的时候报空指针
1.使用listview的时候,在代码中动态设置其高度,在android低版本中,这个低版本是以4.4为界,会报measure的空指针,原因是低版本relativelayout有个bug,使用list ...
- 一个简单的使用Quartz和Oozie调度作业给大数据计算平台执行
一,介绍 Oozie是一个基于Hadoop的工作流调度器,它可以通过Oozie Client 以编程的形式提交不同类型的作业,如MapReduce作业和Spark作业给底层的计算平台(如 Cloude ...
- 【洛谷P1896【SCOI2005】】互不侵犯King
题目描述 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子. 输入输出格式 输入格式: 只有一行,包 ...
- “微信小程序商城构建全栈应用”开发小记
注意事项: 1.application\api\extra下的wx.php记得填写小程序的app_id.app_secret: 2.API测试小工具需要APPID:
- Web前端的缓存机制(那些以代价换来的效率)
对于Web前端而言,cache可以说是无处不在,通常是2个环节之间,就会引入一个cache做为提升整体效率的角色.例如A和B两者之间的数据交换,为了提升整体的效率,引入角色C,而C被用于当做热点数据的 ...