batta Inserita: 20 febbraio 2023 Segnala Share Inserita: 20 febbraio 2023 (modificato) 6 ore fa, chimera1803 ha scritto: certo ma di passi indietro non ne posso fare, devo chiudere il progetto prima possibile per non incorrere a penali. Allora ti conviene commissionare il lavoro ad uno esperto. Guarda che la mia non è "cattiveria gratuita", e non c'è niente di cui vergognarsi nel dover imparare. Non intendevo offendere nessuno, ma solo essere schietto. Il fatto è che hai chiesto aiuto, ma ti sei intestardito a correggere un codice che non è da correggere, ma da rifare da zero. Ti è stato più volte detto che il ciclo FOR non c'entra nulla con quello che devi fare, ma continui a proporre varianti sempre con il ciclo FOR Ripeto: nel dover imparare non c'è nessuna vergogna, ma se ti trovi a dover portare a termine un compito che non sei in grado di portare a termine, l'unica soluzione è incaricare qualcuno capace. Io ti posso anche buttare giù un programmino di esempio per leggere dall'array la variabile corretta ma, come fatto notare anche da @Simone.Salarsi, i tuoi errori non si limitano alla gestione dell'array. Ribadisco che non intendo offendere nessuno, ma non vorrei che, una volta risolto il problema dell'array, ti ritrovassi poi con altri cento problemi. Gestire un asse non significa solo farlo muovere, ma significa anche gestire la sicurezza, significa ripartire dopo un'emergenza, significa referenziare l'asse, significa predisporre comandi jog per la manutenzione, significa fare la diagnostica, significa gestire tutto il ciclo macchina. Non si tratta solo di inserire due blocchi MC_nnnn. Secondo me, l'unica soluzione possibile è commissionare il lavoro ad un esperto, specificando che ti dovrà anche dare indicazioni sul funzionamento. 6 ore fa, chimera1803 ha scritto: la scelta di programmare un macchinario, gestire assi, ricette ed Array non è di certo stata mia. Quindi non hai colpe. La colpa è di chi crede che programmare un PLC sia un lavoro che si impara in pochi giorni, e ti ha mandato allo sbaraglio, incaricandoti di fare un lavoro che non sei in grado di fare. Modificato: 20 febbraio 2023 da batta Link al commento Condividi su altri siti More sharing options...
batta Inserita: 20 febbraio 2023 Segnala Share Inserita: 20 febbraio 2023 Ho fatto un progettino di esempio. Ho generato un file sorgente che comprende il tipo di dati "DatiAsse" e i blocchi di programma. Copia il contenuto in un file di testo al quale metterai estensione .scl Dopo devi importare i sorgenti nella cartella "sorgenti esterne" del progetto TIA Portal Fatto questo, tasto destro sul file importati e "genera blocchi dalla sorgente". ATTENZIONE!!! Se esistono blocchi con lo stesso nome, verranno sovrascritti. Ti conviene fare queste operazioni in un progetto nuovo (che potrai provare anche con il simulatore), e dopo prendere ciò che ti serve e copiarlo nel tuo progetto. Non so che versioni stai utilizzando del TIA, quindi ho generato i sorgenti da TIA V16, oramai un po' vecchiotta, e che (quasi) tutti hanno. In ogni caso, i sorgenti vengono importati anche da versioni precedenti. Ho creato anche un DB con un array per l'asse x ed uno per l'asse y. I due array sono volutamente di dimensioni diverse, per farti vedere che la funzione che andrà a leggere i dati da questi array si adatta automaticamente alla dimensione dell'array che le viene passato come IN/OUT. In ogni elemento dell'array (sempre da assumere come esempio e nulla più) ho inserito la quota di destinazione e la velocità dell'asse, per farti vedere che con una sola istruzione copio la struttura completa, e non devo fare la copia variabile per variabile. Per finire, ho generato gli array con indice che parte da zero, ma tutto funzionerebbe anche se gli array partissero da un indice diverso. Spero ti possa servire. Eco il sorgente: TYPE "DatiAsse" VERSION : 0.1 STRUCT target : Real; speed : Real; END_STRUCT; END_TYPE FUNCTION "FC_LetturaArray" : Void { S7_Optimized_Access := 'TRUE' } VERSION : 0.1 VAR_INPUT restart : Bool; posReached : Bool; END_VAR VAR_OUTPUT target : "DatiAsse"; lastElementReached : Bool; END_VAR VAR_IN_OUT axisParametersArray : Array[*] of "DatiAsse"; id : DInt; xos : Bool; END_VAR VAR_TEMP firstElement : DInt; lastElement : DInt; i : Int; END_VAR BEGIN // Leggi dimensioni array #firstElement := LOWER_BOUND(ARR := #axisParametersArray, DIM := 1); #lastElement := UPPER_BOUND(ARR := #axisParametersArray, DIM := 1); // Su fronte salita "posizione raggiunta", incrementa indice IF #posReached AND #xos THEN #id += 1; // Incrementa indice di una unità END_IF; #xos := NOT #posReached; // Appoggio per fronte salita // Restart (reinizializza indice al primo elemento dell'array) IF #restart THEN #id := #firstElement; END_IF; // Correggi indice se è fuori range IF #id < #firstElement THEN #id := #firstElement; ELSIF #id > #lastElement THEN #id := #lastElement; END_IF; // Leggi target e velocità posizionamento da array #target := #axisParametersArray[#id]; // Segnalazione raggiunto limite massimo array #lastElementReached := #id >= #lastElement; END_FUNCTION DATA_BLOCK "DB_Ricetta" { S7_Optimized_Access := 'TRUE' } VERSION : 0.1 NON_RETAIN VAR RETAIN axis_x : Array[0..15] of "DatiAsse"; END_VAR VAR axis_y : Array[0..7] of "DatiAsse"; END_VAR BEGIN axis_x[0].target := 1000.0; axis_x[0].speed := 20.0; axis_x[1].target := 1010.0; axis_x[1].speed := 21.0; axis_x[2].target := 1020.0; axis_x[2].speed := 22.0; axis_x[3].target := 1030.0; axis_x[3].speed := 23.0; axis_x[4].target := 1040.0; axis_x[4].speed := 24.0; axis_x[5].target := 1050.0; axis_x[5].speed := 25.0; axis_x[6].target := 1060.0; axis_x[6].speed := 26.0; axis_x[7].target := 1070.0; axis_x[7].speed := 27.0; axis_x[8].target := 1080.0; axis_x[8].speed := 28.0; axis_x[9].target := 1090.0; axis_x[9].speed := 29.0; axis_x[10].target := 1100.0; axis_x[10].speed := 30.0; axis_x[11].target := 1110.0; axis_x[11].speed := 31.0; axis_x[12].target := 1120.0; axis_x[12].speed := 32.0; axis_x[13].target := 1130.0; axis_x[13].speed := 33.0; axis_x[14].target := 1140.0; axis_x[14].speed := 34.0; axis_x[15].target := 1150.0; axis_x[15].speed := 35.0; axis_y[0].target := 1000.0; axis_y[0].speed := 20.0; axis_y[1].target := 1010.0; axis_y[1].speed := 21.0; axis_y[2].target := 1020.0; axis_y[2].speed := 22.0; axis_y[3].target := 1030.0; axis_y[3].speed := 23.0; axis_y[4].target := 1040.0; axis_y[4].speed := 24.0; axis_y[5].target := 1050.0; axis_y[5].speed := 25.0; axis_y[6].target := 1060.0; axis_y[6].speed := 26.0; axis_y[7].target := 1070.0; axis_y[7].speed := 27.0; END_DATA_BLOCK FUNCTION_BLOCK "FB_Assi" { S7_Optimized_Access := 'TRUE' } VERSION : 0.1 VAR PB_Restart : Bool; posReached_x : Bool; posReached_y : Bool; lastElementReached_x : Bool; lastElementReached_y : Bool; END_VAR VAR RETAIN parameters_x : "DatiAsse"; parameters_y : "DatiAsse"; id_x : DInt; id_y : DInt; xos : Array[0..7] of Bool; END_VAR BEGIN // Lettura parametri da array asse x "FC_LetturaArray"(restart := #PB_Restart, posReached := #posReached_x, target => #parameters_x, lastElementReached => #lastElementReached_x, axisParametersArray := "DB_Ricetta".axis_x, id := #id_x, xos := #xos[0]); // Lettura parametri da array asse y "FC_LetturaArray"(restart := #PB_Restart, posReached := #posReached_y, target => #parameters_y, lastElementReached => #lastElementReached_y, axisParametersArray := "DB_Ricetta".axis_y, id := #id_y, xos := #xos[1]); END_FUNCTION_BLOCK DATA_BLOCK "DBI_Assi" { S7_Optimized_Access := 'TRUE' } VERSION : 0.1 NON_RETAIN "FB_Assi" BEGIN END_DATA_BLOCK ORGANIZATION_BLOCK "Main" TITLE = "Main Program Sweep (Cycle)" { S7_Optimized_Access := 'TRUE' } VERSION : 0.1 BEGIN "DBI_Assi"(); END_ORGANIZATION_BLOCK 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