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_VAR
Nella 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_REF
viene inizializzato e scritto utilizzandoWrite
metodo delCamBuilder
blocco 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
CamId
nelSTATE_INIT_ONLINE_TABLE_MULTITASK
prima che la camma venga creata.Quindi la creazione della camma viene avviata nell'altra attività nel
STATE_START_CREATE_ONLINE_TABLE_MULTITASK
stato.Quindi, la cam creata viene letta nel
STATE_READ_ONLINE_TABLE_MULTITASK
stato.
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_TYPE
Istanziare 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_VAR
Implementazione:
(* 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.