Windows上のスレッドでリアルタイムの動作を実現するための一つとして、WMXのイベント機能があります。このイベントは指定した条件が満たされたときに、特定の動作を実行する機能になります。
イベントの入力で使用できる条件
コアモーションの入力 CoreMotionEventInputクラス
軸のモーションに合わせて作動する条件となります。例えば、指令の位置決め完了範囲に入った時、指定の速度まで到達したとき、トルクが指定以上になった時など、多くの条件があります。 使用できる条件はCoreMotionEventInputTypeを参照してください。
イベントの入力 EventApiEventInputクラス
他のイベントに合わせて作動する条件です。指定されたデバイスが閉じたとき、別のイベントが指定した時間を継続して作動したときなどの条件があります。使用できる条件はEventApiEventInputTypeを参照してください。
I/Oの入力 IoEventInputクラス
I/Oの状態に合わせて作動する条件となります。入力と出力どちらでも使用可能で、2点入力のAND/OR/NANDなどのロジックが使用できます。使用できる条件はIoEventInputTypeを参照してください。
ユーザーメモリの入力 UserMemoryEventInputクラス
ユーザーメモリの値で作動する条件となります。2点入力のAND/OR/NANDなどのロジックが使用できます。使用できる条件はUserMemoryEventInputTypeを参照してください。
イベントの出力で使用できる条件
軸のモーションを実行する、他のイベントを実行する、APIバッファを実行する、指定のI/Oを出力する、ユーザーメモリの値を変更する機能になります。
コーディング前のプロジェクト準備
イベントの機能を使う場合は、プロジェクトにEventApi_CLRLib.dllの参照が必要となります。参照されていない場合は、参照を追加してください。
参照されていない場合はコンパイル時に [エラー CS0246 型または名前空間の名前 ‘EventControl’ が見つかりませんでした (using ディレクティブまたはアセンブリ参照が指定されていることを確認してください)] が表示されます。
DLLファイルは「C:\Program Files\SoftServo\WMX3\Lib」に配置されています。
デバック時の便利な機能
イベントが登録されているかを、ブレークポイントで確認は困難です。 便利な機能があります。 WOSアプリのイベントタブを表示します。ここに入力と出力の表示がありますので、目的の設定であるかを確認することができます。 イベントが終了している時はこの一覧に表示されませんのでイベントの有効状態も把握することが可能となります。
サンプルコード
1つのデジタル出力でユーザーメモリをONする方法
単一IOの変化でモーション処理を行う機能の検証を行いました。出力がONになった瞬間に、ユーザーメモリーをTrueになります。
※WMX3.6で検証したコード
/// <summary>
/// イベントの登録 1つのデジタル出力でユーザーメモリをON
/// </summary>
private void SetEvent_IO_User()
{
// IO制御のおまじない
Wmx3Lib_io = new Io(API);
eventCtl = new EventControl();
// イベントの機能を使う場合は、プロジェクトにEventApi_CLRLib.dllの参照が必要です
// イベント発動条件の設定
int ewEventID1 = 0; // 割り当てられたイベント番号
var ioEvent1 = new EventControl.Event();
ioEvent1.Enabled = 1; // 1=有効状態
ioEvent1.InputFunction = EventControl.EventInputFunction.IOBit; // 指定されたI/Oビットが1のときにイベント出力を作動
ioEvent1.Input_IOBit.ByteAddress = 0; // I/O入力アドレス
ioEvent1.Input_IOBit.BitAddress = 0; // I/O入力アドレス
ioEvent1.Input_IOBit.Invert = 0; // 0=入力bitが1のときにTRUEと評価 1=入力bitが0のときにTRUEと評価
ioEvent1.Input_IOBit.IOSourceType = IOSourceType.Output; // 対象のデジタルIOは入力?出力?
ioEvent1.OutputFunction = EventControl.EventOutputFunction.SetMBit; // イベント着火時の処理選択 SetMBit=ユーザーメモリーをセット
ioEvent1.Output_SetMBit.ByteAddress = 0; // ユーザーメモリー出力アドレス
ioEvent1.Output_SetMBit.BitAddress = 0; // ユーザーメモリー出力アドレス
ioEvent1.Output_SetMBit.Invert = 0; // 1=このイベントが作動したときに、指定されたイベントは無効
// 1=イベントが作動すると自動的に無効状態になります。無効状態のイベントはEnableEvent関数で有効にしないと再度作動しません。イベントの出力関数がエラーを返して実行に失敗した場合、イベントは無効状態にならず、次の通信サイクルに再び出力関数を実行しようと試みることができます。
// 0=イベントは作動したあとも有効状態で残り続けます。
ioEvent1.Output_SetMBit.DisableAfterActivate = 0;
ioEvent1.Output_SetMBit.SetOffState = 0; // 1=入力関数が負のときにユーザーメモリのビットを0にする
// イベントを登録
eventCtl.SetEvent(ref ewEventID1, ioEvent1);
}
デジタル出力2点のANDをイベントのトリガーとし、軸を移動する方法
複数IOの変化でモーション処理を行う機能の検証を行いました。2点の出力がONになった瞬間に、軸をある位置に移動させるモーションをご紹介いたします。イベントコントロールに[AndIOBit]を使用しています。Invertに0を設定することでデジタル出力がHiになった時をトリガーとしています。
C#のコードサンプルはこちらになります。※WMX3.6で検証したコード
/// <summary>イベントの登録番号</summary>
int posEventID = 1;
/// <summary>イベント制御</summary>
EventControl eventCtl;
/// <summary>
/// イベントの登録
/// </summary>
private void SetEvent()
{
// IO制御のおまじない
Wmx3Lib_io = new Io(API);
eventCtl = new EventControl();
// イベントの機能を使う場合は、プロジェクトにEventApi_CLRLib.dllの参照が必要です
// イベント発動条件の設定(IO入力2つのAndをイベントのトリガーとします)
var posEvent = new EventControl.Event();
posEvent.Enabled = 1;
posEvent.InputFunction = EventControl.EventInputFunction.AndIOBit; // 指定された2つのI/Oビットの両方が1のときにイベントを作動します
posEvent.Input_AndIOBit.ByteAddress[0] = 0; // 1つ目の入力アドレス
posEvent.Input_AndIOBit.BitAddress[0] = 0; // 1つ目の入力アドレス
posEvent.Input_AndIOBit.Invert[0] = 0; // 値が0=入力bitが1のときにTRUEと評価 値が1=入力bitが0のときにTRUEと評価
posEvent.Input_AndIOBit.IOSourceType[0] = IOSourceType.Output; // 対象のデジタルIOは入力?出力?
posEvent.Input_AndIOBit.ByteAddress[1] = 0; // 1つ目の入力アドレス
posEvent.Input_AndIOBit.BitAddress[1] = 1; // 1つ目の入力アドレス
posEvent.Input_AndIOBit.Invert[1] = 0; // 値が0=入力bitが1のときにTRUEと評価 値が1=入力bitが0のときにTRUEと評価
posEvent.Input_AndIOBit.IOSourceType[1] = IOSourceType.Output; // 対象のデジタルIOは入力?出力?
// イベントの動作設定(単軸の絶対位置指令を開始)
posEvent.OutputFunction = EventControl.EventOutputFunction.StartSinglePos;
var singlePos = new EventControl.EventOutputFunctionArguments_StartSinglePos();
singlePos.Axis = 0;
singlePos.Type = WMX3ApiCLR.ProfileType.Trapezoidal;
singlePos.Target = 1000;
singlePos.Velocity = 9000;
singlePos.Acc = 10000;
singlePos.Dec = 10000;
posEvent.Output_StartSinglePos = singlePos;
// イベントを登録
eventCtl.SetEvent(ref posEventID, posEvent);
}
/// <summary>
/// イベントの削除
/// </summary>
private void RemoveEvent()
{
eventCtl.RemoveEvent(posEventID);
}
コメント