閱讀24 返回首頁    go 阿裏雲 go 技術社區[雲棲]


《Arduino計算機視覺編程》一3.2 傳感器數據采集

本節書摘來自華章出版社《Arduino計算機視覺編程》一書中的第3章,第3.2節,作者[土耳其] 歐森·奧茲卡亞(zen zkaya),吉拉伊·伊利茨(Giray Yilliki),更多章節內容可以訪問雲棲社區“華章計算機”公眾號查看。

3.2 傳感器數據采集

對大多數實時應用程序來說,視覺信息和傳感器信息的結合對於更好地理解環境是至關重要的。係統的整體性能和各個子模塊緊密相關,因此有效恰當地實現傳感器數據采集就變得非常重要。
即使檢測的是相同的物理對象,也有很多不同的傳感器。舉一個簡單例子,有很多不同類型的溫度傳感器,盡管它們都是設計用來測量溫度的。如果你想測量皮膚的溫度而不是大氣溫度,那麼該如何選擇一個合適的傳感器?該如何選擇一個采樣間隔?如何處理噪聲?本章的目的是讓你徹底了解傳感器數據采集。在本章的結尾部分有一個用Arduino Uno R3開發的實際傳感器接口的例子。
3.2.1 設置Arduino環境
如前所述,Arduino對於嵌入式係統應用的快速建模來說是一個非常完美的平台。在合適的背景下,因為擁有龐大的庫以及社區支持,Arduino也是一個合適的傳感器數據收集工具。
要開發Arduino應用,你需要在Arduino官方網站(https://arduino.cc/en/Main/Software)下載Arduino集成編輯器。在本書中,所有的應用程序都使用Arduino Uno R3。但同樣的原則通用於其他Arduino平台。下圖為一個典型的Arduino的集成編輯器。

2701cfd0921dad12f3e868e6414d5d9f074364e9

準備好你的Arduino Uno R3,下載Arduino集成編輯器並且設置好環境。安裝過程就和安裝其他應用一樣簡單。然後就可以開始實踐了!
3.2.2 傳感器基礎
重要的是理解傳感器基礎進而充分理解傳感器的接口。在本節中,將會討論基礎的傳感器分類、采樣定理以及處理噪聲的方法。你會學到很多傳感器的知識以及如何在計算機視覺應用中有效地使用它們。
3.2.2.1 傳感器類型
傳感器的類型幾乎是無窮無盡的,但即使如此,對傳感器做一個有意義的分類也有助於選擇所需的傳感器。
最基本的分類方法是基於測量的物理參數。溫度、光照等級、壓力、加速度和濕度都是物理參數的例子。盡管物理參數眾多,但是絕大多數的接口是類似的。一旦你搞明白一個參數並且充分實踐,測試其他物理參數也很容易。
可以根據輸出信號類型將傳感器分為兩類:模擬傳感器和數字傳感器。模擬傳感器輸出連續信息。數字傳感器輸出離散信息。
因為幾乎所有的嵌入式係統都是數字係統,所以在任何情況下,在嵌入式係統中都應該使用傳感器數據的數字格式進行處理。由於這個原因,所有的模擬傳感器都使用特殊的外接模擬數字轉換器(Analog to Digital Converto,ADC)作為接口。這使得我們的開發變得非常簡單。可以使用大致相同的代碼以讀取溫度傳感器數據的方式來讀取光照傳感器的數據。當然,讀出數據的解釋方法是不同的。
通常情況下,數字傳感器都是通過相同的嵌入式通信接口(外設)進行訪問,這些通信接口包括通用同步和異步接收/發送器(USART)、內部集成電路(Inter Integrated Circuit,I2C)以及串行外設接口(Serial Peripheral Interface,SPI)。通過訪問名為寄存器的特殊內存區域,可以設置傳感器並讀取傳感器內部的數據。因此,數字傳感器一般提供了更多可以設置的選項。正因如此,複雜的傳感器比如運動傳感器往往設計為有一個數字格式的接口。最好的消息是一旦你學會使用這些通信接口,其他類型的傳感器的使用都是大同小異的!需要注意的是Arduino集成編輯器提供了與這些通信方式進行接口的庫,這使得這些傳感器更加易於使用。
所以,準備開始學習如何使用這些接口吧!在接下來的內容中,將會覆蓋關於傳感器數據讀取的兩個重要主題:采樣率和噪聲抑製。
3.2.2.2 采樣理論
傳感數據的采樣定義了從傳感器讀取出來的數據的采樣率。如果你需要實時的采樣傳感器數據,那麼應該多久對輸入數據采樣一次?每50ms或是100ms采樣一次是否足夠呢?你該如何確定最佳的采樣率?關於這個問題的一個比較簡單的答案是多試幾個采樣率然後選用效果最佳的那個!但是,這麼做當然失敗率很高。
在信號處理中,Nyquist判據用於確定采樣率。Nyquist判據隻是簡單陳述了采樣率必須至少是輸入信號最高頻率分量的頻率的2倍。給定這麼一個采樣率,可以重建原始輸入信號而不會丟失原始輸入信號攜帶的信息。如果你知道信號的最大頻率分量的頻率是多少,那麼這種方法是非常不錯的。即使在這種情況下,采樣率是信號最大頻率分量的頻率的5倍也是安全的。
但是一般情況下,不太可能限定傳感器數據的最大頻率分量。所以,當選擇傳感器的采樣率時,基於知識推斷一個采樣率的效果更好。很幸運的是數字傳感器的采樣率一般可以通過考慮傳感器的目的進行良好的推測。但是如果使用的是模擬傳感器,你就需要考慮各種限製來猜測一個采樣率了。其中一個選項是選擇盡可能高的采樣率,但是這並不是一個好主意,因為這會導致顯著增多的能量消耗、存儲器占用以及計算時間,所以這個方案會對我們想要盡量控製的東西產生不利影響。因此,解決這個問題必須采用其他的方法。
試想一下如果你想對大氣的溫度數據進行采樣。房間的溫度在一秒鍾內變化10℃是不正常的。在這個示例應用程序的環境中每10s采樣一次在大部分情況下是足夠的。但是如果我們想對加速計進行采樣來檢測運動,應該看下要檢測的最快的運動是什麼,比如在手勢檢測中,最快的運動可能是持續2s左右的手勢。要能夠分離出手勢的模式來,可能需要從手勢的運動中進行200次采樣,所以采樣率為2/200 = 10ms(相當於100Hz),對於這個例子來說這是一個很好的起點。通過這種簡單的推斷有可能確定最佳的采樣頻率。
3.2.2.3 處理噪聲
如果我們要從傳感器中捕獲數據,那麼捕獲的實際測量值裏麵會包含噪聲。在實踐中完全消除噪聲是不可能的,但是可以把噪聲降到一個可接受的範圍內。醫學應用程序的噪聲容忍度很自然地要比一個業餘時間開發的應用程序低。請不要忘記能接受什麼程度的噪聲完全是由應用程序決定的。
與傳感器噪聲的“戰爭”從傳感器的電子接口就開始了。但願每一個廠家都在傳感器用戶手冊或者數據表中放了一個采樣驅動電路(sample driving circuit)。請遵循這個參考設計,除非你有一個足以改變遊戲規則的絕妙設計。
另一個處理噪聲的方法是進行過濾處理來部分地從傳感器數據裏麵移除噪聲。如同采樣率的選擇過程一樣,應用程序的上下文會對傳感器數據的過濾處理產生影響。舉例來說,如果你在處理溫度傳感器的數據,你可以簡單地移除那些高頻數據,它們就是噪聲。這是因為1s發生10℃的變化是非常不合理的。同樣,對於運動檢測,你可以從應用程序中移除那些頻率過高或者過低的部分。
噪聲抑製可以通過基於硬件或者軟件的方案來解決。基於硬件的方案需要電路上的額外組件來實現。另一方麵,基於軟件的方案可以通過編碼來實現。一般在需要非常快速過濾的情況下才會選擇基於硬件的方案,因為它的花費更高。很多時候改變電路不是很方便,所以使用基於軟件的噪聲抑製方案更容易也更加靈活。
因為嵌入式係統的資源往往是有限的,我們不能在嵌入式係統上使用非常複雜的濾波器。但是這不意味著在嵌入式係統上沒有辦法進行有效的過濾。在下麵兩個例子中,你將看到一些簡單有效的過濾實現。
3.2.3 從溫度傳感器中讀取數據
現在你已經有了足夠的知識來進行實踐,從了解一個相對簡單的模擬傳感器開始是非常好的起點。
LM35係列傳感器是精確的攝氏溫度傳感器,它的輸出電壓與攝氏度成線性正比。在室溫下LM35設備在無需外部校準的情況下能達到0.25℃的準確度。在-55℃~150℃的範圍內,它能達到0.75℃的準確度。
用LM35來搭建一個傳感器數據采集係統不需要太多設備。隻需要Arduino Uno R3模塊、LM35設備、麵包板、一些連接線和電腦!很多傳感器也采用類似的結構。距離傳感器、光照傳感器以及任意輸出在0~5V之間的傳感器都可以以類似的方式讀取數據。
LM35有三個引腳:GND、+Vs和VOUT。首先用連接電纜將Arduino Uno R3的+5V引腳與+VS引腳相連。其次將Arduino麵板上的Analog0(或者是A0)引腳與VOUT引腳相連。最後一步是將LM35的GND引腳與Arduino Uno R3的GND引腳相連。連接關係如下圖所示。在這種配置下,LM35隻能測零上的溫度。

a0435643fca0b9b48bbf586fa734555130a6cb89

如前所述,模擬傳感器應該用ADC作為接口。Arduino Uno R3有一個10比特的ADC。利用這10比特數據,可以寫210=1024個數字。這意味著ADC可以把5V電壓分成1024份。比如5V映射到ADC的值為1023,2.5V映射到ADC的值為512。所以可以從ADC的值換算出電壓值,公式如下:

d3ceb86441257bc3c490ec04787e5cf053013987

ADC的采樣值是你從ADC模塊中讀取的值。根據上麵的公式,比如你讀到的ADC采樣值是135,那麼該引腳的電壓就應該是:

3f791d4d04124f10575d26bd533e12b8ed9401c3

LM35的數據手冊上說,每10mv對應著1℃。因此660mv意味著66℃。我們把下列代碼複製到Arduino編輯器中,並且把它下載到Arduino Uno R3:

ebe7cbdbf757a046a640d78b0f095313f2d12973
eb4128392a0c7587de613fc4ff7b26c2a4e07d3d

編譯代碼並把它下載到Arduino Uno R3之後,用一個USB串行終端與Arduino相連,你能看到一個攝氏度值。正如你看到的,我們每秒對傳感器數據采樣一次。
但是問題並沒有解決。LM35能夠測量的最大溫度是150℃,這意味著最大的輸出電壓可能是1.5V。我們隻用了0~5V的一小部分,大部分都被浪費了。所以當前的方案還有提高的空間。室溫150℃並沒有什麼用處,可以找到一個更聰明的方法。
如果我們把模擬參考電壓(第一次是5V)改成一個比較小的值比如1.1V,這樣可以提高測量精度。在這種情況下,公式會發生變化,如下所示:

7aa20d2c303039c908cbe7067da16d7e326aa34f

要改變模擬參考電壓值為1.1V,可以使用analogReference(INTERNAL)函數。我們還用了一個簡單的濾波算法來去掉高頻變化的影響,如下所示:

2d20f06180377376d4ff6e9ea0404c6ebf38743c
548734a6b5d515fc63c8a6c057dca85f40d4fd22

也許最重要的部分是過濾公式。這段代碼使用的濾波器是boxcar積分器。濾波器的一般實現如下所示:

548734a6b5d515fc63c8a6c057dca85f40d4fd22

在上麵的公式中,新的過濾後溫度值(current_output)90%由新的溫度測量值(input)決定,10%由舊的溫度測量值決定。因此高頻溫度噪聲會受到舊溫度測量值10%的抑製。
此外,通過使用一個1.1V的區間,我們有了更高精度的溫度信息。在這種情況下,能夠測量的最高溫度是110℃,這也是可以接受的。總之,現在我們有了一個更好的傳感器接口。
請分析下Arduino的傳感器例子並且試圖找出如何使用在本章中學到的知識來提高這個例子的效果。你可以看到相同的原則可以輕鬆地應用到各種傳感器應用程序上。

最後更新:2017-05-25 11:01:15

  上一篇:go  《Arduino計算機視覺編程》一導讀
  下一篇:go  《計算機存儲與外設》----1.4 Cache設計中要考慮的因素