スマホでPLCを動かしみた【後編】

この記事ではスマホでPLCを動かすためのステップを解説していきます。

この記事は後編です。

前編ではスマホではなくPCでPLCを動かして、前提知識を学びPLCのネットワーク設定をしました。

後編ではスマホアプリを作り、スマホでPLCを動かします。

AndroidStudioでアプリを作る

プロジェクトの作成

新規プロジェクトを作成します。

「ファイル→新規→新規プロジェクト→空のアクティビティ」で作成します。

「プロジェクトの構成」はデフォルトでも大丈夫です。

僕は「名前」だけ変更しています。

ファイルの説明

ファイルが複数作成されました。

いじるファイルは3つ。

  • activity_main.xml
    見た目を作ります。記述で書く方法と、視覚的に配置をする方法があります。今回は視覚的に配置します。
  • AndroidManifest.xml
    デフォルトではネットワークとの通信許可がなく、ここに許可の記述をします。
  • MainActivity.java
    ここにプログラムを記述します。

通常、プログラムは機能ごとにファイル(クラス)を分けますが、複雑になるので1ファイルに全て記述しています。
流用を考慮して通信部分を分けるなら、MainActivityのフォルダで右クリック→新規→Javaクラスで新しいファイルを作成できます。
Java知ってるよって方はチャレンジしてみてください!

レイアウトの作成

まずは見た目から作成。activity_main.xmlファイルを開きます。

テキスト形式かデザイン形式で作成することができます(画面下の方に切り替えボタンがあります)。

デザイン形式が簡単なのでこちらを使用。

ボタンを二つ配置しましょう。

画面左側にあるパレットを開き「Button」を適当な位置に配置します。

2つ配置したらそれぞれのボタンに制約をかけます。試しにボタンの上側をつかんで画面の上部に持っていきましょう。

浮いていたボタンに基準を与えることができたはずです。同じことをボタンの上下左右で行ってください。

制約をかけるとボタンが移動しますが、ボタンの位置はどこでも問題なく制約さえかけれたらOKです。

制約をかけれていないとエラーが出ます。下図では右上に赤丸にビックリマークのアイコンが出ていますね。

次はボタンのidとtextを変更します。

画面右側の属性を開き、設定変更したいボタンをクリックすると属性を見ることができます。

idとは、プログラム側(MainActivity.javaファイル)で使うボタンの識別番号のようなものです。

デフォルトだと1個目に配置したボタンが「button」、2個目に配置したボタンが「button2」になっているはず。

ちょっと気持ち悪いので「button」のidは「button1」に変更しました。

textは文字通りテキストで、変更するとボタンのテキストが変更されます。実は直接変更すべきではないのですが、扱うファイルが増えるので今回は直接変更。

直接変えないでくださいという感じの警告が出ますが無視してOKです。

レイアウトはこれで終了です!

通信の許可を与える

デフォルトでは通信の許可がないので許可を与えましょう。AndroidManifest.xmlのファイルを開き、下記の1行を追加するだけです。

<uses-permission android:name="android.permission.INTERNET" />

プログラムを準備する

MainActivity.javaファイルを開きます。初期状態はこんな感じです。

Javaでいうmainメソッドの記述はonCreateメソッド内に記述します。

ひとまずプログラムをコピペしましょう。

コピペすると「importしますか?」といった感じのメッセージが出るのでimportしてください。

このプログラムは色々なクラス(誰かが作ってくれたプログラムの塊)を使っているのですが、使う前にimportする必要があります。

それを「自動でimportしますよ。いいですか?」と聞いてくれています。必要なクラスしか聞いてきませんが、間違えて別のものをimportしても悪影響は出ません(使わないので)。

注意ポイント

プロジェクトの作成時にパッケージ名を変更している場合は、パッケージ名以外をコピペしてください。

プログラムの詳細

少しずつ説明していきます。

21:findViewById(R.id.button1).setOnClickListener(this);
22:findViewById(R.id.button2).setOnClickListener(this);

findViewByIdというメソッドで、さっき配置したボタンのidを取得しています。さらにsetOnClickListenerで取得したボタンにクリックイベントリスナを登録。

「 ◯◯ . ◯◯ 」→「 ボタン に クリックイベントリスナを登録 」といった感じ。

クリックイベントリスナってなんだ、、って感じですよね。オブジェクト(今回はボタン)をクリックした時に何かして欲しい時に登録するものです。

こうするとボタンが押されたときにイベントが発生します。

今回はボタンが押されたとき、Y0をONもしくはOFFして欲しいので、ONボタン・OFFボタンにそれぞれリスナを登録してます。

14:public class MainActivity extends AppCompatActivity implements View.OnClickListener {

さっきクリックイベントリスナを登録しました。さっきは説明しませんでしたが「リスナ使うよ!」ってことを教えてあげる必要があります。

これはimplements View.OnClickListenerという記述でしています。下記のような感じ。

implements View.OnClickListener → クリックリスナインターフェイスを使えるようにするよ。

これでボタンをクリックしたら「何かをする」ことができるようになりました。

25〜39行:

@Override
public void onClick(View v) {
PlcAsyncTask task = new PlcAsyncTask();

int id = v.getId();

switch (id){
case R.id.button1:
task.execute("00");
break;
case R.id.button2:
task.execute("10");
break;
}
}

ボタンをクリックしたら「何かをする」ことができるようになりましたが、「何か」を教えてあげる必要があります。

その記述をここで指定します。

ざっくりとこんな感じ。

PlcAsyncTask使うね(まだ使うとはいってない)
押したはOFFボタン?ONボタン?どっちか教えて
押したボタンがOFFボタンなら、PlcAsyncTaskを使って。ついでに数字の00をあげるから使ってね。
押したボタンがONボタンなら、PlcAsyncTaskを使って。ついでに数字の10をあげるから使ってね。

つまり、押されたボタンを判定してAsyncTask使う。

AsyncTaskとはメインとサブの処理を分けることができるクラスです。

なぜ処理を分ける必要があるかですが、例えば通信の処理をメイン処理に書くと、通信で待ちが発生したときに処理が止まる問題が出てきます。

ゲームでいう「looding…」状態みたいなイメージ。あのときなにも操作できないですよね。

それだと使いづらいので、処理を分けて待ちが発生しないようにします。今回はPLCとの通信をサブにして待ちが発生しないようにします。

実は、通信処理で処理を分けるのはAndroidStudioの仕様で強制です。

AndroidStudioはgoogleが提供しています。もともとはgoogleもeclipsというエディタを使っていて、使いづらくなり自社で作ったようです。

41〜63行:

private class PlcAsyncTask extends AsyncTask<String, Void, String> {

@Override
protected String doInBackground(String… strings) {
try(
DatagramSocket dSocket = new DatagramSocket()
){
InetAddress plcIp = InetAddress.getByName("192.168.1.100");

String mcCommand = "02FF00025920000000100100" + strings[0];

byte[] data = mcCommand.getBytes();

DatagramPacket sdp = new DatagramPacket(data, data.length, plcIp, 0xC000);

dSocket.send(sdp);

}catch(IOException e){
e.toString();
}
return null;
}
}

ざっくりとこんな感じ。

  • AsyncTaskを流用し、PLC通信用のPlcAsyncTaskを作る
  • チェック例外(やばいエラー)が出る可能性のある処理があるのでtry catchで囲う
  • 通信に必要なデータを準備
  • 送りたいデータ(ONかOFFの情報(さっきもらった「00」か「10」)を付け足して、さらにデータ形式をバイトに変換)
  • ※バイト形式にしているのは決められているからです(メソッドの引数にバイト形式が指定されている)
    • データの長さ
    • 送り先のipアドレス(PLCのip)
    • 送り先のポート(PLCのポート番号)
    • 送信

使っているのはソケット通信で、Javaにはソケット通信に使えるクラスがあるので使っています。

コード量も少ないし簡単にできるなと思いませんか?これはクラスが使えるからです。

ソケット通信では、通常の通信(TCP/IP)だけを使います(MACアドレスなどは使います)。

結果、できることはデータを送るだけ。

言い換えればデータの処理方法は自分で決めれるので、自作の通信方法が作れます。

つまり、MCプロトコルに対応するデータ処理を自分ですればPLCと通信できることになります。

MCプロトコルの伝文フォーマット

ソケット通信でPLCに送るデータには英数字を使いました

詳細は三菱電機が提供しているMCプロトコルのマニュアルを見ましょう。「MELSECコミュニケーションプロトコルリファレンスマニュアル」と検索すると出てきます。

ただ、PLCのマニュアル全般そうなんですが正直わかりづらい。僕が文系だからなのかもしれませんが、わりと理解に苦しみます。

簡単に解説するので、解説をヒントにマニュアルを見てみてください。

02FF0002592000000000010010

このコマンドでしているのは、Y0をONしているだけです。

次に、コマンドの役割ごとに分割します。

①02 ②FF ③0002 ④5920 ⑤00000000 ⑥01 ⑦00 ⑧10
  1. 02
    ビットで書き込み。
  2. FF
    接続したい局番。1対1ならFF。アクセス先以外のPLCの情報を取得するならPLCの局番を指定。
  3. 0002
    CPU監視タイマの値。適当。
  4. 5920
    デバイスの種類を指定。5920だとYデバイス(出力デバイス)。
  5. 00000000
    デバイス番号。Y0を指定するので全部ゼロ。00000001ならY1です。
  6. 01
    通信するデバイスの点数。Y0の1点だけなので01。
  7. 00
    固定値。00でOK。
  8. 10
    ON/OFFの情報。ONさせたいのはY0だけなので本当は「1」だけ。ただし、1桁がダメと言う仕様なので余分にゼロを入れて「10」。

気づいた方もいるかもしれませんが、ボタンによってON/OFFを切り替える仕組みはここです。
Y0のON/OFFのコマンドは最後が違うだけなので、押されたボタンによってOFFボタンなら「00」、ONボタンなら「10」というデータを生成してます。

動作確認

PLCの準備

PCからPLCへのpingを飛ばして接続確認だけしておきましょう。

ここができていないと何をしても先へ進めません。。

※PLCのip、ポートなどの設定は「前編」の記事でしています。

AndroidStudioの準備

動作確認はエミュレータでします。

ツール→AVDマネージャーで下記のウィンドウが開くので、右側にある再生ボタンを押します。

スマホのエミュレータが開くのですが、かなり時間がかかるため何度も押さないように気をつけましょう。

わりとデリケートです。

実機に作ったアプリをインストールするのも簡単です。「android 実機デバッグ」などで検索してみてください。
USBドライバは結構ハマるポイントなので注意です。
https://techacademy.jp/magazine/2433
※USBドライバとは、接続された機器(スマホ)との通信に必要な設定ファイルのようなもの。これがない場合、PCからすると「何か接続されたけどナニコレ?」となります。

エミュレータが起動したら自動でアプリが開きます。

もし開かないなら、アプリはインストールされているはずなのでそこから開いてください。

Androidのキャラクター?のアイコンが、アプリのデフォルトアイコンです。

ON/OFFさせてみましょう!!

まとめ

お疲れ様でした☺️

AndroidStudioは環境構築でハマったり大変ではなかったでしょうか。僕は結構苦労しました。

Java自体も結構難しいですよね。クラス???オブジェクト思考ってなんだよ😭って感じでした。

プログラミング初学者が独学すると高確率で挫折するので、学習するならスクールをおすすめします。

もう少し言うとJavaがわかってもそれだけでできることは限られてしまうので、ネットワーク、データベースなどトータルで教えてくれるスクールが効率いいように感じます。

Javaを学習するメリットも挙げておきます。

Javaがわかると他の言語も大抵わかるようになる
仕事が多い(業務系)

また、今回はOFF/ONだけでしたがスマホのジャイロセンサ使って、スマホを傾けるとPLCが動くなど色々できます。

需要があれば書きますので、twitterでコメントかDMください。

最後まで見ていただきありがとうございます🙇‍♂️

この記事を書いた人

ホクト

プログラミングと嫁が好き。文系出身ながら機械メーカーで電気設計→Webがしたくて退職を決意→転職。電気設計で役に立つweb知識を中心に書きます。