Android系统触摸屏的校正——http://carvencao.blog.sohu.com/156057534.html

转载 2011年01月19日 14:52:00

从校正方法来看, Android 系统触摸屏的校正一般分两种:线性校准与三点(一般用五点)校准;从校正的位置来看,也分两种,驱动层校准和 android 层校准。一般来讲,从 android 层校正由应用软件配合 android 层完成,灵活度比较高,也比较智能化。随时不准随时校正。在这里,详细介绍 android 层的校正过程。

 

为了更好的了解校正的详细过程,有必要了解一下触摸屏数据的运动过程,至少校正的原则,由于涉及到特定的算法,因此不在此报告中提及。

 

触摸屏数据产生于 Linux 内核,在触摸屏驱动中,通过 AD 转换,把触摸点记录为一组组数据(触摸屏坐标),这个数据我们称之为原始数据。这个原始数据非常的重要,毕竟我们的目标就是把这样的一组组触摸屏坐标转换为 LCD 坐标。原始数据产生后,通过 input_report_abs 上报到 android 层。在 android 层会能过 getX getY 捕捉到这一数据,再将捕捉到的数据通过 reportData 分发到窗口。

 

从数据的运动过程,我们大概知道校正要从哪入手了吧。校正的过程其它就是数据的截获 - 修改过程。因为这里介绍的是 android 层的校正,因此,我们需要在 android 层数据将数据截取。 android 层触摸屏的数据是在 /frameworks/base/services/java/com/android/server/ 目录中的文件 InputDevice.java 截取的,因此需要在这个文件中增加一些代码,用于截取原始数据并将原始数据进行校正。

到这里,我们一直有一个大前提,那就是: 1 Linux 驱动层上报的是原始数据; 2 、对原始数据进行校正的校正系数已经产生。因此,在 InputDevice.java 中增加代码之前,我们应该解决掉这两个问题。


校正过程分四步完成:

1 、触摸屏驱动的修改

对第一个问题,我们需要对 Linux 层的触摸屏驱动进行改动,以保证 report 的数据是原汁原味没有进行过任何修改的数据

如果你使用的是进行过校正的触摸屏驱动,需要注意两个地方的修改:

第一处是:

if(xtmp < 0)

                             xtmp = 0;

                      else if(xtmp > TS_RESOLUTION_X-1)

                             xtmp = TS_RESOLUTION_X-1;

 

                      if(ytmp < 0)

                             ytmp = 0;

                      else if(ytmp > TS_RESOLUTION_Y-1)

                             ytmp =TS_RESOLUTION_Y-1;

以上代码需要全部注释掉,不注掉的结果就是当你用五点校准时,不管你怎么点击触摸屏,触摸屏都不会有反应。仔细看看这段代码就知道了,这段代码保证上报的数据在 LCD 坐标范围之内,这是在驱动层校正必写的一段代码,却是我们进行软件校正的绑脚石呵。

第二处是 __init s3c_ts_probe 中的一段代码代码:

if (s3c_ts_cfg->resol_bit= =12) {

               input_set_abs_params(ts->dev, ABS_X, 0, TS_RESOLUTION_X, 0, 0);

               input_set_abs_params(ts->dev, ABS_Y, 0, TS_RESOLUTION_Y, 0, 0);              

        }               

 

需要修改成如下:()

if (s3c_ts_cfg->resol_bit= =12) {

               input_set_abs_params(ts->dev, ABS_X, 0, 0xFFF , 0, 0);

               input_set_abs_params(ts->dev, ABS_Y, 0, 0xFFF , 0, 0);        

        }            

道理跟上一段代码一样。如,我调试的 6410 板子采用的是 12 位转换的,在系统启动过程中,会看到这个的打印信息:

I/KeyInputQueue(    58):    X: min=0 max=4095 flat=0 fuzz=0

I/KeyInputQueue(    58):    Y: min=0 max=4095 flat=0 fuzz=0

由此我们可以看出,对驱动进行修改的原则就是:保证驱动上报的数据是原汁原味没有进行过任何修改的数据。


2 、校正系数的产生

核下系数的产生是靠软件来实现的,由于触摸屏的校正算法特定,因此校正应用程序是通用的。在这个应用程序里要修改的地方有两个,一是别忘了把屏幕的分辨率改成需要的分辨率。二是根据驱动层采用的转换精度调整一下数据:

     final int UI_SCREEN_WIDTH = TS_RESOLUTION_X; 

     final int UI_SCREEN_HEIGHT = TS_RESOLUTION_Y;

 

      x1 = (int)(( event.getX() * 4095 ) / (TS_RESOLUTION_X-1));   //2^12-1=4095

y1 = (int)(( event.getY() * 4095 ) / (TS_RESOLUTION_Y-1));

 

 

这个部分需要注意的问题就是校正系数文件 pointercal 权限的问题,需要在 init.rc 中给该文件的生成提供权限:

chmod 0777 /data/etc

          chmod 0644 /data/etc/pointercal

 

第一句是允许中 /data/etc 中生成 pointercal 文件,第二句是保证 pointercal 文件能被读取。

 

 


现在可以在 InputDevice.java 中增加代码了:

3 、读取校正文件

      static void ReadPointercalFile(){

          TransformInfo t = null;

          try {

              FileInputStream is;

               if(custom_file_exist) {

                   Log.i("TS_DBG", "InputDevice.ReadPointercalFile:read CALIBRATION_FILE from /data/etc");

                  is = new FileInputStream(CALIBRATION_FILE2);

              } else {

                   Log.i("TS_DBG", "InputDevice.ReadPointercalFile:read CALIBRATION_FILE from /system/etc");

                   is = new FileInputStream(CALIBRATION_FILE1);

              }

              byte[] mBuffer = new byte[64];

              int len = is.read(mBuffer);

              is.close();

 

              if (len > 0) {

                  int i;

                  for (i = 0 ; i < len ; i++) {

                      if (mBuffer[i] == '/n' || mBuffer[i] == 0) {

                           break;

                      }

                  }

                  len = i;

              }

 

              StringTokenizer st = new StringTokenizer( new String(mBuffer, 0, 0, len) );

 

              t = new TransformInfo ();

              t.x1 = Integer.parseInt( st.nextToken() );

              t.y1 = Integer.parseInt( st.nextToken() );

              t.z1 = Integer.parseInt( st.nextToken() );

              t.x2 = Integer.parseInt( st.nextToken() );

              t.y2 = Integer.parseInt( st.nextToken() );

              t.z2 = Integer.parseInt( st.nextToken() );

              t.s   = Integer.parseInt( st.nextToken() );

              Log.i("InputDevice.ReadPointercalFile: ", 

                   "t.x1=" + t.x1 + " t.y1=" + t.y1 + " t.z1=" + t.z1 

                + "t.x2=" + t.x2 + " t.y2=" + t.y2 + " t.z2=" + t.z2 + "t.s=" + t.s);

          } catch (java.io.FileNotFoundException e) {

               custom_file_exist = false;

               Log.i("TS_DBG", "FileNotFound!");

          } catch (java.io.IOException e) {

               Log.i("TS_DBG", "IOException");

          }

          tInfo = t;

 


4 、截取原始数据,用校正系数进行校准

if (device.tInfo != null)

         reportData[j + MotionEvent.SAMPLE_X] =

                     (device.tInfo.x1 * x_tmp + 

                     device.tInfo.y1 * y_tmp + 

                     device.tInfo.z1) / device.tInfo.s;

     else

         reportData[j + MotionEvent.SAMPLE_X] =

                      ((reportData[j + MotionEvent.SAMPLE_X]-absX.minValue)

                                      / absX.range) * w;

 

                    

      if (device.tInfo != null)

           reportData[j + MotionEvent.SAMPLE_Y] =

                     (device.tInfo.x2 * x_tmp +

                     device.tInfo.y2 * y_tmp +

                     device.tInfo.z2) / device.tInfo.s;

        else

           reportData[j + MotionEvent.SAMPLE_Y] =

                   ((reportData[j + MotionEvent.SAMPLE_Y]-absY.minValue)

                                       / absY.range) * h;

 

 

 

备注:为了保证 pointercal 顺便的生成,还要保证键盘的正常工作。因为第一次用软件校正,触摸屏不好使,至少要有方向键我确定键保证能顺利进行校正程序(当然第二次和以后就不需要了)。除此之外,还要保证 MENU 键的正常工作,因为校正程序最后一步需要 MEUN 键确认,只有触认后才会生成 pointercal 文件。当然,如果你的按键本来就不够用,确认的按键可以通过修改校正应用程序换成其它键。

相关文章推荐

关于信噪比SNR【转载】1.http://well3216.blog.sohu.com/96624202.html

SNR(Signal to Noise Ratio,信噪比):    指在规定输入电压下的输出信号电压与输入电压切断时,输出所残留之杂音电压之比,也可看成是最大不失真声音信号强度与同时发出的噪音强度...

lseek函数的使用 转载自http://atia.blog.sohu.com/94895919.html

所有打开的文件都有一个当前文件偏移量(current file offset),以下简称为 cfo。cfo 通常是一个非负整数,用于表明文件开始处到文件当前位置的字节数。读写操作通常开始于 cfo,并...

Linux嵌入式系统与硬件平台的关系——转自http://itlin.blog.51cto.com/519307/134301

一、 Linux嵌入式系统 操作系统是一种在计算机上运行的软件,它的主要任务是管理计算机上的系统资源,为用户提供使用计算机及其外部设备的接口。它存在的目的是为了管理所有硬件资源,并且提供应用软件...

【hasLayout触发方式】和【hasLayout——IE中css bug的罪魁祸首】(转自:http://hi.baidu.com/oxid/blog/item/8481e6a28128b3a0caefd044.html 和 http://www.k6

【hasLayout触发方式】 IE中的HTML元素要实现透明,则其必须具备layout,这样的元素有仅可读的属性hasLayout,且其值为true。具体情况如下:body、img、table、tr...
  • lslxdx
  • lslxdx
  • 2011年05月23日 19:49
  • 2304

android中handler用法总结(http://blog.sina.com.cn/s/blog_77c6324101016jp8.html)

一、Handler的定义:     Handler主要接收子线程发送的数据, 并用此数据配合主线程更新UI,用来跟UI主线程交互用。比如可以用handler发送一个message,然后在ha...

Android中Uri的使用转自http://blog.sina.com.cn/s/blog_821e2bb10100spxv.html

1.Uri 通用资源标志符(Universal Resource Identifier, 简称"URI")。 Uri代表要操作的数据,Android上可用的每种资源 - 图像、视频片段等都...

http://www.useragentman.com/blog/2010/07/27/creating-cross-browser-html5-forms-now-using-modernizr-w

Creating Cross Browser HTML5 Forms Now, Using modernizr, webforms2 and html5Forms July 27th, 2010 b...

根据输入日期通过位移方式解决包含当月的前几月自定义函数 http://reportsoft.blog.hexun.com/75077561_d.html

字号:大 中 小 1. 需求概述 A.报表里通常会用到同期比,上年同期比。对有些零售行业的报表可能要求比较高一些,对包含当月的前3,6,12个月的一些同期比,比上年同期等,因此数据的...
  • xjmlyun
  • xjmlyun
  • 2012年04月25日 09:58
  • 784

javax.servlet.Filter详解(二) 转自:http://hi.baidu.com/jxnuywf/blog/item/f3834aee93e2fdf8b2fb95cc.html

转自:http://hi.baidu.com/jxnuywf/blog/item/f3834aee93e2fdf8b2fb95cc.html1.5禁用激活器servlet在对资源应用过滤器时,可通过指...
  • jubincn
  • jubincn
  • 2011年02月15日 12:33
  • 1244

http://www.ruanyifeng.com/blog/2015/07/flex-examples.html

Flex 布局教程:实例篇 作者: 阮一峰 日期: 2015年7月14日 上一篇文章介绍了Flex布局的语法,今天介绍常见布局的Flex写法。...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Android系统触摸屏的校正——http://carvencao.blog.sohu.com/156057534.html
举报原因:
原因补充:

(最多只允许输入30个字)