Creazione di camme a livello di codice
Come di CODESYS SoftMotion versione 4.17.0.0, il CamBuilder Il blocco funzione fornisce un'interfaccia per la creazione di camme a livello di programmazione direttamente nell'applicazione IEC.
Per ulteriori informazioni, vedere l'esempio: Creazione di camme a livello di codice
Utilizzo del blocco funzione CamBuilder (a partire da SM 4.17.0.0)
Per impostazione predefinita, quando si crea un oggetto camma nell'albero dei dispositivi, viene creata la seguente camma elettronica:

La camma è composta da tre polinomi di quinto grado con i seguenti quattro valori limite:
X | Y | V | A |
|---|---|---|---|
0 | 0 | 0 | 0 |
120 | 120 | 1 | 0 |
240 | 240 | 1 | 0 |
360 | 360 | 0 | 0 |
Per creare questa camma a livello di codice, un'istanza di CamBuilder il blocco funzione viene dichiarato per primo:
VAR
camBuilder : SMCB.CamBuilder;
END_VARNella parte di implementazione, il CamBuilder l'istanza deve prima essere inizializzata. Tre segmenti di tipo Poly5 può quindi essere aggiunto utilizzando il file Append metodo:
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)));I polinomi sono definiti tramite le condizioni al contorno sinistra e destra. Nell'esempio, il BoundImplicit la funzione viene sempre utilizzata per il confine sinistro. Di conseguenza, viene applicata la condizione al contorno destra del segmento precedente. Se la BoundImplicit viene utilizzata come limite sinistro per il primo segmento, quindi inizia da zero: in questo esempio, con il segmento Poly5 in (X, Y, V, A) = (0, 0, 0, 0).
Quando il MC_CamTableSelect e MC_CamIn vengono utilizzati i blocchi funzionali, la camma è definita in CamBuilder il blocco funzionale deve infine essere convertito in un MC_CamRef. Esistono due modi per farlo, a seconda di dove viene chiamato CamBuilder
Chiamare il CamBuilder nel task del bus:
Innanzitutto, la parte della dichiarazione deve essere estesa dalle istanze corrispondenti:
VAR ... camRef : MC_CAM_REF; aCamSegments : ARRAY[1..3] OF SMC_CAM_SEGMENT; END_VAR
Quindi l'istanza del blocco funzionale
MC_CAM_REFviene inizializzato e scritto utilizzandoWritemetodo delCamBuilderblocco funzionale.SMCB.InitCamRef(camRef, ADR(aCamSegments), XSIZEOF(aCamSegments)); camBuilder.Write(camRef);
Chiamare CamBuilder in un'altra attività (multitask, multicore):
Innanzitutto, viene creata un'istanza multitask/multicore-safe della videocamera in un GVL, a cui si accede sia dal task bus che dal task CamBuilder.
VAR_GLOBAL safeCam : SMCB.CAM_REF_MULTICORE_SAFE; END_VAR
Quindi la creazione della camma nell'altra attività viene avviata dall'attività del bus.
Per determinare nell'operazione del bus quando la nuova camma è stata scritta nell'altra operazione, il programma ricorda
CamIdnelSTATE_INIT_ONLINE_TABLE_MULTITASKprima che la camma venga creata.Quindi la creazione della camma viene avviata nell'altra attività nel
STATE_START_CREATE_ONLINE_TABLE_MULTITASKstato.Quindi, la cam creata viene letta nel
STATE_READ_ONLINE_TABLE_MULTITASKstato.
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
Nel task CamBuilder, la cam multitask/multicore-safe viene scritta chiamando
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
Condizioni al contorno implicite ed esplicite
Una condizione al contorno implicita definita con BoundImplicit assicura che la transizione al segmento adiacente sia il più agevole possibile. Per fare ciò, la condizione al contorno del segmento adiacente deve essere definita esplicitamente utilizzando il Bound metodo. Quindi se la condizione al contorno sinistra di un segmento è implicita, allora la condizione al contorno destra del segmento precedente deve essere esplicita. Viceversa, se la condizione al contorno destra è implicita, allora la condizione al contorno sinistra del segmento successivo deve essere esplicita.
Il caso d'uso più comune è presumibilmente che solo le giuste condizioni al contorno dei segmenti siano specificate esplicitamente, come nell'esempio sopra. A causa delle condizioni al contorno sinistro implicite, le transizioni dei segmenti sono automaticamente il più fluide possibile e non ci sono spazi vuoti nell'area di definizione. L’esempio seguente è un caso semplice in cui è utile deviare da questo approccio:
L'asse slave dovrebbe spostarsi a velocità costante dalla posizione 20 a 100:
camBuilder.Append(
SMCB.Line(
SMCB.Bound(20, 20),
SMCB.Bound(100, 100)));Prima e dopo questo, a Poly5 il segmento viene utilizzato per l'accelerazione e la decelerazione:
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)));La camma così definita presenta fasi di accelerazione e decelerazione indesiderate nei segmenti Poly5 (velocità in blu):

Per evitare ciò è sufficiente regolare la posizione del master nel segmento di tipo Line (ad esempio, quello del confine sinistro da 20 a 30 e quello del confine destro da 100 a 90):
...
camBuilder.Append(
SMCB.Line(
SMCB.Bound(30, 20),
SMCB.Bound(90, 100)));
...
Non è necessario modificare i segmenti del tipo Poly5 perché vengono aggiunti automaticamente al segmento di linea nel modo più fluido possibile a causa delle condizioni al contorno definite utilizzando BoundImplicit funzione.
Gestione degli errori
IL Append metodo del CamBuilder ritorni del blocco funzione TRUE quando un segmento è stato aggiunto con successo e ritorna FALSE se si è verificato un errore. Dopo un errore non è possibile aggiungere altri segmenti e il file CamBuilder il blocco funzione deve essere reinizializzato utilizzando il comando Init metodo. La causa dell'errore può essere determinata utilizzando IsErrorPending metodo:
camBuilder.IsErrorPending(errorId=> errorId);
Creazione manuale della struttura dati MC_CAM_REF (prima di SM 4.17.0.0)
Importante
Si consiglia di utilizzare il SM3_CamBuilder biblioteca a partire da CODESYS SoftMotion 4.17.0.0.
Strutture dati delle camme
Durante la compilazione del progetto, i dati camma creati vengono convertiti internamente in un elenco di variabili globali. Cliccando Visualizza il codice generato nell'editor camme è possibile visualizzare le variabili globali create automaticamente.
Ogni camma è rappresentata dalla struttura dati MC_CAM_REF. È possibile accedere a questa struttura dati tramite il programma IEC o preelaborando funzioni e blocchi funzionali. È disponibile presso il SM3_Basic biblioteca.
Un blocco funzione che descrive una camma può anche essere generato o popolato dal programma IEC in fase di esecuzione.
Definizione della struttura dei dati:
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_TYPEIstanziare la struttura dei dati:
Cam: MC_CAM_REF; Cam_PointArray : mySMC_CAMTable_LREAL_10000_2;
Calcolo della camma:
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;Camme generate manualmente
È possibile creare una camma elettronica in un programma IEC senza utilizzare l'editor camma.
Dichiarazione:
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_VARImplementazione:
(* 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);Questa camma generata può essere specificata nel file MC_CamTableSelect blocco funzione e il suo output riutilizzato MC_CamIn.
Compilazione delle definizioni di camma
In fase di compilazione, variabili di tipo MC_CAM_REF vengono creati per una camma. Includono una descrizione di ciascun segmento della camma. Strutture dati di questo tipo vengono passate al file MC_CamTableSelect blocco funzione. La struttura fa parte del SM3_Basic biblioteca.