还剩7页未读,继续阅读
文本内容:
简单手势唤醒便携设备的设计方案导读:本文讨论如何唤醒平板电脑等触控装置,无需接触设备,而是采用基本的手势识别及新颖的接近检测传感器本文讨论了相关设计的物理布局、速度限制、检测门限、系统集成,以及人为因素的影响;给出了软件实时的例程厨房里的突发奇想 如果做饭时使用触控设备,您可能会注意到按照设备列出的食谱烹饪并非想象得那么简单技术达人(例如鄙人)走进厨房时,喜欢看着平板电脑或智能手机上的菜谱做饭您可能会说“好吧,这有什么难度?”由于屏幕始终开启会消耗很大电量,通常手持装置在
1、2分钟后没有操作时将自动进入休眠状态那么,当您需要参照食谱时,设备已进入休眠状态此事,您面临两个选择要么强制屏幕保持永久开启;要么用沾满食物的手开启装置,而在屏幕上留下斑斑油渍当然,您可以在每次查看时把手清洗干净,但不断重复洗手、擦干即繁琐,又费水 我时常问自己“____既不让屏幕始终开启,又不会弄脏装置?”实际上,有一种办法一举两得,即通过一个手势(不用接触屏幕)开启显示屏听起来似乎很复杂,是吗?幸运的是,做起来可能比听起来容易一些 接近检测传感器(传感器资料__E讯网) 许多触摸屏装置,尤其是智能手机,内部已经__了红外(IR)接近检测传感器这些传感器一般在通话期间自动打开/关闭屏幕,以避免意外操作手机的输入界面这种传感器技术,加上精明的软件设计,就能实现利用一个手势唤醒装置的功能 基本的设计思路是设备进入休眠状态时,触摸屏关闭,应用处理器处于低功耗模式,依靠接近检测传感器“观察”背景的变化,当接收到的__足够大时,做出适当反应这与接近检测传感器在通话期间关闭屏幕的功能几乎完全相同只是,我们的应用对数据有了不同的解释 首先记录传感器在“正常”背景下的计数值,此时得到的数值可能为零,但实际设计中需要考虑系统失调(例如散射或串扰)然后将得到的数值设置为检测门限,当接收__超过门限时触发中断或向应用处理器发送__,以唤醒系统并打开屏幕总体而言,这种方法非常简单、直观,可利用环境光检测器和IR接近检测传感器实现 本文介绍的方案采用__X44000,接近检测的数据读取时间间隔可以设置在
1.56ms至100ms(与环境光检测传感器轮流读取数据)假设最大检测距离为10cm,LED的辐射角为±15°,那么,可以覆盖的__大约为22cm2或跨距大约为
5.35cm,只有该区域内的__目标才能捕捉到由此,能够以最慢(即最低功耗)的采样速度可靠检测的最快手势动作大约为
0.53mps.在此,我们还假设传感器只需要采集到一次高于门限的__,即可识别经过覆盖区域的目标 举手之劳 理论上讲,该方案的实施非常简单当装置进入休眠模式时,将接近检测传感器置为环境扫描模式,并在检测到目标时发出中断__,指示捕捉到超过预设门限的__可通过I2C接口轮询传感器的状态不幸的是,这种方式会消耗过大功率,超出了大多数用户的预期 这也是接近检测传感器的设计重点,__X44000传感器能够在许多方面摆脱应用处理器的干预,减轻处理器负荷(降低功耗) 使能__X44000的内部接近检测中断(寄存器0x01的第1位),可将唤醒门限写入内部寄存器(0x0B和0x0C)当接近检测传感器的读数超过该门限时,触发中断标识置位,将__X44000的/INT引脚置为低电平当应用处理器检测到该引脚驱动为低电平时,可唤醒装置退出低功耗模式,并打开屏幕,或完成其它需要的动作 但不容忽视 实际应用往往不如理论那么容易,非接触唤醒的具体实施并非只是简单地检测高于门限的__实际上,具体的设计需要考虑诸多因素 __电平与电路布局 最关键的考虑应该是触发唤醒条件的__电平,需要在系统响应灵敏度与误报概率之间进行权衡如果门限过低,则很容易检测到输入(手势工作),但会增大瞬态噪声或突发条件产生误报的概率反之,过高的检测门限能够把误报概率降至几乎为零,但却只能检测到非常接近的目标,甚至对任何输入(即使您疯狂晃动手臂)都反应迟钝 解决这一问题的最佳方式是首先降低系统噪声,可以通过光学方法或严谨的电路布局实现,降低的噪底有助于降低误报概率;其次,选择“平均”检测距离(例如4cm至5cm)并利用参考目标测量__,18%的灰板比较理想,但如果触摸屏上方__了黑色玻璃,测量时也应该使用这样的玻璃,所测得的__电平可以作为设置门限的最佳参考通常可以遵循这样的原则即将电平设置在满幅的8%至15%,即使电平发生变化 可以按照上述经验数据设置__X44000传感器的接近检测门限寄存器,图1所示为__强度随距离变化的关系曲线,采用18%灰板,驱动电流为100__,传感器上方没有玻璃罩蓝线为可以选择的唤醒门限图
1.__X44000接近检测传感器__强度随距离变化的关系曲线,采用18%灰板,100__驱动电流,没有玻璃罩噪声和低通滤波 需要考虑噪声问题时,可利用低通滤波器处理__;另外,__X44000还有几个控制位可以用作触发中断标识之前的屏蔽,采用这种设置时,需要检测到一定数量超出门限的采样值时才会触发中断标示,能够在一定程度上降低噪声的影响 一种稍微复杂的方法是将传感器的读数储存在数据队列中,然后利用定制的FIR软件对其进行滤波处理但这种方法需要提高接近检测传感器的采样速率,否则则会降低能够捕捉到的传感器可视范围内的手势动作速率,特别是把采样速率设置在100ms时利用器件的控制位屏蔽检测时,速率可最多降低16倍(通常选择4x屏蔽即可) 手势速度 手势动作的快慢是我们需要考虑的另一因素最大速度取决于
1.传感器的可视范围;
2.手与传感器之间的距离;
3.采样率;
4.检测门限前两项很容易确定传感器的检测角度,结合传感器与目标之间的距离,利用基本的三角形即可计算出传感器可视范围内目标的__距离例如,如果传感器的视角为30度,最大有效检测距离10cm,那么,传感器可视范围内允许的目标__距离为
5.35cm,覆盖__大约为78cm
2.直线距离结合采样率,即可决定速度限值具体地说,如果采样率为T,那么目标跨越可视区域的时间不得小于T.例如,如果T为100ms(__X44000的最低采样速率),那么按照上例,理论上最大允许的速率为1mps(这实际上已经相当快了)您可能希望捕获到多个采样值来确认触发唤醒,这样的话,会降低允许的速率下限 检测门限也影响最大允许速率一般来说,门限越低,能够捕捉到的手势动作就越快如上所述,应谨慎选择门限,以免产生误报 人为因素 这种应用还会受到人手以及挥手动作等人为因素的影响应通过一些案例确定一般大多数人的习惯,包括他们在屏幕前挥动手掌的速度以及与屏幕之间的距离,另外,是否戴手套也会产生一定的影响不同的应用场合(不同装置)也会影响到设计需求,例如智能手机、平板电脑或汽车仪表盘,对存在具体的设计考虑当然,设计过程中还应考虑用户界面和经验参数 最后,还要对真假手势做出判断,即装置需要判断接收到的__是来自于一个手势动作,还是简单的装置__(例如放置在外套、口袋或背包中,或者是屏幕朝下放置)单纯依靠上述检测原理,很难做出正确的“真伪”鉴别,除非在装置内提供更多的背景信息关于这一问题的讨论超出了本文范围 设计中可以选择只有装置进入特定的应用程序时启动唤醒方案,也可以由用户手动操作使能此外,许多此类装置都有一个加速度传感器,能够检测到屏幕是否背面朝下放置如果用户手动将装置置于休眠模式,则可禁用该功能(例如关机状态) 设计实例 为方便起见,本文附带了三段演示程序代码第一段代码用于手动操作__X44000的接近检测数据读取,概念上简单实现唤醒功能;第二段代码在第一段的基础上进行了扩展,增加了之前讨论的滤波功能;最后一段代码演示利用__X44000中断唤醒触控装置 示例代码1 __interruptvoidTimedInterrupt(void) { uint8proximity_counts; … … if(devi___status==SLEEP_MODE) { //readonebytefromregister0x16 proximity_counts=read_i2c_register(__X44000_ADDR,0x16,1); if(proximity_countsWAKEUP_THRESHOLD) { devi___status=WAKE_MODE; … } else { //dowhateveritisyouneedtoinsleepmode … … } } … … }示例代码2 //exampleinterruptfunctionwherethismightbeimplemented __interruptvoidTimedInterrupt(void) { uint8proximity_counts; uint8filtered_counts; … … if(devi___status==SLEEP_MODE) { //readonebytefromregister0x16 proximity_counts=read_i2c_register(__X44000_ADDR,0x16,1); //weights[QUEUE_SIZE]containsthefilterweightsfortheFIRfilter //data_queue[QUEUE_SIZE]isaFIFOqueuemeanttobetheinputtothefilter filtered_counts=fir_filter(proximity_counts,weights,data_queue); if(filtered_countsWAKEUP_THRESHOLD) { devi___status=WAKE_MODE; … } else { //dowhateveritisyouneedtoinsleepmode … … } } … … } /** *fir_filter() * *ImplementsanFIRfilterintheform *y=w[0]*x[0]+w[1]*x[1]+…+w[QUEUE_SIZE]*x[QUEUE_SIZE] * *Arguments *uint8input-newestdatapointtaken(thatis,x[0]) *uint8*weights-w[0]…w[QUEUE_SIZE] *uint8*queue-thediscretesequen__x[0]…x[QUEUE_SIZE] * *Returns *TheFIR-filteredoutput,y */ uint8fir_filter(uint8input,uint8*weights,uint8*queue) { uint8i; intsum=0; //popfirstentryinthequeue,then //pushnewdataintothelastposition push_into_queue(queue,input); //inputisnowx[0] for(i=0;i{ sum+=weights[i]*queue[i]; } return(sum/QUEUE_SIZE); }示例代码3 //thishandleshardware-levelinterruptsonthemicro __interruptvoidirq_handler(void) { … //ifthehardwareinterruptcamefromthe__X44000sensor //pullingits\INTpinlow if(irq_sour__==__X44000) { //ifthedevi__isinsleepmode if(devi___status==SLEEP_MODE) { devi___status=WAKE_MODE;//wakeupthedevi__ … //reconfigurewhateverelseyouneedhereasthesystemwakesup } //otherwise,handleithoweveritisyouwish else { … } } … } /** *configure___x44000_for_sleep_mode() * *Setsupthe__X44000totriggerahardwareinterruptwhentheproximity *countsgoabovesomesetthreshold. * *Arguments *uint8upper_threshold-thesetthreshold(8-bitmode) * *Returns *n/a */ voidconfigure___x44000_for_sleep_mode(uint8upper_threshold) { uint8__x44000_thresh_registers[]={0x0B,0x0C}; uint8__x44000_upper_thresh[]={0x40,0}; __x44000_upper_thresh[1]=upper_threshold; //doaconsecutivewriteof0followedbyupper_thresholdto //registers0xBand0xC,respectively //__X44000_ADDRisusually0x94 //interruptwilltriggeronlyifproximityvalueisabovethethreshold write_i2c_register(__X44000_ADDR,__x44000_thresh_registers, __x44000_upper_thresh,2); //writetobits2and3ofregister0x0Ahereifyouwishtosetthe //persisttimetoanythingotherthanonesample //writestoregister0x01toenableinterruptsonthe__X44000 __x44000_enable_interrupt(); return; }。