现在的位置: 首页 > 综合 > 正文

触摸屏驱动 之 校正(一)

2017年05月18日 ⁄ 综合 ⁄ 共 2685字 ⁄ 字号 评论关闭

触摸屏为什么点不准之触摸屏校准教程

嵌入式环境下,触摸屏是鼠标的替代也是升级输入设备,下面我们来研究一下触摸屏。

1.基础知识

触摸屏的原理这里不讲,只说下大体思路,触摸屏硬件能够接收到来自用于的触摸,通过若干方式,把数据转换成坐标,此时,坐标是物理坐标,即触摸屏的坐标,而不是显示设备的坐标,显示设备的坐标由软件来定义,而触摸屏的物理坐标是固定的。所以,当我们点击触摸屏,数据被送给驱动,驱动送给应用程序时,我们得到的数据还不是真正的显示设备数据哦,比如点击一点,硬件传来的是(189
123
),(我们约定x在前),这时如果我们说,屏幕上的(189123)点有点击,这时不正确的,这个很容易明白的,物理的点只是采样到的点,并不是真正意义上的显示设备的坐标,毕竟显示坐标由我们来定。那么怎么办呢?~这时,需要校准触摸屏,所有的触摸屏使用前,必须要经过校准。

2.触摸屏校准原理

以上说了触摸屏需要校准的原因,问题出在,物理坐标和屏幕坐标并不匹配,不匹配有两个方面:

第一,物理坐标的1个单位和屏幕坐标的1个单位并不相等,我们知道屏幕坐标1个单位一般是一个像素,而物理坐标的1个单位并不是1个像素.

第二,假设我们把屏幕的左上角定义为(00),那么触摸屏的左上角的物理坐标并不是(0 0)(我们点击之后的物理采样数据)。

综上,校准有两个方面

第一,物理采样坐标与屏幕像素坐标的对应关系,也就是伸缩系数,即单位物理采样数据代表几个单位屏幕像素数据,x坐标和y坐标各有一个伸缩系数,分别记作:xScaleyScale。计算方法很简单,为了精确,可以采样屏幕上的四个点,让用户点击,比如(20
20
),(20200),(300, 200)(300 20),通过横着的线段除以物理采样的数据线段,得到了x的伸缩系数。同理可以得到y的伸缩系数。

第二,物理坐标的相对于屏幕像素坐标的偏移,假如我们不计算偏移,只计算伸缩系数的话,假设用户在屏幕点(20 20)点击,我们经过转换物理采样数据,即乘上伸缩系数,发现,校准后的数据并不是(2020)点,原因就是因为有偏移,原因是触摸屏的物理采样数据,在左上角并不是(00),而是某个正数对,采样到的数据不会是0的,这就是偏移产生的原因,所以,在计算过伸缩系数之后,比如点击屏幕(2020),采样到的数据是(4578),而第一步计算出的伸缩系数分别是0.780.67,那么物理坐标转换成屏幕坐标后是(45*0.78
78*0.67
),此时虽然我们得到了物理坐标对应的屏幕坐标,但是现在屏幕坐标和我们(2020)所在的屏幕坐标并不在一个坐标系,即(00)点不同,所以我们要减去一个坐标系偏移,假设分别是xOffsetyOffset,那么两个坐标做差便得到了xOffsetyOffset。根据上面的四个参数,我们来举个例子,假如屏幕坐标左上角为(00),当我们点击屏幕,此时我们从驱动那里得到物理xy数据,分别乘上xScaleyScale得到相对屏幕坐标,减去(平移)xOffsetyOffset,得到了当前的屏幕坐标。

3.示例代码:

typedef struct tagDATA
{
 double xScale; //
物理坐标xlcd像素坐标x的比例关系,即每个物理坐标代表多少个像素坐标,真实的坐标x=测量出的物理坐标*xScale
 double yScale; //
同上

 int xOffset; //x
轴偏移,即物理坐标1212如果是lcd左上角的点的物理采样数据,那么x偏移是12-0
 int yOffset; //
同上

 int turn; //
旋转角度,即把触摸屏的直线定义为0度,lcd上相同的一条直线相对于0度的偏移角度(暂时不使用)
}TSCALDATA;

 
intpointBas[5][2] =
{
 0, 0,
 20, 20,
 20, 200,
 300, 200,
 300, 20,
};
//4
个校准点,从物理采样得到
int pointGet[5][2];

 double tmpBas =0.0;
 double tmpGet = 0.0;
 //xScale
 tmpBas = (( (double)pointBas[4][0] -(double)pointBas[1][0] ) + ( (double)pointBas[3][0] -(double)pointBas[2][0]))/2.0;
 tmpGet = (( (double)pointGet[4][0] -(double)pointGet[1][0] ) + ( (double)pointGet[3][0] -(double)pointGet[2][0]))/2.0;
 tsCalData.xScale = tmpBas/tmpGet;
 
 //yScale
 tmpBas = (( (double)pointBas[2][1] -(double)pointBas[1][1] ) + ( (double)pointBas[3][1] -(double)pointBas[4][1]))/2.0;
 tmpGet = (( (double)pointGet[2][1] -(double)pointGet[1][1] ) + ( (double)pointGet[3][1] -(double)pointGet[4][1]))/2.0;
 tsCalData.yScale = tmpBas/tmpGet;

 //xOffset
 tmpBas = (((double)pointGet[4][0]*tsCalData.xScale - (double)pointBas[4][0] ) + ((double)pointGet[1][0]*tsCalData.xScale - (double)pointBas[1][0]))/2.0;
 tsCalData.xOffset = (int)tmpBas;

 //yOffset
 tmpBas = (( (double)pointGet[4][1]*tsCalData.yScale- (double)pointBas[4][1] ) + ( (double)pointGet[1][1]*tsCalData.yScale -(double)pointBas[1][1]))/2.0;
 tsCalData.yOffset = (int)tmpBas;

 //write data tofile
 datFd =fopen("../etc/tsCalDat", "wb+");
 fwrite(&tsCalData, sizeof(TSCALDATA),1, datFd);
 fclose(datFd);

 

抱歉!评论已关闭.