觸控設(shè)備手勢(shì)喚醒的設(shè)計(jì)思路及其實(shí)現(xiàn)
需要考慮噪聲問題時(shí),可利用低通濾波器處理信號(hào);另外,MAX44000還有幾個(gè)控制位可以用作觸發(fā)中斷標(biāo)識(shí)之前的屏蔽,采用這種設(shè)置時(shí),需要檢測(cè)到一定數(shù)量超出門限的采樣值時(shí)才會(huì)觸發(fā)中斷標(biāo)示,能夠在一定程度上降低噪聲的影響。
一種稍微復(fù)雜的方法是將傳感器的讀數(shù)儲(chǔ)存在數(shù)據(jù)隊(duì)列中,然后利用定制的FIR軟件對(duì)其進(jìn)行濾波處理。但這種方法需要提高接近檢測(cè)傳感器的采樣速率,否則則會(huì)降低能夠捕捉到的傳感器可視范圍內(nèi)的手勢(shì)動(dòng)作速率,特別是把采樣速率設(shè)置在100ms時(shí)。利用器件的控制位屏蔽檢測(cè)時(shí),速率可最多降低16倍(通常選擇4x屏蔽即可)。
手勢(shì)速度
手勢(shì)動(dòng)作的快慢是我們需要考慮的另一因素。最大速度取決于:1. 傳感器的可視范圍;2. 手與傳感器之間的距離;3. 采樣率;4. 檢測(cè)門限。前兩項(xiàng)很容易確定:傳感器的檢測(cè)角度,結(jié)合傳感器與目標(biāo)之間的距離,利用基本的三角形即可計(jì)算出傳感器可視范圍內(nèi)目標(biāo)的移動(dòng)距離。例如,如果傳感器的視角為30度,最大有效檢測(cè)距離10cm,那么,傳感器可視范圍內(nèi)允許的目標(biāo)移動(dòng)距離為5.35cm,覆蓋面積大約為78cm2。直線距離結(jié)合采樣率,即可決定速度限值。 具體地說,如果采樣率為T,那么目標(biāo)跨越可視區(qū)域的時(shí)間不得小于T。例如,如果T為100ms (MAX44000的最低采樣速率),那么按照上例,理論上最大允許的速率為1mps (這實(shí)際上已經(jīng)相當(dāng)快了)。您可能希望捕獲到多個(gè)采樣值來確認(rèn)觸發(fā)喚醒,這樣的話,會(huì)降低允許的速率下限。
檢測(cè)門限也影響最大允許速率。一般來說,門限越低,能夠捕捉到的手勢(shì)動(dòng)作就越快。如上所述,應(yīng)謹(jǐn)慎選擇門限,以免產(chǎn)生誤報(bào)。
人為因素
這種應(yīng)用還會(huì)受到人手以及揮手動(dòng)作等人為因素的影響。應(yīng)通過一些案例確定一般大多數(shù)人的習(xí)慣,包括他們?cè)谄聊磺皳]動(dòng)手掌的速度以及與屏幕之間的距離,另外,是否戴手套也會(huì)產(chǎn)生一定的影響。不同的應(yīng)用場(chǎng)合(不同裝置)也會(huì)影響到設(shè)計(jì)需求,例如智能手機(jī)、平板電腦或汽車儀表盤,對(duì)存在具體的設(shè)計(jì)考慮。當(dāng)然,設(shè)計(jì)過程中還應(yīng)考慮用戶界面和經(jīng)驗(yàn)參數(shù)。
最后,還要對(duì)真假手勢(shì)做出判斷,即裝置需要判斷接收到的信號(hào)是來自于一個(gè)手勢(shì)動(dòng)作,還是簡(jiǎn)單的裝置移動(dòng)(例如:放置在外套、口袋或背包中,或者是屏幕朝下放置)。單純依靠上述檢測(cè)原理,很難做出正確的“真?zhèn)?rdquo;鑒別,除非在裝置內(nèi)提供更多的背景信息。關(guān)于這一問題的討論超出了本文范圍。
設(shè)計(jì)中可以選擇只有裝置進(jìn)入特定的應(yīng)用程序時(shí)啟動(dòng)喚醒方案,也可以由用戶手動(dòng)操作使能。此外,許多此類裝置都有一個(gè)加速度傳感器,能夠檢測(cè)到屏幕是否背面朝下放置。如果用戶手動(dòng)將裝置置于休眠模式,則可禁用該功能(例如關(guān)機(jī)狀態(tài))。
設(shè)計(jì)實(shí)例
為方便起見,本文附帶了三段演示程序代碼。第一段代碼用于手動(dòng)操作MAX44000的接近檢測(cè)數(shù)據(jù)讀取,概念上簡(jiǎn)單實(shí)現(xiàn)喚醒功能;第二段代碼在第一段的基礎(chǔ)上進(jìn)行了擴(kuò)展,增加了之前討論的濾波功能;最后一段代碼演示利用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
...
...
}
}
...
...
}
評(píng)論