intel x86 galileoボードの センサーを操作する · intel galileo gen...

10
ORACLE.COM/JAVAMAGAZINE /////////////////// SEPTEMBER/OCTOBER 2016 05 //internet of things / 記事では、計測した環境光に反応して赤、緑、青(RGB)のLEDを 調整するプロジェクトについて説明し、実際に開発を行います。 この過程を通して、 Java SE 8でアナログ入力やパルス幅変調(PWM) 出力を扱う方法について理解できるでしょう。本記事では、 Javaもサ ポートされている最新バージョンのIntel IoT Development Kitを使用 します。また、Pentiumアーキテクチャに基づいたArduino互換x86チ ップを搭載したIntel Galileo Gen 2ボードを制御するために、高水準 インタフェースを提供するupmとmraaの両方のライブラリを利用しま す。さらに、配線した電子部品、センサー、アクチュエータの制御方法 についても説明します。 前提条件 Intel Galileo Gen 2ボードでは、Yocto Poky Linuxイメージが起動しま す。このイメージは、 Intel Galileo用Linuxオペレーティング・システム のmicroSDカード向けイメージの最新バージョンです。Galileo用の最 新バージョンのYocto Pokyイメージは、 IntelのWebサイトからダウン ロードできます。 開発には、 Intel System Studio IoT Editionソフトウェアを使用し ます。このEclipseベースのIDEを使うと、 Javaをメインのプログラミン グ言語として簡単に新しいIoTプロジェクトを作ることができます。ま た、利用可能な最新バージョンのmraaとupmの2つのライブラリを両 方とも使用します。mraaライブラリは、Linuxプラットフォームで通信を 行うための低水準のスケルトン・ライブラリです。upmライブラリは、 センサーやアクチュエータと通信するための一連のライブラリです。 いずれも、 Intel IoT Development Kitに含まれています。 Intel System Studio IoT Editionは、 IntelのIoTサイトからダウンロードできます。 Javaで新しいIoTプロジェクトを開始する際に直面する可能性が ある主な問題の1つは、 Intel System Studio IoT Editionに含まれる upmおよびmraaライブラリのバージョンが、 Intel Galileo Gen 2ボー ドで実行されているYocto Poky Linuxにインストールされているラ イブラリのバージョンと一致しなければならないことです。残念なが ら、 IDEに含まれている同期機能を使うとさまざまな問題が発生しま す。そのため、最初にIDEのライブラリをアップデートし、次にボード をアップデートするというように、別々に操作を行うことをお勧めしま す。 IDEのメイン・メニューで「Intel(R) IoT | Libraries Update…」を 選択し、利用可能な最新バージョンのライブラリをインストールする 手順に従ってください。 ボードでmicroSDカードのLinuxオペレーティング・システム・イ メージの起動プロセスが終了し、イーサネット・ポートがLANに接続さ れると、DHCPサーバーによってボードにIPアドレスが割り当てられま す。このIPアドレスは後ほど必要になります。割り当てられたアドレス は、さまざまな方法で確認できます。たとえば、DHCPサーバーのWeb インタフェースにアクセスすれば、そこで、ボード上のラベルに記載さ れているMACアドレスに一致するデバイスに割り当てられたIPアドレ スを確認できます。 ゼロ・コンフィギュレーション・ネットワーク実装によって、LAN上 で自動的にボードとサービスを検出することもできます。Windows では、Bonjour Browser for Windows (無料)を、OS Xでは、Bonjour Browser for OS X(無料)を使うことができます。 いずれのアプリケーションも、利用可能なBonjourサービスを表 GASTÓN HILLAR Intel x86 Galileoボードの センサーを操作する IoTの神髄であるデータの取得と応答をJavaと安価なx86プロセッサ・ボードを使った実例で学ぶ

Upload: vulien

Post on 13-Dec-2018

237 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Intel x86 Galileoボードの センサーを操作する · Intel Galileo Gen 2ボードでは、Yocto Poky Linuxイメージが起動しま す。このイメージは、Intel Galileo用Linuxオペレーティング・システム

ORACLE.COM/JAVAMAGAZINE /////////////////// SEPTEMBER/OCTOBER 2016

05

//internet of things /

本記事では、計測した環境光に反応して赤、緑、青(RGB)のLEDを調整するプロジェクトについて説明し、実際に開発を行います。

この過程を通して、Java SE 8でアナログ入力やパルス幅変調(PWM)出力を扱う方法について理解できるでしょう。本記事では、Javaもサポートされている最新バージョンのIntel IoT Development Kitを使用します。また、Pentiumアーキテクチャに基づいたArduino互換x86チップを搭載したIntel Galileo Gen 2ボードを制御するために、高水準インタフェースを提供するupmとmraaの両方のライブラリを利用します。さらに、配線した電子部品、センサー、アクチュエータの制御方法についても説明します。

前提条件Intel Galileo Gen 2ボードでは、Yocto Poky Linuxイメージが起動します。このイメージは、Intel Galileo用Linuxオペレーティング・システムのmicroSDカード向けイメージの最新バージョンです。Galileo用の最新バージョンのYocto Pokyイメージは、IntelのWebサイトからダウンロードできます。

開発には、Intel System Studio IoT Editionソフトウェアを使用します。このEclipseベースのIDEを使うと、Javaをメインのプログラミング言語として簡単に新しいIoTプロジェクトを作ることができます。また、利用可能な最新バージョンのmraaとupmの2つのライブラリを両方とも使用します。mraaライブラリは、Linuxプラットフォームで通信を行うための低水準のスケルトン・ライブラリです。upmライブラリは、センサーやアクチュエータと通信するための一連のライブラリです。いずれも、Intel IoT Development Kitに含まれています。Intel System

Studio IoT Editionは、IntelのIoTサイトからダウンロードできます。Javaで新しいIoTプロジェクトを開始する際に直面する可能性が

ある主な問題の1つは、Intel System Studio IoT Editionに含まれるupmおよびmraaライブラリのバージョンが、Intel Galileo Gen 2ボードで実行されているYocto Poky Linuxにインストールされているライブラリのバージョンと一致しなければならないことです。残念ながら、IDEに含まれている同期機能を使うとさまざまな問題が発生します。そのため、最初にIDEのライブラリをアップデートし、次にボードをアップデートするというように、別々に操作を行うことをお勧めします。IDEのメイン・メニューで「Intel(R) IoT | Libraries Update…」を選択し、利用可能な最新バージョンのライブラリをインストールする手順に従ってください。

ボードでmicroSDカードのLinuxオペレーティング・システム・イメージの起動プロセスが終了し、イーサネット・ポートがLANに接続されると、DHCPサーバーによってボードにIPアドレスが割り当てられます。このIPアドレスは後ほど必要になります。割り当てられたアドレスは、さまざまな方法で確認できます。たとえば、DHCPサーバーのWebインタフェースにアクセスすれば、そこで、ボード上のラベルに記載されているMACアドレスに一致するデバイスに割り当てられたIPアドレスを確認できます。

ゼロ・コンフィギュレーション・ネットワーク実装によって、LAN上で自動的にボードとサービスを検出することもできます。Windowsでは、Bonjour Browser for Windows(無料)を、OS Xでは、Bonjour Browser for OS X(無料)を使うことができます。

いずれのアプリケーションも、利用可能なBonjourサービスを表

GASTÓN HILLAR

Intel x86 Galileoボードのセンサーを操作するIoTの神髄であるデータの取得と応答をJavaと安価なx86プロセッサ・ボードを使った実例で学ぶ

Page 2: Intel x86 Galileoボードの センサーを操作する · Intel Galileo Gen 2ボードでは、Yocto Poky Linuxイメージが起動しま す。このイメージは、Intel Galileo用Linuxオペレーティング・システム

ORACLE.COM/JAVAMAGAZINE /////////////////// SEPTEMBER/OCTOBER 2016

06

//internet of things /

示するもので、galileoという名前のものにだけ着目すれば大丈夫です。galileoという名前のSSHサービス用に表示されるIPアドレスが、ボードとの接続を確立するために使用できるIPアドレスです。

次に、お気に入りのSSH端末ツールを使って、Intel Galileo Gen 2ボードで実行されているYocto Linuxに接続します。その際に、先ほど取得したIPアドレスと、rootユーザーおよび空のパスワードを使用します。続いて、SSH端末から次のコマンドを実行します。

opkg updateopkg install mraaopkg install upm

次に、「Create an IoT Project」をクリックし、IDEで「Java Project」を選択します。この例では、プロジェクト名をAmbientLightAndLedとし、Intel Galileo Gen 2ボードの接続名とIPアドレスを入力します。こうすると、IDEにより、指定したボードにプロジェクトをアップロードして実行する環境が構築されます。プロジェクトからの出力はコンソールに表示され、コマンドは端末から実行できます。しかし、よくあるように、動作の仕組みがわかってしまえば、独自のスクリプトを作成して独自のコマンドを実行し、生成されたJARをアップロードして実行する方が簡単なことがわかるでしょう。IDEによって統合デバッグ環境が提供されるため、Javaでmraaライブラリやupmライブラリを使うようになると、とても便利になります。

電子部品の配線フォトレジスタは、光依存性抵抗(LDR)やフォトセルとも呼ばれる電子部品です。この部品は高い水準の正確性を備えた、環境光を検知する最適な手段というわけではありません。しかし、暗い環境であるかどうかを判定する場合には有用であり、今回の例では、レイテンシ(光の明暗を伝える遅延)も問題にはなりません。さらに複雑なプロジェクトで環境光を検知する必要がある場合は、正確性とレイテンシも考慮してください。

フォトレジスタは、環境光の強度に応じて抵抗が変化する可変抵抗です。環境光の強度が増加するとフォトレジスタの抵抗が低下し、強度が減少すると抵抗が上昇します。

ボードでは、アナログ入力ピンの電圧値を読み取ることができま

す。今回は、分圧回路構成に含まれる2つの抵抗の1つとしてフォトレジスタを使用します。分圧回路の出力電圧値は、フォトレジスタへの入射光が強い場合には高くなり、入射光が弱い場合またはまったくない場合には低くなります。

Intel Galileo Gen 2ボードでは、PWM出力ピンとして6つのデジタルI/Oピンのみを使用できます。これらの6つのピンには、チルダ記号

(~)の後にボード上の番号が付いた名前が付いています。今回は、フォトレジスタを含む分圧回路の正(+)の側をA0と表示

されたアナログピンに接続します。さらに、次のPWM対応ピンを使ってRGB LEDの輝度レベルを制御します。

■ ピン~6をRGB LEDの赤色コンポーネント用のアノード・ピンに接続 ■ ピン~5をRGB LEDの緑色コンポーネント用のアノード・ピンに接続 ■ ピン~3をRGB LEDの青色コンポーネント用のアノード・ピンに接続

今回の例を動作させるには、次のパーツが必要になります。 ■ フォトレジスタ ■ 10,000Ω(10kΩ)の抵抗(許容差5%)。抵抗のカラー・コードは、茶、黒、橙、金

■ カソード・コモンの5mm RGB LED ■ 270Ωの抵抗(許容差5%)3個。抵抗のカラー・コードは、赤、紫、茶、金

Page 3: Intel x86 Galileoボードの センサーを操作する · Intel Galileo Gen 2ボードでは、Yocto Poky Linuxイメージが起動しま す。このイメージは、Intel Galileo用Linuxオペレーティング・システム

ORACLE.COM/JAVAMAGAZINE /////////////////// SEPTEMBER/OCTOBER 2016

07

//internet of things /図 1は、前述の電子部品をブレッドボードに接続して必要な

配線を行い、Intel Galileo Gen 2 ボードとの配線を終えたものです(元の図は、有名な Fritzing マルチプラットフォーム・アプリケーションを使って作成しました。Fritzingファイルは、Java Magazineダウンロード・サイトからダウンロードできる、本記事に関連するコード・バンドルに含まれています)。

PWM 対応の GPIO(汎用入出力)ピンには、~6、~5、~3 の3 つがあります。それぞれを 270 Ωの抵抗に接続し、各色の LEDに対応するアノード・ピンに配線します。カソード・コモンはグランド(GND)に接続し、アナログ入力ピン A0 を、フォトレジスタと10k Ω抵抗(許容差 5%)で構成された分圧回路に接続します。フォトレジスタを IOREF ピンに配線します。今回はボードのデフォルトの構成を使っているため、IOREF の電圧は 5V です。10k Ωの抵抗は、GND に配線します。

PWMを使用してLEDの明るさを調整するクラスのコーディング必要な配線を終えた後は、暗い環境であるかどうかを判定し、環境光の値に応じてRGB LED の 3 色の明るさを制御する Javaコードを書く必要があります。このコードは、抵抗値を電圧に変換した結果を読み取り、そのアナログ値をデジタル表現に変換します。さらに、デジタル値を電圧値にマッピングし、その電圧値を暗さの度合い、すなわち環境光計測値にマッピングします。

コードを読みやすくわかりやすいものにするために、以降で説明する Javaクラスでは、実行した各操作の結果のチェックを行っていません。ただし、完成版のコードでは、さまざまな mraaクラスのインスタンスにおける各メソッド呼出しの結果をチェックし、戻り値が mraa.Result.SUCCESS であることを確認する必要があります。

この例では、次の 3 つのクラスを作成します。 ■ VariableBrightnessLed:ボードに接続された LED を表します。このクラスにより、輝度レベルを制御できます。

■ VoltageInput:ボードのアナログ入力ピンに接続された電圧源を表します。アナログ入力から読み取った未処理値を電圧値にマッピングできます。

■ SimpleLightSensor:光センサーを表します。VoltageInput インスタンスで計測された電圧値を光計測値と説明に変換できます。

次に、VariableBrightnessLedクラスとSimpleLightSensorクラスのインスタンスを作成するBoardManagerクラスを作成し、2 つのクラスとやり取りを行います。最後に、これまで説明した各クラスの操作を統括するAmbientLightAndLedというマスター・クラスを作成します。

図1:ブレッドボードに接続し、Intel Galileo Gen 2ボードに配線した電子部品

Page 4: Intel x86 Galileoボードの センサーを操作する · Intel Galileo Gen 2ボードでは、Yocto Poky Linuxイメージが起動しま す。このイメージは、Intel Galileo用Linuxオペレーティング・システム

ORACLE.COM/JAVAMAGAZINE /////////////////// SEPTEMBER/OCTOBER 2016

08

//internet of things /

それではまず、ボードに接続されたLEDを表すVariableBrightnessLedクラスを新規に作成します。LEDは、0以上255以下の輝度レベルをとることができます。次のコードは、すべてのクラスで使用するインポート文と新しいクラスのコードを示しています。

import mraa.Aio;import mraa.Pwm;

class VariableBrightnessLed { private final int gpioPin; private final String name; private final Pwm pwm; private int brightnessLevel; public VariableBrightnessLed(int gpioPin, String name) { this.name = name; this.gpioPin = gpioPin; this.pwm = new Pwm(gpioPin); this.pwm.period_us(700); this.pwm.enable(true); // 輝度レベルの初期値を0に設定 this.setBrightnessLevel(0); } public void setBrightnessLevel( int brightnessLevel) { int validBrightnessLevel = brightnessLevel; if (validBrightnessLevel > 255) { validBrightnessLevel = 255; } else if (validBrightnessLevel < 0){ validBrightnessLevel = 0; } float convertedLevel =

validBrightnessLevel / 255f; this.pwm.write(convertedLevel); this.brightnessLevel = validBrightnessLevel; System.out.format( "%s LED connected to PWM Pin #%d " + "set to brightness level %d.%n", this.name, this.gpioPin, validBrightnessLevel); } public int getBrightnessLevel() { return this.brightnessLevel; } public int getGpioPin() { return this.gpioPin; }}

VariableBrightnessLedクラスのインスタンスを作成する際には、LEDが接続されているGPIOピン番号をint型のgpioPin引数で、LEDの名前をString型のname引数で指定する必要があります。コンストラクタは、受け取ったgpioPinを、ピンを表す引数として使用し、新しいmraa.Pwmインスタンスを作成します。その参照をpwmフィールドに保存し、period_usメソッドを呼び出してPWMの周期を700マイクロ秒(700µs)に設定します。これによって、700µsの間に信号をオン状態にする時間の割合を出力デューティ比で指定できるようになります。

たとえば、出力デューティ比が0.10(10%)の場合、700µsのうち70µsの間、信号がオンになります。次に、コンストラクタはtrueをパラメータにしてpwm.enableメソッドを呼び出し、PWM対応ピンの状

Page 5: Intel x86 Galileoボードの センサーを操作する · Intel Galileo Gen 2ボードでは、Yocto Poky Linuxイメージが起動しま す。このイメージは、Intel Galileo用Linuxオペレーティング・システム

ORACLE.COM/JAVAMAGAZINE /////////////////// SEPTEMBER/OCTOBER 2016

09

//internet of things /

態を有効に設定します。これによって、コードからpwm.writeメソッドを呼び出してPWMピンの出力デューティ比の設定を開始できるようになります。

最後に、コンストラクタはbrightnessLevel引数の値として0を使い、setBrightnessLevelメソッドを呼び出します。これによって、コンストラクタは指定されたピン番号に配線されたLEDの輝度レベルを0に設定し、消灯します。具体的には、この呼出しによって、指定された色のコンポーネントのRGB LEDが消灯します。

このクラスには、setBrightnessLevelメソッドが宣言されています。このメソッドでは、0以

上255以下の輝度レベルをPWMピンで使う適切な出力デューティ比の値に変換しています。このメソッドは、int型のbrightnessLevel引数で輝度レベル値を受け取ります。

コードでは、最初に輝度レベルが0以上255以下の値であることを確認しています。値が範囲外の場合は、最低値または最高値にした上で、輝度レベルをローカル変数validBrightnessLevelに保存します。

次に、PWMピンで必要となる出力デューティ比を計算し、輝度レベルを1.0fから0.0fの間の浮動小数点値(100%から0%)として表現します。そのためには、有効な輝度レベル(validBrightnessLevel)を255fで割る必要があります。その値は、convertedLevel変数に保存されます。次の行では、比率を示す引数としてconvertedLevel変数を使ってthis.pwm.writeメソッドを呼び出しています。これによって、PWM出力に設定されているピンの出力デューティ比をconvertedLevelに設定します。

最後に、有効な輝度レベルをbrightnessLevelフィールドに保存します。このフィールドには、getBrightnessLevelメソッドから読取り専用でアクセスできます。最後の行では、LEDの識別名、配線先のピン番号、および設定した輝度レベルを出力しています。この行は、System.out.formatを使って出力しています。生成されたJARフ

ァイルをIDEから実行するか、ボード上で実行されているYocto LinuxにSSH経由で接続してコマンドを実行すると、出力の内容を確認できます。後ほど、有用な情報を出力することのメリットについて説明します。

アナログ入力による環境光計測ここで、ボード上のアナログ入力ピンに接続された電圧源を表すVoltageInputクラスを新しく作成します。この新しいクラスのコードを以下に示します。

class VoltageInput { private final int analogPin; private final Aio aio; public VoltageInput(int analogPin) { this.analogPin = analogPin; this.aio = new Aio(analogPin); // ADC(アナログ・デジタル・ // コンバータの略)の分解能を // 12ビット(0から4095)に設定 this.aio.setBit(12); } public float getVoltage() { long rawValue = this.aio.read(); float voltageValue = rawValue / 4095f * 5f; return voltageValue; }

public int getAnalogPin() { return analogPin; }}

このクラスにはメソッドが宣言されており、0以上255以下の輝度レベルをPWMピンで使う適切な出力デューティ比の値に変換しています。

Page 6: Intel x86 Galileoボードの センサーを操作する · Intel Galileo Gen 2ボードでは、Yocto Poky Linuxイメージが起動しま す。このイメージは、Intel Galileo用Linuxオペレーティング・システム

ORACLE.COM/JAVAMAGAZINE /////////////////// SEPTEMBER/OCTOBER 2016

10

//internet of things /

VoltageInputクラスのインスタンスを作成する際には、電圧源が接続されているアナログ・ピン番号をint型のanalogPin引数で指定する必要があります。コンストラクタでは、受け取ったアナログ・ピン番号をanalogPinフィールドに保存しています。この値には、getAnalogPinメソッドから読取り専用でアクセスできます。次に、コンストラクタは、受け取ったanalogPinを、ピンを表す引数として使用し、新しくmraa.Aioインスタンスを作成します。その参照をaioフィールドに保存し、setBitメソッドを呼び出してアナログ・デジタル・コンバータ(ADC)の分解能を12ビットに設定します。こうすると、ADCは0Vから5Vを表す4,096種類の値(212 = 4096)を提供するようになります。ADCから読み取った値が0の場合は0V、4095の場合は5Vを意味します。

アナログ・ピンから読み取った未処理値は、線形関数を適用して変換し、対応する入力電圧値にマッピングする必要があります。そのために、コードではアナログ・ピンから読み取った未処理値に5を掛けてから4095で割り、未処理値から入力電圧値を得ています。分解能を12ビットにしているため、検出する値は5V/4095 = 0.001220012V、つまり約1.22ミリボルトの精度になります。

VoltageInputクラスには、getVoltageメソッドが宣言されています。このメソッドでは、まずthis.aio.readメソッドを呼び出してアナログ・ピンから未処理値を取得し、long型の変数rawValueに保存しています。この変数に値を保存するのは、デバッグを容易にし、コードの仕組みをわかりやすくするためです。次に、rawValueを4,095で割ってから5を掛けたものをfloat型の変数voltageValueに保存しています。このメソッドは、最終的にvoltageValue変数の値を返します。以上のような仕組みによって、このメソッドは、this.aio.readメソッドから取得した未処理値を変換して電圧値を返しています。

以上で、電圧源から電圧値を取得できるクラスを作成しました。次は、新しくSimpleLightSensorクラスを作成します。このクラスは、分圧回路に含まれ、ボードのアナログ・ピンに配線されているフォトレジスタを表します。この新しいクラスでは、先ほど作成した、アナログ入力を読み取って変換するVoltageInputクラスを使用します。この新しいクラスを使うと、電圧値を光の測定値に変換し、その説明を表示できるようになります。この新しいクラスのコードを以下に示します。

class SimpleLightSensor { // 光レベルの説明 public static final String LL_EXTREMELY_DARK = "Extremely dark"; public static final String LL_VERY_DARK = "Very dark"; public static final String LL_JUST_DARK = "Just dark"; public static final String LL_SUNNY_DAY = "Like a sunny day"; // 光レベルを決定する最大電圧 private static final float EXTREMELY_DARK = 2.1f; private static final float VERY_DARK = 3.1f; private static final float JUST_DARK = 4.05f; private final VoltageInput voltageInput; private float measuredVoltage = 0f; private String lightLevel = SimpleLightSensor.LL_SUNNY_DAY; public SimpleLightSensor(int analogPin) { this.voltageInput = new VoltageInput(analogPin); this.measureLight(); }

Page 7: Intel x86 Galileoボードの センサーを操作する · Intel Galileo Gen 2ボードでは、Yocto Poky Linuxイメージが起動しま す。このイメージは、Intel Galileo用Linuxオペレーティング・システム

ORACLE.COM/JAVAMAGAZINE /////////////////// SEPTEMBER/OCTOBER 2016

11

//internet of things /

public void measureLight() { this.measuredVoltage = this.voltageInput.getVoltage(); if (this.measuredVoltage < SimpleLightSensor.EXTREMELY_DARK) { this.lightLevel = SimpleLightSensor.LL_EXTREMELY_DARK; } else if (this.measuredVoltage < SimpleLightSensor.VERY_DARK) { this.lightLevel = SimpleLightSensor.LL_VERY_DARK; } else if (this.measuredVoltage < SimpleLightSensor.JUST_DARK) { this.lightLevel = SimpleLightSensor.LL_JUST_DARK; } else { this.lightLevel = SimpleLightSensor.LL_SUNNY_DAY; } } public String getLightLevel() { return this.lightLevel; }}

このクラスでは、次の3つのクラス・フィールドが定義されています。これらのフィールドでは、各光レベルを決定する最大電圧値を指定しています。 ■ EXTREMELY_DARK:2.1V ■ VERY_DARK:3.1V ■ JUST_DARK:4.05V

取得した電圧が2.1Vよりも低い場合、極端に暗い環境です。取得した電圧が3Vよりも低い場合、かなり暗い環境です。取得した電圧が4.05Vよりも低い場合、少し暗い環境です。これらの値は、特定のフォトレジ

スタ向けのものです。お使いの構成で個別の環境を判定する際に使う電圧値を確認する必要があるかもしれません。その場合でも、クラス・フィールドの値を変更するだけで構いません。

SimpleLightSensorクラスの主な目的は、定量値(電圧値)を定性値(環境光の説明)に変換することです。このクラスでは、光レベルを説明する次の4つのクラス・フィールドが宣言されています。

■ LL_EXTREMELY_DARK ■ LL_VERY_DARK ■ LL_JUST_DARK ■ LL_SUNNY_DAY

SimpleLightSensorクラスのインスタンスを作成する際には、analogPin引数に、フォトレジスタを含む分圧回路が接続されているアナログ・ピン番号を指定する必要があります。コンストラクタは、受け取ったanalogPin引数を使ってVoltageInputインスタンスを新しく作成し、その参照をvoltageInputフィールドに保存します。次の行では、measureLightメソッドを呼び出しています。このメソッドは、VoltageInputインスタンス(this.voltageInput)から取得した電圧値を光レベルの説明に変換します。

このクラスでは、measureLightメソッドが宣言されています。このメソッドでは、this.voltageInput.getVoltageメソッドを呼び出して取得した電圧値をmeasuredVoltageフィールドに保存しています。次の行では、先ほど説明したクラス・フィールドを使って、measuredVoltageフィールドの値が各光レベルを決定する最大電圧よりも低いかどうかを判定しています。コードでは、計測した電圧値に応じた適切な値をlightLevelフィールドに設定しています。その後、getLightLevelメソッドを呼び出すと、光レベルの説明にアクセスできます。

この新しいクラスを使うと、電圧値を光の測定値に変換し、その説明を表示できるようになります。

Page 8: Intel x86 Galileoボードの センサーを操作する · Intel Galileo Gen 2ボードでは、Yocto Poky Linuxイメージが起動しま す。このイメージは、Intel Galileo用Linuxオペレーティング・システム

ORACLE.COM/JAVAMAGAZINE /////////////////// SEPTEMBER/OCTOBER 2016

12

//internet of things /

ボード・マネージャによる、1つの入力と3つの出力の制御次は、BoardManagerクラスを新しく作成します。このクラスでは、先ほど作成したSimpleLightSensorクラスの1つのインスタンスと、VariableBrightnessLedクラスの3つのインスタンスを作成します。こうすることによって、RGB LEDの各色コンポーネントに、VariableBrightnessLedクラスのインスタンスが1つずつ割り当てられます。このクラスは、環境光が変化したときにアクションを発動します。具体的には、計測した環境光に応じて、RGB LEDの3つの色コンポーネントの明るさを調整します。この新しいクラスのコードを以下に示します。

class BoardManager { public final SimpleLightSensor lightSensor; public final VariableBrightnessLed redLed; public final VariableBrightnessLed greenLed; public final VariableBrightnessLed blueLed; public BoardManager() { this.lightSensor = new SimpleLightSensor(0); this.redLed = new VariableBrightnessLed(6, "Red"); this.greenLed = new VariableBrightnessLed(5, "Green"); this.blueLed = new VariableBrightnessLed(3, "Blue"); } public void setRGBBrightnessLevel(int value) { this.redLed.setBrightnessLevel(value); this.greenLed.setBrightnessLevel(value); this.blueLed.setBrightnessLevel(value); } public void updateLedsBasedOnLight() {

String lightLevel = this.lightSensor.getLightLevel(); switch (lightLevel) { case SimpleLightSensor.LL_EXTREMELY_DARK: this.setRGBBrightnessLevel(255); break; case SimpleLightSensor.LL_VERY_DARK: this.setRGBBrightnessLevel(128); break; case SimpleLightSensor.LL_JUST_DARK: this.setRGBBrightnessLevel(64); break; default: this.setRGBBrightnessLevel(0); break; } }}

BoardManagerクラスには、次の4つのフィールドが宣言されており、コンストラクタが各フィールドを初期化しています。

■ lightSensor:SimpleLightSensorのインスタンスです。アナログ・ピンA0に接続されている分圧回路に含まれるフォトレジスタを表します。

■ redLed:VariableBrightnessLedのインスタンスです。GPIOピン~6に接続されているRGB LEDの赤色コンポーネントを表します。

■ greenLed:VariableBrightnessLedのインスタンスです。GPIOピン~5に接続されているRGB LEDの緑色コンポーネントを表します。

■ blueLed:VariableBrightnessLedのインスタンスです。GPIOピン~3に接続されているRGB LEDの青色コンポーネントを表します。

setRGBBrightnessLevelメソッドは、受け取った

Page 9: Intel x86 Galileoボードの センサーを操作する · Intel Galileo Gen 2ボードでは、Yocto Poky Linuxイメージが起動しま す。このイメージは、Intel Galileo用Linuxオペレーティング・システム

ORACLE.COM/JAVAMAGAZINE /////////////////// SEPTEMBER/OCTOBER 2016

13

//internet of things /

valueを引数として、3つのVariableBrightnessLedインスタンスのsetBrightnessLevelメソッドを呼び出します。これによって、一度の呼出しでRGB LEDの3つの色コンポーネントが同じ輝度レベルに設定されます。

updateLedsBasedOnLightメソッドは、SimpleLightSensorインスタンスから光レベルの説明を取得し、先ほど説明したsetRGBBrightnessLevelメソッドを呼び出します。これにより、計測した光に応じてRGB LEDの3つのコンポーネントの輝度レベルを設定します。極端に暗い場合は、輝度レベルを255に設定します。かなり暗い場合は、輝度レベルを128に設定します。少し暗い

場合は、輝度レベルを64に設定します。それ以外は、輝度レベルを0に設定します。この場合、RGB LEDは完全に消灯します。

次に、BoardManagerクラスを利用して環境光を計測し、計測した環境光に応じてRGB LEDの3つの色コンポーネントの輝度を設定するコードを記述します。この新しいAmbientLightAndLedクラ

スのコードを以下に示します。

public class AmbientLightAndLed { public static void main(String[] args) { String lastlightLevel = ""; BoardManager board = new BoardManager(); while (true) { board.lightSensor.measureLight(); String newLightLevel = board.lightSensor.getLightLevel(); if (newLightLevel != lastlightLevel) { // 計測した光レベルが変わった lastlightLevel = newLightLevel; System.out.format(

"Measured light level: %s%n", newLightLevel); board.updateLedsBasedOnLight(); } try { Thread.sleep(1000); } catch (InterruptedException e) { System.err.format( "Sleep interruption: %s", e.toString()); } } }}

このクラスには、mainメソッドが宣言されています。プロジェクトをボードにアップロードして起動すると、このクラスが実行されます。最初に、ローカル変数lastLightLevelが空文字列で初期化され、boardという名前の、BoardManagerクラスのインスタンスが作成されます。次に、メソッドは無限ループに入ります。

ループの中では、board.lightSensor.measureLightメソッドが呼び出され、環境光の計測値が更新されます。次の行では、board.lightSensor.getLightLevelを呼び出して取得した光レベルの説明を、newLightLevelローカル変数に保存しています。新しい光レベルが最後に記録された環境光レベルと異なる場合、lastLightLevel変数の値を更新し、計測された光レベルを出力して、board.updateLedsBasedOnLightメソッドを呼び出します。

この例を実行し、懐中電灯やスマートフォンを使ってフォトレジスタに当てる光を変えてみてください。メッセージの出力が確認され、RGBが暗くなって最終的に消灯するはずです。環境光が暗くなると、RGB LEDは明るくなります。

図2は、IDEのコンソール・ウィンドウに表示される出力の例です。コンソール・ウィンドウには、コードから出力されたすべてのメッセージが表示されます。そのため、各部品で何が起きているのかを簡単に理解できます。

SimpleLightSensorクラスの主な目的は、定量値(電圧値)を定性値(環境光の説明)に変換することです。

Page 10: Intel x86 Galileoボードの センサーを操作する · Intel Galileo Gen 2ボードでは、Yocto Poky Linuxイメージが起動しま す。このイメージは、Intel Galileo用Linuxオペレーティング・システム

ORACLE.COM/JAVAMAGAZINE /////////////////// SEPTEMBER/OCTOBER 2016

14

//internet of things /

まとめ今回の簡単な例では、Java SE 8を活用してIntel Galileo Gen 2ボード上のIoTコンポーネントとやり取りする高水準のコードを作成する例を示しました。mraaライブラリやupmライブラリは定期的に更新されています。この2つとJavaを組み合わせることによって、既存の知識を活用しつつ、多様な入力、出力、センサー、ディスプレイ、アクチュエータと連携するIoTプロジェクトを簡単に進めることができるようになります。</article>

Gastón Hillar(@gastonhillar):Javaが初めてリリースされた頃からソフトウェア・アーキテクトとして働いており、ソフトウェアの設計、開発に関する20年の経験を有する。ソフトウェア開発、ハードウェア、電子工学、Internet of Thingsに関する多くの著書がある。

Yocto ProjectのYocto Poky LinuxイメージIntel System Studio IoT Edition User Guide for Java

learn more

図2:コンソール・メッセージ

この最新の強化提案は、コマンドラインから実行されるJDKツールに引数を渡す構文の共通化を提案するものです。ドキュメントで指摘されているように、現在のJDKツールではスイッチの表記規則が共通化されていません。たとえば、ほとんどの読者はすべてのツールで一貫性のあるヘルプ・コマンドを望むでしょうが、現在は、-?、-help、--helpなど、ツールによって異なっています。

JEP 293は、主に今後のコマンドラインJDK製品での統一を提唱するものです。有用であるとして、このJEPで採用が提案されている形式は、一連のGNU構文表記規則です。この規則の大部分は、getopt(3)に記述されています。これらの表記規則は、1つのハイフンと1文字(組み合わせ可能)のオプションに加え、いわゆる「長い」オプションとして2つのハイフンを使うものです。この方式は、多くのユーザーにとっておなじみであり、構文を解析しているライブラリがすでに存在するため、もっとも好ましいと考えられています。とはいえ、特殊性(-Wが予約されている)による悪影響や、POSIX構文との競合が発生する部分もあります。もちろん、この種の意見交換、つまりコミュニティでのJDKの変更に関する議論を求める部分こそ、まさにこれらのJEPのポイントです。

この提案では、既存ツールのオプションの変更は提案されていません。そのため、互換性が失われる予定はありません。しかし、新しいリリースでは、すべてのツールにおいて、合意された構文をサポートすることが推奨され、やがて既存のツールもそれに準拠するように重複したスイッチが導入される可能性があります。

JEP 293:コマンドライン・オプションの形式の改定

注目のJDK強化提案

//java proposals of interest /

Listening for transport dt_socket at address: 8009Red LED connected to PWM Pin #6 set to brightness level 0.Green LED connected to PWM Pin #5 set to brightness level 0.Blue LED connected to PWM Pin #3 set to brightness level 0.Measured light level: Extremely darkRed LED connected to PWM Pin #6 set to brightness level 255.Green LED connected to PWM Pin #5 set to brightness level 255.Blue LED connected to PWM Pin #3 set to brightness level 255.Measured light level: Extremely darkRed LED connected to PWM Pin #6 set to brightness level 128.Green LED connected to PWM Pin #5 set to brightness level 128.Blue LED connected to PWM Pin #3 set to brightness level 128.