Vai al contenuto
PLC Forum

Partecipa anche tu alla Live su Youtube martedì 28/01/2025 per festeggiare i 24 anni di PLC Forum

Per ulteriori informazioni leggi questa discussione: https://www.plcforum.it/f/topic/326513-28012025




Gestione 6 azionamenti Estun tramite Modbus RTU


Messaggi consigliati

Inserito: (modificato)

Ciao a tutti,

premetto che è la prima volta che mi trovo a gestire un azionamento che non sia collegato ad un CN, quindi ho un sacco di problemi.

 

Sto utilizzando una Cpu 1214FC con un modulo CM 1241 e devo gestire 6 assi tutti con queste funzioni:

- movimento in JOG entrambe le direzioni

- cambio velocità JOG

- lettura della posizione (encoder a bordo dei motori)

 

Ogni asse si muove singolarmente.

Per due assi devo anche gestire la posizione in automatico (ma questo è un problema che affronterò più avanti)

 

Al momento sono riuscito a configurare la comunicazione e far muovere i motori in JOG (Modbus_Comm_Load + Modbus_Master). Già questo è per me un enorme risultato.

 

Adesso arriva la parte difficile e per la quale vi chiedo supporto:

 

Come imbastisco tutto il sistema? Per ovviare al problema di non poter richiamare Modbus_Master fino a quando non ha finito la sua elaborazione, stavo pensando di richiamarla da un SCL di cui allego il codice. In questo modo posso richiamare il mio FC FunzioneModbus da ogni parte senza preoccupazioni.

Ho però forti dubbi che così possa funzionare. Per prima cosa non ho capito se posso richiamare Modbus_Master variando i parametri ma con il solito DB di istanza. Inoltre ho paura che questo sistema possa bloccare troppo la CPU (anche perché le funzioni di scrittura avverranno solo in determinati momenti, mentre quelle di lettura di tutti e 6 gli assi devono essere fatte in continuazione).

 

AIUTO!

 

Grazie a tutti e buon lavoro,

Claudio.

 

FunzioneModbus.png

 

EDIT: scusate ma mi sono accorto che la prima condizione del WHILE non è #Busy ma è #Done.

Modificato: da Cip77

Inserita:
41 minuti fa, Cip77 scrisse:

Per prima cosa non ho capito se posso richiamare Modbus_Master variando i parametri ma con il solito DB di istanza.

Certo che lo puoi fare, basta che non ci siano richiami contemporanei della stessa funzione con lo stesso DB di istanza.

 

43 minuti fa, Cip77 scrisse:

Inoltre ho paura che questo sistema possa bloccare troppo la CPU

No, per la CPU non c'è nessun problema.
Il problema, piuttosto, sta nella lentezza del Modbus. Personalmente preferirei usare il Modbus per leggere e scrivere i parametri (scrittura da fare solo quando un parametro viene modificato), ma impartire i comandi di marcia/jog con uscite del PLC.

Inserita:

Inoltre utilizzare il Modbus siccome non raggiunge velocità elevate la comunicazione con ogni slave avviene con uno slave per volta ed ogni volta devi ovviamente modificare l'indirizzo dello slave con cui comunichi, comandi di velocità contemporanei sono un po' difficili e si crea quindi una latenza di comando, metterli in marcia può essere semplice perchè se l'inverter lo può ricevere gli dai un comando di broadcast e contemporaneamente a tutti dai il medesimo comando ma comandare le velocità contemporaneamente diventa difficile, questo dipende se ti è necessario. Diciamo che con il Modbus comandi di singoli assi si fanno, situazioni un po' più complesse non sono semplici da realizzare, tienilo in conto

Inserita:

Intanto grazie per le risposte.

1 ora fa, batta scrisse:

Certo che lo puoi fare, basta che non ci siano richiami contemporanei della stessa funzione con lo stesso DB di istanza.

Ottimo. Ho previsto quel blocco SCL proprio per evitare questo.

 

1 ora fa, batta scrisse:

Il problema, piuttosto, sta nella lentezza del Modbus. Personalmente preferirei usare il Modbus per leggere e scrivere i parametri (scrittura da fare solo quando un parametro viene modificato), ma impartire i comandi di marcia/jog con uscite del PLC.

Sfortunatamente non ho la possibilità di comandarli in versione cablata (quindi con le uscite del PLC). Devo per forza usare il profibus.

 

50 minuti fa, leleviola scrisse:

Inoltre utilizzare il Modbus siccome non raggiunge velocità elevate la comunicazione con ogni slave avviene con uno slave per volta ed ogni volta devi ovviamente modificare l'indirizzo dello slave con cui comunichi, comandi di velocità contemporanei sono un po' difficili e si crea quindi una latenza di comando, metterli in marcia può essere semplice perchè se l'inverter lo può ricevere gli dai un comando di broadcast e contemporaneamente a tutti dai il medesimo comando ma comandare le velocità contemporaneamente diventa difficile, questo dipende se ti è necessario. Diciamo che con il Modbus comandi di singoli assi si fanno, situazioni un po' più complesse non sono semplici da realizzare, tienilo in conto

Non sono inverter, ma azionamenti. In versione manuale gli assi vanno mossi uno per volta, sempre. Serve per il posizionamento.

In versione automatica invece dovrei settare la posizione di 2 assi, ma non contemporaneamente. Posso farlo 1 alla volta (si tratta sempre di un posizionamento) e poi inizia la lavorazione che muoverà, nel momento giusto, un solo asse.

 

La velocità mi preoccupa solo in versione manuale in quanto, quando premo, ad esempio, il pulsante JOG+ mi scrive il registro per attivare la funzione di JOG+ e quando lascio il pulsante scriverà lo stesso registro per disattivarla. 

 

Il mio dubbio più grande è proprio capire come fare a procedere con la struttura del programma. Più blocchi che all'occorrenza richiamano l'SCL con la giusta funzione? Un blocco unico per la gestione di tutti i tipi di movimenti di tutti gli azionamenti con attivazioni a seconda di una variabile? Altro?

 

Grazie ancora,

Claudio.

Inserita:

Buongiorno,  vi aggiorno (vado lento perché è un lavoro complicato ma secondario, quindi riesco a dedicargli poco tempo):

 

ho visto che il tempo medio di esecuzione di ogni singola chiamata di Modbus_Master varia tra 20 e 50 ms ... di conseguenza, il blocco che avevo fatto per la lettura degli encoders di tutti e 6 gli assi, che veniva eseguito ogni 500ms, già mi crea problemi di esecuzione in quanto a volte sorpassa i 300ms. Di conseguenza devo cambiare nuovamente approccio. Al momento faccio eseguire una sola lettura per scan: in questo modo non ho problemi di lentezza di esecuzione ma ho, ovviamente, lentezza nell'aggiornamento delle quote degli assi. Eseguendo il blocco ogni 250 ms e ipotizzando un tempo di esecuzione di 50 ms un asse mi si aggiorna ogni 2 secondi (poco meno). Inoltre devo tenere in conto che ho le operazioni di scrittura da gestire e a cui, in qualche modo, devo dare la priorità, in quanto per far partire un asse in JOG devo scrivere un registro. Ma anche per fermare il JOG devo scrivere un registro.

Suggerimenti? Domande?

 

Grazie,

Claudio.

Inserita:

Buongiorno, altro aggiornamento:

visto la carenza di idee, al momento ho risolto il problema della lentezza di aggiornamento delle quote, bloccando l'aggiornamento di tutti gli assi tranne quello selezionato. In questo modo posso richiamare la funzione più volte.

Come ultima cosa, mi sono scordato di riportare un errore importante che ho trovato nel blocco SCL che ho postato sopra: testando DONE, BUSY ed ERROR restituiti dalla funzione, il blocco andava in loop. Ho quindi cambiato testando DONE, BUSY ed ERROR presenti nel DB legato a MODBUS_MASTER; nel mio caso Modbus_Master_DB. In questo modo funziona perfettamente.

 

Ciao,

Claudio.

Inserita:
25 minuti fa, Cip77 scrisse:

al momento ho risolto il problema della lentezza di aggiornamento delle quote, bloccando l'aggiornamento di tutti gli assi tranne quello selezionato

Se hai bisogno di leggere le quote con un aggiornamento veloce, il Modbus è l'ultima strada da seguire. Se ti puoi permettere di aggiornare la lettura da un solo drive velocizzi il sistema, ma rimane comunque lento. Dipende da cosa ci devi fare, con quella quota.

 

27 minuti fa, Cip77 scrisse:

mi sono scordato di riportare un errore importante che ho trovato nel blocco SCL che ho postato sopra: testando DONE, BUSY ed ERROR restituiti dalla funzione, il blocco andava in loop

Appena eseguivi la funzione, al ciclo successivo ti restituiva Busy = True, e non elaboravi più la funzione stessa.
Con la modifica che hai fatto funziona, ma è comunque sbagliato il concetto: il richiamo della funzione lo puoi fare incondizionato, ed agire solo sul comando REQ.

Inserita:
18 minuti fa, batta scrisse:

Appena eseguivi la funzione, al ciclo successivo ti restituiva Busy = True, e non elaboravi più la funzione stessa.

Altro mio errore, che avevo corretto e non riportato qui: non testavo e non testo Busy, ma Done. Ho dovuto testare direttamente quelli presenti nel DB perché quelli della funzione restano sempre false.

 

19 minuti fa, batta scrisse:

Con la modifica che hai fatto funziona, ma è comunque sbagliato il concetto: il richiamo della funzione lo puoi fare incondizionato, ed agire solo sul comando REQ.

Qui, scusami, ma non ho capito.

 

Grazie e ciao,

Claudio.

Inserita:
1 ora fa, Cip77 scrisse:

Qui, scusami, ma non ho capito.

Tu hai messo il richiamo della funzione all'interno di un While.
Può anche andare bene, ma devi essere sicuro di non elaborare la funzione solo quando non serve.
Per esempio, il While potrebbe essere condizionato anche dalla condizione di Busy, ma al contrario di come è nel tuo esempio, ovvero in OR e non in AND.
Trovo però molto pericoloso mettere una funzione come questa in un ciclo While, perché mi blocca l'esecuzione del programma fino a quando non esco dal While.
Se è questo che vuoi, fallo pure, ma devi essere sicuro di ciò che stai facendo, perché potresti anche mandare in stop la cpu per intervento del watchdog.

Al posto del While, potresti usare un IF.

Oppure, la funzione la richiami sempre, ad ogni ciclo, senza condizionamenti, ed agisci solo sul comando REQ per attivare la comunicazione.

 

Poi, molto dipende da come hai sviluppato il resto del programma.
Per esempio, per utilizzare parametri diversi si possono richiamare istanze diverse di Modbus_Master, ma non contemporaneamente (una sola istanza alla volta).
In questo caso, diventa necessario condizionare il richiamo di Modbus_Master.

Personalmente preferisco fare un solo richiamo (ed avere una sola istanza) e cambiare i parametri.
Se crei un array con la struttura dei parametri, ti basta modificare l'indice dell'array.

 

Inserita: (modificato)

Ho capito. Cerco di spiegare il funzionamento attuale.

Quando, per qualche motivo, devo leggere/scrivere un parametro (timer scaduto, pressione di un pulsante, etc.) viene fatto richiamando il blocco ChiamataModbus (il precedente FunzioneModbus) che allego come immagine qui sotto. A questo blocco vengono passati l'indirizzo dello slave "#Azionamento", la funzione da eseguire "#Funzione" (ovvero il registro modbus da leggere/scrivere) e la modalità "#Modalità" (0 lettura, 1 scrittura).

 

L'esecuzione di questo blocco, in caso di funzionamento corretto, impiega circa 20/50 ms.

 

Utilizzare questo sistema, mi permette di fare le chiamate di lettura/scrittura dei registri senza preoccuparmi di possibili sovrapposizioni in quanto, non è possibile che si verifichino.

 

Magari l'approccio non è giusto, e questo è proprio il motivo per cui avevo aperto questo post: capire come fosse meglio affrontare la questione.

 

Uno degli scenari possibili della macchina è questo: seleziono la modalità manuale (selettore) e seleziono un' asse da muovere (altro selettore). A questo punto lo muovo in Jog+ o Jog- (due pulsanti) mentre guardo la quota dell'asse (lettura encoder).

 

Gestire la questione in modbus diventa questo:

- selettore da auto a manuale: scrivo il parametro per attivare l'asse selezionato in JOG

- selettore scelta asse: scrivo il parametro per disattivare l'asse precedente e scrivo il parametro per attivare l'asse selezionato

- premo il pulsante JOG + o -: scrivo il parametro per attivare il movimento in JOG con con direzione scelta

- rilascio il pulsante JOG + o -: scrivo il parametro per disattivare il movimento in JOG con con direzione scelta

- ciclicamente leggo il parametro encoder per l'asse selezionato

 

Ho pensato che per gestire questo (ma sfortunatamente non finisce qui) il modo più semplice fosse quello sopra descritto.

Al momento è così e sta funzionando, ma sono speranzoso nella tipica frase: 

"Claudio ma che mi combini? È molto meglio e più semplice se invece fai così ...."

 

Scusate la lungaggine ma spero almeno di essere stato chiaro.

 

Claudio.

 

Non mi fa aggiungere l'immagine, per cui vi lascio il link al codice: https://pastebin.com/Q3jXZT4N

 

P.s. intanto grazie Batta, soprattutto per la pazienza.

Modificato: da Cip77
Non mi fa caricare l'immagine

Crea un account o accedi per commentare

Devi essere un utente per poter lasciare un commento

Crea un account

Registrati per un nuovo account nella nostra comunità. è facile!

Registra un nuovo account

Accedi

Hai già un account? Accedi qui.

Accedi ora
×
×
  • Crea nuovo/a...