CODESYS Example Projectを調べてみた #1
はじめに
少し前からCODESYSを使い始めたので、Example Projectを活用したconnpassでの勉強会を始めてみました。
せっかくやるからには学びの記録を残そうと思い、コードリーディング中の気づきや、Example Projectを動かす手順などをまとめることにしました。
CODESYSのExample Projectは以下のサイトにあります。第1回目は「Object Oriented Programming.project」を見ていきます。
Example Projectのセットアップ
上記のサイト右上にダウンロードボタンがあるので、それをクリックすることで.projectファイルをダウンロードできます。ダウンロードしたファイルをダブルクリックするとCODESYSの開発環境が立ち上がります。複数バージョンの開発環境が入っている場合は、どのバージョンの環境で立ち上げるか確認画面がでてきます。
私のCODESYS開発環境は、V3.5 SP20 Patch 3ですが、Example Projectは、V3.5.14.0なので、バージョンを上げるかどうかの確認画面が出てきます。勉強目的なので、とりあえず自分の環境にバージョンを上げることにしました。
V3.5.20を選択
development phaseを選択
Set All to Newestを選択して、OKをクリック
Yesを選択
この状態ではerrorが発生するので、画面のアイコンをクリックしてUpdate placeholder "library name"を実行します。
DeviceをUpdateします。Deviceを右クリックして、Update Deviceを選択します。適当にデバイスを選んで、Update Deviceボタンを押します。
Example Projectの中身
Building_Objectsフォルダ内にInterface、RoomFBs、Visualizationサブフォルダがあり、メインはBuildingManager(PRG)となっていました。
BuildingManager(PRG)の中で、RoomType1, 2, 3をつかって部屋タイプに応じたインスタンスを8つ生成していました。部屋インスタンスをまとめて管理する配列も定義してあり、その際にはインターフェースのIRoom型をつかっていました。
PROGRAM BuildingManager
VAR
(* define all rooms *)
r1:RoomType1;
r2:RoomType3;
r3:RoomType2;
r4:RoomType3;
r5:RoomType1;
r6:RoomType3;
r7:RoomType2;
r8:RoomType1;
(* Array of rooms simpilifies working with the building.*)
Rooms: ARRAY [1..iNumberOfRooms] OF IRoom:=[r1,r2,r3,r4,r5,r6,r7,r8];
CheckTimeOfDay: CheckFB; (* It's getting day? It's getting night? *)
xDusk: BOOL; (* nighttime *)
xDawn:BOOL; (* daytime*)
itfTemp: ITemp;
xTemp: BOOL; (* Result of the Interface mapping.*)
i: INT;
END_VAR
プログラムの処理については、部屋配列をFORループで回して、xDawn, xDusk, xTempなどの条件(朝、夕、気温のチェック)に応じてインターフェースのメソッドを呼び出すようになっていました。
(* Check if there is daytime or nighttime.*)
CheckTimeOfDay(xGetsDay=>xDawn,xGetsNight=>xDusk);
FOR i:=1 TO iNumberOfRooms DO
IF xDawn THEN (* Daytime*)
Rooms[i].Operation_Daytime(); (* Disable the light and depending on the roomtype set the temperature. *)
END_IF
IF xDusk THEN (* Nighttime *)
Rooms[i].Operation_Nighttime(); (* Enable the light and depending on the roomtype set the temperature. *)
END_IF
(* If temperature is available for the Room, then set the temperature --> RoomType3*)
xTemp:=__QUERYINTERFACE(Rooms[i], itfTemp);
IF xTemp AND i=6 THEN
(* Now itfTemp has the address of Rooms[6] *)
itfTemp.SetTemperature(35); (* The temperature of the Rooms[6] is set. *)
END_IF
END_FOR
気づき・疑問
- Update Deviceを実行するとUpdate placeholderを実行しなくてもよかった?
- Interfaceでメソッドを定義して、FBでIMPLEMENTS "Interface Name" で実装する。
- FBは、EXTENDS "FB name" で継承できる。
- 継承ど実装を同時にするときは、EXTENDS ”FB name” IMPLEMENTS ”Interface Name”のようにFBの定義に続けて書けばよい。
- __QUERYINTERFACE(対象のオブジェクト, 取得したいインターフェース) を使用して、指定されたオブジェクトが特定のインターフェースを実装しているかどうかを確認し、インターフェースの参照を取得できる。結果はインターフェースの参照として返され、インターフェースが実装されていない場合には NULL が返される。第1引数にインスタンス(対象オブジェクト)を指定し、第2引数にInterface型の変数を指定する。処理が成功すると、第2引数にインターフェースへの参照が設定される。
- https://content.helpme-codesys.com/en/CODESYS Development System/_cds_operator_queryinterface.html
Discussion