🤖

CODESYS Example Projectを調べてみた#8 (Trace)

2025/03/01に公開

Trace

今回は、Traceについて調べました。このExampleでは、CmpTraceMgrというライブラリを使用しています。CmpTraceMgrは、IECプログラムやランタイムシステムコンポーネント、Editor上のTraceに関連するパケット(レコードの入れ物)とレコード(監視したい変数)を制御できます。

セットアップ

まずはExampleコードをダウンロードし、デバイスをアップデートします。私の環境(CODESYS V3.5 SP20 Patch2)ではライブラリが不足していたため、以下のボタンから追加することでビルドできました。

プログラムの内容

Exampleには、TraceRecordingExampleIECTraceConfigurationという2つのアプリケーションが含まれています。

  • TraceRecordingExample: 視覚的なTraceの設定を行う例
  • IECTraceConfiguration: STコードからCmpTraceMgrを利用する例

それぞれの中身を確認していきましょう。

TraceRecordingExample

PLC_PRG(PRG)内では、GEN FBを使ってSIN波形、TRIANGLE波形、RECTANGLE波形の3種類を生成し、iSignal1、iSignal2、iSignal3に出力しています。GEN FBは、Utilライブラリ内のSignalsに含まれています。

PLC_PRG(PRG)
PROGRAM PLC_PRG
VAR
	generator1 : GEN;
	iSignal1 : INT;
	generator2 : GEN;
	iSignal2 : INT;
	generator3 : GEN;
	iSignal3 : INT;

	// Starts the trace recording
	xStartVisuTraceTrigger : BOOL;
END_VAR

// Generate three signals
generator1(MODE := GEN_MODE.SINE, BASE := TRUE, PERIOD := TIME#500MS, AMPLITUDE := 500, OUT => iSignal1);
generator2(MODE := GEN_MODE.TRIANGLE, BASE := TRUE, PERIOD := TIME#2000MS, AMPLITUDE := 200, OUT => iSignal2);
generator3(MODE := GEN_MODE.RECTANGLE, BASE := TRUE, PERIOD := TIME#300MS, AMPLITUDE := 1000, OUT => iSignal3);

生成したiSignal1、iSignal2、iSignal3の値は、WebVisuのTraceWidgetで表示します。
Application内のTraceを選択し、Configurationをクリックすると「Trace Configuration」画面が表示されます。左側のTrace Recordを選択すると「Record Settings」を変更できます。オシロスコープを操作するような感覚で設定できそうです。

Trace Configuration

Trace以下にあるPLC_PRG.iSignal1,2,3を選択すると、変数の設定を行えます。Variableと表示されているプルダウンメニューをParameterに切り替えると、system parameterも記録できるようです。ただしOnline Helpによると、CmpTraceMgrコンポーネントが必要とのことです。

Variable settings

TraceVisuの画面でTraceWidgetを選択すると、Visualization_Trace1という名前のTraceが作成されています。先ほど直接設定したTraceとは別物のようですが、設定内容はほぼ同じです。

TraceVisu

「Display Settings」ボタンを押すと、X軸・Y軸の設定画面が表示されます。

Display Settings

「Advanced」ボタンを押すと、サンプリング周期の設定が可能です。

Advanced

また、「Copy from Trace」ボタンを押すと、Trace Instanceの内容がコピーされます。

Copy from Trace Instance

TraceVisu画面には、トリガ用ボタンや保存ボタン、保存ファイル名入力フォームが用意されています。Online Helpによると、これらはInsert Elements for Controlling Traceで追加されるようです。Windows上のDeviceにプログラムをダウンロードして「Store」を実行してみましたが、正しく動作しなかったため、CODESYSControl.cnfなどで追加設定が必要なのかもしれません。

store filenmame
store button

IECTraceConfiguration

2つ目のアプリケーションは、CmpTraceMgrを使ってTraceのレコードやパケットを制御する例です。パケットはトレース全体の入れ物であり、サンプリング周期やバッファサイズなどを設定します。レコードは、パケットが記録する具体的な変数とその属性を管理します。

サンプルコードでは、xStartをトリガにパケットを作成し、その後にレコード(iSignal)を追加してトレースを開始します。アプリケーションに含まれるTraceオブジェクト(Trace1)は、以下のような設定になっています。

IECTraceConfiguration Trace1

サンプルプログラムは次のとおりです。

PLC_PRG(PRG)
PROGRAM PLC_PRG
VAR
	xStart : BOOL := TRUE;
	xStop : BOOL := FALSE;
	iSignal : INT;          // The signal to record
	
	fbTraceManager : FBTraceMgr;

	PacketConfig : TracePacketConfiguration;
	hPacket1 : CmpTraceMgr.RTS_IEC_HANDLE;

	RecordConfig : TraceRecordConfiguration;	
	hRecord1 : CmpTraceMgr.RTS_IEC_HANDLE;

	pApp : POINTER TO APPLICATION;		
	xError : BOOL;
	generator1 : GEN;
END_VAR

IF xStart THEN
	// パケットの設定
	PacketConfig.pszName := ADR('IECTraceConfiguration.Trace1'); // Name of trace
	PacketConfig.pszApplicationName := ADR('IECTraceConfiguration'); 
	PacketConfig.pszIecTaskName := ADR('Task'); // Name of the task
	PacketConfig.pszComment := ADR('Demo packet');
	PacketConfig.ulEveryNCycles := 1;
	PacketConfig.ulBufferEntries := 1000;
	PacketConfig.ulFlags := TRACE_PACKET_FLAGS.TRACE_PACKET_FLAGS_TIMESTAMP_MS AND TRACE_PACKET_FLAGS.TRACE_PACKET_FLAGS_AUTOSTART;

    // CreatePacket()で上記の設定に従いパケットを作成
	IF (NOT fbTraceManager.CreatePacket(PacketConfig := PacketConfig, hPacket => hPacket1)) THEN
		xError := TRUE;
	END_IF

	// レコードの設定
	RecordConfig.pszVariable := ADR('iSignal');
	RecordConfig.tcClass := INT_TO_UDINT(TypeClass.TYPE_INT);
	RecordConfig.ulSize := SIZEOF(iSignal);
	pApp := AppFindApplicationByName('IECTraceConfiguration', 0); 
	AppGetAreaOffsetByAddress(pApp, ADR(iSignal), ADR(RecordConfig.tvaAddress.taAddress.Area.usArea), ADR(RecordConfig.tvaAddress.taAddress.Area.ulOffset)); 
	RecordConfig.tvaAddress.ulAddressFlags := TRACE_VAR_ADDRESS_FLAGS_IEC OR TRACE_VAR_ADDRESS_FLAGS_AREA_OFFSET;
 	RecordConfig.ulGraphColor := 16#FF00FF00; // green
	RecordConfig.ulGraphType := 1;            // Line with points
	
	// 警告範囲と色の設定
	RecordConfig.fCriticalLowerLimit := -90;
	RecordConfig.fCriticalUpperLimit := 90;
	RecordConfig.bActivateMinWarning := TRUE;
	RecordConfig.bActivateMaxWarning := TRUE;
	RecordConfig.ulMinWarningColor := 16#FFFF0000;  // red
	RecordConfig.ulMaxWarningColor := 16#FF0000FF;  // blue

    // AddRecord()でレコードをパケットに追加
	IF (NOT fbTraceManager.AddRecord(RecordConfig := RecordConfig, hPacket := hPacket1, hRecord => hRecord1)) THEN
		xError := TRUE;
	END_IF

    // StartPacket()でパケットを開始
	IF (NOT fbTraceManager.StartPacket(hPacket := hPacket1)) THEN
		xError := TRUE;
	END_IF
	xStart := FALSE;
END_IF

IF xStop THEN
    // StopPacket()でパケットを停止
	IF (NOT fbTraceManager.StopPacket(hPacket := hPacket1)) THEN
		xError := TRUE;
	END_IF
	xStop := FALSE;
END_IF

// Generate a sine signal
generator1(MODE := GEN_MODE.SINE, BASE := TRUE, PERIOD := TIME#5000MS, AMPLITUDE := 100, OUT => iSignal);

このプログラムでは、FBTraceMgrというFB(ファンクションブロック)を介してTrace Managerの機能を呼び出しています。CreatePacket(), AddRecord(), StartPacket(), StopPacket()などのメソッドがあらかじめ実装されているので、生のCmpTraceMgrよりも扱いやすい形となっています。

FBTraceMgr(FB)
FUNCTION_BLOCK FBTraceMgr
VAR_INPUT
END_VAR
VAR_OUTPUT
END_VAR
VAR
	_lastError : UDINT;	
	_hPacket : CmpTraceMgr.RTS_IEC_HANDLE;
	_hRecord : CmpTraceMgr.RTS_IEC_HANDLE;
END_VAR
CreatePacket(METHOD)
METHOD CreatePacket : BOOL
VAR_INPUT
	PacketConfig : TracePacketConfiguration;	
END_VAR
VAR_OUTPUT
	hPacket : CmpTraceMgr.RTS_IEC_HANDLE;
END_VAR

hPacket := TraceMgrPacketCreate(PacketConfig, _lastError);

IF hPacket <> CmpTraceMgr.RTS_INVALID_HANDLE THEN
	// Complete the trace packet
	TraceMgrPacketComplete(hPacket);
	CreatePacket := TRUE;
	RETURN;
END_IF
CreatePacket := FALSE;
AddRecord(METHOD)
METHOD AddRecord : BOOL
VAR_INPUT
	RecordConfig : TraceRecordConfiguration;
	hPacket : CmpTraceMgr.RTS_IEC_HANDLE;
END_VAR
VAR_OUTPUT
	hRecord : CmpTraceMgr.RTS_IEC_HANDLE;
END_VAR

hRecord := TraceMgrRecordAdd(hPacket, RecordConfig, _lastError);

IF hRecord <> CmpTraceMgr.RTS_INVALID_HANDLE THEN
	TraceMgrPacketComplete(hPacket);
	AddRecord := TRUE;
	RETURN;
END_IF
AddRecord := FALSE;

その他のメソッドについては、Exampleコード本体を参照してください。

気づきと学び

  • 信号処理や数値処理でよく使う機能は、Utilライブラリを探すと見つかるかもしれません。
  • Traceでは、変数のリアルタイム表示だけでなく、Store/Load機能や統計的処理も可能です。

まとめ

  • Traceはオシロスコープのように信号の追加やトリガー設定が行えます。
  • ST内でTraceを制御したい場合は、CmpTraceMgrを利用します。ライブラリ活用のポイントは以下のとおりです。
    1. TraceMgrPacketCreateでトレースの“枠”を作り、周期やバッファ数、フラグを設定する。
    2. TraceMgrRecordAddで記録したい変数・型・アドレスを指定し、可視化のグラフ設定や警告値を設定する。
    3. TraceMgrPacketStart / TraceMgrPacketStopでトレースのオン/オフを制御する。

Discussion