ここから細かい制御が出来るようになる。マオです。
今まではコマンドで個別に部品を制御してたけど、プログラムで制御する事により複雑な事が出来るようになる。
使える言語は様々で推奨はPythonらしい。
ここでは既に開発環境が整っているJavaを使用していく。
GPIOを使うには、Pi4Jというライブラリが必要になる。
もし、RaspberryPiが直接ネットワークに繋がっているなら、インストールは簡単に終わる。
curl -s get.pi4j.com | sudo bash
これをsudoが出来るユーザで実行するだけだ。
JDKなんかはデフォルトで入ってるようなので、問題無いっぽい。
ライブラリは「/opt/pi4j/lib」にインストールされる。
今回の回路は前回のタクタイルスイッチと前々回のフルカラーLEDを使って、スイッチを押すごとに色が変わっていく物を作る。
注意点はコマンドの時とGPIOの番号が違う所だ。
コマンドではGPIO16だった所が、Pi4JではGPIO27となる。
詳細は公式のPin Numbering(Raspberry Pi 2 Model Bはここ)にあるので、確認しよう。
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import com.pi4j.io.gpio.GpioController; import com.pi4j.io.gpio.GpioFactory; import com.pi4j.io.gpio.GpioPinDigitalInput; import com.pi4j.io.gpio.GpioPinDigitalOutput; import com.pi4j.io.gpio.PinPullResistance; import com.pi4j.io.gpio.PinState; import com.pi4j.io.gpio.RaspiPin; import com.pi4j.io.gpio.event.GpioPinDigitalStateChangeEvent; import com.pi4j.io.gpio.event.GpioPinListenerDigital; public class ButtonDeLedTikatika { public static void main(String[] args) { // #1 final GpioController gpio = GpioFactory.getInstance(); // #2 final GpioPinDigitalOutput led_red = gpio.provisionDigitalOutputPin(RaspiPin.GPIO_29, PinState.HIGH); led_red.setShutdownOptions(true); final GpioPinDigitalOutput led_green = gpio.provisionDigitalOutputPin(RaspiPin.GPIO_25, PinState.HIGH); led_green.setShutdownOptions(true); final GpioPinDigitalOutput led_blue = gpio.provisionDigitalOutputPin(RaspiPin.GPIO_28, PinState.HIGH); led_blue.setShutdownOptions(true); // #3 final GpioPinDigitalInput button = gpio.provisionDigitalInputPin(RaspiPin.GPIO_27, PinPullResistance.PULL_UP); button.setShutdownOptions(true); // #4 button.addListener(new GpioPinListenerDigital() { private byte flag; @Override public void handleGpioPinDigitalStateChangeEvent(GpioPinDigitalStateChangeEvent pin_event) { if(pin_event.getState().isLow()) { flag += flag < 7 ? 1 : -flag; led_red.setState((flag & 1) != 0 ? PinState.LOW : PinState.HIGH); led_green.setState((flag & 2) != 0 ? PinState.LOW : PinState.HIGH); led_blue.setState((flag & 4) != 0 ? PinState.LOW : PinState.HIGH); } } }); // #5 BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); try { while(!in.ready()) { Thread.sleep(1000); } in.readLine(); } catch (IOException | InterruptedException e) { e.printStackTrace(); } // #6 gpio.shutdown(); } }
以上が制御するプログラム。
#1でGPIOをなんやかんやするインスタンスを貰う。
なんやかんやするインスタンスを使って、#2でLED部分の設定をしている。
赤をGPIO29、緑をGPIO25、青をGPIO28に繋いである。
二つ目の引数にあるPinState.HIGHはデフォルトの出力状態を指定している。
このLEDは電圧がかかっていると消えるので、実行されると消えた状態になる。
setShutdownOptionsは終了時に関わる設定なので、そっちで説明するので飛ばす。
#3はタクタイルスイッチ部分の設定だ。
GPIO27に接続してあり、二つ目の引数PinPullResistance.PULL_UPはプルアップ抵抗の設定をしている。
#4はタクタイルスイッチの状態が変化された時の処理を登録している。
各色の状態は3ビット(0~7)で記録して、ビットが立っている部分が光る。
スイッチが押されると処理がされ、電圧がLowになるのでif分の中が実行される。
フラグ管理をしているflagに1を加算するか、7から溢れる場合は0に戻している。
setStateでPinState.LOWかPinState.HIGHを指定する事で、電圧を変更する事が出来る。
これによりスイッチを押すたびに、消えた状態からレッド→グリーン→イエロー→ブルー→マゼンタ→シアン→ホワイトとなり、次でまた消える。
#5はエンターキーを押すまで、プログラムを抜けないようにループさせている。
GPIOの制御部分は別スレッドで動く為に、この部分が無いと処理が終了してしまう。
#6の部分でGPIOを開放(コマンドにおけるunexport)したりする。
しかし、#2や#3でやっているsetShutdownOptions(true)を指定していないと開放してくれない。
setShutdownOptionsでは色々と開放後のピンの状態も指定出来たりする。
実行は一般ユーザからクラスファイルが置いてあるディレクトリで以下のコマンドで出来る。
sudo java -cp .:"/opt/pi4j/lib/*" ButtonDeLedTikatika
意外とサクサクとここまで出来てしまった。
基礎は終わったので、ここから難易度がドンドン上がって大変な事になりそうだ・・・(遠い目)