Java Embedded (7)Raspberry Pi GPIO 的基礎應用與實作(上)
Java Embedded(6)認識 Raspberry Pi 的 GPIO << 前情 7-1 認識GPIO的針腳與應用Raspberry Pi的GPIO每一個針腳都提供不同的用途,Model B有26個針腳,Model B+與Pi 2 Model B有40個針腳,有提供電源和其它的應用,可以分為四類:
Raspberry Pi這類單板電腦,跟一般個人電腦在應用上最大的差異,就是可以連接各種需要的設備與零件到GPIO,撰寫程式碼讀取需要的資訊與控制設備。像這個用來偵測物體距離的超音波感應器(左側),還有用來控制機器人或其它裝置的伺服馬達(右側),這兩種設備可以連接到Raspberry Pi GPIO的一般用途針腳: 這兩個設備連接到GPIO的I²C針腳,是可以用來讀取氣溫的感應器(左側),還有讀取環境光源亮度與物體接近的感應器(右側): 這個長得像IC的零件,用途是把類比訊號轉換為數位訊號,它會連接到GPIO的SPI針腳。因為Raspberry Pi的GPIO只能傳送與接收數位的訊號,目前仍有很多設備傳送與接收類比訊號,如果需要讀取設備傳送的類比訊號,就需要這類零件執行轉換的工作,例如某些溫、濕度感應器: 瞭解Raspbeery Pi提供的GPIO針腳以後,目前會先討論電源和一般用途這兩種針腳的應用與實作,完成這一篇討論的內容後,你就可以使用程式控制LED。 7-2 WiringPi與Pi4J在一般個人電腦上運作的應用程式,可以讀取鍵盤、滑鼠和一般設備的輸入資訊,也可以控制螢幕的顯示,使用圖形使用者介面提供使用者操作的功能。像Raspberry Pi這類單板電腦,與個人電腦最大的差異,就是提供一些輸出與輸入的介面,讓應用程式控制連接到電腦的設備,也可以讀取設備傳輸的資訊,例如控制伺服馬達(Servo Motor)的運轉,或是讀取感應器傳輸的氣溫資訊。 在Raspberry Pi上運作的應用程式,需要透過GPIO針腳與各種的設備與零件互動,就需要特別的程式庫,而且通常是採用C語言撰寫的。Raspberry Pi有一套很常見的GPIO程式庫「WiringPi」,WiringPi是由一位在英格蘭的Gordon Henderson使用C語言撰寫的,採用GNU LGPLv3授權、http://www.gnu.org/licenses/lgpl.html。WiringPi的網站是http://wiringpi.com/。 Java技術需要透過JNI與使用C語言撰寫的程式庫互動,目前Raspberry Pi有一套Pi4J程式庫,可以讓你直接使用Java程式語言,透過WiringPi與GPIO執行互動。Pi4J是目前最常用的Java GPIO類別庫,由Robert Savage與Chris Walzl開發,他們也為這個專案申請一個網域名稱,官方網站是http://pi4j.com/。 Pi4J在2015/04/18發表1.0正式版本。從之前的0.0.5版本,就已經有很多人使用它來開發一些專案。目前支援與提供的功能都非常穩定。Pi4J有這些主要的功能與特性:
Java應用程式使用Pi4J的Java類別庫,用法就跟一般的Java類別庫一樣,可以很方便的使用Java技術,開發控制各種硬體設備的應用程式。這是Java應用程式、Pi4J類別庫與WiringPi程式庫的架構圖型: Pi4J採用WiringPi為控制GPIO的底層程式庫,WiringPi另外為Raspberry Pi的針腳編製一組編號,從GPIO00到GPIO17,可以控制18個針腳,在板子上看到的這一組GPIO針腳編號是「P1」,在Raspberry Pi Model B Revision 2的板子上,多了一組編號為「P5的針腳」,額外提供電源與四個GPIO針腳,不過這一組針腳只是八個電路板上的洞,還要自已焊接針腳才可以使用。所以Revision 2多了GPIO28到GPIO31四個針腳: 不同的技術採用的GPIO針腳編號會不太一樣,以針腳編號12來說,一般會採用GPIO18的編號,不過WiringPi把它定義為GPIO_00,在使用Pi4J開發應用程式的時候要特別留意。這個圖型是完成的針腳對照表,接下來使用的是Pi4J欄位的編號: Raspberry Pi Model B Rev 2、Model B+與Raspberry Pi 2 Model B,都有40個針腳。Pi4J 1.0都有完整的支援:
7-3 在工作電腦與Raspberry Pi安裝Pi4J開始撰寫控制GPIO的應用程式,就會使用到Pi4J提供的類別庫,因為通常還是會在一般的個人電腦執行開發的工作,所以還是需要在工作的電腦下載Pi4J類別庫。依照下列的步驟設定工作電腦的開發環境:
撰寫好的應用程式在Raspberry Pi運作的時候,也需要用到Pi4J提供的類別庫,Pi4J準備好一個Linux的套件,裡面已經包含WiringPi程式庫。接下來為Raspberry Pi下載與安裝Pi4J套件:
7-4 第一個GPIO應用程式在開始撰寫程式之前,先瞭解目前要完成的工作,把需要的零件連接好。這個範例程式在執行以後,可以點亮連接好的LED,經過三秒以後,關閉LED並結束應用程式。這個範例需要這些零件:
你可以選擇其它針腳來控制LED,不過現在先使用針腳編號12,也就是Pi4J的GPIO_00。依照下面的線路圖,連接好所有需要的零件,建議在連接線路之前,先關閉Raspberry Pi的電源: 現在可以開始撰寫第一個控制GPIO的Java應用程式,依照下面的步驟完成撰寫程式的工作:
把「MyGPIO.java」改為下面的程式碼: package mygpio; import com.pi4j.io.gpio.GpioController; import com.pi4j.io.gpio.GpioFactory; import com.pi4j.io.gpio.GpioPinDigitalOutput; import com.pi4j.io.gpio.PinState; import com.pi4j.io.gpio.RaspiPin; public class MyGPIO { public static void main(String[] args) { // 建立GPIO控制物件 final GpioController gpio = GpioFactory.getInstance(); // 建立控制GPIO_01輸出的物件 final GpioPinDigitalOutput pin = gpio.provisionDigitalOutputPin( RaspiPin.GPIO_01, "My LED", PinState.LOW); System.out.println("LED ON..."); // 設定GPIO_01的狀態,設定為true表示這個針腳會輸出3.3V的電壓 pin.setState(true); delay(3000); System.out.println("LED OFF..."); // 設定GPIO_01的狀態,設定為fasle表示這個針腳不會輸出電壓 pin.setState(false); System.out.println("Bye..."); // 最後記的要關閉GPIO gpio.shutdown(); } private static void delay(int ms) { try { Thread.sleep(ms); } catch (InterruptedException e) { System.out.println(e.toString()); } } } 儲存程式碼以後,在專案目錄上按滑鼠右鍵選擇「Clean and Build」,NetBeans會幫你編譯並包裝好這個應用程式。接下來啟動Raspberry Pi電源,開機完成後,依照下列的步驟,為這個加入專案遠端執行的設定:
完成這個專案的遠端執行設定以後,在專案名稱「MyGPIO」上按滑鼠右鍵選擇「Run」,NetBeans自動把應用程式上傳到Raspberry Pi並執行。執行以後會看到下面的錯誤訊息: wiringPiSetup: Unable to open /dev/mem: Permission denied Exception in thread "main" java.lang.RuntimeException: Unable to open GPIO direction interface for pin [11]: Permission denied at com.pi4j.wiringpi.GpioUtil.export(Native Method) at com.pi4j.io.gpio.RaspiGpioProvider.export(RaspiGpioProvider.java:67) at com.pi4j.io.gpio.impl.GpioPinImpl.export(GpioPinImpl.java:165) at com.pi4j.io.gpio.impl.GpioControllerImpl.provisionPin(GpioControllerImpl.java:520) at com.pi4j.io.gpio.impl.GpioControllerImpl.provisionDigitalOutputPin(GpioControllerImpl.java:645) at com.pi4j.io.gpio.impl.GpioControllerImpl.provisionDigitalOutputPin(GpioControllerImpl.java:672) at com.pi4j.io.gpio.impl.GpioControllerImpl.provisionDigitalOutputPin(GpioControllerImpl.java:684) at pi4jdemo.Pi4JDemo.main(Pi4JDemo.java:14) 之前討論的內容也是採用這樣的作法,在遠端執行應用程式,不過現在卻出現一些錯誤訊息,LED當然也沒有被程式點亮。這是因為這個應用程式執行以後,需要控制Raspberry Pi的硬體設備,所以需要系統管理員的權限。你可以在登入Raspberry Pi以後,試著執行已經上傳的應用程式: cd /home/pi/NetBeansProjects/MyGPIO/dist java -jar MyGPIO.jar 執行程式以後會看到同樣的錯誤訊息。再試著使用下列的指令執行應用程式: sudo java -jar MyGPIO.jar 執行程式以後就會正確的點亮LED,三秒鐘後關閉LED並結束應用程式。所以在執行這類應用程式的時候,必須在最前面加上「sudo」以管理員的權限執行。 瞭解執行GPIO應用程式的作法以後,再回來執行NetBeans的相關設定。先看看你的NetBeans視窗標題顯示的版本,如果還是「NetBeans 8.0」的話,選擇功能表「Help -> Check for Updates」,執行所有的更新。如果已經是「NetBeans 8.0.1」的話,就不用執行更新。 確認NetBeans的版本是8.0.1以後,選擇功能表「Tools -> Java Platrofms」,選擇剛才使用的遠端執行設定檔,參考下面的圖型加入「sudo」的設定,然後選擇「Close」: 在專案名稱「MyGPIO」上按滑鼠右鍵選擇「Run」執行這個應用程式,就可以正確的點亮與關閉LED。你可以參考下面的程式片段,讓LED持續閃爍一段時間: for (int i = 0; i < 10; i++) { pin.setState(true); delay(500); pin.setState(false); delay(500); } 7-5 控制更多的GPIO完成第一個GPIO應用程式了,雖然只是簡單的控制LED,不過使用Java應用程式控制硬體設備,應該是以前沒有的經驗。現在你可以試試控制兩個LED,這個實作需要這些零件:
這個實作準備透過GPIO01與GPIO02控制兩個LED,參考下面的線路圖,連接所有零件: 你可以參考前面討論的作法,建立一個新的應用程式,程式碼的部份就讓你自己發揮,試試讓兩棵LED同時點亮與關閉,或是讓兩棵LED輪流點亮與關閉。 課程相關的檔案都可以GitHub瀏覽與下載。 |
r58711052
10/31
想請問各位前輩~raspberry pi 3執行java後出現:unable to determine hardware version. I see : hardware :BCM2835,請問該如何解決?謝謝!