EXOR#Part19_Scatter Diagramを使ってみよう

今回の記事ではEXORのex707MにインストールされいているCodesys RuntimeとOMRONのNX502-1300とEthernet/IP通信し、1ms周期でデータ交換し、10ms周期でデータをCodesys内部メモリに保存します。

そして保存されたデータをEXOR JMobile Scatter Diagramから表示させます。

さ、FAを楽しもう!

前書き

いつも私の技術ブログとYouTubeチャンネルをご覧いただき、心より感謝申し上げます。また、いまFullさん(full@桜 八重 (@fulhause) / X)と共に毎週水曜日の夜にお届けしている「高橋クリス」ラジオ番組を運営しています。

技術は独り占めせず、届けるもの

私たちは工場の生産技術や制御に関する技術情報を、ブログや動画などで無料公開しています。「知識は誰でもアクセスできるべき」という信念のもと、現場で役立つ具体的なノウハウやトラブル事例などを発信してきました。すべて無料で続けているのは、「知らなかったせいで困る人」を少しでも減らしたいからです。

また、もしあなたの現場で…

  • 「このPLCとデバイスの組み合わせ、ちゃんと動くのかな?」
  • 「EtherCAT通信でうまくいかない部分を検証してほしい」
  • 「新しいリモートI/Oを試したいけど社内に検証環境がない」

など、困っている構成や試してみたいアイデアがあれば、ぜひお知らせください。機器の貸出や構成の共有が可能であれば、検証し、記事や動画で発信します(ご希望に応じて匿名対応も可能です)。

支援のかたち

現在、私達の活動はほぼ無償で続けており、記事や動画の制作には、時間と検証環境の整備が必要です。この活動を継続的にコンテンツを提供するためには、皆様の温かいご支援が大変重要です。

メンバーシップ(ラジオの応援)

Fullさんとのラジオをより充実させるための支援プランです。

https://note.com/fulhause/membership/join

Amazonギフトリスト

コンテンツ制作に必要な機材・書籍をリストにしています。

https://www.amazon.co.jp/hz/wishlist/ls/H7W3RRD7C5QG?ref_=wl_share

Patreon(ブログ・動画活動への応援)

月額での小さなご支援が、記事の執筆・検証環境の充実につながります。

https://www.patreon.com/user?u=84249391

Paypal

小さな支援が大きな力になります。

https://paypal.me/soup01threes?country.x=JP&locale.x=ja_JP

知ってたら助かること、届けたいだけです

あなたの応援が、知識の共有をもっと自由で持続可能なものにしてくれます。これからもどうぞよろしくお願いします。

soup01threes*gmail.com

https://x.com/3threes2

技術はひとりじゃもったいない。

Reference Link

EXOR#Part04_Codesysを入れよう
EXOR#Part14_Codesysと接続とAlias機能
Codesys#OMRONとEthernet/IP Tag通信しよう

Implementation

今回の記事ではOMRON NX502-1300側・Codesys側・JMobile側の3つの実装に分けています。

OMRON 側

最初はOMRON NX502-1300側から構築します。

グローバル変数定義

Sysmac StudioからData→Global Variablesを開きます。

Codesys Runtimeと接続する Ethernet/IP Tagを定義します。

今回の記事では使用するのはarrRealDataだけで、Network Publishを”Output”に設定します(OMRON NX502-1300→Codesys Runtime)。

IP 設定

Controller Setup→Build-in Ethernet/IP Port Settingsを開き、IPアドレスを実際のネットワーク構成に合わせて設定しましょう。

Ethernet/IP接続設定

次はNX502-1300のEthernet/IP接続を構築します。Tools→Ethernet/IP Connection Settingsをクリックします。

今回はNX502-1300のPORT1を使用しますので、Port1を選択→右クリック→Editします。

Registration Allをクリックし先程グローバル変数で宣言したOutput変数を登録します。

プログラム

次は検証用のプログラムを作成します。

VAR

こちらはFOR Loop用の変数を定義します。

Code

このプログラムは、8つのREAL型データを生成するシミュレーション用のコードです。

まず、配列の先頭要素に0.01を加算して、0から20までゆっくりカウントアップさせます。20を超えたら0にリセットして繰り返します。

次にFORループで、先頭の値を基準にして残り7つの要素にも値を設定します。各要素には先頭値に対してインデックス×100のオフセットを加えています。

arrRealData[0]:= arrRealData[0]+0.01;

IF arrRealData[0] >20.0 THEN
arrRealData[0]:=0.0;
END_IF;
FOR iCounter:=0 TO 7 DO

arrRealData[iCounter]:=arrRealData[0]+TO_REAL(iCounter)*100;
END_FOR;

ダウンロード

最後にプロジェクトをNX502-1300にダウンロードしてください。

Codesys側

次はCodesys Runtime側を構築します。

EDSファイルをダウンロード

OMRONのHPからNX5のEDS FILEをDownloadします。

https://www.fa.omron.co.jp/products/family/3900/download/software.html

EDSファイルをインストールする

次はOMRON NX5のEDS FileをCodesys側でインストールするため、Tools>Device Repositoryをクリックします。

Installをクリックし、OMRONのHPからDownloadしたEDS Fileをインストールしましょう。

イーサネットドライバを追加する

CodesysプロジェクトにEtherent Driverを追加するために、Device→右クリック→Add Deviceします。

Ethernetを選び、Add Deviceします。

Ethernet/IP Scanner ドライバーを追加

次はEthenret Driverを選択し、右クリック>Add Deviceしましょう。

イーサネットインターフェース設定

General→Network InterfaceでEthernet/IPインタフェースを設定しましょう。

NX502-1300を追加

次はOMRONのNX502-1300のEthernet/IP接続を追加するためにEthernet/IP Scanner右クリック→Add Deviceします。

NX502-1300を選択し、Add Deviceで追加します。

IP設定

NX502-1300を開き、IPアドレスを実機に合わせて設定してください。

Ethernet/IP接続設定

次はEthernet/IP接続を追加するために、Connections→Add Connectionsをクリックします。

Input Only(Tag Type)を選択します。

Symbolic Name欄をSysmac Stuido側で設定したOutput Tagsに合わせます。

PRIは実際のアプリケーションに合わせ設定します。

T→OサイズはSysmac Stuido側で設定した変数サイズに合わせます。

マッピング

次はMappingを行います。Ethernet/IP I/O Mappingを開き、先頭アドレスを指定します。

今回の例では%IB100に指定します。

構造体

eSystem

これはDINT型の列挙体(ENUM)を使って、システム定数を定義しています。

iDataTotalLengthはデータの総長として2999を、iTotalUnitはユニットの総数として7を設定しています。

{attribute ‘qualified_only’}
{attribute ‘strict’}
TYPE eSystem :
(
iDataTotolLength := 2999
,iTotolUnit := 7
)DINT
;
END_TYPE

uArray1200Bytes

これは同じメモリ領域を、BYTE配列とREAL配列の両方でアクセスできるようにするUNION型の定義です。1200バイトのメモリを確保し、それをBYTEとして扱いたいときはarrBで、REALとして扱いたいときはarrRでアクセスします。REALは4バイトなので、1200÷4=300要素になります。

TYPE uArray1200Bytes :
UNION
arrB: ARRAY[0..1199]OF BYTE;
arrR: ARRAY[0..299]OF REAL;
END_UNION
END_TYPE

stMotorData

これはモーターに関するデータを格納するための構造体です。rCurrentValueは現在値を保持するREAL型の変数です。arrDataYは先ほど定義したeSystem.iDataTotolLength(2999)を使って、3000要素のREAL配列としてデータ履歴を格納します。

TYPE stMotorData :
STRUCT
rCurrentValue :REAL;
arrDataY:ARRAY[0..eSystem.iDataTotolLength]OF REAL;
END_STRUCT
END_TYPE

gGVLIO

これは先ほど定義したUNION型を、PLCの入力メモリ領域に直接マッピングするグローバル変数の定義です。AT %IB100により、入力バイト領域のアドレス100番地から1200バイト分を確保しています。これで外部デバイスからの入力データを、BYTEとしてもREALとしてもアクセスできます。

{attribute ‘qualified_only’}
VAR_GLOBAL
data AT %IB100 :uArray1200Bytes;
END_VAR

gData

これはトレンドグラフやデータロギング用のグローバル変数をまとめて定義しています。

arrDataXはX軸用の時間やインデックスを格納する配列で、3000要素あります。udtMotorDatasは先ほど定義したモーターデータ構造体を8ユニット分(0〜7)配列にしたものです。

{attribute ‘qualified_only’}
VAR_GLOBAL

arrDataX:ARRAY[0..eSystem.iDataTotolLength]OF DINT;
udtMotorDatas:ARRAY[0..eSystem.iTotolUnit]OF stMotorData;
arrDataX2:ARRAY[0..299]OF DINT;
arrDataY2:ARRAY[0..299]OF REAL;

END_VAR

タスク

次はLoggingプログラム用のタスクを作成します。

タイプがCyclicなので、10ミリ秒ごとにp03Unit01Loggingというプログラムが繰り返し実行されます。優先度1は比較的高い設定で、他の低優先度タスクより先に処理されます。

番号

項目

設定値

意味

Priority

1

タスクの優先度(0が最高、31が最低)

Interval

10

実行周期(10ms)

POU

p03Unit01Logging

このタスクで実行するプログラム

fbLogging

次はLogging用のFBを作成します。

VAR

これはデータロギング用のファンクションブロックの変数定義部です。

FUNCTION_BLOCK fbLogging
VAR_INPUT
xStart :BOOL;
rLogPeriod :REAL;
rLogValue :REAL;
strDateTime:STRING;
ixlog :BOOL;
END_VAR
VAR_OUTPUT
iLoggedIndex:INT;
xDone:BOOL;
xError:BOOL;
xBusy:BOOL;
END_VAR
VAR_IN_OUT
io:stMotorData;

END_VAR
VAR
fbTON2:Standard.TON;
iIndex:INT:=0;
fbftrig:Standard.F_TRIG;
fbrtrig:Standard.R_TRIG;
END_VAR

Code

これはファンクションブロックの実行部で、設定した周期でデータを配列に記録していく処理です。

//Start the Logging Period time,Real=>Time
IF xStart THEN
fbTON2.PT:=TO_TIME(rLogPeriod*1000);
END_IF;
//Timer
fbTON2(IN:=NOT fbTON2.Q AND xStart);

//
fbftrig(CLK:=xStart);
fbrtrig(CLK:=xStart);

IF fbrtrig.Q THEN
xBusy:=TRUE;
xError:=FALSE;
xDone:=FALSE;
iIndex:=0;
END_IF

IF fbftrig.Q THEN
xDone:=TRUE;
xBusy:=FALSE;
END_IF

IF
ixlog
AND xStart
AND iIndex <30000
THEN

io.arrDataY[iIndex]:=rLogValue;
iIndex:=iIndex+1;

END_IF

iLoggedIndex:=iIndex;

タイマー設定

rLogPeriodが秒単位なので、1000倍してミリ秒に変換しています。

fbTON2.PT := TO_TIME(rLogPeriod * 1000);

自己リセットタイマー

xStartがONの間、周期的にパルスを生成し続けます。

fbTON2(IN := NOT fbTON2.Q AND xStart);

開始処理(立ち上がり)

IF fbrtrig.Q THEN
xBusy := TRUE;
iIndex := 0; // インデックスリセット
END_IF

終了処理(立ち下がり)

IF fbftrig.Q THEN
xDone := TRUE;
xBusy := FALSE;
END_IF

データ記録

IF ixlog AND xStart AND iIndex < 2999THEN
io.arrDataY[iIndex] := rLogValue;
iIndex := iIndex + 1;
END_IF

プログラム

最後はプログラムの作成です。これは8台のモーターデータを並列でロギングするための管理プログラムで、各FBに同時にデータを記録させる構造になっています。

VAR

これは8ユニット分のデータロギングを管理するプログラムの変数定義部です。

PROGRAM p03Unit01Logging
VAR
xStartLog:BOOL;
fbLogging:ARRAY[0..eSystem.iTotolUnit] OF fbLogging;
xDone,xError,xBusy:ARRAY[0..eSystem.iTotolUnit] OF BOOL;
fbStartTimer:Standard.TON;
iIndex:ARRAY[0..eSystem.iTotolUnit]OF DINT;
iTotolData:DINT;
xInited:BOOL;
fbBlink :Util.BLINK;
iCounter: DINT;
iLoop: DINT;
xLoggingNotBusy: BOOL;
fbtrig4:Standard.R_TRIG;
rCurrentValue:REAL:=1.0;
END_VAR

Code

これは8ユニット分のデータを並列でロギングするメイン処理です。

FOR iLoop :=0 TO eSystem.iTotolUnit DO
IF fbLogging[iLoop].xBusy THEN
xLoggingNotBusy:=FALSE;
END_IF
END_FOR
FOR iLoop :=0 TO 299 DO
gData.arrDataX2[iLoop]:=iLoop;
END_FOR
FOR iLoop :=0 TO eSystem.iDataTotolLength DO
gData.arrDataX[iLoop]:=iLoop;
END_FOR
//
fbtrig4(CLK:=gDebug.bInput.1 OR gSystem.xLogStart OR gHMI.arriSwitch[0]=1);
IF fbtrig4.Q AND NOT xLoggingNotBusy THEN
xStartLog:=TRUE;
END_IF;
IF gHMI.arriSwitch[0]=1 THEN
gHMI.arriSwitch[0]:=0;
END_IF


fbBlink(
ENABLE:=xStartLog
,TIMELOW:=T#0.5S
,TIMEHIGH:=T#0.5S
);

gDebug.bOutput.0:=fbBlink.OUT;

//init
IF NOT xInited THEN
xInited:=TRUE;
FOR iLoop :=0 TO eSystem.iTotolUnit DO
gData.arrDataX[iLoop]:=iLoop;
END_FOR
END_IF;

//Signal Simulation
gRetainParamaters.stMotors[0].rTotolLoggingTime:=30;
fbStartTimer(IN:=xStartLog,PT:=
TO_TIME(gRetainParamaters.stMotors[0].rTotolLoggingTime*1000)
);
IF fbStartTimer.Q THEN
xStartLog:=FALSE;
END_IF

//Logging
FOR iCounter:=0 TO eSystem.iTotolUnit DO
gData.udtMotorDatas[iCounter].rCurrentValue:=gGVLIO.data.arrR[iCounter];
rCurrentValue:=gData.udtMotorDatas[iCounter].rCurrentValue;

fbLogging[iCounter].ixlog:=TRUE;
fbLogging[iCounter](
xStart:=xStartLog
,ixlog:=
,rLogValue:=rCurrentValue
,io:=gData.udtMotorDatas[iCounter]
,strDateTime:=gSystem.strCurrentDateTime
,xDone=>xDone[iCounter]
,xError=>xError[iCounter]
,xBusy=>xBusy[iCounter]
,iLoggedIndex=>iIndex[iCounter]
);
fbLogging[iCounter].ixlog:=FALSE;
END_FOR;

ダウンロード

最後にプロジェクトをCodesys Runtimeにダウンロードしてください。

JMobile側

最後はEXORのJMobile側です。

Codesys Tag

Codesys用の接続を作成します。

EXOR内部のCodesys Runtimeにアクセスするだけなので、IPアドレスは127.0.0.1でOKです。

Tag

次はCodesysにアクセスするTagを追加します。下図に示してあるIMPORTボタンをクリックします。

Codesys3 XML v1.0を選択し→Okで進みます。

CodesysプロジェクトのXMLを開きます。

下図のタグを追加します。

配列をまとめてTAGを追加したほうが、Tag数の節約ができます。

Scatter Diagram追加

次は画面にScatter Diagramを追加します。

X-Tag/Y-Tag

X-TagとY-Tagは実際Scatter Diagramに表示するX/Y軸のデータになります。

自動更新

Scatter Diagramにイベンドを追加し、配列データが更新されたとき自動的にScatter Diagramをアップデートできるようにします。

X-Min Y-Min

Scatter DiagramのX/Y軸の最大表示値を設定します。

画面

最終はData0-7、8ページ分のScatter Diagram画面作成し、またLogボタンを押しとLogging開始します。

ダウンロード

最後にプロジェクトをJMobile Runtimeにダウンロードしてください。

結果

CodesysとNX502-1300の間にEthernet/IP通信成立できました。

WiresharkからにもCIP I/Oメッセージのにも確認できました。

こちらの動画から動作確認できます。

シェアする

  • このエントリーをはてなブックマークに追加

フォローする