2018年9月20日 星期四

模組介紹 : faya極限開關模組


學習目標 : 認識faya極限開關模組的功能及使用方式
學習時間 : 60min
示範模組 : (1) faya brickNano
                   (2) faya 極限開關模組 (1~2)
                   (3) faya 串列七段顯示模組
工具 : (1) 樂高積木底板 (相容)

====================功能介紹====================
極限開關利用一個鐵製把柄來帶動開關的導通與否,非常適合偵測物體是否存在,或是物體最後是否有停在某一點。極限開關最早是用來定義一物體行進的範圍(移動限制),因此稱為極限開關。

faya極限開關模組組合了一個極限開關和兩顆LED當作按壓時的指示燈,對應關係如下:
  • 當開關未按下時,紅色LED亮,輸出埠NC = HIGH,NO = LOW
  • 當按下開關時,綠色LED亮,輸出埠NC = LOW,NO =HIGH
因此輸出埠NC (Normal Close) 和 NO (Normal Open) 擁有相反的輸出狀態,使用者可以自行取用:


====================原理知識====================
以下解釋提供給有需要知道背後原理的人:

由電路圖可看出當極限開關未按壓時,開關停在NC位置,此時紅色LED導通亮起,輸出埠NC電壓約為VCC-1.7V(壓降) = HIGH。反之,當按壓極限開關時,開關停在NO位置,此時綠色LED導通亮起,輸出埠NO為HIGH。


由於內部結構的關係,極限開關的機械彈跳問題特別嚴重,我們曾經在[模組介紹 : faya按鍵模組] 討論過彈跳的現象,極限開關無論在按下或放開鐵餅時,產生的彈跳次數會比一般按鍵式開關多了好幾次,我們在接下來的教學範例中,就會介紹如何透過軟體程式將彈跳去除。


上圖為按鍵式按鈕的彈跳狀態,原本輸出狀態為LOW,按下按鍵時,經過幾次彈跳才穩定為HIGH狀態,同樣的放開按鈕時,也會有幾次彈跳的現象,才會穩定成LOW狀態,由於MCU的速度很快,它能夠看到每次的彈跳現象,因此雖然我們只感覺按了一次按鈕,實際上MCU已經記錄到好幾次的ON-OFF變化了,此現象在極限開關更為明顯。

====================範例實作 (一)====================

了解模組功能(原理)後,我們用以下範例來展示模組的功能:

目標:
(1) 當按下極限開關時,串列七字節顯示器計數+1
(2) 不包含除彈跳程式

接線:
(1) 電源線連接
     如下圖所示,連接的說明請看這篇文章 簡易版


(2) 訊號線連接
      Arduino_D12   ===>  串列七字節顯示模組_DIN
      Arduino_D11   ===>  串列七字節顯示模組_CLK
      Arduino_D10   ===>  串列七字節顯示模組_LOAD

     

     Arduino_A4   ===>  極限開關模組_NO


範例程式:

備註:
- 串列七段顯示模組的使用方式請參考[模組介紹:串列七段顯示模組]
- L36: if((input != lastInput)&&(input == HIGH)); 偵測數位腳位上源觸發時的語法,第一個判斷邏輯準位是否改變,第二個判斷狀態須為HIGH時,總和以上兩個半段就是在信號上源時


-L37~L47: 每次的上源觸發會讓計數器加1,當達到9999時歸0

範例結果:


討論:

影片中我們發現彈跳的問題非常嚴重,而且彈跳發生在兩個時刻,一個是按下開關的時候,另一個是放開開關的時候,如下圖所示:


我們在下一個範例利用先利用一個簡單易懂、但比較沒效率的程式來解決彈跳問題,讓大家從影片中比較並瞭解如何透過程式改善機械彈跳。

====================範例實作 (二)====================

目標:
(1) 當按下極限開關時,串列七字節顯示器計數+1
(2) 使用delay()除彈跳

接線:
(1) 電源線連接 ==> 和範例實作(一)相同
(2) 訊號線連接 ==> 和範例實作(一)相同

範例程式:
備註:
L47 : 讓CPU忙著執行delay()函式 (25毫秒),而沒有時間偵測上源觸發後的彈跳現象
L48 : 當我們按了開關以後,未放開開關前,由於輸出會得到HIGH(1),程式會一直停在這一行
L49 : 讓CPU忙著執行delay()函式 (25毫秒),而沒有時間偵測放開開關後的彈跳現象


範例結果:


討論:
影片中可以觀察出無論在按下或放開開關時,彈跳的現象都被抑制了,而且當手指頭壓著開關時,計數器的數字是不會增加的。這個範例可以很快的理解如何利用軟體除彈掉,但是透過delay的方式,對於程式的撰寫是非常沒有效率的,因為此時CPU除了執行delay和卡在while回圈內,什麼事都不能做。下一個範例會利用Arduino內的彈跳範例,利用硬體timer來有效率的除彈跳。

====================範例實作 (三)====================

目標:
(1) 當按下極限開關時,串列七字節顯示器計數+1
(2) 使用Arduino提供的除彈跳範例

接線:
(1) 電源線連接 ==> 和範例實作(一)相同
(2) 訊號線連接 ==> 和範例實作(一)相同

範例程式:

備註:
L40 : 當我們壓下/放開按鈕時,會讀到不同的HIGH / LOW值,此行就是在偵測此狀態的轉換
L41:  偵測到轉換後,立刻啟用timer,注意到此timer是用內建的硬體執行,沒有耗到CPU資源
L44:  按下/放開按鈕後,會有debounce現象產生,因此我們利用timer延遲25ms,等到彈跳現象結束後,再來執行程式。
L45~46 : 過了延遲時間後,按鈕會由LOW轉HIGH或者HIGH轉LOW,達到穩定的狀態,此時就能夠更新按鈕態
L48: 因為按下按鈕後為HIGH,因此設下此條件,避免放開按鈕由HIGH轉LOW時也進入接下來的程式
L49~L59 : 同之前的範例程式

範例結果:


討論:
影片中可看出和上個範例實作一樣有良好的除彈跳結果,由於我們用硬體timer執行時間的延遲,沒有用到CPU的資源,因此程式會有效率許多。但是大家應該會發現,如此一來,程式需要更多的變數,程式閱讀上變得比較複雜,我們在下一個範例,會利用函式庫的方式來執行軟體除彈跳,讓程式的閱讀看起來簡單些。

====================範例實作 (四)====================

目標:
(1) 當按下極限開關時,串列七字節顯示器計數+1
(2) 使用Bounce2 函式庫除彈跳

接線:
(1) 電源線連接 ==> 和範例實作(一)相同
(2) 訊號線連接 ==> 和範例實作(一)相同

範例程式:

備註:
L14: 這個程式需要用到Bounce2函式庫,請點此下載。下載後解壓縮到Arduino的Libraries資料夾,重新開啟Arduino即可掛上此library。
L18: 需要宣告使用Brounce物件,定義名稱(debouncer)後,以供未來呼叫。
L25/26 : 固定寫法,設定按鍵模式和延遲時間
L36 : 監測按鍵
L37 : 當偵測到上源觸發時,執行以下的程式

範例結果:


討論:
同樣的,我們得到一個完美的除彈跳結果,程式變的簡易許多,使用library的另一個好處是當我們有許多會產生彈跳現象的輸入裝置時,我們不必像上一個範例宣告一堆變數,只要事先宣告bounce()物件,事後進行呼叫即可,除了有效率,程式也會變得易讀許多,請參看我們下一個範例。

====================範例實作 (五)====================

目標:
(1) 當按下(下方)極限開關時,串列七字節顯示器計數-1
(2) 當按下(上方)極限開關時,串列七字節顯示器計數+1
(3) 使用Bounce2 函式庫除彈跳

接線:
(1) 電源線連接
     如下圖所示,連接的說明請看這篇文章 簡易版


(2) 訊號線連接
      Arduino_D12   ===>  串列七字節顯示模組_DIN
      Arduino_D11   ===>  串列七字節顯示模組_CLK
      Arduino_D10   ===>  串列七字節顯示模組_LOAD


     Arduino_A3  ===> (上方) 極限開關模組_NO
     Arduino_A4  ===> (下方) 極限開關模組_NO


範例程式:
備註:
L20~21 : 由於這個範例有兩個裝置需要除彈跳,因此我們宣告了兩次除彈跳物件,並分別命名以便之後呼叫
L29~32 : 寫法和上個範例相同,只是都要設定兩次
L45~55 : 上數程式
L57~67 : 下數程式

範例結果:


討論:
這個範例充份表現出透過除彈跳函式庫,讓程式看起來易寫易讀許多,bounce2函式庫裡面還有另一個下源觸發的函式 debouncer.fell() 會有機會用到,有興趣了解更多函式庫內容的,可參照官方網頁說明。

歡迎大家在底下留言或到我們的粉絲團留言喔!
====================================
fayalab 粉絲團
FB本篇留言版

沒有留言:

張貼留言