(例)ベッコフ TwinCAT
ここでは、ベッコフ TwinCAT バージョン3.1の EtherCAT モジュールに EYE+ を簡単に統合する例を紹介します。
前提条件
- 始める前に、以下のファイルが既にダウンロードされていることを確認してください。
EYE+ EtherCAT ESI ファイル(電子データシート)
容易な統合を可能にする EYE+ TwinCAT プロジェクトテンプレート(事前に宣言された変数を含む)【オプション】
これらのファイルは、 EtherCAT ダウンロード からダウンロードできます。
必要なファイルをダウンロードしたら、ベッコフ TwinCAT のインストールフォルダに ESI ファイルを必ずインストールしてください。
<path_to_twincat_install>\3.1\Config\Io\EtherCAT
<path_to_twincat_install>
は、通常 C:\TwinCAT\
です。
ESI ファイルを正しいフォルダにインストールしたら、ベッコフ TwinCAT を再起動したことを確認してください。
基本的な統合
すべての準備が整ったら、新しいベッコフ TwinCAT プロジェクトの作成に進みます。そして、左上の部分にある以下のアイコンを押して、設定モード(Configuration Mode)になっていることを確認してください。
その後、EtherCAT バスをスキャンして EYE+ とマスターデバイスを認識し、位置を特定する準備が整いました。スキャンオプションは、左ペインにあるデバイス(Devices)を右クリックすることで利用できます。
スキャンプロセスには数秒かかるかもしれませんが、現在バスに接続されているすべてのデバイスが検出されます。
注釈
スキャンが終了してもお使いの EYE+ がリストに表示されない場合は、正しく接続され、電源が入っていることを確認してください。それでも問題が解決しない場合は、サポートチームまでお問い合わせください。
正しくスキャンが完了できると、デバイス(Devices)の下のリストに EYE+ のボックスも表示されます。
オプションのテンプレートをダウンロードされた方は、次のステップに進んでください。テンプレートをインポートすることで、 EYE+ を完全に活用するために必要なすべての変数が作成されます。テンプレートのインポートは簡単で、PLC プロジェクトを右クリックして、ZIP からインポート(Import From ZIP)をクリックします。
正しくインポートできていれば、変数の構造全体が利用できるようになります。
TwinCAT 内で変数を利用できるようにプロジェクトを構築する必要があります。変数を EYE+ の変数にマッピングするには、マルチリンク機能(Multi Link functionality)を使うと簡単に行うことができます。
変数のマッピングが完了し、ランニングモードで再起動すると、レジスタのライブフィードバックが得られるはずです。
次のサンプルコードでは、コントローラで以前作成したレシピの自動運転を開始し、最初のパーツを取得することができます。これを行うには、 udRecipeID
をそのレシピの ID に設定し、 boStart
を True に設定してください。認識されたパーツの座標は reRobotTargetX
、 reRobotTargetY
、 reRobotTargetRz
で返されます。
(*
* This sample code is distributed under the license CC0 1.0 Universal,
* you can get a copy of the license at https://creativecommons.org/publicdomain/zero/1.0/
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*)
VAR
udRecipeID: UDINT;
boStart: BOOL;
R_TRIG_Start: R_TRIG;
boStop: BOOL;
R_TRIG_Stop: R_TRIG;
boClearError : BOOL;
inLastErrorID: UDINT;
eState: UDINT;
reRobotTargetX: REAL;
reRobotTargetY: REAL;
reRobotTargetRz: REAL;
END_VAR
VAR CONSTANT
STATE_IDLE: UDINT := 0;
STATE_START_PRODUCTION: UDINT := 10;
STATE_ROBOT_MOVE_OUT_FOV: UDINT := 20;
STATE_GET_PART: UDINT := 30;
STATE_ROBOT_PICK_PLACE: UDINT := 50;
STATE_STOP_PRODUCTION: UDINT := 60;
STATE_ERROR: UDINT := 100;
END_VAR
R_TRIG_Start(CLK:= boStart);
R_TRIG_Stop(CLK:= boStop);
CASE eState OF
STATE_IDLE:
IF R_TRIG_Start.Q THEN
eState := STATE_START_PRODUCTION;
END_IF
STATE_START_PRODUCTION:
EYEplus.suEYEplusOutputGLO.udRecipeIDGOU := udRecipeID;
EYEplus.suEYEplusOutputGLO.boStartProductionTriggerGOU := TRUE;
IF EYEplus.suEYEplusInputGLO.boStartProductionDoneGIN AND NOT EYEplus.suEYEplusInputGLO.boIsErrorGIN THEN
EYEplus.suEYEplusOutputGLO.boStartProductionTriggerGOU := FALSE;
eState := STATE_ROBOT_MOVE_OUT_FOV;
ELSIF EYEplus.suEYEplusInputGLO.boIsErrorGIN THEN
EYEplus.suEYEplusOutputGLO.boStartProductionTriggerGOU := FALSE;
eState := STATE_ERROR;
END_IF
STATE_ROBOT_MOVE_OUT_FOV:
//Robot move out of field of view
//Check that the movement is done before to go first get_part
eState := STATE_GET_PART;
STATE_GET_PART:
EYEplus.suEYEplusOutputGLO.boGetPartTriggerGOU := TRUE;
IF EYEplus.suEYEplusInputGLO.boGetPartDoneGIN AND NOT EYEplus.suEYEplusInputGLO.boIsErrorGIN THEN
reRobotTargetX := EYEplus.suEYEplusInputGLO.rePose1XGIN;
reRobotTargetY := EYEplus.suEYEplusInputGLO.rePose1YGIN;
reRobotTargetRz := EYEplus.suEYEplusInputGLO.rePose1RzGIN;
EYEplus.suEYEplusOutputGLO.boGetPartTriggerGOU := FALSE;
eState := STATE_ROBOT_PICK_PLACE;
ELSIF EYEplus.suEYEplusInputGLO.boIsErrorGIN THEN
EYEplus.suEYEplusOutputGLO.boGetPartTriggerGOU := FALSE;
eState := STATE_ERROR;
END_IF
STATE_ROBOT_PICK_PLACE:
//Robot pick and place the part
//Check that the movement is done before to go make another get_part
eState := STATE_GET_PART;
STATE_STOP_PRODUCTION:
EYEplus.suEYEplusOutputGLO.udStopStateGOU := 16#FF;
IF EYEplus.suEYEplusInputGLO.boStopStateDoneGIN AND NOT EYEplus.suEYEplusInputGLO.boIsErrorGIN THEN
EYEplus.suEYEplusOutputGLO.udStopStateGOU := 16#00;
eState := STATE_IDLE;
ELSIF EYEplus.suEYEplusInputGLO.boIsErrorGIN THEN
EYEplus.suEYEplusOutputGLO.udStopStateGOU := 16#00;
eState := STATE_ERROR;
END_IF
STATE_ERROR:
EYEplus.suEYEplusOutputGLO.udStopStateGOU := 16#00;
EYEplus.suEYEplusOutputGLO.boStartProductionTriggerGOU := FALSE;
EYEplus.suEYEplusOutputGLO.boGetPartTriggerGOU := FALSE;
inLastErrorID := EYEplus.suEYEplusInputGLO.udErrorIDGIN;
EYEplus.suEYEplusOutputGLO.boClearErrorTriggerGOU := boClearError;
IF NOT EYEplus.suEYEplusInputGLO.boIsErrorGIN THEN
EYEplus.suEYEplusOutputGLO.boClearErrorTriggerGOU := FALSE;
eState := STATE_STOP_PRODUCTION;
END_IF;
END_CASE
IF R_TRIG_Stop.Q THEN
EYEplus.suEYEplusOutputGLO.boStartProductionTriggerGOU := FALSE;
EYEplus.suEYEplusOutputGLO.boGetPartTriggerGOU := FALSE;
EYEplus.suEYEplusOutputGLO.boClearErrorTriggerGOU := FALSE;
eState := STATE_STOP_PRODUCTION;
END_IF