step-80 Inserito: 2 febbraio 2014 Segnala Share Inserito: 2 febbraio 2014 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 . Grazie anticipatamente a tutti Matteo Link al commento Condividi su altri siti More sharing options...
rguaresc Inserita: 2 febbraio 2014 Segnala Share Inserita: 2 febbraio 2014 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 More sharing options...
lelos Inserita: 2 febbraio 2014 Segnala Share Inserita: 2 febbraio 2014 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 More sharing options...
valvolina Inserita: 2 febbraio 2014 Segnala Share Inserita: 2 febbraio 2014 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 More sharing options...
step-80 Inserita: 2 febbraio 2014 Autore Segnala Share Inserita: 2 febbraio 2014 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 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 Link al commento Condividi su altri siti More sharing options...
lelos Inserita: 2 febbraio 2014 Segnala Share Inserita: 2 febbraio 2014 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 More sharing options...
step-80 Inserita: 2 febbraio 2014 Autore Segnala Share Inserita: 2 febbraio 2014 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 More sharing options...
rguaresc Inserita: 2 febbraio 2014 Segnala Share Inserita: 2 febbraio 2014 (modificato) 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: 2 febbraio 2014 da rguaresc Link al commento Condividi su altri siti More sharing options...
step-80 Inserita: 2 febbraio 2014 Autore Segnala Share Inserita: 2 febbraio 2014 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 More sharing options...
step-80 Inserita: 3 febbraio 2014 Autore Segnala Share Inserita: 3 febbraio 2014 (modificato) 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 Grazie! Modificato: 3 febbraio 2014 da step-80 Link al commento Condividi su altri siti More sharing options...
step-80 Inserita: 3 febbraio 2014 Autore Segnala Share Inserita: 3 febbraio 2014 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 More sharing options...
step-80 Inserita: 3 febbraio 2014 Autore Segnala Share Inserita: 3 febbraio 2014 Dunque aggiornamento: provato anche il cambio acc/dec , funziona tutto a meraviglia. Non so davvero come ringraziarvi tutti! Link al commento Condividi su altri siti More sharing options...
step-80 Inserita: 3 febbraio 2014 Autore Segnala Share Inserita: 3 febbraio 2014 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 More sharing options...
valvolina Inserita: 3 febbraio 2014 Segnala Share Inserita: 3 febbraio 2014 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 More sharing options...
step-80 Inserita: 3 febbraio 2014 Autore Segnala Share Inserita: 3 febbraio 2014 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 More sharing options...
Messaggi consigliati
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 accountAccedi
Hai già un account? Accedi qui.
Accedi ora