简单手势唤醒便携设备的设计思路及其代码
图1. MAX44000接近检测传感器信号强度随距离变化的关系曲线,采用18%灰板,100mA驱动电流,没有玻璃罩。
噪声和低通滤波
需要考虑噪声问题时,可利用低通滤波器处理信号;另外,MAX44000还有几个控制位可以用作触发中断标识之前的屏蔽,采用这种设置时,需要检测到一定数量超出门限的采样值时才会触发中断标示,能够在一定程度上降低噪声的影响。
一种稍微复杂的方法是将传感器的读数储存在数据队列中,然后利用定制的FIR软件对其进行滤波处理。但这种方法需要提高接近检测传感器的采样速率,否则则会降低能够捕捉到的传感器可视范围内的手势动作速率,特别是把采样速率设置在100ms时。利用器件的控制位屏蔽检测时,速率可最多降低16倍(通常选择4x屏蔽即可)。
手势速度
手势动作的快慢是我们需要考虑的另一因素。最大速度取决于:1. 传感器的可视范围;2. 手与传感器之间的距离;3. 采样率;4. 检测门限。前两项很容易确定:传感器的检测角度,结合传感器与目标之间的距离,利用基本的三角形即可计算出传感器可视范围内目标的移动距离。例如,如果传感器的视角为30度,最大有效检测距离10cm,那么,传感器可视范围内允许的目标移动距离为5.35cm,覆盖面积大约为78cm2。直线距离结合采样率,即可决定速度限值。具体地说,如果采样率为T,那么目标跨越可视区域的时间不得小于T。例如,如果T为100ms (MAX44000的最低采样速率),那么按照上例,理论上最大允许的速率为1mps (这实际上已经相当快了)。您可能希望捕获到多个采样值来确认触发唤醒,这样的话,会降低允许的速率下限。
检测门限也影响最大允许速率。一般来说,门限越低,能够捕捉到的手势动作就越快。如上所述,应谨慎选择门限,以免产生误报。
人为因素
这种应用还会受到人手以及挥手动作等人为因素的影响。应通过一些案例确定一般大多数人的习惯,包括他们在屏幕前挥动手掌的速度以及与屏幕之间的距离,另外,是否戴手套也会产生一定的影响。不同的应用场合(不同装置)也会影响到设计需求,例如智能手机、平板电脑或汽车仪表盘,对存在具体的设计考虑。当然,设计过程中还应考虑用户界面和经验参数。
最后,还要对真假手势做出判断,即装置需要判断接收到的信号是来自于一个手势动作,还是简单的装置移动(例如:放置在外套、口袋或背包中,或者是屏幕朝下放置)。单纯依靠上述检测原理,很难做出正确的“真伪”鉴别,除非在装置内提供更多的背景信息。关于这一问题的讨论超出了本文范围。
设计中可以选择只有装置进入特定的应用程序时启动唤醒方案,也可以由用户手动操作使能。此外,许多此类装置都有一个加速度传感器,能够检测到屏幕是否背面朝下放置。如果用户手动将装置置于休眠模式,则可禁用该功能(例如关机状态)。
设计实例
为方便起见,本文附带了三段演示程序代码。第一段代码用于手动操作MAX44000的接近检测数据读取,概念上简单实现唤醒功能;第二段代码在第一段的基础上进行了扩展,增加了之前讨论的滤波功能;最后一段代码演示利用MAX44000中断唤醒触控装置。
示例代码1
__interrupt void TimedInterrupt( void )
{
uint8 proximity_counts;
....
....
if ( device_status == SLEEP_MODE )
{
// read one byte from register 0x16
proximity_counts = read_i2c_register(MAX44000_ADDR,0x16,1);
if (proximity_counts > WAKEUP_THRESHOLD)
{
device_status = WAKE_MODE;
...
}
else
{
// do whatever it is you need to in sleep mode
...
...
}
}
...
...
}
示例代码2
// example interrupt function where this might be implemented
__interrupt void TimedInterrupt( void )
{
uint8 proximity_counts;
uint8 filtered_counts;
....
....
if ( device_status == SLEEP_MODE )
{
// read one byte from register 0x16
proximity_counts = read_i2c_register(MAX44000_ADDR,0x16,1);
// weights[QUEUE_SIZE] contains the filter weights for the FIR filter
// data_queue[QUEUE_SIZE] is a FIFO queue meant to be the input to the filter
filtered_counts = fir_filter(proximity_counts,weights,data_queue);
if (filtered_counts > WAKEUP_THRESHOLD)
{
device_status = WAKE_MODE;
...
}
else
{
// do whatever it is you need to in sleep mode
...
...
}
}
...
...
}
/**
* fir_filter()
*
* Implements an FIR filter in the form
* y = w[0]*x[0] + w[1]*x[1] + ...+ w[QUEUE_SIZE]*x[QUEUE_SIZE]
*
* Arguments:
* uint8 input - newest datapoint tak
- 设计用于嵌入式系统的图形用户界面(12-20)
- 复杂电路接地和供电的实用方法(07-06)
- 可穿戴设备有哪些图形内存需求?(03-16)
- 大联大世平集团推出基于 Intel、Rockchip、Spreadtrum的平板电脑解决方案(12-21)
- 大联大旗下富威推出基于晶晨M801的平板电脑参考设计(12-21)
- 智能手机和平板电脑设计中的单键开 / 关机和复位的智能方案(10-29)