Java Embedded (7)Raspberry Pi GPIO 的基礎應用與實作(上) by Michael | CodeData
top

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個針腳,有提供電源和其它的應用,可以分為四類:

  • 電源 :Model B的針腳編號1與17的3.3V,針腳編號2與4的5V,針腳編號6、9、14、20與25的接地(GND)。Model B+與Pi 2 Model B多了針腳編號30、34與39的接地(GND)。這些針腳可以提供連接Raspberry Pi零件的電源,例如LED與感應器。不過要特別注意零件需要的電源是3.3V或5V,如果接錯了,很有可能燒壞零件。
  • 一般用途 :Model B的針腳編號7、11、12、13、15、16、18與22,Model B+與Pi 2 Model B多了針腳編號29、31、32、33、35、36、37、38與40。這些針腳可以設定為輸入或輸出,設定為輸出的時候,可以使用程式控制輸出的電壓,例如沒有輸出的0V或3.3V;設定為輸入的時候,可以透過程式偵測輸入的電壓。
  • I²C :Model B的針腳編號8與9。Model B+與Pi 2 Model B多了針腳編號27(I²C IDSD)與28(I²C IDSC),保留給PiPlate ID EEPROM使用。I²C(Inter-Integrated Circuit)是一種串列通訊匯流排,由飛利浦公司在1980年代研發,讓主機板、嵌入式系統或行動電話可以連接低速週邊裝置而發展,是一種很常見的架構,有很多設備都採用I²C設計,例如行動電話的接近與光線感應器。
  • SPI :針腳編號19、21、23、24與26。SPI(Serial Peripheral Interface Bus)是一種類似I²C的序列資料傳輸協定,也有很多採用這種架構的設備。

Raspberry Pi這類單板電腦,跟一般個人電腦在應用上最大的差異,就是可以連接各種需要的設備與零件到GPIO,撰寫程式碼讀取需要的資訊與控制設備。像這個用來偵測物體距離的超音波感應器(左側),還有用來控制機器人或其它裝置的伺服馬達(右側),這兩種設備可以連接到Raspberry Pi GPIO的一般用途針腳:

JavaEmbedded_07_01

這兩個設備連接到GPIO的I²C針腳,是可以用來讀取氣溫的感應器(左側),還有讀取環境光源亮度與物體接近的感應器(右側):

JavaEmbedded_07_02

這個長得像IC的零件,用途是把類比訊號轉換為數位訊號,它會連接到GPIO的SPI針腳。因為Raspberry Pi的GPIO只能傳送與接收數位的訊號,目前仍有很多設備傳送與接收類比訊號,如果需要讀取設備傳送的類比訊號,就需要這類零件執行轉換的工作,例如某些溫、濕度感應器:

JavaEmbedded_07_03

瞭解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提供的類別,直接使用WiringPi程式庫與GPIO互動
  • 設定GPIO針腳的控制方向(輸入或輸出)
  • 控制與讀取GPIO針腳的狀態
  • 監聽GPIO針腳狀態的改變
  • 支援I²C與SPI通訊協定

Java應用程式使用Pi4J的Java類別庫,用法就跟一般的Java類別庫一樣,可以很方便的使用Java技術,開發控制各種硬體設備的應用程式。這是Java應用程式、Pi4J類別庫與WiringPi程式庫的架構圖型:

JavaEmbedded_07_04

Pi4J採用WiringPi為控制GPIO的底層程式庫,WiringPi另外為Raspberry Pi的針腳編製一組編號,從GPIO00到GPIO17,可以控制18個針腳,在板子上看到的這一組GPIO針腳編號是「P1」,在Raspberry Pi Model B Revision 2的板子上,多了一組編號為「P5的針腳」,額外提供電源與四個GPIO針腳,不過這一組針腳只是八個電路板上的洞,還要自已焊接針腳才可以使用。所以Revision 2多了GPIO28到GPIO31四個針腳:

JavaEmbedded_07_05

不同的技術採用的GPIO針腳編號會不太一樣,以針腳編號12來說,一般會採用GPIO18的編號,不過WiringPi把它定義為GPIO_00,在使用Pi4J開發應用程式的時候要特別留意。這個圖型是完成的針腳對照表,接下來使用的是Pi4J欄位的編號:

JavaEmbedded_07_06

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類別庫。依照下列的步驟設定工作電腦的開發環境:

  1. 開啟瀏覽器,輸入這個網址:http://pi4j.com/
  2. 選擇「Download」後選擇「pi4j-1.0.zip」並儲存下載的檔案:

    http://pi4j.com/

  3. 選擇「Download」後選擇「http://code.google.com/p/pi4j/downloads」:JavaEmbedded_07_07
  4. 解壓縮上一個步驟下載的檔案,「pi4j-1.0/lib/」目錄下存放Pi4J的Java類別庫,後面在撰寫應用程式的時候,就需要為專案加入需要的類別庫檔案。

撰寫好的應用程式在Raspberry Pi運作的時候,也需要用到Pi4J提供的類別庫,Pi4J準備好一個Linux的套件,裡面已經包含WiringPi程式庫。接下來為Raspberry Pi下載與安裝Pi4J套件:

  1. 在工作電腦使用SSH登入Raspberry Pi。
  2. 執行下面的指令,從Pi4J網站下載Pi4J套件:

    wget http://get.pi4j.com/download/pi4j-1.0.deb
  3. 執行指令以後會從網際網路下載Pi4J套件:

    --2015-04-23 18:11:03--  http://get.pi4j.com/download/pi4j-1.0.deb
    Resolving get.pi4j.com (get.pi4j.com)... 54.231.9.236
    Connecting to get.pi4j.com (get.pi4j.com)|54.231.9.236|:80... connected.
    HTTP request sent, awaiting response... 200 OK
    Length: 616120 (602K) [application/octet-stream]
    Saving to: `pi4j-1.0.deb'
    
    100%[======================================>] 616,120      171K/s   in 3.5s    
    
    2015-04-23 18:11:07 (171 KB/s) - `pi4j-1.0.deb' saved [616120/616120]
  4. 執行下面的指令安裝Pi4J套件:

    sudo dpkg -i pi4j-1.0.deb
  5. 執行指令以後顯示的訊息:

    Selecting previously unselected package pi4j.
    (Reading database ... 92469 files and directories currently installed.)
    Unpacking pi4j (from pi4j-1.0.deb) ...
    Setting up pi4j (1.0) ...
  6. 安裝完成後,Pi4J的安裝目錄是「/opt/pi4j」。

7-4 第一個GPIO應用程式

在開始撰寫程式之前,先瞭解目前要完成的工作,把需要的零件連接好。這個範例程式在執行以後,可以點亮連接好的LED,經過三秒以後,關閉LED並結束應用程式。這個範例需要這些零件:

  • LED一顆
  • 電阻(220 ohm)一個
  • 杜邦線(公-母)兩條
  • 麵包板一個

你可以選擇其它針腳來控制LED,不過現在先使用針腳編號12,也就是Pi4J的GPIO_00。依照下面的線路圖,連接好所有需要的零件,建議在連接線路之前,先關閉Raspberry Pi的電源:

JavaEmbedded_07_09

現在可以開始撰寫第一個控制GPIO的Java應用程式,依照下面的步驟完成撰寫程式的工作:

  1. 啟動NetBeans。
  2. 選擇功能表「File -> Java Project…」。
  3. Categories選擇「Java」,Projects選擇「Java Application」,然後選擇「Next」。
  4. Project Name輸入「MyGPIO」後選擇「Finish」。
  5. 在專案MyGPIO下的「Libraries」目錄,按滑鼠右鍵後選擇「ADD JAR/Folder…」。
  6. 選擇「pi4j-1.0/lib/」目錄下的「pi4j-core.jar」檔案,選擇「選擇」按鈕,把Pi4J類別庫檔案加入專案。

把「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電源,開機完成後,依照下列的步驟,為這個加入專案遠端執行的設定:

  1. 在NetBeans選擇功能表「Tools -> Java Platrofms」。
  2. 檢查是否已經建立好Raspberry Pi遠端執行環境,確認遠端Java SE 8執行環境的名稱。如果還沒有建立的話,參考之前的說明,建立一個Java SE 8的遠端執行環境。
  3. 在專案名稱「MyGPIO」上按滑鼠右鍵選擇「Properties」,選擇「Run」目錄後選擇「New…」按鈕。
  4. 在對話框輸入一個名稱後選擇「OK」按鈕。
  5. 「Runtime Platform」選擇剛才建立的遠端Raspberry Pi Java平台,選擇「OK」完成設定。

完成這個專案的遠端執行設定以後,在專案名稱「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」:

JavaEmbedded_07_10

在專案名稱「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,這個實作需要這些零件:

  • LED兩顆
  • 電阻(220 ohm)兩個
  • 杜邦線(公-母)三條

這個實作準備透過GPIO01與GPIO02控制兩個LED,參考下面的線路圖,連接所有零件:

JavaEmbedded_07_11

你可以參考前面討論的作法,建立一個新的應用程式,程式碼的部份就讓你自己發揮,試試讓兩棵LED同時點亮與關閉,或是讓兩棵LED輪流點亮與關閉。

課程相關的檔案都可以GitHub瀏覽與下載。

http://github.com/macdidi5/JavaEmbedded

後續 >> Java Embedded (8)Raspberry Pi GPIO 的基礎應用與實作(下)

分享:
按讚!加入 CodeData Facebook 粉絲群

相關文章

留言

留言請先。還沒帳號註冊也可以使用FacebookGoogle+登錄留言

r5871105210/31

想請問各位前輩~raspberry pi 3執行java後出現:unable to determine hardware version. I see : hardware :BCM2835,請問該如何解決?謝謝!

熱門論壇文章

熱門技術文章