# Fullmo MovingCap CODE - micropython example. # original file name: mcdrive.pyi """Modulo mcdrive stub/interfaccia per i servoazionamenti fullmo MovingCap / CODE / Micropython Il modulo/libreria Python mcdrive consente l'accesso alle funzioni del servoazionamento MovingCap e al dizionario oggetti CiA402. * WriteObject e ReadObject forniscono accesso generale a tutti gli oggetti disponibili del dizionario dell'azionamento MovingCap. Se si ha familiarità con gli oggetti standard CiA 402 / CANopen / CoE EtherCAT e gli oggetti specifici del produttore come documentati nel manuale utente MovingCap, questo è tutto ciò che serve per scrivere un'applicazione master completa. * Funzioni aggiuntive sono fornite come scorciatoia e modo più veloce per scrivere le applicazioni. Essenzialmente eseguono diverse operazioni di scrittura/lettura sugli oggetti CiA 402 per ottenere lo stesso risultato. Si prega di fare riferimento ai nostri esempi per vedere come far muovere il motore con solo poche righe di codice. """ __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: """Scrive valore oggetto CANopen (solo numerico) :param index: Indice CANopen [unsigned16], es. 0x607A per "posizione di destinazione" :type index: int :param subindex: Subindice CANopen [unsigned8], es. 0 :type subindex: int :param value: Nuovo valore per questo oggetto [integer32] :type value: int :return: 0 se riuscito, o il codice di errore interno dallo stack CANopen. È possibile ignorare questo valore di solito. Controllare solo quando non si è sicuri se l'indice/subindice è un oggetto valido per l'accesso in scrittura. :rtype: int """ ret = 0 return ret def ReadObject(index : int, subindex : int) -> int: """Legge valore oggetto CANopen (solo numerico) :param index: Indice CANopen [unsigned16], es. 0x6064 per "valore posizione effettiva" :type index: int :param subindex: Subindice CANopen [unsigned8], es. 0 :type subindex: int :return: Valore oggetto corrente [integer32]. Se l'oggetto non è un oggetto valido per l'accesso in lettura, viene restituito un valore di errore interno dello stack CANopen. Nota: il valore di ritorno è sempre integer32, anche se l'entry del dizionario oggetti ha un tipo di dato CANopen diverso. :rtype: int """ value = 0 return value def WriteControl(control : int): """Scrive control word CiA 402 (oggetto CANopen 6040h.0h) :param control: Nuovo valore [unsigned16] :type control: int """ pass def EnableDrive(): """Prepara per il funzionamento. Questa funzione commuta attraverso gli stati richiesti della macchina a stati CiA 402, fino a raggiungere "operation enabled" (funzionamento abilitato). Questo è equivalente a controllare lo statusword dell'azionamento tramite `ReadStatusword` e comandare i cambi di stato richiesti usando `WriteControl`. La sequenza è: * Se l'azionamento è in stato di errore: WriteControl(0x80) fault reset -> nuovo stato "switch on disabled" * WriteControl(0x6) shutdown -> nuovo stato "ready to switch on" * WriteControl(0x7) switch on -> nuovo stato "switched on" * WriteControl(0xf) enable operation -> nuovo stato "operation enabled" Vengono eseguite solo le transizioni richieste. Se l'azionamento è già nello stato "operation enabled" (ReadStatusword è 0x27), la funzione ritorna immediatamente. Vedere anche `PowerQuit` :return: 1 se il passaggio a "operation enabled" ha successo. 0 se fallisce. :rtype: int """ value = 0 return value def StopMotion(): """Entra nello stato 'Quick Stop', dopo aver impostato il parametro 605Ah.0h Quick stop option code = 6 : "Rallentare su rampa quick stop e rimanere in quick stop attivo". Utilizza l'oggetto 6085h.0h Quick Stop deceleration value. Vedere anche `ContinueMotion` per riprendere il funzionamento dopo un Quick Stop. """ pass def ContinueMotion(): """Riprende il movimento. Questa funzione continua il movimento dopo essere entrati in uno stato Quick Stop (es. usando `StopMotion`). """ pass def PowerQuit(): """Reimposta la modalità operativa a zero (vedere `SetOpMode`), quindi commuta la macchina a stati CiA 402 a "switch on disabled". Questo spegne in sicurezza l'azionamento mantenendo la connessione. Vedere anche `EnableDrive` """ pass def StorePermanent(): """Memorizza le impostazioni dei parametri correnti nella memoria non volatile. Salva la configurazione corrente dell'azionamento (parametri) in EEPROM/Flash in modo che persistano dopo il ciclo di alimentazione. Questo include parametri di movimento, impostazioni I/O, e altri valori di configurazione che sono stati modificati dai valori predefiniti. Nota: L'uso eccessivo di questa funzione può usurare la memoria non volatile. Chiamare solo quando necessario per salvare le modifiche di configurazione. Nota: Sebbene sia possibile chiamare StorePermanent() durante il movimento, si possono verificare piccoli glitch/scatti nei movimenti di traiettoria ad alta velocità poiché l'accesso EEPROM richiede il congelamento di altri task per un breve periodo di tempo. """ pass def GoPosAbs(targetPos : int): """Avvia un nuovo movimento verso una posizione assoluta. * Se richiesto, passa alla modalità operativa 1 - modalità posizionamento profilo (SetOpMode(1)) * Imposta il nuovo target (vedere `SetTargetPos`) * Avvia il posizionamento usando la modalità CiA 402 "single setpoint": la nuova posizione target viene elaborata immediatamente. Il controllo di posizionamento utilizza "6083h.0h profile acceleration" (`SetAcc`) e "6084h.0h profile deceleration" (`SetDec`) per il movimento. Utilizzare `ChkReady` e `ChkError` per attendere la fine del posizionamento e rilevare errori durante l'esecuzione. Vedere anche 'GoPosRel' :param targetPos: Nuova posizione target assoluta [integer32] :type targetPos: int """ pass def GoPosRel(relativePos : int): """Avvia un nuovo movimento verso una posizione relativa. Come `GoPosAbs`, ma specifica una posizione relativa. Per impostazione predefinita "relativa" significa "relativa alla posizione target precedente utilizzata", ma l'oggetto "60F2h.0h positioning option code" può specificare un significato diverso, es. "relativa alla posizione effettiva corrente". :param relativePos: Nuova posizione target relativa [integer32] :type relativePos: int """ pass def GoVel(targetVelocity : int): """Avvia un nuovo funzionamento a velocità costante. * Se richiesto, passa alla modalità operativa 3 - modalità velocità profilo (SetOpMode(3)) * Imposta nuova velocità target e Le modifiche di velocità vengono applicate usando l'oggetto "6083h.0h profile acceleration" (vedere `SetAcc`). Se la direzione viene cambiata (es. da velocità positiva a negativa), l'oggetto "6085h.0h quickstop deceleration" viene utilizzato fino a quando la velocità è zero, poi viene applicato 6083h.0h per accelerare nella direzione opposta. Il parametro di decelerazione non ha influenza. :param targetVelocity: Nuova velocità target [integer32] :type targetVelocity: int """ pass def SetTargetPos(targetPos : int): """Scorciatoia per scrivere l'oggetto "607Ah.0h target position" :param targetPos: Nuova posizione target [integer32] :type targetPos: int """ pass def SetPosVel(profileVelocity : int): """Scorciatoia per scrivere l'oggetto "6081h.0h profile velocity" :param profileVelocity: Nuova velocità profilo [unsigned32] :type profileVelocity: int """ pass def SetAcc(profileAcceleration : int): """Scorciatoia per scrivere l'oggetto "6083h.0h profile acceleration" :param profileAcceleration: Nuova accelerazione profilo [unsigned32] :type profileAcceleration: int """ pass def SetDec(profileDeceleration : int): """Scorciatoia per scrivere l'oggetto "6084h.0h profile deceleration" :param profileDeceleration: Nuova decelerazione profilo [unsigned32] :type profileDeceleration: int """ pass def GoHome(method : int, velocity : int, acceleration : int, offset : int): """Avvia la corsa di riferimento/homing CiA 402 * Passa alla modalità operativa 6 - modalità velocità profilo (SetOpMode(3)) * Imposta gli oggetti 6098h.0h homing method, 6099h.1h homing speed, 609Ah.0h homing acceleration e 607Ch.0h homing offset * Avvia il movimento Valori `method` comuni per MovingCap sono: * 37 o 35 = non muoversi. Imposta la posizione effettiva corrente come nuova posizione zero. * -18 = corsa di riferimento blocco in direzione positiva * -19 = corsa di riferimento blocco in direzione negativa Utilizzare `ChkReady` e `ChkError` per attendere la fine della corsa di homing e rilevare errori durante l'esecuzione. :param method: Metodo di homing CiA 402 [unsigned8] :type method: int :param velocity: Velocità di homing [unsigned32] :type velocity: int :param acceleration: Accelerazione di homing [unsigned32] :type acceleration: int :param offset: Posizione offset di homing [integer32]. Dopo un'operazione di homing riuscita, rendere questo valore di posizione la nuova posizione effettiva. :type offset: int """ pass def SetOpMode(opMode: int): """Scorciatoia per scrivere l'oggetto "6060h.0h modes of operation" :param opMode: Nuova modalità operativa [unsigned8]: 0 - nessuna modalità. 1 - modalità posizione profilo. 3 - modalità velocità profilo. 6 - modalità homing. :type opMode: int """ pass def GetOpMode() -> int: """Scorciatoia per leggere l'oggetto "6060h.0h modes of operation" :return: Modalità operativa [unsigned8], vedere `SetOpMode` :rtype: int """ opMode = 0 return opMode def SetTorque(torque : int): """Scorciatoia per scrivere l'oggetto "6073h.0h max current" :param torque: Nuovo valore corrente massima [unsigned16], che è direttamente in relazione alla coppia massima durante il funzionamento. L'unità del valore è 0.1%, cioè torque = 100 significa "10% coppia" e torque = 1000 significa "100% coppia" (predefinito). :type torque: int """ pass def ChkIn(inNo : int) -> int: """Controlla l'ingresso digitale :param inNo: N. ingresso da 1..10 (a seconda del modello MovingCap) :type inNo: int :return: 0 se basso. 1 se alto (attivo) :rtype: int """ pass def SetOut(outNo : int): """Imposta/Attiva uscita digitale :param outNo: N. uscita da 1..4 (a seconda del modello MovingCap) :type outNo: int """ pass def ClearOut(outNo : int): """Reimposta/disattiva uscita digitale :param outNo: N. uscita da 1..4 (a seconda del modello MovingCap) :type outNo: int """ pass def GetActualPos() -> int: """Scorciatoia per leggere l'oggetto "6064h.0h position actual value" :return: Posizione effettiva [integer32] :rtype: int """ actualPos = 0 return actualPos def ReadStatusword() -> int: """Scorciatoia per leggere l'oggetto "6041h.0h statusword" :return: Valore statusword CiA 402 [unsigned16] :rtype: int """ statusWord = 0 return statusWord def ChkReady() -> int: """Controlla se l'azionamento ha terminato il movimento corrente (il bit "target reached" dello statusword è impostato), o si è verificato un errore (il bit "error" è impostato). Utilizzare questo dopo una nuova chiamata a `GoPosAbs`, `GoPosRel` o `GoHome`. :return: 1 se pronto. 0 se non pronto (ancora). :rtype: int """ isReady = 0 return isReady def ChkEnabled() -> int: """Controlla se l'azionamento è nello stato "operation enabled". Questo controlla lo statusword CiA 402 per determinare se l'azionamento è pronto per i comandi di movimento. Restituisce lo stesso valore di `ChkReady` - controlla sia target reached che stato abilitato. :return: 1 se abilitato e pronto. 0 se non abilitato o non pronto. :rtype: int """ isEnabled = 0 return isEnabled def ChkMoving() -> int: """Controlla se l'azionamento sta attualmente eseguendo un movimento. Questo monitora lo stato dell'azionamento per determinare se il movimento è in corso. Utile per rilevare quando l'azionamento è in movimento attivo rispetto a fermo. :return: 1 se in movimento. 0 se fermo. :rtype: int """ isMoving = 0 return isMoving def ChkError() -> int: """Controlla se il bit "error" dello Statusword è impostato. :return: 1 se errore. 0 se nessun errore. :rtype: int """ isError = 0 return isError def ChkMfrStatus(bitIndex : int) -> int: """Controlla un bit specifico dall'oggetto 1002h.0h manufacturer status register. Bit di errore Ethernet MovingCap disponibili: 0 Error over volt (Uzk) 1 Error under volt (Uzk) 2 Error Ack 3 Error over temp 4 Error I2T / Derating 5 Abort connection 6 Error stroke 7 Error communication 8 Error Sensor 9 Error Hardware Enable 11 Error Over Current 12 Error External Force / Torque :param bitIndex: Il numero del bit da 0..15 :type bitIndex: int :return: 1 se errore. 0 se nessun errore. :rtype: int """ isError = 0 return isError def SendEmcyMsg(errorNumber: int, errorRegister: int = 0, errorCode: int = 0x509b) -> None: """Invia un messaggio di emergenza (EMCY). Questa funzione invia un messaggio di Emergenza CANopen (EMCY) con informazioni di errore personalizzate. I messaggi EMCY vengono utilizzati per segnalare condizioni di errore al master di rete o ai sistemi di monitoraggio. La funzione supporta due convenzioni di chiamata per retrocompatibilità: - Forma completa: SendEmcyMsg(errorNumber, errorRegister, errorCode) - Forma breve: SendEmcyMsg(errorNumber) - utilizza errorRegister=0x00 ed errorCode=0x509b predefiniti :param errorNumber: Numero di errore specifico del produttore [unsigned32]. Questo è tipicamente un codice di errore personalizzato definito dall'applicazione. :type errorNumber: int :param errorRegister: Valore registro errori CANopen [unsigned8], predefinito 0x00. Registro codificato a bit come da specifica CANopen (errore generico, corrente, tensione, temperatura, ecc.) :type errorRegister: int :param errorCode: Codice errore di emergenza CANopen [unsigned16], predefinito 0x509b. Codice di errore standard o specifico del produttore come da specifica CANopen. :type errorCode: int Esempio: SendEmcyMsg(0x12345678) # Forma semplice SendEmcyMsg(0x12345678, 0x01, 0x5000) # Forma completa con tutti i parametri """ pass