日記；回すだけⅤ ④ ST言語（ファンクションブロック）でモータを回す記述＜その4 独立したPOU＞

　TwinCAT3でプログラムを書くときに使えるファンクションブロックを利用する方法は、現時点で、筆者が知りえているのは三つあります。

- [MAINにST言語で記述](https://qiita.com/jamjam/items/1a535ead711ce96c581d)
- [POUのMAINの下にアクションを追加し、ファンクションブロックダイアグラムを利用する](https://qiita.com/jamjam/items/d3049c024740f2ce42c8)
- MAINのPOUと同じレベルにPOUを追加し、ファンクションブロックダイアグラムを利用する

　最初の方法は、MAINにすべて書かれるので、ファンクションブロックの入力（今回はExecuteとPosition）は、MAINのプログラムの中でそのまま利用できました。
　2番目のMAINの中に作ったアクションでは、ExecuteとPositionは、変数を別途、fb_Executeとfb_Positionとして定義し、INPUT変数として扱うことで、MAINのプログラムの中で扱えました。
　今回は、MAINと同列のPOUを新たに作り、その中にファンクションブロックダイアグラムを張り付けていきます。そのファンクションブロックダイアグラムにあるExecuteとPositionをアクセスするために、外部変数GVLsを利用して、変数を別途、fb_Executeとfb_Positionとして定義し、INPUT変数として扱い、MAINのプログラムの中で利用します。
![e715.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/2c4ca7c4-f4d4-2ed5-cc9d-a7073e34b63d.png)


### 新たなPOUを作る
##### 準備
　機器のスキャンが終わって、PLD内でソフトの開発ができるところまで準備ができているとします。
![e701.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/bc6baba9-b15a-ee4f-7731-866faf62c198.png)

　ReferencesにTc2_MC2ライブラリを追加します。
　GVLsの上で右クリックをしてグローバル変数一覧を選択します。
![e702.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/3b8c97dc-8e3a-beca-45e6-830f1ee8d9d6.png)
　名前をGVLmotionにしました。
![e703.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/c59d0f61-4950-d623-7ffc-9cace88c5004.png)
　真ん中のプログラム・エリアにGVLmotionのタブが追加されました。
![e704.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/48f0d2b3-cd13-ff7b-a1ec-732135addc12.png)


　POUsの上で右クリックをして、追加、POUを選択します。
![e705.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/060c2455-7c16-f97f-1def-8c9837e73649.png)

　名前は、POU_movePositionにしました。型はプログラム、記述言語はファンクションブロックダイアグラムになっていること確認してOpenを押します。
![e706.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/e28124a2-2952-a9e4-c483-4cbda038fcf4.png)

　三つのタブができました。左からタブの上で右クリックして垂直タブグループを選択し、3分割にしていきます。
![e707.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/aa780258-1fe2-2f8f-bc53-9275b32bae29.png)
　POU_movePositionに行きます。
　![e708.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/1bee131a-a79b-0a8c-8e22-0d546d83e992.png)

###### POU_movePositionにファンクションブロックダイアグラムをおいていく
　前回と同じように、fb_MC_Power、fb_MC_MoveAbsolute、fb_MC_ReadActualPositionと名前を付け、入力も、前回と同じように修正します。
![e709.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/8a04bdd7-197a-4c41-3765-1cf19f95be4d.png)
　POU_movePositionの変数エリアにある記述をはぎ取ってGVLmotionにコピペします。
![e710.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/e1820ec7-45f8-8f50-9146-7518154850f7.png)
　
　POU_movePositionの名前や変数に赤いアンダラインが引かれます。変数がグローバル・エリアに移されたので、それらの先頭に、``GVLmotion.``を追加していきます。
![e711.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/384dd928-6a33-ac2e-6b95-0d3daf81ea8d.png)

　ビルドして、エラーがないことを確認します。

###### MAINにswなどの操作を追加
　MAINに、sw1、LED例の記述を追加します。

![e712.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/f8791f90-65ee-d38a-08ae-f907c3c853b6.png)

　ビルドします。
　軸関係の設定は、第2回を参照して、完了してください。

　AX1をダブルクリックして、設定のPLCにリンクが空白だったら追加します。
![e713.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/353fb94c-1619-257a-376c-a545bc71b6b5.png)
　I/Oのリンクの変更を行います。
　ビルドします。
　構成の有効化をクリックします。
　実行します。

![e714.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/72ceb3e8-d72a-53d3-a465-fa1c6f8452b9.png)


　MAINのソースです。

```cpp
PROGRAM MAIN
VAR
    Digital_inputs AT  %I*: UDINT;  // sw1,sw2
    Digital_outputs  AT %Q*: UDINT; // LED
END_VAR
```

```cpp
IF  Digital_inputs = 917504 THEN  // sw1
	Digital_outputs := 851968;
	GVLmotion.fb_Execute  := TRUE;
    GVLmotion.fb_Position := 10;
	POU_movePosition();
  
ELSIF Digital_inputs = 851968  THEN  // sw2
	Digital_outputs := 917504;
	GVLmotion.fb_Execute  := TRUE;
    GVLmotion.fb_Position := -10;
	POU_movePosition();
	
ELSE
	GVLmotion.fb_Execute  := FALSE;
    GVLmotion.fb_Position := 1;
	POU_movePosition();
	
END_IF
```

　GVLmotionです。

```cpp
{attribute 'qualified_only'}
VAR_GLOBAL
	fb_MC_Power: MC_Power;
	AX1: AXIS_REF;
	fb_MC_MoveAbsolute: MC_MoveAbsolute;
	fb_Execute: BOOL;
	fb_Position: LREAL;
	fb_MC_ReadActualPosition: MC_ReadActualPosition;
END_VAR
```