Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1145084
  • 博文数量: 276
  • 博客积分: 8317
  • 博客等级: 少将
  • 技术积分: 2329
  • 用 户 组: 普通用户
  • 注册时间: 2006-09-12 08:17
个人简介

http://ads.buzzcity.net/adpage.php?partnerid=40096

文章分类

全部博文(276)

文章存档

2013年(1)

2012年(38)

2011年(102)

2010年(85)

2009年(45)

2008年(5)

分类: 嵌入式

2010-11-29 16:21:51

转载自(http://blog.sina.com.cn/wyw1976) 作者邮箱(wyw1976@gmail.com)
(1)触摸屏为什么需要校正?
    触摸屏与LCD显示屏是两个不同的物理器件。LCD处理的像素,例如我们通常所说的分辨率是600x800,实际就是指每行的宽度是600个像素,高度是 800个像素,而触摸屏处理的数据是点的物理坐标,该坐标是通过触摸屏控制器采集到的。两者之间需要一定的转换。
    其次, 在安装触摸屏时,不可避免的存在着一定的误差,如旋转,平移的,这同样需要校正解决。
    再次,电阻式触摸屏的材料本身有差异而且随着时间的推移,其参数也会有所变化,因此需要经常性的校正(电容式触摸屏只需要一次校正即可,这是由两者不同的材料原理造成的,具体可参阅有关电阻式和电容式触摸屏对比的文章)
(2)如何校正?
    触摸屏的校正过程一般为: 依次在屏幕的几个不同位置显示某种标记(如"+"), 用触摸笔点击这些标记, 完成校正。
    如果PT(x, y)表示触摸屏上的一个点, PL(x, y)表示LCD上的一个点,校正的结果就是得到一个转换矩阵M, 使PL(x, y) = M·PT(x, y)。
(3) 校正原理
    我们知道二维几何变换包含三种平移、旋转和缩放。这三者的矩阵表示为:
平移MT:


缩放MS:


旋转MR:


所以  PL =MR·MT·MS· PT, 将这个公式展开,其结果为:

    在上面的公式中,LCD上的坐标(XL 、YL)和触摸屏上的坐标(XT 、YT)是已知的,而其他的则是我们需要求的:θ, SY, SX, TY, SX共有5个变量,至少需要五个方程,因为每组点坐标(PL, PT)可以得到两个方程,因此我们需要采集三组点坐标。但是上面的方程涉及三角函数,运算复杂,我们可以进一步简化为:

变量虽然多了一个,但是解题过程简单多了,更适合计算机计算,而且采集点的数量仍然为3组。
    假设LCD三个点的坐标为(XL1, YL1),(XL2, YL2),(XL2, YL2), 对应触摸屏上的三个点是(XT1, YT1),(XT2, YT2)。(XT3, YT3), 则联立两个方程组为:

   这样,触摸屏的校正实际上就是解上面的方程组,得到6个系数:A、B、C、D、E、F。而上面方程组按照克莱姆法则解即可。
   在得到6个系数后,以后通过触摸屏得到的所有坐标,带入公式(1)中就可以得到LCD上以像素表示的坐标。
附:克拉姆法则



我们在触摸屏校正原理说过,只需要三组点坐标,我们就可以完成触摸屏的校正,其基本公式为:

    实际上,在校正时,采集的触摸屏的点坐标有一定的误差,也就是说采集几个三组点坐标,分别计算A、B、C、D、E、F,其结果不尽相同。
    在tslib的ts_calibrate中,采集了五组点坐标,具体代码参见ts_calibrate.c中的perform_calibration()。
    一般来说,采集的点越多,校正的精确性就越高。 为了在计算过程中兼顾5个点的坐标, ts_calibrate将公式(1)变换如下:

   以第一组(A、B、C)为例, 进一步变换为:

   n表示坐标的数量,ts_calibrate中就是5, 分别对XT, YT, XL, XLXT,XLYT,(XT)2 ,(YT)2 ,YT 求和,带入公式(3)中,就可以求出A、B、C,同理可求D、E、F。
   解的时候用的是逆矩阵的方法,即:
       
   P0 = M · P1 ======> (M)-1 P0 = P1

   我们可以看出,运用上述方法可以处理任意多的采集点,而不局限于5个,只是采集点过多就会冗余,对校正精确性的提高作用很少,反而增加了计算时间。

1,触摸屏校准通用方法
主要采用以下公式,实现触摸屏校正,其中XL, YL是显示屏坐标,XT, YT是触摸屏坐标,
XL = XT*A+YT*B+C;
YL = XT*D+YT*E+F;    公式(1)
由于具体计算是希望是整数运算,所以实际中保存的ABCDEF为整数,而增加一个参数Div, 由以下公式实现:
XL = (XT*A+YT*B+C) / Div;
YL = (XT*D+YT*E+F) / Div;    公式(2)
因此通常保存的参数是七个。
一般通过3个采样点就可以实现校准,tslib则使用了5个采样点,可实现更准确的校准。
2,用Linux的proc文件系统实现触摸屏校正
Android本身并不带触摸屏校准,因此要校准触摸屏最好完全在底层驱动完成,而
Android获取到的数据直接将是校准后的坐标数据
1) 首先在touchscreen的驱动加载时,创建一个proc文件,如:
C代码
  1. ts_proc_entry = create_proc_entry("driver/micc_ts", 0, NULL);  
  2. if (ts_proc_entry) {  
  3.         ts_proc_entry->write_proc = ts_proc_write;  
  4. }  

可在ts_proc_write()定义自己的proc数据传递格式。
2) 在touchscreen驱动用默认参数,完成校准,如果不用校准,则设置为:
A=1, B=0, C=0, D=0, E=1, F=0, Div=1
3) 修改tslib—ts_calibrate获得需要的参数A,B,C,D,E,F,Div;
注意要在运行前改为如下参数:
A=1, B=0, C=0, D=0, E=1, F=0, Div=1
如:
echo +a 1 > /proc/driver/micc_ts
echo +b 0 > /proc/driver/micc_ts
echo +c 0 > /proc/driver/micc_ts
echo +d 0 > /proc/driver/micc_ts
echo +e 1 > /proc/driver/micc_ts
echo +f 0 > /proc/driver/micc_ts
echo +g 1 > /proc/driver/micc_ts
保证ts_calibrate获得的是没有校准过的数据,并拷贝至/etc/目录下。
4) 将参数传入内核。
ts_calibrate运行后会输出一个pointercal文件,最好简单修改一下输出格式,如运行一下:
cat $TSLIB_CALIBFILE > /proc/driver/micc_ts,

即可一次性输入七个参数。
当然也可以一个一个地输入,有点太麻烦,
5) 用ts_test测试校准效果。
注意:ts_test默认驱动输出的数据是未校准的,会另外再进行一次校准,需将main()函数中ts_read()改为ts_read_raw(),运行后,可看到校准后的效果。
6) Linux内核启动时,将校准参数传入内核。
修改/etc/init.d/rcS,加入如下行,在启动加载校准数据:
cat /etc/pointercal > /proc/driver/micc_t
s
这样通过直接读取触摸屏数据即可获得校准后数据
阅读(2312) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~