プログラムによるカムの作成
現在 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 図書館。