Windows IOT with RPi ~ラズパイ x JavaでLチカをやってみる~

イントロダクション

ラズパイでJavaプログラミングをやりたいと思っていたのですが、なかなか着手できずにいましたが、昨日LANのインターフェースを買ってきました。

これで、Windowsと接続してIOTしたいなと思っている次第です。

Widnows IOT

はじめに、IOTというとArduino、ichigo-jam、Microbitなどもあるのですが、Javaプログラミングをやりたかったらラズパイになります。
容量的にラズパイクラスのPCでないと動かないためです。JavaMEも残念ながらArduinoなどではデータのサイズが足らない状態です。。。

Microsoftの「Windows Iot for Raspberry Pi」を参考にして学習していきます。

VNCセットアップを行う

次に、WindowsPCからラズパイにアクセスして作業がやりたいので、リモート接続(リモートデスクトップ)の設定を行います。

Windows PCに接続する動画があるのでそれを見ると早いです。

この動画を見ると、必要な機材から丁寧に説明してくれている。残念ながら英語で説明してくれている。。。
日本語版があるといいんだけど。。。

一時停止ながら聞いていくと、WindowsIotのスターターパックみたいなのも、あるようです。

ラズパイの接続

筆者は、自力でラズパイをインストールしたので、インストール済みのラズパイを接続しました。WindowsIotの場合はSDカードのインストールからやるようです。

調べてみると、リモート接続でVNCを使用するようです。セキュリティ的に「xrdp」を使用する方法は、できなくなったようです。※Raspberry DeskTop

VNC接続手順

ラズパイに、VCNの設定を行う。

  1. ラズパイのメニュー→設定→インターフェースを開く右上の「V2」があることを確認

  2. SSH、VNC、I2Cの3つを「ON」に設定します。OKボタンを押下

  3. V2というのが右上部に表示されるのでそれをクリックしてIPアドレスをメモなどで覚えておきます。

  4. WindowsでVNC Viewerをインストールします。
      WindowsにインストールしたVNCビューワーで表示します。

いろいろとインストールする

まずここで使用したいものは「Py4J」というライブラリです。これはJavaからGPIOを使うために必要になります。
同様に、作成したプロジェクトを管理、学習のためにチェックアウトしたい時に便利な「Maven」をインストールしたいと思います。

まずは、ラズパイのアップデートをしましょう。

sudo apt update

Py4Jのインストール

Py4Jのサイトを参考にします。

ネットワーク接続がうまくいかなかったので、とりあえず、手動インストールしました。

  1. ここからDEBファイルをダウンロード※上記のリンク先にあります。
  2. VNC Veiwerでファイルを送信
  3. 「sudo dpkg -i pi4j-1.2.deb」コマンドでインストール

WringPiをインストール

下のコマンドでインストールします。やることはGitからソースを取得してビルドする。ということです。

git clone https://github.com/WiringPi/WiringPi.git
cd WringPi
./build

インストールできたら、確認します。

gpio -v

pigpioのインストール

sudo apt-get install pigpio

Mavenのインストール

次のコマンドで一発インストール

 sudo apt install maven -y

Javaのインストール

Oracleのサイトに次の文章がありました。

ありがたいことに、BellSoftがLiberica JDKを提供しています。

というわけで、次の手順でインストールします。

  1. 上のリンク先からDEBファイルをダウンロード
  2. VNC Viewerでファイル送信
  3. インストールをします。
  4. Javaのバージョンを切り替える

Javaを動かす

そして、Javaに触ります。ラズパイには、BlueJというIDE(開発ツール)がデフォルトでインストールされています。そして、チュートリアルのプロジェクトも入っています。

入ってない場合

下のコマンドで一発インストールできます。

sudo apt-get install bluej

チュートリアル

詳細は、BlueJのチュートリアルサイトにありました。
プロジェクト名が「LEDチュートリアル」のようです。ここをクリックするとダウンロードできます。

ダウンロードしたら、VNC Vewerでファイルをラズパイに送信できます。

BlueJを起動して、Controllerクラスを実行するのには、Controllerクラスを右クリックして、「new」してやれば実行できます。

余談

プログラムの実行というとメインメソッドを探してしまうのですが、BlueJの場合は、コンストラクタを実行することができるので、メインメソッドを探さなくてもよさそうです。BlueJがSwingで動いているからかな?

しかしエラーが。。。

早速プロジェクトを実行してみたら、下のようなエラーが出た。

重大: Unable to load [libpi4j.so] using path: [/lib/raspberrypi/dynamic/libpi4j.so]

原因は、そのまんま「「libpi4j.so]が見つからない」というエラーでした。
なので、これをダウンロードしてプロジェクト直下に配置してやるのが解決策でした。手順は以下の通りです。

libpi4j.soを取得

Py4Jのページにパスの指定方法が書いてありました。Javaを起動するときに下のようにやります。

ライブラリ取得先

上記のページに記載がありました。

ネイティブ ライブラリの入手先
Pi4J ネイティブ ライブラリは、アーキテクチャ固有のファイルを抽出することで取得できます。libpi4j-xxx.soプラグイン JAR ファイルのリソースからファイルを取得します。

さらに、Pi4J ネイティブ ライブラリは、Maven リポジトリで独立したアーティファクトとして公開されます。 https://oss.sonatype.org/#nexus-search;quick~pi4j-library-pigpio

libpi4j.soを参照する

ダウンロードしてきたファイルをBlueJプロジェクトで参照しないといけません。参照する方法は次のような3パターンがあります。

パターン1

Javaコマンドの実行時にVM引数を渡してやる方法。

java --Dpi4j.library.path="system" ...
-or-
java --Dpi4j.library.path="local" ...
-or-
java --Dpi4j.library.path="/some/directory" ...

パターン2

プログラムでシステムプロパティを追加する方法

System.setProperty("pi4j.library.path", "/some/directory");
-or-
System.setProperty("pi4j.library.path", "system");
-or-
System.setProperty("pi4j.library.path", "local");

パターン3

実行しているBlueJプロジェクトのフォルダに直接配置。下の画像のように配置します。

JavaでLチカをやってみる

準備ができたので、今回の目的であるLチカに着手したいと思います。

コードの分析

Controllerクラスを解析します。ちなみに、ラズパイにもともと入っていたコードです。

READMEを読む

Project "LEDButton"
Authors: Fabio Hedayioglu, Ian Utting and Michael Kölling

飛ばします。

This project is part of the material for the tutorial for BlueJ on the Raspberry Pi.

このプロジェクトは、Raspberry Pi 上の BlueJ のチュートリアルの素材の一部です。

 It is Part of the first and second tutorial: GPIO: LED and GPIO: Button.

最初と 2 番目のチュートリアルの一部です: GPIO: LED および GPIO: ボタン。

This is a simple object to demonstrate the use of an LED and a Button
connected to the Raspberry Pi using GPIOs.

LED とボタンの使用法を示す簡単なオブジェクトです。
GPIO を使用して Raspberry Pi に接続します。

You can manipulate LEDs and Buttons and interact with them either interactively
or programatically, by editing the class Controller.

LED とボタンを操作し、インタラクティブに操作できます。
または、クラス コントローラーを編集してプログラム的に。

This project is designed in such a way to make the manipulation of LEDs and Buttons
very easy and straightfoward, making it accessible even to the novice programmer.

このプロジェクトは、LED とボタンを操作するように設計されています。
非常に簡単かつ簡単なので、初心者プログラマーでもアクセスできます。

All the implementation details are isolated to the user, in order to make the
teaching and use of the LED and Button classes completely free from low level details.

すべての実装の詳細は、ユーザーに分離されます。
LED およびボタンのクラスの教育と使用には、低レベルの詳細は一切含まれません。

The LED and Button classes are flexible and can be used in general purpose projects.

LED クラスと Button クラスは柔軟性があり、汎用プロジェクトで使用できます。

コード内容

下のコードを読んでみると次のようにまとめられます。

  1. LEDは6ピンを使用、ボタンは7ピンを使用する。

つまり、GPIOの6番ピンでLED、ボタンは6番とチュートリアルにあるが、これは、今回使用しているラズパイ3とモデルが違うようなので、別途調べる。。。

こちらがそれのようだ。

/**
 * A controller for an LED at pin 6 and a Button at pin 7.
 * 
 * Creates an LED (called led) and a Button (called button) for you to control.
 * 
 * Class used for the BlueJ on Raspberry Pi turorial.
 * 
 */
public class Controller implements ButtonListener
{
   private LED led;
   private Button button;

   /**
    * Setup the Controller.
    */
   public Controller()
   {
       led = new LED(6);             // Create the LED at pin 6 controlled by this
       button = new Button(7);       // Create the Button at pin 7 controlled by this
       button.addListener(this);     // Make the button tell us when it has changed (See buttonChanged() below)
   }

   /**
    * Turn the led on.
    * (Exercise 1.2)
    * 
    */
   public void turnLEDOn()
   {
       //put your code here.
   }

   /**
    * Turn the led off.
    * (Exercise 1.2)
    * 
    */
   public void turnLEDOff()
   {
       //put your code here.
   }

   /**
    * Keep the LED on for a given period of time, then turn it off.
    * @param time the length of the flash in milliseconds (1/1000ths of a second).
    * (Exercise 1.3)
    * 
    */
   public void flash(int time)
   {
       //put your code here.
   }

   /**
    * Blink the LED a number of times, each time the LED is kept on for a given period.
    * (Exercise 1.4)
    * 
    */
   public void flashSOS()
   {
       // Put your code here
   }

   /**
    * To be called by the Button when it is pressed or released.
    * (Exercises 2.1, 2.2 and 2.3)
    * 
    */
   public void buttonChanged(boolean isPressed)
   {
       // Put your code here
   }

   /**
    * Returns the amount of time in milliseconds between the LED turning on and the button being pressed.
    * @return the reaction time in milliseconds.
    * (Exercise 2.4)
    * 
    */
   public int reactionTime()
   {
       // Replace the line below with your code
       return 0;
   }

   /*
    *  You don't need to change the methods below this point.
    *  They are just to help you with the examples on the web page.
    */

   /**
     * Cause the program to sleep for a short time.
     * @param milisec the number of milliseconds to sleep.
     * 
     */
    public void sleepMillisec(int millisec)
    {
        try
        {
            Thread.sleep(millisec);
        }
        catch ( InterruptedException e)
        {
        }
    }

   private static long startTime = System.currentTimeMillis();

   /**
    * The current time, measured in milliseconds since the program started.
    * @return integer with measured time in milliseconds.
    * 
    */
   public int timeNow()
   {
       return ((int) (System.currentTimeMillis() - startTime));
   }

}

実行

しかし、またエラーが。。。

6月 27, 2023 9:46:59 午前 com.pi4j.util.NativeLibraryLoader load
重大: Unable to load [libpi4j.so] using path: [/lib/raspberrypi/dynamic/libpi4j.so]
java.lang.UnsatisfiedLinkError: /tmp/libpi4j9090757756364282176.so: /tmp/libpi4j9090757756364282176.so: 間違った ELF クラスです: ELFCLASS32 (Possible cause: architecture word width mismatch)

ラズパイのOSが64ビットだった。。。32ビットしかないのでわ?

最終的に再インストール

再度インストールして、セットアップを行いました。再度トライ!
しかし、またまたエラー。。。これは、BlueJでLEDクラスをインスタンス化したときにエラーが出ました。

java.lang.UnsatisfiedLinkError: 'int com.pi4j.wiringpi.Gpio.wiringPiSetup()'

何ともならなかったので、とりあえずコマンドで実行してみました。

コマンドで実行したところ何とか動きました。しかしコマンドで動かしたいわけではないので。。。

改めてBlueJから起動したところLEDボタンが表示できました。

なぞだ。。。

投稿者:

takunoji

音響、イベント会場設営業界からIT業界へ転身。現在はJava屋としてサラリーマンをやっている。自称ガテン系プログラマー(笑) Javaプログラミングを布教したい、ラスパイとJavaの相性が良いことに気が付く。 Spring framework, Struts, Seaser, Hibernate, Playframework, JavaEE6, JavaEE7などの現場経験あり。 SQL, VBA, PL/SQL, コマンドプロント, Shellなどもやります。

コメントを残す