G-sensor 介绍

article/2025/10/6 3:07:49

转自:http://blog.chinaunix.net/uid-29595319-id-4200772.html

G-sensor

G-sensor是加速度传感器,可以通过其来获得分别来自三个不同轴向上的加速度用以通知上层应用做出相应处理。

 

由于地球的引力作用,gsensor平放时,Z轴方向能感应到1g的重力加速度,如果移动或倾斜,此时垂直的重力加速度会分解到X,Y,Z轴上。所以旋转手机时,X,Y,Z轴的值不断变化,可以理解为手机处在一个坐标系中,我们判断手机是否旋转就是判断X,Y,Z当前的值。

 

下图为基本原理图:

 

飞思卡尔mma7455 管脚配置图:

       

     I2C总线连接适配电路图:

   

 

 

 

G-sensor的应用

如甩动换歌,换墙纸,TV调台,实现根据手机放置状态自动切换横竖屏,如翻转静音等应用功能。

在系统中G-sensor的两种使用方式

<1> 中断方式:在此方式中首先会对G-sensor器件设定一个阈(yu)值,器件感知加速度当值大于设定的阈值时器件触发CPU中断,系统得到一次甩动事件,系统将该事件处理为一个消息并将其发送给应用层,应用层得到消息判断任务状态如果有MP3,TV等任务运行及对该任务进行切歌换台等操作,如果无任务则切换墙纸。

<2> 查询方式:当进入某个需要使用到G-sensor的应用时,应用先打开一个定时器每当定时器超时溢出时便查询一次G-sensor当前状态值,用以判断当前手机状态。如果三个轴向上的值超过一定范围即认为手机静置状态改变调用相应处理函数执行操作。该种方式主要应用于视频播放即菜单显示的横竖屏切换。

    相关代码

   Custom_equipment.h

Custom_equipment.c

    由于使用不同的芯片所以在代码中作了兼容匹配。对应每一个芯片都有一套

    [chipname]_init                初始化函数

    [chipname]_enablelatch,         中断使能函数

[chipname]_clearlatch,          清中断函数

[chipname]_read_x_value,        读x轴值

   [chipname]_read_y_value,        读y轴值

   [chipname]_read_z_value,        读z轴值

   [chipname]_entersleep           进入睡眠

函数,函数的函数指针在名为GSensor_Funcs的结构体中。在函数gsensor_read_and_check_id函数中通过读取芯片id然后将对应结构体赋给结构体指针gsensor_func在通过该指针调用对应函数,从而实现了芯片的自动匹配。read_position_status_handler函数为最终的G-sersor的最终处理函数。当该函数被调用后如果有符合要求的事件产生则该函数会向上发出一条消息供给应用层处理。在此函数中有一个名为g_gsensor_settings[]的数组,该数组记录的是需要使用G-sensor的应用程序的开关。传感器三个轴向上的加速度值存储在另外一个名为curr_gsensor_info[3]的数组之中。

Email:wei7758@126.com

Blog:http://blog.csdn.net/yinwei520

Author: Yww

Time:2011-8-22

一、首先建立这样一个全局的观念:

    Android中sensor在Android系统架构中的位置及其工作。方框图如下:

从以上方框图中,可以看出Android中sensor在系统分为四层:驱动层(Sensor Driver)、硬件抽象层(Native)、中间层(Framework)、应用层(Java)。硬件抽象层与中间层可以合并一起作为Framework层。

针对我们xx这里一个具体的Gsensor,下面将以具体的源码形式来讲解以上的这个系统框图。

 

二、驱动层(Sensor Driver Layer)

芯片ADXL345为GSensor,至于硬件的具体工作原理,须分析ADXL345的DataSheet。驱动源码位于:xx\custom\common\kernel\accelerometer\adxl345目录。

由于ADXL345是以I2C形式接口挂接到Linux系统,因此同时需要分析Linux的I2C子系统架构(略)。其源码位于:

1、  xx\platform\xx\kernel\drivers\i2c

2、  kernel\drivers\i2c

查看ADXL345.c文件,分析针对于其硬件工作原理的几个函数。硬件初始化:

 

[cpp]  view plain copy print ?
  1. static int adxl345_init_client(struct i2c_client *client, int reset_cali)  
  2.   
  3. {  
  4.   
  5.     struct adxl345_i2c_data *obj = i2c_get_clientdata(client);  
  6.   
  7.     int res = 0;  
  8.   
  9.    
  10.   
  11.     adxl345_gpio_config();//配置GPIO口,这里由于不使用中断,所以将中断引脚配置成输入输出口。  
  12.   
  13.       
  14.   
  15.     res = ADXL345_CheckDeviceID(client); //检测设备ID,通过读ADXL345的DEVID寄存器  
  16.   
  17.     if(res != ADXL345_SUCCESS)  
  18.   
  19.     {  
  20.   
  21.         return res;  
  22.   
  23.     }     
  24.   
  25.    
  26.   
  27.     res = ADXL345_SetPowerMode(client, false);//设置电源模式,ADXL345有几种电源模式,这里设置false值指不让芯片处于messure模式  
  28.   
  29.     if(res != ADXL345_SUCCESS)  
  30.   
  31.     {  
  32.   
  33.         return res;  
  34.   
  35.     }  
  36.   
  37.       
  38.   
  39.    
  40.   
  41.     res = ADXL345_SetBWRate(client, ADXL345_BW_100HZ);//设置带宽,100Hz  
  42.   
  43.     if(res != ADXL345_SUCCESS ) //0x2C->BW=100Hz  
  44.   
  45.     {  
  46.   
  47.         return res;  
  48.   
  49.     }  
  50.   
  51.    
  52.   
  53.     //设置数据格式,具体见datasheet  
  54.   
  55.     res = ADXL345_SetDataFormat(client, ADXL345_FULL_RES|ADXL345_RANGE_2G);  
  56.   
  57.     if(res != ADXL345_SUCCESS) //0x2C->BW=100Hz  
  58.   
  59.     {  
  60.   
  61.         return res;  
  62.   
  63.     }  
  64.   
  65.    
  66.   
  67.     gsensor_gain.x = gsensor_gain.y = gsensor_gain.z = obj->reso->sensitivity;  
  68.   
  69.    
  70.   
  71.     //设置中断寄存器,关闭中断  
  72.   
  73.     res = ADXL345_SetIntEnable(client, 0x00);//disable INT          
  74.   
  75.     if(res != ADXL345_SUCCESS)   
  76.   
  77.     {  
  78.   
  79.         return res;  
  80.   
  81.     }  
  82.   
  83.    
  84.   
  85.     if(0 != reset_cali)  
  86.   
  87.     {   
  88.   
  89.         /*reset calibration only in power on*/  
  90.   
  91.         res = ADXL345_ResetCalibration(client);  
  92.   
  93.         if(res != ADXL345_SUCCESS)  
  94.   
  95.         {  
  96.   
  97.             return res;  
  98.   
  99.         }  
  100.   
  101.     }  
  102.   
  103.    
  104.   
  105. #ifdef CONFIG_ADXL345_LOWPASS  
  106.   
  107.     memset(&obj->fir, 0x00, sizeof(obj->fir));    
  108.   
  109. #endif  
  110.   
  111.    
  112.   
  113.     return ADXL345_SUCCESS;  
  114.   
  115. }  


 

    函数的分析都注释在原理里,红色部分。具体寄存器的设置查看ADXL345的datasheet,具体I2C的通信查看I2C.c文件(i2c控制器的驱动)。

    关键问题:这里有个问题,没有弄懂,就是从ADXL345数据寄存器里读取原始数据之后,这个数据并不是我们应用程序所要用的,它需要转化,经过查看代码,可以发现这样一段注释:

/*

 * @sign, map: only used in accelerometer/magnetic field

 *   sometimes, the sensor output need to be remapped before reporting to framework.

 *   the 'sign' is only -1 or +1 to align the sign for framework's coordinate system

 *   the 'map' align the value for framework's coordinate system. Take accelerometer

 *      as an exmaple:

 *      assume HAL receives original acceleration: acc[] = {100, 0, 100}

 *      sign[] = {1, -1, 1, 0};

 *      map[]  = {HWM_CODE_ACC_Y, HWM_CODE_ACC_X, HWM_CODE_ACC_Z, 0};

 *      according to the above 'sign' & 'map', the sensor output need to remap as {y, -x, z}:

 *      float resolution = unit_numerator*GRAVITY_EARTH/unit_denominator;

 *      acc_x = sign[0]*acc[map[0]]*resolution;

 *      acc_y = sign[1]*acc[map[1]]*resolution;

 *      acc_z = sign[2]*acc[map[2]]*resolution;

 */

struct hwmsen_convert {

    s8 sign[C_MAX_HWMSEN_EVENT_NUM];

    u8 map[C_MAX_HWMSEN_EVENT_NUM];

};

这样一个转换算法的物理意义是怎样的?????

三、硬件抽象层(Native)

硬件抽象层主要是提供硬件层实现的接口,其代码路径如下:

hardware\libhardware\include\hardware\ sensors.h

其中:

struct sensors_module_t为sensor模块的定义。

struct sensors_module_t {

    struct hw_module_t common;

    int (*get_sensors_list)(struct sensors_module_t* module,

                            struct sensor_t const** list);

};

 

Struct sensor_t为某一个sensor的描述性定义。

struct sensor_t {

    const char*     name;          /*    传感器的名称 */

    const char*     vendor;         /* 传感器的vendor */

    int             version;         /*    传感器的版本 */

    int             handle;         /*    传感器的句柄 */

    int             type;           /*    传感器的类型 */

    float           maxRange;     /*    传感器的最大范围 */

    float           resolution;      /*    传感器的辨析率 */

    float           power;         /* 传感器的耗能(估计值,mA单位)*/

    void*           reserved[9];

}

 

struct sensors_event_t表示传感器的数据

/**

 * Union of the various types of sensor data

 * that can be returned.

 */

typedef struct sensors_event_t {

    int32_t version; /* must be sizeof(struct sensors_event_t) */

    int32_t sensor; /* sensor identifier */

    int32_t type;   /* sensor type */

    int32_t reserved0;  /* reserved */

   int64_t timestamp;  /* time is in nanosecond */

    union {

        float     data[16];

 

        /* acceleration values are in meter per second per second (m/s^2) */

        sensors_vec_t   acceleration;

        /* magnetic vector values are in micro-Tesla (uT) */

        sensors_vec_t   magnetic;

        sensors_vec_t   orientation; /* orientation values are in degrees */

        sensors_vec_t   gyro; /* gyroscope values are in rad/s */

        float    temperature; /* temperature is in degrees centigrade (Celsius) */

        float    distance; /* distance in centimeters */

       float     light;    /* light in SI lux units */

        float     pressure; /* pressure in hectopascal (hPa) */

    };

    uint32_t        reserved1[4];

} sensors_event_t;

    显然,在看完这些数据结构之后,我们都会有这样一个疑问:

    这里只是申明了一些结构体,而这些结构体在使用时需要定义,而且结构体中还有一些函数指针,这些函数指针所对应的函数实现又在哪里呢??显然,那必定还要有一个.c源文件来实现这样的一些函数。经过搜索,其文件名为:sensors_hwmsen.c,路径为:

\xxk\source\hardware\sensor\hwmsen。在这里,你会看到get_sensors_list等函数的实现。

 

四、中间层(Framework)

    这里,我也把它叫做JNI层,这里实现了JNI接口。其源码目录如下:

frameworks\base\core\jni\ android_hardware_SensorManager.cpp

在源码里,我们可以看到JNI接口的函数列表:

static JNINativeMethod gMethods[] = {

    {"nativeClassInit", "()V",              (void*)nativeClassInit },

    {"sensors_module_init","()I",           (void*)sensors_module_init },

    {"sensors_module_get_next_sensor","(Landroid/hardware/Sensor;I)I",

                                            (void*)sensors_module_get_next_sensor },

 

    {"sensors_create_queue",  "()I",        (void*)sensors_create_queue },

    {"sensors_destroy_queue", "(I)V",       (void*)sensors_destroy_queue },

    {"sensors_enable_sensor", "(ILjava/lang/String;II)Z",

                                            (void*)sensors_enable_sensor },

 

    {"sensors_data_poll",  "(I[F[I[J)I",     (void*)sensors_data_poll },

};

这些JNI接口所对应的实现,请看源码。

 

当然了,你可能又有疑问了,上层Java又是怎样来调用这些本地接口的呢??在android_hardware_SensorManager.cpp源码下面有这样一个函数:

int register_android_hardware_SensorManager(JNIEnv *env)

{

    return jniRegisterNativeMethods(env, "android/hardware/SensorManager",

            gMethods, NELEM(gMethods));

}

这个函数就将以上的JNI接口(gMethods数组)注册进系统。看上去很简单,其实过程是很复杂的。整个native方法初始化过程如下:start(AndroidRuntime.cpp,938行)->startReg(AndroidRuntime.cpp,1360 行)-> register_jni_procs(AndroidRuntime.cpp,1213行)。这样JAVA上层就能够调用这些JNI接口来操纵底层硬件了。

 

五、应用层(Java)

传感器系统的JAVA部分包含了以下几个文件:

u       SensorManager.java

实现传感器系统核心的管理类SensorManager

u       Sensor.java

单一传感器的描述性文件Sensor

u       SensorEvent.java

表示传感器系统的事件类SensorEvent

u       SensorEventListener.java

传感器事件的监听者SensorEventListener接口

u       SensorListener.java

传感器的监听者SensorListener接口



http://chatgpt.dhexx.cn/article/Uv5Mpvvi.shtml

相关文章

G-sensor概述及常用概念整理【转】

本文转载自:http://www.jianshu.com/p/d471958189a0?nomobile=yesG 本文对G-sensor进行整理,先介绍G-sensor的一些基本概念,再具体讲解BOSCH、ST、ADI三家的G-sensor,其中BOSCH的G-sensor重点讲BMA222E,ST的G-sensor重点讲LIS2DH12,ADI的G-sensor具体讲ADXL362。 一、G-…

初次使用Fleck+redis订阅发布实现学习小demo

https://www.cnblogs.com/SupPilot/p/10396333.html 首先安装Fleck的程序包添加引用下面是客户端代码&#xff1a; 客户端代码&#xff1a; 运行效果&#xff1a; 遇到的问题&#xff1a; Q:通常每个套接字地址(协议/网络地址/端口)只允许使用一次 A:是因为本萌新把WebSocke…

core+Fleck+redis

1.新建core版控制台程序引用 2.初始化websocket class Program { //客户端url以及其对应的Socket对象字典 static IDictionary<string, IWebSocketConnection> dic_Sockets new Dictionary<string, IWebSocketConnection>(); static …

[c#]使用Fleck实现简单的WebSocket含兼容低版本IE

WebSocket是html5的一种协议,那么就表示要使用websocket客户端的浏览器就要支持html5。 对于不支持的使用flash去解决。 Fleck源码地址 服务端采用的是Fleck,Fleck的好处就是简单方便,作者已经进行了完整的封装,可以根据自己情况进行修改 兼容低版本IE 使用flash实现兼容低…

C#实现WebSocket(基于Fleck-服务端和WebSocketSharp-客户端)

C#实现WebSocket(基于Fleck-服务端和WebSocketSharp-客户端) 官网&#xff1a;https://github.com/sta/websocket-sharp 客户端 private void btn_Connect_Click_1(object sender, EventArgs e){Console.WriteLine("Websocket Demo");WebSocket web new WebSocket(…

C#通过fleck实现wss协议的WebSocket多人Web实时聊天(附源码)

前言 最近想做一个Web版的即时聊天为后面开发的各项功能做辅助&#xff0c;就需要浏览器与服务器能够实时通讯。而WebSocket这种双向通信协议&#xff0c;就很合适用来实现这种需求。 本篇文章主要解决C#如何实现WebSocket服务端和Javascript客户端基于wss协议的安全通信问题。…

Asp.Net Mvc基于Fleck开发的多人网页版即时聊天室

一、项目的核心说明 1、Fleck这个是实现websocket一个比较简单第三方组件&#xff0c;它不需要安装额外的容器。本身也就几个接口可供调用。 2、项目是基于.net framework 4.7.2 &#xff0c;在vs2019上开发的&#xff0c;没试过在低版本上运行。但是代码上没怎么用到新特性&…

winfrom+Fleck 上传文件

最近这个项目要做一个Winfrom上传Execl到服务器。 就想到之前用Fleck做的一个小功能&#xff0c;但是客户端Web端的。百度吧&#xff0c;看有没有办法&#xff0c;开始找到fw4 &#xff0c;但是要引用它的dll&#xff0c;是可以&#xff0c;继续找了会结果找到ClientWebSocket…

C#工作总结(一):Fleck的WebSocket使用

一.引子&#xff08;Foreword&#xff09; 最近公司里面要做窗体和网页交互的功能。网上找了一下资料&#xff0c;这里做一个简单的扩充和整理&#xff0c;部分内容可能是摘自其他博客&#xff0c;这里会注明出处和原文地址供大家和自己日后查阅。 二.基础知识&#xff08;Foun…

Fleck说明文档翻译

CSDN ZslLoveMiwa的博客 Fleck Fleck是一个在C#中的WebSocket服务器端的一个实现.。分支自Nugget项目, Fleck不需要任何的继承、容器亦或是需要增加的引用就可以使用。 实例 下面是一个把客户端网页发来的消息回发到客户端的服务器程序。 var server new WebSocketServer(&q…

fleck 客户端_C#中使用Fleck实现WebSocket通信简例

Fleck是一个开源的使用C#封装的WebSocket服务端工具库。 一、服务端搭建 这里选择在.net core 2.1框架下新建了一个控制台程序 在项目里使用NuGet引入Fleck包 NuGet引入Fleck包 其它方式也可以,最终引入项目里都是Fleck.dll Fleck.dll 二、服务端实例 Github上的简单例子: 简…

Fleck WebSocket使用

作为笔记存储. 最近公司有这方面的使用需求。在网上查了一些资料后。得到了想要的结果。以下记录摘抄至网上资料 1.首先,服务端。项目NuGet直接引用Fleck类库。 code: 1 //客户端url以及其对应的Socket对象字典2 IDictionary<string, IWebSocket…

车牌识别技术原理

车牌识别技术原理 车牌识别技术原理都是一样的&#xff0c;具体流程如下&#xff1a;图像捕捉与获取、车牌定位、字符分割字符识别、输出结果。不一样的是在上述环节中采用不同的技术&#xff0c;比如作为核心技术的车牌定位&#xff0c;就可能用到(1)自适应边界搜索法、(2)区…

python实现车牌识别

原始图象 代码 from hyperlpr import HyperLPR_plate_recognition import cv2 from PIL import ImageFont, ImageDraw, Image import numpy as npimage cv2.imread("car.jpg")#读入图片 resultHyperLPR_plate_recognition(image)#识别车牌 plate result[0][0] #…

基于形态学处理的车牌提取,字符分割和车牌识别算法matlab仿真

目录 1.算法仿真效果 2.MATLAB核心程序 3.算法涉及理论知识概要 4.完整MATLAB 1.算法仿真效果 matlab2022a仿真结果如下&#xff1a; 2.MATLAB核心程序 ........................................................................... figure(8);subplot(3,2,2),imshow(d…

车牌识别算法介绍与实践

汽车牌照自动识别整个处理过程分为预处理、边缘提取、车牌定位、字符分割、字符识别五大模块&#xff0c;其中字符识别过程主要由以下3个部分组成&#xff1a; ①正确地分割文字图像区域&#xff1b; ②正确的分离单个文字&#xff1b; ③正确识别单个字符。 用MATLAB软件编…

基于android的车牌识别程序,基于Android平台车牌识别算法,实现手机识别车牌

原标题:基于Android平台车牌识别算法,实现手机识别车牌 近年来,随着移动行业的爆发式发展,手机配置不断提高,基于手机平台的信息采集、图像处理、数据传输等方面的研究也成为了热点,这使得基于手机平台上的车牌识别成为可能。传统的车牌识别系统一般都基于固定的桌面平台…

【车牌识别】基于HOG特征提取和GRNN网络的车牌识别算法matlab仿真

1.软件版本 matlab2017b 2.系统原理 从图的算法流程图可知&#xff0c;基于车牌图像字符特征提取和神经网络的识别算法其首先将训练样本数据进行预处理&#xff0c;得到质量较高的样本数据&#xff0c;然后对这些样本数据进行HOG特征提取&#xff0c;再将特征数据通过神经网络…

【XLPNet车牌识别算法】第二章 检测部分-算法篇1

【XLPNet车牌识别算法】第二章 检测部分-算法篇1 1. XLPNet检测算法前言2. XLPNet检测算法详解2.1 起源2.2 算法细节2.1 算法命名2.2 数据集2.3 预备知识2.4 核心&#xff1a;旋转高斯分布&#xff08;Rotated Gaussian Distribution&#xff09;2.4.1 基于高斯策略的样本分配2…

车牌识别算法 基于yolov5的车牌检测+crnn中文车牌识别 支持12种中文车牌识别

yolov5 车牌识别算法&#xff0c;支持12种中文车牌类型 基于yolov5的车牌检测 车牌矫正以及 基于CRNN的车牌识别 1.单行蓝牌 2.单行黄牌 3.新能源车牌 4.白色警用车牌 5 教练车牌 6 武警车牌 7 双层黄牌 8 双层武警 9 使馆车牌 10 港澳牌车 11 双层农用车牌 12 民航车牌 效果如…