多点触控已是当今触控技术开发者最热衷的研究课题。看似简单的触控动作,其实背后隐藏着错综复杂的运作过程,包括将触控动作转成数位讯号,并推算触碰位置,然后和主控端进行通讯并执行解译等步骤,每一个设计环节都将影响最终效能的呈现。
本文将对追踪触碰动作进行全面的阐述,从电容感测的物理原理,一直到萤幕的最终动作。包括介绍系统如何侦测到手指的位置,以及判读手指位置的各种方法,并介绍手机的软体堆叠,说明应用程式的设计方法,最后再揭露双指捏放手势与萤幕缩放之间的设计内幕。
电容/系统设置到位触控操作更灵活
大部分的智慧型手机触控萤幕都能对手指电容产生反应,触控萤幕内有许多排列整齐的感测器,会侦测出因手指移动所导致的电容变化。当你的手指触碰到萤幕时,就会影响这些感测器的自容(Self-capacitance),以及彼此之间的互容(Mutual Capacitance)。大多数智慧型手机都是感测互容而不是自容。由于互容是反映一对感测器之间的互动关系,因此可用来收集有关萤幕上每个位置的资讯(X×Y个感测点);自容则仅能用来侦测每个感测器的反应(X+Y个样本),而不是每个点。
电容感测含有数个层:顶层是玻璃或塑胶材质,接者依序是一个光学透明胶(OCA)层、触控感测器及平面液晶显示器(LCD)。触控感测器是由许多感测元件所排列而成的网格,尺寸通常为5毫米×5毫米。
这些感测器采用氧化铟锡(ITO)制成。 ITO具有许多特别的属性,为制作触控萤幕的绝佳材质:超过90%透明度并具有导电性。有些设计采用钻石状图纹,不会和LCD的纹线重叠,视觉观感较佳,其他则采用较简单的「直条与横条」图案设计。如果在充分的光照下,以正确的角度观察你的装置,并关闭液晶萤幕,就能看到ITO感测器的线纹。
图1 互容基本原理
基本上,感测互容的原理(图1)和感测自容完全不同。感测自容通常是量测含有感测器的电阻-电容(RC)电路之时间常数;感测互容的程序则包括量测X轴与Y轴感测器之间的互动。系统会感测经过每个X轴与Y轴的讯号,借此侦测感测器之间的耦合值(图2)。耐人寻味的是,手指的触碰动作会降低互容耦合值,但手指触碰动作却会增加自容的值。
图2 互容侦测反应
不论是哪一种方法,光量测电容是不够的,系统必须回应的是电容的变化,而不是个别的电容值。系统会对每个感测器设定一个基准值,这个基准值是经过长时间温度与其他因素变化后求出的讯号长期平均值,让系统允许讯号在各种状况下产生些微的波动。在建构触控萤幕系统时面临其中一项挑战,就是建立适当的基准值。例如,当手指触碰到萤幕,系统必须能适当地启动。当沾水的手指或手掌碰到萤幕时,系统也必须能启动。
当感测到的电容减去基准值时,就得到一个讯号值阵列,代表图3所示的手指触碰状况。有许多种方法可根据这项资讯来判断手指的位置,其中最简单的方法是计算质心--质量中心(Centriod),计算出一维或二维轴向感测数值的加权平均值。运用一维质心计算法,根据上述例子的X轴数据,可算出(5×1+15×2+25×3+10×4)/(5+15+25+10)=150/55= 2.73。接着以液晶萤幕的解析度为标准,将这个位置值适当地缩放,以便和萤幕重叠。若ITO感测器的图案超出液晶萤幕的边缘,则必须进行一些转换计算。
图3 由个别的电容值判定手指位置
接触范围的边缘,让手指位置的问题变得更复杂。举上述的阵列为例,若面板的边缘处碰到这些线条区,采用上述的简单质心推算法,当左侧下移时,右侧就会开始被「上拉」。为解决这个问题,必须用特别的边缘处理技巧来检查剩下讯号的形状,再推测手指没有接触到萤幕表面的部分。
CPU/USB助阵 触控感测功能升级
当一个有效的触碰讯号出现,且触碰动作的X/Y轴座标被侦测到之后,主控端中央处理器(CPU)就可以得到要处理的资料。嵌入式触控萤幕元件会透过I2C介面或串列周边介面(SPI)来进行通讯。较大尺寸的触控萤幕通常会采用通用序列汇流排(USB)介面,因为包括Windows、Mac OS以及Linux等作业系统,都有内建USB介面的人机介面装置(HID)支援功能。
虽然采用多个不同的介面,作业系统的驱动程式到最后做的事却大致类似,以Android的驱动程式为例,由于Android与MeeGo都以Linux为开发基础,因此这三种作业系统都使用类似的驱动程式。
触控萤幕驱动程式的岔断触发器是一个岔断服务函式(Interrupt Service Routine, ISR),负责作业执行绪的排程。 ISR中并没有执行任何作业来维护岔断的延迟以及避免优先权倒置。当作业系统呼叫作业执行绪,会启动一个通讯交易,从装置读取资料,然后切换至睡眠模式。当通讯交易完成后,主控端驱动程式就得到自己要处理的资料。
主控端驱动程式会把装置制造商采用的资料格式,转换成标准格式。在Linux环境中,驱动程式会透过一连串的次函式(Subroutine)呼叫来复制事件区域,接着再透过一个最终呼叫来传送事件资料。例如,要建立一个单一触碰Linux输入事件,整段程式可写成:
input_report_abs(ts->input, ABS_X, t->st_x1); // Set X location
input_report_abs(ts->input, ABS_Y, t->st_y1); // Set Y location
input_report_abs(ts->input, ABS_PRESSURE, t->st_z1); // Set Pressure
input_report_key(ts->input, BTN_TOUCH, CY_TCH); // Finger is pressed
input_report_abs(ts->input, ABS_TOOL_WIDTH, t->tool_width);// Set width
input_sync(ts->input);// Send event
提升触控效能 Android不可或缺
这个触控事件之后交给作业系统来处理,如Android会把事件的历史资料储存在手势处理缓冲区,然后把事件传递给View这个类别。有多款触控萤幕元件,如赛普拉斯(Cypress)TrueTouch产品已经支援硬体手势处理功能(图4)。硬体手势处理功能可纾解主控端作业系统的负荷,分担手势处理的工作,还能依照不同情况免去处理所有触控资料的负担,一直到看到手势为止。
图4 手势触控类型
举例来说,若你正开发相片浏览器,主控端不必处理数十或数百个触控事件的封包,就能让使用者翻阅下一张相片,直到使用者实际翻阅下一张相片之前,不会出现任何岔断。
感测/回应Android View/Widget至关重要
Android的View类别会判断触控事件发生时系统正执行哪些应用,在萤幕上显示的每个应用,都有至少一个View类别。这个类别中含有许多方法负责处理使用者的输入,其中包括OnTouchListener,负责处理从输入驱动器收到的资讯,以及MotionEvent中的额外资讯。
如果你曾写过Windows环境下能接收滑鼠事件的程式,就会惊讶地发现滑鼠事件与触控介面之间的差异。 MotionEvent这个类别内含许多方法,包括WM_LBUTTONDOWN常见到的方法,例如GetX与GetY,以及处理触控的位置还有手指停留在面板上的时间。
当应用看到事件后,就会对触控动作做出回应,这种回应通常是由微程式(Widget)来执行,而不是由应用程式来负责。 Android的Widget内含一些简单项目,像是按钮等,还有包括许多复杂的介面,像是资料挑选器(Data Picker),以及附有取消钮的进度显示条视窗。
应用程式也可直接处理与回应触控动作。绘图程式可选择混用两种方法,在绘图区使用直接触控输入功能,并搭配Widget负责处理选单与按钮的操作功能。
Windows /Android手势辨认各擅胜场
Windows Touch处理功能与Android之间的一项差别,就是解译手势。 Android提供为数众多的手势创作工具,但没有提供任何内建的手势定义。每个设计者都可自由创作自己的手势(图5),包括像手写辨识等复杂的手势。这种方法催生出许多应用,像是字符辨识的搜寻功能,但意谓在两个不同的Android平台上,同样的手势动作启动的是不一样的功能。
图5 Google通用公共授权Android标志
至于Windows则提供一组固定且众所周知的手势,并支援作业系统层级应用,包括GID_PAN、GID_ZOOM、GID_ROTATE、GID_PRESSANDTAP及GID_TWOFINGERTAP。这些手势动作在任何程式都启动相同的动作,这点让使用者能快速学会使用新程式。两种方法都各自有其优点。
触控设计迈向未来的过程中会遇到技术层面的挑战,还得应付许多层面之间的互动问题。从选择材料、制造到电子,都是触控感测必须面临的议题。当系统把触控动作转成数位讯号后,还必须推算其位置和主控端进行通讯以及执行解译等步骤。如今这些问题都已被克服,软体研发业者必须在这些基础上开发令人惊艳的应用。
|
||||||
|
||||||