プログラムによるカムの作成
現在 CODESYS SoftMotion バージョン4.17.0.0、 CamBuilder
ファンクション ブロックは、IEC アプリケーションで直接プログラムによってカムを作成するためのインターフェイスを提供します。
詳細については、次の例を参照してください。 プログラムによるカムの作成
CamBuilder 関数ブロックの使用 (SM 4.17.0.0 以降)
デバイス ツリーにカム オブジェクトが作成されると、次のカムがデフォルトで作成されます。

カムは、次の 4 つの境界値を持つ 3 つの 5 次多項式で構成されます。
X | Y | V | A |
---|---|---|---|
0 | 0 | 0 | 0 |
120 | 120 | 1 | 0 |
240 | 240 | 1 | 0 |
360 | 360 | 0 | 0 |
このカムをプログラム的に作成するには、 CamBuilder
関数ブロックは最初に宣言されます:
VAR camBuilder : SMCB.CamBuilder; END_VAR
実装部分では、 CamBuilder
インスタンスは最初に初期化する必要があります。 Poly5
その後、 Append
方法:
camBuilder.Init(); camBuilder.Append( SMCB.Poly5( SMCB.BoundImplicit(), SMCB.Bound(120, 120, 1))); camBuilder.Append( SMCB.Poly5( SMCB.BoundImplicit(), SMCB.Bound(240, 240, 1))); camBuilder.Append( SMCB.Poly5( SMCB.BoundImplicit(), SMCB.Bound(360, 360)));
多項式は左境界条件と右境界条件によって定義されます。例では、 BoundImplicit
関数は常に左境界に使用されます。その結果、前のセグメントの右境界条件が適用されます。 BoundImplicit
関数が最初のセグメントの左境界として使用された場合、ゼロから始まります。この例では、Poly5 セグメントは (X, Y, V, A) = (0, 0, 0, 0) です。
いつ MC_CamTableSelect
そして MC_CamIn
ファンクションブロックが使用されています。カムは CamBuilder
ファンクションブロックは最終的に次のように変換する必要があります MC_CamRef
。これを行うには、CamBuilder の呼び出し先に応じて 2 つの方法があります
バスタスクでCamBuilderを呼び出す:
まず、宣言部分を対応するインスタンスで拡張する必要があります。
VAR ... camRef : MC_CAM_REF; aCamSegments : ARRAY[1..3] OF SMC_CAM_SEGMENT; END_VAR
次に、ファンクションブロックインスタンス
MC_CAM_REF
を使用して初期化され、書き込まれますWrite
の方法CamBuilder
ファンクションブロック。SMCB.InitCamRef(camRef, ADR(aCamSegments), XSIZEOF(aCamSegments)); camBuilder.Write(camRef);
別のタスク(マルチタスク、マルチコア)でCamBuilderを呼び出す:
最初に、カムのマルチタスク/マルチコアセーフインスタンスが GVL で作成されます。このインスタンスには、バスタスクと CamBuilder タスクの両方からアクセスされます。
VAR_GLOBAL safeCam : SMCB.CAM_REF_MULTICORE_SAFE; END_VAR
その後、バスタスクから他のタスクでのカムの作成が開始されます。
新しいカムが他のタスクにいつ書き込まれたかをバスタスクで判断するために、プログラムは次の情報を記憶します。
CamId
でSTATE_INIT_ONLINE_TABLE_MULTITASK
カムが作成される前。その後、カムの作成は次のタスクで開始されます。
STATE_START_CREATE_ONLINE_TABLE_MULTITASK
状態。次に、作成されたカムがに読み込まれます。
STATE_READ_ONLINE_TABLE_MULTITASK
状態。
PROGRAM BUS_TASK VAR state : UDINT; error : SMC_ERROR; camIdBeforeCreate : UDINT; camSegments: ARRAY[0..99] OF SMC_CAM_SEGMENT; camRef: MC_CAM_REF; END_VAR VAR CONSTANT STATE_INIT_ONLINE_TABLE_MULTITASK : UDINT := 0; STATE_START_CREATE_ONLINE_TABLE_MULTITASK : UDINT := 10; STATE_READ_ONLINE_TABLE_MULTITASK : UDINT := 20; STATE_ERROR : UDINT := 1000; END_VAR CASE state OF STATE_INIT_ONLINE_TABLE_MULTITASK: camIdBeforeCreate := GVL.safeCam.CamId; state := STATE_START_CREATE_ONLINE_TABLE_MULTITASK; STATE_START_CREATE_ONLINE_TABLE_MULTITASK: CamBuilderTask.BuildCam := TRUE; state := STATE_READ_ONLINE_TABLE_MULTITASK; STATE_READ_ONLINE_TABLE_MULTITASK: IF CamBuilderTask.Error THEN error := CamBuilderTask.ErrorId; state := state + STATE_ERROR; ELSIF GVL.safeCam.CamId <> camIdBeforeCreate THEN error := GVL.safeCam.GetCopy( camRef:= camRef, pCamSegments:= ADR(camSegments), arraySize:= XSIZEOF(camSegments)); IF error = SMC_NO_ERROR THEN state := state + 10; ELSE state := state + STATE_ERROR; END_IF END_IF END_CASE
CamBuilderタスクでは、マルチタスク/マルチコアセーフカムは呼び出して書き込まれます
CamBuilder.WriteMulticoreSafe()
:PROGRAM CamBuilderTask VAR_INPUT BuildCam : BOOL; END_VAR VAR_OUTPUT Error : BOOL; ErrorId : SMC_ERROR; END_VAR VAR camBuilder : SMCB.CamBuilder; END_VAR IF BuildCam THEN BuildCam := FALSE; camBuilder.Init(); camBuilder.Append(SMCB.Poly5(SMCB.BoundImplicit(), SMCB.Bound(120, 120, 1))); camBuilder.Append(SMCB.Poly5(SMCB.BoundImplicit(), SMCB.Bound(240, 240, 1))); camBuilder.Append(SMCB.Poly5(SMCB.BoundImplicit(), SMCB.Bound(360, 360))); Error := camBuilder.IsErrorPending(errorID=> ErrorId); IF NOT Error THEN ErrorId := camBuilder.WriteMulticoreSafe(GVL.safeCam); Error := ErrorId <> SMC_NO_ERROR; END_IF END_IF
暗黙的境界条件と明示的境界条件
暗黙の境界条件は次のように定義される。 BoundImplicit
隣接セグメントへの移行が可能な限りスムーズになるようにします。これを行うには、隣接セグメントの境界条件を明示的に定義する必要があります。 Bound
方法。したがって、セグメントの左境界条件が暗黙的である場合、前のセグメントの右境界条件は明示的にする必要があります。逆に、右境界条件が暗黙的である場合、後続のセグメントの左境界条件は明示的にする必要があります。
最も一般的な使用例は、上記の例のように、セグメントの右側の境界条件のみが明示的に指定されていると考えられます。左側の境界条件が暗黙的であるため、セグメントの遷移は自動的に可能な限りスムーズになり、定義領域にギャップはありません。次の例は、このアプローチから逸脱すると便利な単純なケースです。
スレーブ軸は位置 20 から 100 まで一定の速度で移動する必要があります。
camBuilder.Append( SMCB.Line( SMCB.Bound(20, 20), SMCB.Bound(100, 100)));
この前後には、 Poly5
セグメントは加速と減速に使用されます。
camBuilder.Append( SMCB.Poly5( SMCB.BoundImplicit(), SMCB.BoundImplicit())); camBuilder.Append( SMCB.Line( SMCB.Bound(20, 20), SMCB.Bound(100, 100))); camBuilder.Append( SMCB.Poly5( SMCB.BoundImplicit(), SMCB.Bound(120, 120, 0)));
このように定義されたカムには、Poly5 セグメント (速度は青色) に不要な加速フェーズと減速フェーズがあります。

これを避けるには、タイプセグメントのマスター位置を調整するだけで十分です。 Line
(例えば、左の境界が 20 から 30 に、右の境界が 100 から 90 に)
... camBuilder.Append( SMCB.Line( SMCB.Bound(30, 20), SMCB.Bound(90, 100))); ...

タイプのセグメントを調整する必要はない Poly5
定義された境界条件により、可能な限り滑らかに線分に自動的に追加されるため、 BoundImplicit
関数。
エラー処理
の Append
方法の CamBuilder
ファンクションブロックの戻り値 TRUE
セグメントが正常に追加されたときに、 FALSE
エラーが発生した場合。エラーが発生すると、それ以上セグメントを追加することができなくなり、 CamBuilder
関数ブロックは、 Init
メソッド。エラーの原因は、 IsErrorPending
方法:
camBuilder.IsErrorPending(errorId=> errorId);
データ構造 MC_CAM_REF の手動作成 (SM 4.17.0.0 より前)
重要
使用することをお勧めします SM3_カムビルダー ライブラリ CODESYS SoftMotion 4.17.0.0。
カムのデータ構造
プロジェクトのコンパイル時に、作成されたカムデータは内部的にグローバル変数リストに変換されます。 生成されたコードを表示する カム エディターでは、自動的に作成されたグローバル変数を表示できます。
各カムはデータ構造によって表される MC_CAM_REF
このデータ構造には、IECプログラムまたは前処理関数と関数ブロックを使用してアクセスできます。 SM3_Basic
図書館。
カムを記述する機能ブロックは、実行時に IEC プログラムによって生成または設定することもできます。
データ構造の定義:
TYPE mySMC_CAMTable_LREAL_10000_2 : STRUCT Table: ARRAY[0..9999] OF ARRAY[0..1] OF LREAL; (* set all scaling definitions to 0 and 1 result: all values of the table are not scaled *) fEditorMasterMin: REAL := 0; fEditorMasterMax: REAL := 1; fEditorSlaveMin: REAL := 0; fEditorSlaveMax: REAL := 1; fTableMasterMin: REAL := 0; fTableMasterMax: REAL := 1; fTableSlaveMin: REAL := 0; fTableSlaveMax: REAL := 1; END_STRUCT END_TYPE
データ構造のインスタンス化:
Cam: MC_CAM_REF; Cam_PointArray : mySMC_CAMTable_LREAL_10000_2;
カムの計算:
Cam.byType:=2; Cam.byVarType:=6; Cam.nTappets:=0; Cam.strCAMName:='myCAM'; Cam.pce:= ADR(CAM_PointArray); FOR i:=0 TO 9999 DO (* example cam: master 0..360, slave 0..100, constant velocity *) Cam_PointArray.Table[i][0]:=UDINT_TO_LREAL(I)/10000 * 360; (* X *) Cam_PointArray.Table[i][1]:=UDINT_TO_LREAL(I)/10000 * 100; (* Y *) END_FOR Cam.nElements:=10000 Cam.xStart:=0.0; Cam.xEnd:=360.0;
手動で生成されたカム
カム エディタを使用せずに IEC プログラムでカムを作成できます。
宣言:
VAR i: INT; CAM: MC_CAM_REF := ( byType:=2, (* non-equidistant *) byVarType:=2, (* UINT *) nElements:=128, xStart:=0, xEnd:=360); Table: SMC_CAMTable_UINT_128_2 := ( fEditorMasterMin := 0, fEditorMasterMax := 360, fTableMasterMin := 0, fTableMasterMax := 6000, fEditorSlaveMin := 0, fEditorSlaveMax := 360, fTableSlaveMin := 0, fTableSlaveMax := 6000); END_VAR
実装:
(* Create cam disk (example straight line); unambiguous *) FOR i:=0 TO 127 DO Table.Table[i][0] := Table.Table[i][1] := REAL_TO_UINT(i / 127.0 * 6000); END_FOR (* Link pointer; must be done in every cycle! *) CAM.pce := ADR(Table);
この生成されたカムは、 MC_CamTableSelect
ファンクションブロックとその出力を再利用して MC_CamIn
。
カム定義のコンパイル
コンパイル時に、型の変数 MC_CAM_REF
カム用に作成されます。カムの各セグメントの説明が含まれます。この種のデータ構造は、 MC_CamTable選択
機能ブロック。この構造は、 SM3_Basic
図書館。