Vai al contenuto
PLC Forum


Consigli Per Problema Blocchi Mc-M258


Messaggi consigliati

Salve a tutti, chiedo a voi aiuto per risolvere un problema su un programma che sto scrivendo. Si tratta di Somachine,il plc utilizzato è un M258 ed il linguaggio utilizzato è ST. E' il primo programma che scrivo in tale linguaggio.

Dunque semplificando dispongo di un motore brushless Lexium 32 collegato al plc tramite bus di campo CanOpen (in realtà sono di più ma non fa differenza).

Ho necessità di far eseguire al motore ( che muove un sistema carro-cinghia con corsa di circa 300 mm) dei posizionamenti in sequenza scaturiti da un solo comando di start.

Esempio: premo start----->termina il primo movimento------>inizia subito il secondo ecc fino alla fine dell'ultimo movimento,quando ad una nuova pressione di start deve corrispondere una nuova missione. Molto semplice,se non banale,e a dir il vero sono cose che ho sempre fatto utilizzando per ogni movimento un blocchetto Mc_moveabsolute. I problemi sono nati quando mi sono messo in testa di eseguire tutti i movimenti con un solo blocco,passandogli di volta in volta i nuovi valori e ridando start aspettando il position end. Tutto funziona nella mia testa ma quando vado a mettere il progetto in macchina niente. Il primo movimento viene eseguito ma il tutto si blocca li. Se fra un movimento e l'altro inserisco una condizione(esempio un timer che ritarda la seconda partenza,oppure la seconda partenza condizionata da un determinato sensore che scatta ecc)allora i movimenti vengono eseguiti,almeno sino a quando non arrivano altri due movimenti concatenati. Li non riesco proprio.

Chiedo umilmente lume a voi esperti, perchè c'ho perso dietro ormai svariate notti e non arrivo ad una soluzione. Ad oggi il programma funziona,ma solo perchè mi sono 'rassegnato' ad usare il sistema dei blocchi multipli. Solo che l'idea di avere 'fallito' mi da i nervi e vorrei capire dove sbagliavo.

Allego per chi ha voglia un esempio di un semplice posizionamento a tre step da un comando di start,cosi come lo scrivevo io,sperando di fare cosa gradita e capire dove sbagliavo.Inutile dire che ogni commento/critica ,anche se non strettamente legata al problema,sarà accolta con enorme piacere.

Un appello ai moderatori: se ci fosse la possibilità,mi farebbe enorme piacere che la discussione fosse spostata magari in una sezione più visibile,in modo da avere più opinioni possibili. Ovviamente se fosse possibile :smile: .

Grazie anticipatamente a tutti

Matteo

bpml.jpg

Link al commento
Condividi su altri siti


Secondo me è questo:

Il valore di FASE_PROVA commuta senza discontinuità tra 5, 10, 15 per cui la catena di OR a destra dell'Execute di MOVE Absolute rimane sempre vera.
Il MOVE Absolute parte con il fronte e dovresti azzerare un attimo FASE_PROVA prima di attribuirgli il nuovo valore per rendere momentaneamente falsa la catena di OR.

Link al commento
Condividi su altri siti

ciao

Il valore di FASE_PROVA commuta senza discontinuità tra ...

mi sembra strano.. comunque prova a fare lo stesso con l'istruzione select ..case per toglierti ogni dubbio.

Link al commento
Condividi su altri siti

Ciao

Di seguito un piccolo esempio che testa tutti i passaggi

1) preparazione variabili

2) start posizionamento

3) verifica posizionamento partito

4) verifica posizionamento terminato e stop variabile di avvio posizionamento

5) passaggio al posizionamento successivo

così senz'altro c'è qualche giro di programma in più (che si può ottimizzare),

ma vedi metodicamente tutti i passaggi.

Fatta l'esperienza ottimizzi.

// INIZZIALIZZAZIONE FASE PROVA
IF NOT START_PROVA THEN
FASE_PROVA := 0; START_POSIZIONAMENTO:= FALSE;
END_IF


// AVVIO CICLO POSIZIONAMENTI
IF START_PROVA AND (FASE_PROVA = 0) THEN
FASE_PROVA := 10;
END_IF


CASE FASE_PROVA OF

// PREPARAZIONE VARIABILI PRIMO POSIZIONAMENTO
10 : VEL_PROVA := VEL_1; POS_PROVA := POS_1;
FASE_PROVA := 20;
// AVVIO POSIZIONAMENTO 1 (START POSIZIONAMENTO VA MESSO SULL'INGRESSO "EXECUTE")
20 : START_POSIZIONAMENTO := TRUE;
FASE_PROVA := 30;
// POSIZIONAMENTO 1 AVVIATO
30 : IF MOVEABS_PROVA.BUSY THEN
FASE_PROVA := 40;
END_IF
// POSIZIONAMENTO 1 TERMINATO
40 : IF MOVEABS_PROVA.DONE THEN
FASE_PROVA := 50;
START_POSIZIONAMENTO := FALSE;
END_IF
// FASE INTERMEDIA PER AVVIO SUCCESSIVO POSIZIONAMENTO
50 : FASE_PROVA := 100;

// PREPARAZIONE VARIABILI SECONDO POSIZIONAMENTO
100 : VEL_PROVA := VEL_2; POS_PROVA := POS_2;
FASE_PROVA := 200;
// AVVIO POSIZIONAMENTO 1 (START POSIZIONAMENTO VA MESSO SULL'INGRESSO "EXECUTE")
200 : START_POSIZIONAMENTO := TRUE;
FASE_PROVA := 300;
// POSIZIONAMENTO 1 AVVIATO
300 : IF MOVEABS_PROVA.BUSY THEN
FASE_PROVA := 400;
END_IF
// POSIZIONAMENTO 1 TERMINATO
400 : IF MOVEABS_PROVA.DONE THEN
FASE_PROVA := 500;
START_POSIZIONAMENTO := FALSE;
END_IF
// FINE POSIZIONAMENTI
500 : FASE_PROVA := 0;
START_PROVA := FALSE;

END_CASE;

saluti da Valvolina

Link al commento
Condividi su altri siti

Ragazzi innanzi tutto grazie per il vostro prezioso contributo.

Il valore di FASE_PROVA commuta senza discontinuità tra 5, 10, 15 per cui la catena di OR a destra dell'Execute di MOVE Absolute rimane sempre vera.

Questo l'avevo intuito,almeno a livello teorico. Che tu me ne dia conferma per me è un sollievo. Problema è che non sapevo come farvi fronte a livello pratico.

Il MOVE Absolute parte con il fronte

Questo l'ho già provato varie volte ma non funziona. Ho inserito la catena di OR come imput CLK di un istruzione R_TRIG (fronte di salita),mettendo sull'imput Execute il risultato dell'istruzione (cioè il bit che risultava alto solo per una scansione). Ma non funziona,o almeno non funzionava a me. A proposito,cosi facendo teoricamente dovrei aver avuto il segnale POSIZIONAMENTO_TERMINATO alto anch'esso per una scansione,giusto?

@ valvolina: Grazie per il tuo esempio,mi hai aperto una nuova strada. Domani provo e poi vi faccio sapere :smile:

Nel frattempo se qualcun'altro ha qualche opinione ....

P.S Quanto mi piace ST! Me ne sono innamorato. Non è stato amore a prima vista, ma ora che lo sto capendo di più mi intriga un sacco,e difficilmente tornerei indietro :thumb_yello:

Link al commento
Condividi su altri siti

ciao

P.S Quanto mi piace ST! Me ne sono innamorato. Non è stato amore a prima vista, ma ora che lo sto capendo di più mi intriga un sacco,e difficilmente tornerei indietro

ogni linguaggio ha i suoi pro e contro.....esempio più è evoluito più usa memoria più rallenta la scansione.

ci sono cose che è più facile ed intuitivo con il ladder altre con l'ST altre con AWL anche se ognuno può portare al medesimo risultato logico.

Link al commento
Condividi su altri siti

Sante parole Lelos, io davo solo una mia opinione ( magari tra sei mesi scopriró cfc e cambieró idea) . Certo se lo dite voi con la vostra esperienza mi fido

Link al commento
Condividi su altri siti

potresti inserire subito prima del blocco MOVEABSOLUTE


nuova_var := POSIZIONAMENTO_TERMINATO;

e, se questa nuova variabile è true inibisci la condizione modificando

((FASE_PROVA=5) OR (FASE_PROVA=10) OR (FASE_PROVA=15) AND NOT(nuova_var))

In questo modo quando è completato il movimento, per una scansione di programma si attiva il Done e per una scansione la condizione diventa falsa

Modificato: da rguaresc
Link al commento
Condividi su altri siti

Nell ' esempio riportato da valvolina ho notato che il merker 'start posizionamento ' viene alzato e abbassato piu volte a seconda dello stato di 'fase prova'. Questo mi confonde un po, perchè ho sempre creduto che si dovesse scrivere una variabile booleana in un solo punto del programma. Sbaglio? O in casi come questo è consentito farlo?

Link al commento
Condividi su altri siti

potresti inserire subito prima del blocco MOVEABSOLUTE

nuova_var := POSIZIONAMENTO_TERMINATO;

e, se questa nuova variabile è true inibisci la condizione modificando

((FASE_PROVA=5) OR (FASE_PROVA=10) OR (FASE_PROVA=15) AND NOT(nuova_var))

In questo modo quando è completato il movimento, per una scansione di programma si attiva il Done e per una scansione la condizione diventa falsa

Questa potrebbe essere una soluzione. Ora vedrò di attuarle tutte :thumb_yello:

Grazie!

Modificato: da step-80
Link al commento
Condividi su altri siti

Ragazzi sono felicissimo, la soluzione proposta da valvolina funziona alla grande!!

Tra l' altro non credevo si potesse mettere un costrutto if dentro un costrutto case.

Questo sistema di testare fase per fase mi piace moltissimo , peccato abbia già fatto tutto il programma col metodo' facile'

Link al commento
Condividi su altri siti

Ragazzi rinnovo la domanda: il fatto di scrivere piu volte un bit all interno di un programma è possibile? È considerato errore?

Il fatto di evitare di scrivere piu volte vale solo per le uscite fisiche?

Il programma gira divinamente. Grazie ancora

Link al commento
Condividi su altri siti

ciao,

non è una disgrazia scrivere più volte un merker in un programma,

l'importante è avere il controllo di quello che si fa.

Quando non sai bene come organizzare il programma, conviene:

per ogni fase di un ciclo che deve attivare una uscita, fare un merker apposito,

poi andare in or con tutti i merker sull'uscita.

questa cosa probabilmente di costa di più in quantità di istruzioni,

ma ti consente di razionalizzare meglio l'organizzazione del programma.

ad esempio se aprendo una protezione devi spegnere l'uscita,

avendola scritta in posto solo ti risulterà più facile.

saluti da Valvolina

Link al commento
Condividi su altri siti

Perfetto, proprio come immaginavo.

Per curiosità, quando vi capita di dover fare posizionamenti tipo me, usate blocchi giá fatti oppure preferite fare 'vecchia maniera'?

So che i blocchetti mc sono comodi, ma so anche che consumano molte piu risorse di sistema.

Voi come usate fare?

Link al commento
Condividi su altri siti

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...