# Fullmo MovingCap CODE - micropython example. # original file name: mcdrive.pyi """Stub/interfaz del módulo mcdrive para variadores servo MovingCap fullmo / CODE / Micropython El módulo/biblioteca Python mcdrive permite el acceso a las funciones del variador servo MovingCap y al diccionario de objetos CiA402. * WriteObject y ReadObject proporcionan acceso general a todos los objetos disponibles del diccionario del variador de MovingCap. Si está familiarizado con los objetos estándar CiA 402 / CANopen / CoE EtherCAT y los objetos específicos del fabricante tal como se documentan en el manual de usuario de MovingCap, esto es todo lo que necesita para escribir una aplicación maestra completa del variador. * Se proporcionan funciones adicionales como un atajo y una forma más rápida de escribir sus aplicaciones. Esencialmente realizan varias operaciones de escritura/lectura en los objetos CiA 402 para lograr el mismo resultado. Por favor, consulte nuestros ejemplos para ver cómo poner su motor en movimiento con solo unas pocas líneas de código. """ __author__ = "Oliver Heggelbacher" __email__ = "oliver.heggelbacher@fullmo.de" __version__ = "50.00.10.xx" __date__ = "2025-11-04" def WriteObject(index : int, subindex : int, value : int) -> int: """Escribir valor de objeto CANopen (solo numérico) :param index: índice CANopen [unsigned16], ej. 0x607A para "target position" :type index: int :param subindex: subíndice CANopen [unsigned8], ej. 0 :type subindex: int :param value: nuevo valor para este objeto [integer32] :type value: int :return: 0 si tiene éxito, o el código de error interno de la pila CANopen. Generalmente puede ignorar este valor. Verifique solo cuando no esté seguro de si el índice/subíndice es un objeto válido para acceso de escritura. :rtype: int """ ret = 0 return ret def ReadObject(index : int, subindex : int) -> int: """Leer valor de objeto CANopen (solo numérico) :param index: índice CANopen [unsigned16], ej. 0x6064 para "position actual value" :type index: int :param subindex: subíndice CANopen [unsigned8], ej. 0 :type subindex: int :return: valor actual del objeto [integer32]. Si el objeto no es válido para acceso de lectura, se devuelve un valor de error interno de la pila CANopen. Note que el valor de retorno es siempre integer32, incluso si la entrada del diccionario de objetos tiene un tipo de datos CANopen diferente. :rtype: int """ value = 0 return value def WriteControl(control : int): """Escribir palabra de control CiA 402 (objeto CANopen 6040h.0h) :param control: nuevo valor [unsigned16] :type control: int """ pass def EnableDrive(): """Preparar para operación. Esta función cambia a través de los estados requeridos de la máquina de estados CiA 402, hasta que se alcanza "operation enabled". Esto es equivalente a verificar la palabra de estado del variador mediante `ReadStatusword` y comandar los cambios de estado requeridos usando `WriteControl`. La secuencia es: * Si el variador está en estado de error: WriteControl(0x80) reinicio de fallo -> nuevo estado "switch on disabled" * WriteControl(0x6) shutdown -> nuevo estado "ready to switch on" * WriteControl(0x7) switch on -> nuevo estado "switched on" * WriteControl(0xf) enable operation -> nuevo estado "operation enabled" Solo se realizan las transiciones requeridas. Si el variador ya está en estado "operation enabled" (ReadStatusword es 0x27), la función retorna inmediatamente. Ver también `PowerQuit` :return: 1 si el cambio a "operation enabled" es exitoso. 0 si falla. :rtype: int """ value = 0 return value def StopMotion(): """Entra en estado 'Quick Stop', después de configurar el parámetro 605Ah.0h Quick stop option code = 6 : "Slow down on quick stop ramp and stay in quick stop active". Usa el objeto 6085h.0h Quick Stop deceleration value. Ver también `ContinueMotion` para reanudar la operación después de un Quick Stop. """ pass def ContinueMotion(): """Reanudar movimiento. Esta función continúa el movimiento después de entrar en un estado Quick Stop (ej. usando `StopMotion`). """ pass def PowerQuit(): """Restablece el modo de operación a cero (ver `SetOpMode`), luego cambia la máquina de estados CiA 402 a "switch on disabled". Esto apaga de forma segura el variador manteniendo la conexión. Ver también `EnableDrive` """ pass def StorePermanent(): """Almacenar la configuración actual de parámetros en memoria no volátil. Guarda la configuración actual del variador (parámetros) en EEPROM/Flash para que persistan después del ciclo de energía. Esto incluye parámetros de movimiento, configuración de E/S, y otros valores de configuración que se han cambiado desde los valores predeterminados. Nota: El uso excesivo de esta función puede desgastar la memoria no volátil. Llame solo cuando sea necesario guardar cambios de configuración. Nota: Aunque es posible llamar a StorePermanent() en medio del movimiento, puede experimentar fallas/tartamudeos menores en movimientos de trayectoria de alta velocidad ya que el acceso a EEPROM requiere congelar otras tareas por un corto período de tiempo. """ pass def GoPosAbs(targetPos : int): """Iniciar nuevo movimiento a una posición absoluta. * Si es necesario, cambiar al modo de operación 1 - modo de posicionamiento de perfil (SetOpMode(1)) * Configurar el nuevo objetivo (ver `SetTargetPos`) * Iniciar posicionamiento usando el modo CiA 402 "single setpoint": la nueva posición objetivo se procesa inmediatamente. El control de posicionamiento usa "6083h.0h profile acceleration" (`SetAcc`) y "6084h.0h profile deceleration" (`SetDec`) para el movimiento. Use `ChkReady` y `ChkError` para esperar el final del posicionamiento y detectar errores durante la ejecución. Ver también 'GoPosRel' :param targetPos: nueva posición objetivo absoluta [integer32] :type targetPos: int """ pass def GoPosRel(relativePos : int): """Iniciar nuevo movimiento a posición relativa. Igual que `GoPosAbs`, pero especifica una posición relativa. Por defecto "relativo" significa "relativo a la posición objetivo precedente usada", pero el objeto "60F2h.0h positioning option code" puede especificar un significado diferente, ej. "relativo a la posición actual presente". :param relativePos: nueva posición objetivo relativa [integer32] :type relativePos: int """ pass def GoVel(targetVelocity : int): """Iniciar nueva operación de velocidad constante. * Si es necesario, cambiar al modo de operación 3 - modo de velocidad de perfil (SetOpMode(3)) * Configurar nueva velocidad objetivo y Los cambios de velocidad se aplican usando el objeto "6083h.0h profile acceleration" (ver `SetAcc`). Si se cambia la dirección (ej. de velocidad positiva a negativa), se usa el objeto "6085h.0h quickstop deceleration" hasta que la velocidad sea cero, luego se aplica 6083h.0h para acelerar en la dirección opuesta. El parámetro de deceleración no tiene influencia. :param targetVelocity: nueva velocidad objetivo [integer32] :type targetVelocity: int """ pass def SetTargetPos(targetPos : int): """Atajo para escribir el objeto "607Ah.0h target position" :param targetPos: nueva posición objetivo [integer32] :type targetPos: int """ pass def SetPosVel(profileVelocity : int): """Atajo para escribir el objeto "6081h.0h profile velocity" :param profileVelocity: nueva velocidad de perfil [unsigned32] :type profileVelocity: int """ pass def SetAcc(profileAcceleration : int): """Atajo para escribir el objeto "6083h.0h profile acceleration" :param profileAcceleration: nueva aceleración de perfil [unsigned32] :type profileAcceleration: int """ pass def SetDec(profileDeceleration : int): """Atajo para escribir el objeto "6084h.0h profile deceleration" :param profileDeceleration: nueva deceleración de perfil [unsigned32] :type profileDeceleration: int """ pass def GoHome(method : int, velocity : int, acceleration : int, offset : int): """Iniciar ejecución de referenciación/homing CiA 402 * Cambiar al modo de operación 6 - modo de velocidad de perfil (SetOpMode(3)) * Configurar objetos 6098h.0h homing method, 6099h.1h homing speed, 609Ah.0h homing acceleration y 607Ch.0h homing offset * Iniciar movimiento Valores `method` comunes para MovingCap son: * 37 o 35 = no mover. Configurar la posición actual presente como nueva posición cero. * -18 = ejecución de referencia de bloque en dirección positiva * -19 = ejecución de referencia de bloque en dirección negativa Use `ChkReady` y `ChkError` para esperar el final de la ejecución de homing y detectar errores durante la ejecución. :param method: método de homing CiA 402 [unsigned8] :type method: int :param velocity: Velocidad de homing [unsigned32] :type velocity: int :param acceleration: Aceleración de homing [unsigned32] :type acceleration: int :param offset: Posición de offset de homing [integer32]. Después de una operación de homing exitosa, hacer de este valor de posición la nueva posición actual. :type offset: int """ pass def SetOpMode(opMode: int): """Atajo para escribir el objeto "6060h.0h modes of operation" :param opMode: nuevo modo de operación [unsigned8]: 0 - sin modo. 1 - modo de posición de perfil. 3 - modo de velocidad de perfil. 6 - modo de homing. :type opMode: int """ pass def GetOpMode() -> int: """Atajo para leer el objeto "6060h.0h modes of operation" :return: modo de operación [unsigned8], ver `SetOpMode` :rtype: int """ opMode = 0 return opMode def SetTorque(torque : int): """Atajo para escribir el objeto "6073h.0h max current" :param torque: Nuevo valor de corriente máx. [unsigned16], que está directamente relacionado con el par máximo durante la operación. La unidad de valor es 0,1%, es decir torque = 100 significa "10% par" y torque = 1000 significa "100% par" (predeterminado). :type torque: int """ pass def ChkIn(inNo : int) -> int: """Verificar entrada digital :param inNo: N° de entrada de 1..10 (según el modelo MovingCap) :type inNo: int :return: 0 si bajo. 1 si alto (activo) :rtype: int """ pass def SetOut(outNo : int): """Activar salida digital :param outNo: N° de salida de 1..4 (según el modelo MovingCap) :type outNo: int """ pass def ClearOut(outNo : int): """Desactivar salida digital :param outNo: N° de salida de 1..4 (según el modelo MovingCap) :type outNo: int """ pass def GetActualPos() -> int: """Atajo para leer el objeto "6064h.0h position actual value" :return: posición actual [integer32] :rtype: int """ actualPos = 0 return actualPos def ReadStatusword() -> int: """Atajo para leer el objeto "6041h.0h statusword" :return: valor de palabra de estado CiA 402 [unsigned16] :rtype: int """ statusWord = 0 return statusWord def ChkReady() -> int: """Verificar si el variador ha terminado el movimiento actual (bit "target reached" de la palabra de estado activado), o si ocurrió un error (bit "error" activado). Use esto después de una nueva llamada `GoPosAbs`, `GoPosRel` o `GoHome`. :return: 1 si listo. 0 si no está listo (todavía). :rtype: int """ isReady = 0 return isReady def ChkEnabled() -> int: """Verificar si el variador está en estado "operation enabled". Esto verifica la palabra de estado CiA 402 para determinar si el variador está listo para comandos de movimiento. Devuelve el mismo valor que `ChkReady` - verifica tanto el objetivo alcanzado como el estado habilitado. :return: 1 si habilitado y listo. 0 si no habilitado o no listo. :rtype: int """ isEnabled = 0 return isEnabled def ChkMoving() -> int: """Verificar si el variador está ejecutando actualmente un movimiento. Esto monitorea el estado del variador para determinar si hay movimiento en progreso. Útil para detectar cuándo el variador está en movimiento activo vs. estacionario. :return: 1 si en movimiento. 0 si estacionario. :rtype: int """ isMoving = 0 return isMoving def ChkError() -> int: """Verificar si el bit "error" de la palabra de estado está activado. :return: 1 si hay error. 0 si no hay error. :rtype: int """ isError = 0 return isError def ChkMfrStatus(bitIndex : int) -> int: """Verificar un bit específico del registro de estado del fabricante objeto 1002h.0h. Bits de error disponibles de MovingCap Ethernet: 0 Error sobretensión (Uzk) 1 Error subtensión (Uzk) 2 Error Ack 3 Error sobretemperatura 4 Error I2T / Reducción de potencia 5 Abortar conexión 6 Error carrera 7 Error comunicación 8 Error sensor 9 Error habilitación hardware 11 Error sobrecorriente 12 Error fuerza / par externo :param bitIndex: el número de bit de 0..15 :type bitIndex: int :return: 1 si hay error. 0 si no hay error. :rtype: int """ isError = 0 return isError def SendEmcyMsg(errorNumber: int, errorRegister: int = 0, errorCode: int = 0x509b) -> None: """Enviar un mensaje de emergencia (EMCY). Esta función envía un mensaje de emergencia CANopen (EMCY) con información de error personalizada. Los mensajes EMCY se usan para señalar condiciones de error al maestro de red o sistemas de monitoreo. La función admite dos convenciones de llamada para compatibilidad hacia atrás: - Forma completa: SendEmcyMsg(errorNumber, errorRegister, errorCode) - Forma corta: SendEmcyMsg(errorNumber) - usa errorRegister=0x00 y errorCode=0x509b predeterminados :param errorNumber: Número de error específico del fabricante [unsigned32]. Típicamente es un código de error personalizado definido por la aplicación. :type errorNumber: int :param errorRegister: Valor del registro de error CANopen [unsigned8], predeterminado 0x00. Registro codificado por bits según especificación CANopen (error genérico, corriente, tensión, temperatura, etc.) :type errorRegister: int :param errorCode: Código de error de emergencia CANopen [unsigned16], predeterminado 0x509b. Código de error estándar o específico del fabricante según especificación CANopen. :type errorCode: int Ejemplo: SendEmcyMsg(0x12345678) # Forma simple SendEmcyMsg(0x12345678, 0x01, 0x5000) # Forma completa con todos los parámetros """ pass