FANUC PMCプログラミング入門(第3回)

# FANUC PMCプログラミング入門

## ジャンプ命令を活用した制御構文の実現

FOR/WHILEのループ制御やIF/SWITCHなどの条件分岐の制御構文、**PMCプログラムではありません**。

第1回目の記事で紹介した通りラダープログラムというのは上から下のネットに、さらにネット内は左から右に処理が流れます。プログラムの終端まで実行したら再び先頭に戻り処理を高速に繰り返すという特徴を持ったコントローラになります。どちらかといえば回路設計に近いため一般的なプログラミング言語の制御構文は不要という背景があります。
ラダープログラミングにおいてプログラム先頭から終端までの1回の処理時間を**スキャンタイム**と呼びます。
PLCではFOR命令が提供されているものもありますが、複雑な分岐処理や繰り返し処理を多用するとスキャンタイムがばらつく要因となり様々なトラブルを引き起こしやすくなります。使用する際には注意が必要です。

とはいえPMCプログラムで複雑な分岐処理やループが必要となることもあります。
そのような場合は**ジャンプ命令**を活用することで様々な制御構文を実現出来ます。

### JMP/JMPE命令

JMP命令は後方(下)に配置されたJMPE命令までジャンプ制御を行います。

![PMC#1-JMP (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390544/d11bf3d7-a212-4f53-f198-6af8ba313358.png)


JMP命令のACTコイルがTrueの時にJMPE命令の次のネットから処理が実行されます。
上のラダーをC言語で表現すると以下のような処理になります。

```c
if ( !ACT ) // JMP
{
    // ステートメント
} // JMPE
```

### JMPB/LBL命令

JMP命令は後方に配置されたJMPEへ飛ぶだけです。前方(上)へのジャンプや入れ子構造のステートメントを構成するためにはJMPB/LBL命令を使用します。ループやSWITCH分岐を構築することも可能です。

![PMC#1-JMPB.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390544/0b1c652f-c2f5-7c78-398b-f260eac66a0e.png)

ジャンプ先はLBL命令を配置しジャンプ元とジャンプ先に同じLアドレスを設定します。

### JMPC命令

メインプログラムからサブプログラムを呼び出した状態で呼び出し元のメインプログラム上の任意のラベルに戻る命令です。
gotoで別の関数に飛ぶようなものです。なぜこんな命令があるのか理解に苦しみます。
ただでさえ読みづらいラダーが益々読みにくくなるため使わないことをお勧めします。

## ラダープログラムの構造化

PMCプログラミングを新規作成するとメインラダーとしてレベル1とレベル2が作成されます。プログラム開始時はメインプログラムレベル1とレベル2に処理を実装します。
このまま何も考えずにラダー開発を続けると当然ながら巨大な巻物が出来上がります。変更時の影響範囲の把握といったラダー解析作業の負担増加の要因になります。
メインラダーにすべてを詰め込もうとはせずに機能ごとに処理を分けることが重要になってきます。

PMCプログラミングではいくつかの方法が提供されています。

|方式|説明|
|----|----|
|サブプログラム|メインプログラムから呼び出すサブ関数|
|ファンクションブロック(FB)|インスタンスを持つ一塊の処理|
|分割ラダー|メインプログラムのラダーを分割して管理する機能|
|多系統PMC|複数のシーケンス制御を同時に実行する機能| 

多系統PMCは本記事の第1回で紹介しているので、今回はそれ以外の方式について紹介します。

## サブプログラム

CNCの加工プログラムでは頻出する処理をサブプログラムとして登録しておきメインプログラムからそれらを呼び出すことが出来ます。PMCのサブプログラムも考え方はほぼ同じです。
プログラム番号に紐づいたサブプログラムを作成し、メインプログラムよりプログラム番号を指定してサブプログラムを呼び出します。サブプログラムの実行が完了したらメインプログラムに戻り、処理の続きを実行します。

![PMC#1-サブプログラム概要.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390544/ade58d92-8405-4d4f-3da5-a5a60afd7c0a.png)

メインプログラムからサブプログラムの呼び出しはCALL命令(条件付き呼び出し)もしくはCALLU命令(ACT不要の無条件呼び出し)を使用します。サブプログラムはSP命令より始めプログラムの終端にSPE命令を配置します。

### ファンクションブロック

ファンクションブロックはよく使う処理や演算といった処理を関数としてまとめたものです。サブプログラムと異なり入出力のパラメータを持つことができます。ファンクションブロックはレゴブロックのようにラダー図内に配置して使用します。入出力パラメータをつなぎ**インスタンス名**を指定します。ファンクションブロックの内部データはインスタンスごとに独立して割り当てられます。（オブジェクト指向言語におけるインスタンスに似ています）

### 分割ラダー

別のファイルで作成したラダープログラムを順番に実行する際に分割ラダーを使用します。PMCならではの構造化プログラミング構成方法といえます。

![PMC#1-分割 (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390544/d85c9bf7-6321-7833-311f-90aa9ec9f505.png)


分割ラダーは以下のようなシーンで活用します。

* ラダープログラムの一部を保護したい場合  
ラダープログラムはファイル単位で保護をかけることが出来ます。  
たとえばPMCラダープログラムの一部をCNC使用者に表示させたくない場合にはその隠蔽したい部分を分割ラダーとして別ファイルにして保護をかけることが可能です。
* 機械制御を基本部・拡張部で分割したい場合  
とある工作機械メーカS社がマシニングセンタX1,X5,X10と3つの兄弟製品を販売していたとします。この時3製品それぞれにラダープログラムを作成するのは大変です。そこで基本設計部はメインラダーに作成し、それぞれの製品ごとの機能差分を分割ラダーに実装するという構成をとることでラダープログラムの再利用がすすみ、開発効率を向上させることが出来ます。
* 特注対応したい場合  
S社の大口顧客の一つT製作所が「うちに納品する製品にこういう機能を追加してくれ」なんて要望を出してくる場合があります。制御の一部を標準製品処理から特注処理に差し替えたいといった場合に、その部分が分割ラダーで構成されていれば分割ラダーファイルを差し替えるだけで特注製品用の機械制御に切り替えることが出来ます。

複数機種対応や特注対応はサブプログラムやファンクションブロックでも実現可能ですが、分割ラダーは対象機種の機械制御に使用しない部分は組み込まれないという利点があります。
CNCは一般的なPCと異なり大容量の記憶媒体を持っていません。ラダープログラムはFROMと呼ばれるFlash ROM(不揮発性メモリ)に格納されますがすべての製品の制御を担う共通ラダープログラムをつくると大容量のメモリが必要となってコスト増加になってしまうので使用されないプログラムは可能な限り載せない方が良いでしょう。



---

[目次へ](https://qiita.com/oshino_maru/items/0ae69da0c668efd5061c)

※読んでいただきありがとうございました。質問・修正点等ありましたらお気軽にご連絡ください。
前回までの記事にLGTM押していただけた方にこの場を借りてお礼申し上げます。
(誰かが読んでくれているんだなと。ニッチネタ投稿のモチベーションになっています)