Crear cámaras mediante programación
A partir de CODESYS SoftMotion versión 4.17.0.0, la CamBuilder
El bloque de funciones proporciona una interfaz para crear levas mediante programación directamente en la aplicación IEC.
Para obtener más información, consulte el ejemplo: Crear cámaras mediante programación
Usando el bloque de funciones CamBuilder (a partir de SM 4.17.0.0)
La siguiente cámara se crea de forma predeterminada cuando se crea un objeto de cámara en el árbol de dispositivos:

La leva consta de tres polinomios de quinto grado con los siguientes cuatro valores límite:
X | Y | V | A |
---|---|---|---|
0 | 0 | 0 | 0 |
120 | 120 | 1 | 0 |
240 | 240 | 1 | 0 |
360 | 360 | 0 | 0 |
Para crear esta cámara mediante programación, una instancia de la CamBuilder
El bloque de funciones se declara primero:
VAR camBuilder : SMCB.CamBuilder; END_VAR
En la parte de implementación, el CamBuilder
La instancia primero debe inicializarse. Tres segmentos de tipo Poly5
Luego se puede agregar usando el Append
método:
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)));
Los polinomios se definen mediante las condiciones de contorno izquierda y derecha. En el ejemplo, el BoundImplicit
La función siempre se utiliza para el límite izquierdo. Como resultado, se aplica la condición de contorno derecho del segmento anterior. Si el BoundImplicit
La función se utiliza como límite izquierdo para el primer segmento, luego comienza en cero: en este ejemplo, con el segmento Poly5 en (X, Y, V, A) = (0, 0, 0, 0).
Cuando el MC_CamTableSelect
y MC_CamIn
se utilizan bloques de funciones, la leva definida en CamBuilder
el bloque de funciones finalmente tiene que convertirse en un MC_CamRef
. Hay dos maneras de hacerlo, dependiendo de dónde se llame al CamBuilder
Llamar a CamBuilder en la tarea del bus:
En primer lugar, la parte de la declaración debe ser extendida por las instancias correspondientes:
VAR ... camRef : MC_CAM_REF; aCamSegments : ARRAY[1..3] OF SMC_CAM_SEGMENT; END_VAR
Luego, la instancia del bloque de funciones
MC_CAM_REF
se inicializa y escribe con elWrite
método delCamBuilder
bloque de funciones.SMCB.InitCamRef(camRef, ADR(aCamSegments), XSIZEOF(aCamSegments)); camBuilder.Write(camRef);
Llamar al CamBuilder en otra tarea (multitarea, multinúcleo):
En primer lugar, se crea una instancia de la cámara segura para múltiples tareas/multinúcleo en una GVL, a la que acceden tanto la tarea bus como la tarea CamBuilder.
VAR_GLOBAL safeCam : SMCB.CAM_REF_MULTICORE_SAFE; END_VAR
A continuación, la creación de la cámara en la otra tarea se inicia desde la tarea del bus.
Para determinar en la tarea del bus cuándo se escribió la nueva cámara en la otra tarea, el programa recuerda el
CamId
enSTATE_INIT_ONLINE_TABLE_MULTITASK
antes de crear la cámara.A continuación, se inicia la creación de la cámara en la otra tarea del
STATE_START_CREATE_ONLINE_TABLE_MULTITASK
estado.A continuación, la cámara creada se lee en el
STATE_READ_ONLINE_TABLE_MULTITASK
estado.
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
En la tarea CamBuilder, la cámara multitarea/segura para múltiples núcleos se escribe llamando
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
Condiciones de contorno implícitas y explícitas
Una condición de frontera implícita definida con BoundImplicit
se asegura de que la transición al segmento adyacente sea lo más suave posible. Para hacer esto, la condición de contorno del segmento adyacente debe definirse explícitamente usando el Bound
método. Entonces, si la condición de frontera izquierda de un segmento es implícita, entonces la condición de frontera derecha del segmento anterior tiene que ser explícita. Por el contrario, si la condición de frontera derecha está implícita, entonces la condición de frontera izquierda del segmento posterior tiene que ser explícita.
El caso de uso más común es presumiblemente que solo se especifican explícitamente las condiciones de contorno correctas de los segmentos, como en el ejemplo anterior. Debido a las condiciones implícitas del límite izquierdo, las transiciones de los segmentos son automáticamente lo más suaves posible y no hay espacios en el área de definición. El siguiente ejemplo es un caso sencillo en el que resulta útil desviarse de este enfoque:
El eje esclavo debe viajar a velocidad constante desde la posición 20 a 100:
camBuilder.Append( SMCB.Line( SMCB.Bound(20, 20), SMCB.Bound(100, 100)));
Antes y después de esto, un Poly5
El segmento se utiliza para aceleración y desaceleración:
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 leva así definida tiene fases de aceleración y desaceleración no deseadas en los segmentos Poly5 (velocidad en azul):

Para evitar esto, es suficiente ajustar la posición del maestro en el segmento de tipo Line
(por ejemplo, el del límite izquierdo de 20 a 30 y el del límite derecho de 100 a 90):
... camBuilder.Append( SMCB.Line( SMCB.Bound(30, 20), SMCB.Bound(90, 100))); ...

No es necesario ajustar los segmentos de tipo Poly5
porque se agregan automáticamente al segmento de línea de la manera más suave posible debido a las condiciones de contorno definidas usando el BoundImplicit
función.
Manejo de errores
El Append
método de la CamBuilder
retornos del bloque de funciones TRUE
cuando un segmento se ha agregado exitosamente y regresa FALSE
si ha ocurrido un error. Después de un error, no se pueden agregar más segmentos y el CamBuilder
El bloque de funciones debe reinicializarse utilizando el Init
método. La causa del error se puede determinar utilizando el IsErrorPending
método:
camBuilder.IsErrorPending(errorId=> errorId);
Creación manual de la estructura de datos MC_CAM_REF (antes de SM 4.17.0.0)
Importante
Se recomienda utilizar el SM3_CamBuilder biblioteca a partir de CODESYS SoftMotion 4.17.0.0.
Estructuras de datos de levas.
Al compilar el proyecto, los datos de la cámara creados se convierten internamente en una lista de variables globales. Haciendo click Mostrar código generado En el editor de cámaras, puede mostrar las variables globales creadas automáticamente.
Cada cámara está representada por la estructura de datos. MC_CAM_REF
. Puede acceder a esta estructura de datos mediante el programa IEC o mediante funciones de preprocesamiento y bloques de funciones. Está disponible por el SM3_Basic
biblioteca.
El programa IEC también puede generar o completar un bloque de funciones que describe una leva en tiempo de ejecución.
Definición de la estructura de datos:
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
Creación de instancias de la estructura de datos:
Cam: MC_CAM_REF; Cam_PointArray : mySMC_CAMTable_LREAL_10000_2;
Calculando la leva:
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;
Cámaras generadas manualmente
Se puede crear una leva en un programa IEC sin utilizar el editor de levas.
Declaración:
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
Implementación:
(* 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);
Esta leva generada se puede especificar en el MC_CamTableSelect
bloque de funciones y su salida se utiliza nuevamente para MC_CamIn
.
Compilación de definiciones de cámaras
En tiempo de compilación, variables de tipo MC_CAM_REF
se crean para una cámara. Incluyen una descripción de cada segmento de la leva. Las estructuras de datos de este tipo se pasan al MC_CamTableSelect
bloque de funciones. La estructura es parte de la SM3_Basic
biblioteca.