佳工机电网 在线工博会 注册 登录 手机版 English | 关于我们 联系我们
关键字  
  选择展区 >>
您的位置: 首页 > 电子/通讯/办公文具展区 > 电子产品展厅 > 产品库 > 平板电脑 > 技术论文 > 正文 产品库 会展 人才 帮助 | 注册 登录  
电子产品
 按行业筛选
 按产品筛选
查看本类全部文章

e展厅 产品库 最新动态 技术文章 企业目录 资料下载 视频/样本 反馈/论坛
  技术应用 | 基础知识 | 外刊文摘 | 业内专家 | 文章点评 投稿 发表科技文章 
在Android的驱动程序中对加速度传感器的数据进行方向和坐标的转换
作者:陈刚
欢迎访问e展厅
展厅
1
电子产品展厅
平板电脑, 电子书阅读器, 笔记本电脑, IC卡设备, GPS/卫星导航系统, ...
摘要:Android 是面向智能手机和其他便携式设备的最受欢迎的操作系统(OS)之一。它为多种传感器提供了标准的API 接口,包括加速度计。加速度计的标准API 定义了原始加速度数据的坐标系统。用户必须将从传感器中读取的原始数据转换为标准单位,并使其符合系统定义的坐标方向。本文介绍了Android 中的坐标系统是如何定义的,以及如何在Android 系统的驱动代码中对3 轴加速度计数据的方向和坐标进行转换。本文讨论的示例代码基于飞思卡尔的Android 2.2 和2.3 驱动程序,加速度计则以飞思卡尔的MMA8452Q 加速度传感器为例。
关键词:加速度计,传感器驱动,Android

一部智能手机或便携设备应具有Wi-Fi 和互联网功能,能够运行应用软件等诸多特征,而且一定会具有内置传感器。高端智能手机可能集成接近传感器,环境光传感器,3 轴加速度计,以及磁力计等多种传感器。 Android 2.3 添加了一些支持多种新型传感器的API,包括陀螺仪、旋转向量、线性加速度、重力和气压传感器等。应用软件可以使用这些新型传感器,将它们组合起来,就可以实现高精确度的高级运动检测功能。

3 轴加速度计或低g 值传感器是Android API 支持的传感器之一,具有特定的坐标系统,可以给应用程序提供标准的接口数据。坐标空间的定义与手机屏幕的默认方向有关,如图1所示。

newmaker.com
图 1. 3 轴加速度计的Android 坐标系统

在Android 坐标系统中,坐标原点位于屏幕的左下角,X 轴水平指向右侧,Y 轴垂直指向顶部,Z 轴指向屏幕前方。在该系统中,屏幕后方的坐标具有负的Z 轴值。Android 加速度计数据定义为:

Sensor.TYPE_ACCELEROMETER

所有数值都采用SI 标准单位(m/s2),测量手机的加速度值,并减去重力加速度分量。

values[0]:x 轴上的加速度值减去Gx
values[1]:y 轴上的加速度值减去Gy
values[2]:z 轴上的加速度值减去Gz

例如,当设备平放在桌上并推着其左侧向右移动时,x 轴加速度值为正。当设备平放在桌上时,加速度值为+9.81,这是用设备的加速度值 (0 m/s2) 减去重力加速度值 (-9.81 m/s2)得到的。

当设备平放在桌上放,并以加速度A m/s2 朝天空的方向推动时,加速度值等于A+9.81,这是用设备加速度值(+A m/s2)减去重力加速度值(-9.81 m/s2)得到的。

表 1 列出了与设备的各个位置相对应的传感器的加速度值读数。用户可以用下表检查加速度计的方向与系统坐标是否一致。

表 1. 不同位置上各轴的加速度值
newmaker.com

通过加速度传感器读取3 轴加速度值时,需要假设传感器的3 轴方向与系统坐标是一致的。但是在实际的产品中,可能会使用不同的传感器芯片,或者采用不同的安装方向,因此数据方向也会不同。图2 所示的是飞思卡尔MMA8452Q 3 轴加速度传感器的方向定义。

newmaker.com
图 2. MMA8452Q 的方向定义

在图 2 中,我们可以看到当安装芯片时,必须让引脚1 处于右下角的位置(PD),并安装在PCB 的前方,这样才能与Android 坐标系统的默认位置相符。这样安装后,用户可确定数据方向与系统坐标定义是一致的。在任何其他情形下,数据都无法与系统定义保持完全一致,所以需要更改数据方向和坐标。在某些情况下,X 和Y 轴必须交换,或者既要改变方向,也要交换X-Y 轴。

判断是否需要改变方向或交换X-Y 轴的方法如下所述:

1. 将设备放置在朝上(UP)的位置,如表1 中所示。

2. 从传感器中读取3 轴的数据。如果Y 轴上的数据为 ±1 g (±9.81m/s2),其他两个轴上的数据大约为0,则不需要交换X-Y 轴。否则,需要交换X 和Y 轴,请转至步骤3。

2.1. 在该位置上,如果Y 轴上读取的数据为+1 g (+9.81m/s2),则Y 轴的方向不需要改变,如果数据为负,则Y 轴的方向需要改变。

2.2. 将设备放置在朝左(LEFT)的位置,如表1 中所示。X 轴上读取的数据应为±1g (±9.81m/s2),其他两个轴上的数据应大约为0。如果X 轴上的数据为正,则其方向不需要改变;否则X 轴的方向需要改变。然后,执行第4 步判断Z 轴的方向。

3. 设备仍然放置在朝上(UP)的位置,并从传感器中读取3 个轴的数据。此时X 轴上的数据应为 ±1 g (±9.81m/s2),其他两个轴上的数据大约为0,需要X-Y 交换。

3.1. 在该位置上,如果X 轴的数据读取为+1 g (+9.81m/s2),则X 轴的方向不需要改变;否则需要改变。
3.2. 将设备放置在向左(LEFT)位置上,如表1 中所示。Y 轴上读取的数据应为±1g (±9.81m/s2),其他两个轴上的数据应大约为0。如果Y 轴上的数据为正,则其方向不需要改变;否则需要改变。然后执行第4 步判断Z 轴的方向。

4. 将设备放置在正面朝上(FRONT-UP)的位置,并从传感器中读取3 轴数据。如果 Z轴上的数据为+1 g (+9.81m/s2),其他两个轴上的数据大约为0,则Z 轴方向无需改变;如果Z 轴数据为-1 g (-9.81m/s2),则Z 轴方向需要改变。

在 Android 系统中,传感器数据由内核空间中的Linux 驱动读取,然后由HAL 层驱动发送至API。分层结构如图3 所示。因此,传感器数据可以在Linux 驱动层或在HAL 层上进行转换。

newmaker.com
图 3. Android 驱动架构

在 Android HAL 文件中改变 X、Y 和Z 轴的方向

在 HAL 文件中,会有一组宏定义,用于把从传感器中读取的加速度数据转换为标准单位(m/s2)。如以下代码:

// conversion of acceleration data to SI units (m/s^2)
#define CONVERT_A (GRAVITY_EARTH / LSG)
#define CONVERT_A_X (-CONVERT_A)
#define CONVERT_A_Y (CONVERT_A)
#define CONVERT_A_Z (CONVERT_A)

在这个宏定义中,常量GRAVITY_EARTH 是一个标准重力加速度值,即9.81m/s2,LSG为一个重力加速度值的最小有效计数值,例如,MMA8452 在正常模式下的读数为1024。因此,CONVERT_A 用于把从加速度传感器中读取的数据,从数字读数转换为标准重力加速度单位。

通过分别修改CONVERT_A_X、CONVERT_A_Y 和CONVERT_A_Z,我们可以轻松地改变X、Y 和Z 轴的方向。如果该轴的方向与系统定义相反,可以使用(-CONVERT_A)来改变其方向。如果方向一致,就使用(CONVERT_A),则保持方向不变。

这个宏定义位于FSL Android 9 (Android 2.2)驱动程序的HAL文件sensor.c 中。对于FSLAndroid 10 (Android 2.3),您可以在’libsensors’文件夹的HAL 文件Sensor.h 中找到它。

在 Android 2.2 HAL 文件中交换X 轴和Y 轴

在某些情况下,X 和Y 轴必须进行交换,以便使传感器数据的坐标与系统坐标保持一致。

对于 FSL Android 9 (Android 2.2)驱动程序来说,X 轴和Y 轴的交换非常简单。首先,在HAL 文件sensor.c 中,在函数sensor_poll() 中找到以下代码:

switch (event.code) {
case ABS_X:
sSensors.acceleration.x = event.value * CONVERT_A_X;
break;
case ABS_Y:
sSensors.acceleration.y = event.value * CONVERT_A_Y;
break;
case ABS_Z:
sSensors.acceleration.z = event.value * CONVERT_A_Z;
break;
}

然后,根据如下所示修改代码:

switch (event.code) {
case ABS_X:
sSensors.acceleration.y = event.value * CONVERT_A_Y;
break;
case ABS_Y:
sSensors.acceleration.x = event.value * CONVERT_A_X;
break;
case ABS_Z:
sSensors.acceleration.z = event.value * CONVERT_A_Z;
break;
}

在 Android 2.3 的HAL 文件中交换X 轴和Y 轴

在 Android 2.3 的HAL 文件中交换X 轴和Y 轴会更加复杂些,因为它具有更复杂的HAL文件结构。所有HAL 文件都位于文件夹‘libsensors’中。文件AccelSensor.cpp 中的两个函数需要修改。

首先,修改函数AccelSensor()的代码,如下所示:

if (accel_is_sensor_enabled(SENSOR_TYPE_ACCELEROMETER)) {
mEnabled |= 1<if (!ioctl(data_fd, EVIOCGABS(EVENT_TYPE_ACCEL_X), &absinfo)) {
mPendingEvents[Accelerometer].acceleration.y = absinfo.value * CONVERT_A_Y;
}
if (!ioctl(data_fd, EVIOCGABS(EVENT_TYPE_ACCEL_Y), &absinfo)) {
mPendingEvents[Accelerometer].acceleration.x = absinfo.value * CONVERT_A_X;
}
if (!ioctl(data_fd, EVIOCGABS(EVENT_TYPE_ACCEL_Z), &absinfo)) {
mPendingEvents[Accelerometer].acceleration.z = absinfo.value * CONVERT_A_Z;
}
}

然后,修改函数processEvent()的代码,如下所示:

void AccelSensor::processEvent(int code, int value)
{
switch (code) {
case EVENT_TYPE_ACCEL_X:
mPendingMask |= 1<mPendingEvents[Accelerometer].acceleration.y = value * CONVERT_A_Y;
break;
case EVENT_TYPE_ACCEL_Y:
mPendingMask |= 1<mPendingEvents[Accelerometer].acceleration.x = value * CONVERT_A_X;
break;
case EVENT_TYPE_ACCEL_Z:
mPendingMask |= 1<mPendingEvents[Accelerometer].acceleration.z = value * CONVERT_A_Z;
break;
}
}

完成后,X 轴和Y 轴的数据就互相交换了。

在 Kernel 驱动文件中交换X 轴和Y 轴

X 轴和Y 轴的数据交换可以在底层的Linux 驱动中,在刚开始读取传感器数据时实施。通过这种方法,无论传感器芯片以何种方式安装在PCB 中,或者使用各种不同类型的传感器,HAL 文件都可以保持一致。

对于 Android 2.2 和2.3 来说,执行该操作的最便捷的方式是修改函数report_abs()中的代码。在该函数中,传感器数据通过调用函数mma8452_read_data()读取,如下所示(当使用的传感器为MMA8452Q 时):

if (mma8452_read_data(&x,&y,&z) != 0) {
//DBG("mma8452 data read failed\n");
return; }

X 轴和Y 轴可以通过以下方式轻松交换:

if (mma8452_read_data(&y,&x,&z) != 0) {
//DBG("mma8452 data read failed\n");
return; }

对于 Android 2.2,MMA8452 的Kernel 驱动文件为mma8452.c;对于Android 2.3,驱动文件是‘hwmon’文件夹中的mxc_mma8452.c。

在 Kernel 驱动文件中改变 X、Y 和Z 轴的方向

传感器数据的方向也可以在Kernel 驱动文件中更改。以下带有注释的语句可以添加到函数report_abs()中,从而改变数据方向:

if (mma8452_read_data(&y,&x,&z) != 0) {
//DBG("mma8452 data read failed\n");
return;
}
x *= -1; //Reverse X direction
y *= -1; //Reverse Y direction
z *= -1; //Reverse Z direction
input_report_abs(mma8452_idev->input, ABS_X, x);
input_report_abs(mma8452_idev->input, ABS_Y, y);
input_report_abs(mma8452_idev->input, ABS_Z, z);
input_sync(mma8452_idev->input);

总结

Android 系统已经为加速度计定义了坐标系统,因此用户必须转换从实际传感器中读取的数据,从而与其保持一致。无论是否需要转换,都应检查X、Y 和Z 轴的方向以及X-Y轴坐标。我们可以更改HAL 文件或Kernel 驱动文件来改变轴的方向,或交换X 和Y 轴,但是不要同时修改HAL 文件和Kernel 驱动。

参考资料
1. Android Coordinate System
http://developer.android.com/reference/android/hardware/SensorEvent.html
2. Reference Code and User’s Guide on ‘Android MMA8452.tar.gz’.
3. Reference Code and User’s Guide on ‘mma8452_imx51_android10_v100.tar.gz’.
4. Datasheet ‘MMA8452Q.pdf’.(end)
文章内容仅供参考 (投稿) (如果您是本文作者,请点击此处) (9/20/2012)
查看更多平板电脑相关文章: more
·简单手势唤醒便携设备的设计思路及其代码 Ilya Veygman (6/28/2012)
·电容式触摸实现新一代平板电脑运算 爱特梅尔 Binay Bajaj (5/1/2012)
·如何真正确保Android设备安全性无虞? Chris Buerger,Wind River (4/24/2012)
·平板需要正确的用户界面才能走向成功 Denis Margolin (4/9/2012)
·针对平板电脑的可重复使用的音频 newmaker (10/22/2011)
·移动MIMO:针对平板电脑和超级手机的颠覆性技术 Bart Giordano (8/20/2011)
·如何保障Android开放环境的安全性 中道 理 (8/2/2011)
·iPad2加速医疗设备诊断级产品便携化 newmaker (7/22/2011)
·百佳泰测试报告 - 平板装置音质表现大比拼 Allion Test Labs, Inc (7/19/2011)
·CIO故事:当CEO要送给所有员工iPad newmaker (5/20/2011)
查看更多电子产品相关文章: more
·USB 3.0实测评鉴与报告:快速领略问题症结与解决方案 百佳泰Allion Labs, Inc (8/7/2012)
·浅析电子产品的调试工艺管理 满新丽 (7/23/2012)
·在系统设计中添加“黑盒子”故障记录议 newmaker (7/5/2012)
·简单手势唤醒便携设备的设计思路及其代码 Ilya Veygman (6/28/2012)
·远程医疗选择PAN或WAN接口的度量标准 Iboun Taimiya Sylla (6/23/2012)
·EMI通过介质干扰电路的途径 德州仪器 (TI) Bonnie C. Baker (6/5/2012)
·EMI的来源及其造成的干扰 德州仪器 Bonnie C. Baker (5/30/2012)
·ZigBee和Z-Wave的区别与未来 newmaker (5/21/2012)
·“嵌入式视觉”的处理技术选择 Jeff Bier (5/18/2012)
·Molex采用激光直接成型(LDS)技术的天线 newmaker (5/3/2012)
查看相关文章目录:
·电子/通讯/办公文具展区 > 电子产品展厅 > 平板电脑 > 电子产品文章
·电子/通讯/办公文具展区 > 手机/通信/网络设备展厅 > 手机 > 手机/通信/网络设备文章
·工业自动化展区 > 传感器展厅 > 加速度传感器 > 传感器文章
文章点评 查看全部点评 投稿 进入贴吧


对 电子产品 有何见解?请到 电子产品论坛 畅所欲言吧!


网站简介 | 高级会员服务 | 广告服务 | 服务条款 | English | Showsbee | 会员登录  
© 1999-2018 newmaker.com. 佳工机电网·嘉工科技