樂萬德 王永輝 趙妮 李珂 程海洋
(西安航空學院 陜西省西安市 710077)
近年來,Arduino 作為一款便捷靈活、方便上手的開源電子原型平臺,受到了很多高校的青睞。陸澤華等對Arduino 單片機在信息技術教育中的應用進行了探究[1],李梅等設計了基于Arduino 家居安防智能報警電路[2],許金等設計了可見光濁度檢測創新實驗[3],耿麗娟等設計了基于Arduino 的智能防盜系統[4],Arduino 的應用和研究非常廣泛,如何利用好Arduino 培養學生的創新創業能力成為研究熱點。本文旨在在這些研究成果的基礎上進一步探索基于Arduino 平臺的創新創業教育方法及過程。
Arduino 平臺包含各種型號的Arduino 板和Arduino IDE 軟件。Arduino 創始人于2005年開始討論這個項目,僅用了3 天時間就實現了最初的創意開發板[5]。Arduino UNO 于2011年9月份正式發布,目前廣泛應用的是Arduino UNO R3,即第三版。Arduino 平臺具有豐富的控制板序列及擴展板序列,支持多種傳感器及外圍電路,如Proteus 等仿真平臺對Arduino 具有越來越完善的功能支持[6]。LED燈、蜂鳴器、按鍵這幾個元器件雖然簡單,但這也是最基本最常用的聲光及控制器件。Arduino 基礎的開發板及套件具有很高的性價比,我們鼓勵學生在接觸更廣泛的傳感器甚至虛擬開發平臺之前,認真做好基礎元器件的熟悉及創新實踐,正所謂大道至簡,然后觸類旁通。這種強化實踐基礎的方法在教學實踐中證明非常有效。
面對LED、蜂鳴器和按鍵開關等基本元器件實驗項目,通過按鍵控制來控制LED 等的亮和滅、控制蜂鳴器的響和停等基本操作學生基本都能想到;進一步需要引導學生通過按鍵的次數來控制LED 燈的亮度等級、蜂鳴器的頻率變化等,逐漸體現出創意設計的意味;最后引導學生通過這幾個簡單元器件設計出了一個非常有趣的聲光組合“眼疾手快”訓練器。其基本設計思路如下:
(1)“眼疾手快”訓練器的LED 燈根據設置的難度等級進行隨機閃爍,每次閃爍亮燈與滅燈的時間間隔由隨機函數產生,難度等級越高,隨機時間間隔越短。
(2)LED 燈亮起后,玩家第一時間按下按鍵,從LED 燈亮燈開始計時,在規定的時間內按下按鍵被定義為“擊中”并得分,超時按下按鍵則本次按鍵不得分。規定的時間也與難度等級有關,難度也高,留給玩家按鍵的時間越短。
(3)游戲需防止玩家一直按著按鍵或者連續不斷進行按鍵等漏洞。

圖1:系統外圍電路及與Arduino 的接口

圖2:系統的兩個并行任務
(4)擊中得分,蜂鳴器發出得分音樂聲音。
(5)為增加娛樂性,游戲開始時響起特殊的音樂,提醒玩家游戲即將開始。
(6)項目可拓展,硬件上可拓展為雙LED,雙按鍵,雙手控制等多種拓展玩法。軟件上可隨著后臺數據的積累做統計后對游戲難度參數及分級做進一步優化。
根據上述創意,基于Arduino UNO 控制板及其對應芯片ATmega328,用Proteus 設計外圍電路仿真電路圖及其與Arduino UNO 的接口如圖1所示,Arduino UNO 電路板略。LED 燈經過分壓電阻后接在Arduino UNO 數字口IO7 上,設置為輸出模式。buzzer 分別接在IO3,設置為輸出模式。注意根據選用buzzer 的電氣特性參數,有的buzzer 可能需要外接電源。本實驗中,選用集成了分壓電路的LED 等和集成功能的buzzer。按鍵分別接在A0 口模擬輸入口上。
為了項目的需要,亮燈滅燈時間不能采用固定的時間間隔,而是采用隨機數生成時間間隔。一方面,Arduino 系統不斷地查詢時間,如果時間滿足了預先隨機數對應的時間,則LED 等的亮燈滅燈狀態發生變化。另一方面,Arduino 還要不斷地查詢開關狀態的變化,以確定開關的按下事件,并記錄下按鍵的時間,與亮燈的時間比對,以判定此次按鍵是否符合要求并進一步觸發計分、播放提示音等動作。這樣,監聽時間以決定LED 燈的亮滅與監聽開關的狀態就形成了兩個并行的任務,如圖2所示。
Arduino 默認沒有操作系統,對于這樣的并行任務需要自行設計處理。對于閃燈,學生首先想到的是用delay( )函數,但delay( )會獨占CPU,任何一個任務使用了delay( ),其它任務也就停下來了,不適合并行任務。對于開關的觸發事件,學生首先想到的是中斷,但是中斷發生時delay( )函數不會生效,millis( )函數的計時數值也不會持續增加[5]。計時及計算時間差是本項目的關鍵因素之一,中斷方案將會非常困難。因此本項目中最合適的解決方案是利用millis( )或者micros( )函數。本項目選用millis( )函數,函數則僅僅是一個時間記錄者,在LED 閃燈任務里用millis( )函數來控制閃燈并不會讓其他任務停滯。通過不停地循環查詢并記錄下LED 燈的亮燈時間和開關按下的時間,就可以模擬多任務的并行運行。本項目中引入基于millis( )函數的狀態機,狀態機是一種能解決多任務并發的有效方法[7]。定義兩個狀態機,一個狀態機記錄LED 等的狀態并采用相應的策略,一個狀態機記錄按鍵的狀態及時間。
據前述分析,LED 狀態機以給定的一組隨機數進行閃燈,設計LED 狀態機類圖主要成員如圖3所示。為了項目的擴展性,系統設計中使用了面向對象的思想進行類的封裝。LED 狀態機的關鍵參數包括LED 當前是亮的狀態還是滅的狀態,用變量ledState 來表示,另外需要記錄當前LED 燈狀態的時間,以決定是否需要改變LED燈的狀態,用變量ledChangeTime 來記錄某次狀態的起始時間點。當LED 等變為亮燈狀態時,用ledOnTime 記下該時間點,供按鍵狀態機checkButtonState( )函數使用。
其它成員變量還包括:ledPin 是連接LED 的Arduino 端口號,flashTimes 是LED 閃燈的次數,這兩個參數通過構造函數傳入。randomFlahsTime 為一個長度為flashTimes 的數組,數組長度為閃燈次數,數組中的元素通過隨機數函數獲得。
通過updateLEDState 函數結合LED 燈當前狀態及當前狀態的持續時間,根據閃燈隨機數時間對LED 燈的狀態進行更新。
按鍵狀態機類如圖4所示。

圖3:LED 狀態機

圖4:按鍵狀態機

圖5:基于Arduino的手指靈敏度訓練器實驗裝置

圖6:實驗結果及后臺顯示
項目選用的是按壓式開關,需要判定按壓開關時按下還是彈起兩種狀態。按鍵狀態機的關鍵參數是按鍵當前的狀態及之前按鍵的狀態,分別用變量buttonState 和previousButtonState 來表示,如果當前開關為按下狀態,并不能判定開關按下事件發生,只有當當前開關為按下狀態且之前的狀態為彈起狀態,才能判定為開關按下事件發生。
其他參數包括記錄開關按下的時間buttonDownTime。buttonPin是連接button 的Arduino 端口號。buttonCount 記錄按鍵的次數,如果按鍵次數達到預設值,則再按下按鍵無效,有效地避免了選手不停地按鍵的作弊行為。
checkButtonState( )函數執行上述算法規則,包括判定按鍵按下,記錄按鍵按下的時間,與LED 狀態機中的ledOnTime 比對,滿足閾值要求判定為按鍵擊中。
以LED 所連接的IO 口ledPin 和閃燈次數flashTimes 做為clsLED 構造函數的參數,以按鍵pin 腳buttonPin 及按鍵次數buttonCount 作為clsButton 構造函數,分別在setup 函數和loop 函數外分別構造clsLED 和clsButton 的對象。在loop 函數里分別調用clsLED 的成員函數updateLEDState 和clsButton 的成員函數checkButtonState,實現兩個狀態及之間的協同工作。
通過狀態機類的設計,很容易構造出多個狀態機對象,比如可以構造第二組LED 燈及按鍵,同時針對左右手,進一步提高可玩性。
為了提高項目的可玩性,對蜂鳴器進行了tone( )函數音樂編程,tone 函數的原理不難,但要編出悅耳的音樂需要一些音樂知識和編程技巧。本文按鍵擊中聲音采用了頻率按正弦規律變化的警報音,使玩家提高注意力。進一步的Arduino tone 的使用及音樂編程課參考文獻[8,9]。

實驗裝置如圖5所示。Arduino UNO 板7 號數字口接LED 燈,3 號數字口接蜂鳴器,A0 口接按鍵。LED 燈、蜂鳴器和按鍵為集成元件模塊、簡單易用,所需電源由UNO 板引出。為了實驗的方便和可擴展性,采用了面包板進行了轉接。
實驗中定義了不同的難度等級,以LEVEL1 為例,QUICKNESS 是閃燈后按鍵按下的最晚時間,TIMES 是總的允許的按鍵次數,MININTERVAL 與MAXINTERVAL 為隨機數產生的取值范圍:


圖6為選擇難度級別LEVEL1的某次測試通過串口顯示的結果,按鍵時間與LED 亮燈的時間差如果小于規定的500ms,則蜂鳴器發聲且提示soundHitted OK 并且將記分。最后根據擊中的次數與總的允許按鍵的次數取百分比得到總成績score.本次實驗中一次擊中距離亮燈時間664ms,超過500ms,擊中失敗,沒有擊中提示且不計分,其他9 次均小于設定的500ms,因此最終成績為90 分。實驗結果符合設計預期。
本文是在輔導大學生創新訓練過程中,引導學生用聲、光、按鍵等基本元器件,培養學生創新思維過程中形成的項目。項目原材料簡單,但創意有趣,引入了狀態機很好地解決了LED 閃燈與開關按鍵查詢并行任務,并基于此開發了手指靈敏度訓練器,項目設計過程中用面向對象的思想和方法對狀態機進行了類封裝,方便項目進一步拓展。該項目在大學生基于Arduino 平臺進行創新實踐訓練初級階段中起到了良好的效果。