电阻式触摸屏校准算法分析
<一> 算法分析
电阻式触摸屏在X,Y坐标方向上是线性的,比如S32采用的触摸屏,理论上Xmin=0,Xmax=1023,Ymin=0,Ymax=1023。但是实际的触摸屏,往往是xmin>0,xmax<1023,ymin>0,ymax<1023。所以就需要校准。
此文讨论的校准算法,其原理就是利用触摸屏的线性特性,针对被校准的触摸屏,获取其真正的x,y的范围,即xmin,ymin,xmax,ymax将其记录下来。以后当触摸事件发生,将触摸屏报告的原始坐标(x,y)按比例投射到0~1023的坐标上即可。注意,TP与LCD在相同的坐标方向上,具有相似性,即比例一致性。
看看对原始坐标的处理:
If (x<xmin) x=0;
El if (x>xmax) x=xmax-xmin;
El x=1023*(x-xmin)/(xmax-xmin);
If (y<ymin) y=0;
El if (y>ymax) y=ymax-ymin;
El y=1023*(y-ymin)/(ymax-ymin);
可见,对原始坐标,先减去一个0位置的偏移量(x-xmin),然后求得它X范围上的比率((x-xmin)/(xmax-xmin)),再乘以1023,就得到了投射到(0~1023)上的坐标。
再看看校准算法。在以下的讨论中,所谓物理坐标,指触摸屏上的坐标PT;所谓逻辑坐标,指LCD上的坐标PL。LCD的宽度(W)对应TP的X方向,LCD的高度(H)对应TP的Y方向。
通过点击三个校准点Po(x,y), Px(x,y), Py(x,y),我们能得到图中内层方框的X,Y的物理坐标范围,即
Xm = Px.x – Po.x Ym = Py.y – Po.y
将此图投射到LCD上,有如下(物理值->逻辑值)的对应关系:Xl->Lwl,Xm->Lwm,Xr->Lwr,Yb->Lhb,Ym->Lhm,Yt->Lht。根据TP与LCD的比例一致性,可以这样计算得到Xl,Xr,Yb,Yt:
Xl = (Xm/ Lwm) * Lwl Xr = (Xm/ Lwm) * Lwr
Yb = (Ym/Lhm) * Lhb Yt = (Ym/Lhm) * Lht
于是我们的目的达到了:
x范围:xmin = Po.x – Xl xmax = Px.x + Xr
y范围:ymin = Po.y – Yb ymax = Py.y + Yt
增值税暂行条例实施细则<二> 代码实现
1、对触屏上报的物理坐标值PT的处理。
PTx = (((x > input_dev->absmax[ABS_X]) ? (input_dev->absmax[ABS_X] - input_dev->absmin[ABS_X]) : ((x <= input_dev->absmin[ABS_X]) ? 0 : (x - input_dev->absmin[ABS_X]))) * 1023) /(input_dev->absmax[ABS_X] - input_dev->absmin[ABS_X]);
PTy = (((y > input_dev->absmax[ABS_Y]) ? (input_dev->absmax[ABS_Y] - input_dev->absmin[ABS_Y]) : ((y <= input_dev->absmin[ABS_Y]) ? 0 : (y - input_dev->absmin[ABS_Y]))) * 1023) /(input_dev->absmax[ABS_Y] - input_dev->absmin[ABS_Y]);
2、应用层根据上报的物理坐标,换算得到对应LCD宽高的逻辑坐标值PL。
PLx = (PTx/1023)*240
Ply = (Pty/1023)*400
3、校准数据的计算过程。
factor_x = (ts_cal_cmd.cur_ts_maxx - ts_cal_cmd.cur_ts_minx) / ts_cal_cmd.gui_w;
factor_y = (ts_cal_cmd.cur_ts_maxy - ts_cal_cmd.cur_ts_miny) / ts_cal_cmd.gui_h;
/* calculate the real boundary from the data collected by Android calibration application */
/*+++++++++++++++++++++++++++++++++++*/
high_adc_x = (ts_cal_cmd.p_ts.px.x * factor_x) ;
low_adc_x = (ts_cal_cmd.p_ts.po.x * factor_x) ;
high_adc_y = (ts_cal_cmd.p_ts.py.y * factor_y) ;
low_adc_y = (ts_cal_cmd.p_ts.po.y * factor_y) ;
unit_adc_x = (high_adc_x - low_adc_x)/((ts_cal_cmd.p_gui.px.x - ts_cal_cmd.p_gui.po.x) / ts_id_x_size);
unit_adc_y = (high_adc_y - low_adc_y)/((ts_cal_cmd.p_gui.py.y - ts_cal_cmd.p_gui.po.y) / ts_id_y_size);
g_ts_range.max_x = high_adc_x + ((ts_cal_cmd.gui_w - ts_cal_cmd.p_gui.px.x)/ts_id_x_size) * unit_adc_x;
g_ts_range.min_x = low_adc_x - (ts_cal_cmd.p_gui.po.x)/ts_id_x_size * unit_adc_x;
头痛英语
g_ts_range.max_y = high_adc_y + (ts_cal_cmd.gui_h - ts_cal_cmd.p_gui.py.y)/ts_id_y_size * unit_adc_y;
g_ts_range.min_y = low_adc_y - (ts_cal_cmd.p_gui.po.y)/ts_id_y_size * unit_adc_y;;
g_ts_range.y_th = unit_adc_y;
/*-----------------------------------*/
/* report the calibrated boundary data*/
/*+++++++++++++++++++++++++++++++++++*/有关家的歌曲
g_ts_range.min_x += ts_cal_cmd.cur_ts_minx;
g_ts_range.max_x += ts_cal_cmd.cur_ts_minx;
g_ts_range.min_y += ts_cal_cmd.cur_ts_miny;咳嗽痰里有血
g_ts_range.max_y += ts_cal_cmd.cur_ts_miny;
ts_cal_cmd.cur_ts_cal_minx = g_ts_range.min_x;
ts_cal_cmd.cur_ts_cal_maxx = g_ts_range.max_x;北京的蓝天
ts_cal_cmd.cur_ts_cal_miny = g_ts_range.min_y;
ts_cal_cmd.cur_ts_cal_maxy = g_ts_range.max_y;
4、填入代码中的默认校准数据
T_ts_calibrate_gui_cmd g_default_cal_data = {
1,
0,1023, 0,1023, //cur_ts_minx,maxx,miny,maxy
240, 400, // LCM: width/height defined in im9815_lcm.h
{ // Calibration points: po, px, py
{20, 20},
{220, 20},
{20, 380}
},
{ // Touch points: po, px, py
{20, 20},
{220, 20},
{20, 380}
},
20, 20, // x, y grid size
0,1023, 0,1023, //cur_ts_cal_minx,maxx,miny,maxy 一言九鼎造句
念奴娇赤壁怀古教学设计
};
<三> 实例分析
1、第1次使用触屏,进入图形校准界面。
2、载入默认校准数据g_default_cal_data,
3、得到3个校准点的物理坐标, 用默认校准数据参与处理,上报,最后转换为逻辑坐标。
点(20,20): 触屏得到的坐标Po(260,210)->上报坐标(260,210)->逻辑坐标(61,82)
点(220,20) 触屏得到的坐标Px(865,200) ->上报坐标(865,200)->逻辑坐标(203,78)
青螺点(20,380) 触屏得到的坐标Py(250,950) ->上报坐标(250,950)->逻辑坐标(59,371)
4、将得到的3个校准点的逻辑坐标,代入新校准数据的计算过程。