albertid Inserito: 3 ottobre 2019 Segnala Share Inserito: 3 ottobre 2019 Buongiorno a tutti, mi scuso in anticipo perchè probabilmente è un quesito banale, ma non sono riuscito a trovare nulla a riguardo. Sto cercando di creare una funzione SCL dove in ingresso do un Byte di uscita, nella funzione vorrei recuperare l'indirizzo di questo byte per poter scrivere i byte consecutivi a quello (ho trovato qui sul forum che la funzione POKE potrebbe fare al caso mio per andare a scrivere conoscendo gli indirizzi). Qualcuno potrebbe illuminarmi la via? grazie mille Link al commento Condividi su altri siti More sharing options...
batta Inserita: 3 ottobre 2019 Segnala Share Inserita: 3 ottobre 2019 5 minuti fa, albertid scrisse: dove in ingresso do un Byte di uscita ??? Non mi è molto chiaro. Link al commento Condividi su altri siti More sharing options...
albertid Inserita: 3 ottobre 2019 Autore Segnala Share Inserita: 3 ottobre 2019 4 minuti fa, batta scrisse: ??? Non mi è molto chiaro. Intendo dire che io di quella variabile voglio solo ricavarne l'indirizzo, non voglio scriverla direttamente, nel mio caso è un byte Q, ma potrebbe essere un I, non credo ci siano grosse differenze, sbaglio? Link al commento Condividi su altri siti More sharing options...
max.bocca Inserita: 3 ottobre 2019 Segnala Share Inserita: 3 ottobre 2019 Gli ingressi sono 16#81, le uscite 16#82 le db 16#84 I comandi sono peek e poke. Link al commento Condividi su altri siti More sharing options...
albertid Inserita: 4 ottobre 2019 Autore Segnala Share Inserita: 4 ottobre 2019 14 ore fa, max.bocca scrisse: Gli ingressi sono 16#81, le uscite 16#82 le db 16#84 I comandi sono peek e poke. Grazie per la risposta, intendevo dire come recuperare l'indirizzo non come scrivere o leggere il valore. Piano piano ci sto arrivando leggendo la documentazione, passo l'indirizzo all'FC con una variabile di tipo Any, poi con la funzione FILL vado a scrivere il valore Link al commento Condividi su altri siti More sharing options...
batta Inserita: 4 ottobre 2019 Segnala Share Inserita: 4 ottobre 2019 Per lavorare con gli indirizzi, meglio se usi AWL. Però io farei un passo indietro: sei proprio sicuro che ti serva veramente leggere l'indirizzo? Se spieghi cosa devi fare, forse troviamo un'altra strada. Link al commento Condividi su altri siti More sharing options...
albertid Inserita: 4 ottobre 2019 Autore Segnala Share Inserita: 4 ottobre 2019 (modificato) 50 minuti fa, batta scrisse: Per lavorare con gli indirizzi, meglio se usi AWL. Però io farei un passo indietro: sei proprio sicuro che ti serva veramente leggere l'indirizzo? Se spieghi cosa devi fare, forse troviamo un'altra strada. Perchè consigli di utilizzare AWL? non l'ho mai usato, pensavo fosse SCL il "futuro", forse AWL è più a basso livello? Il mio obiettivo è scrivere una stringa dentro un dispositivo profinet, ho 16 Byte di uscita nei quali voglio scrivere una stringa di 16 char, i char "vuoti" devono essere settati a 0. Ho scritto questo codice che sembra funzionare, ma sono apertissimo a consigli. Grazie mille per il supporto FUNCTION "65007_ScriviByteConsecutivi" : Void { S7_Optimized_Access := 'FALSE' } VERSION : 0.1 VAR_INPUT Stringa : String; END_VAR VAR_IN_OUT IndirizzoAreaMemoria : Any; END_VAR VAR_TEMP StrLen : Int; i : Int; RetVal : Int; END_VAR VAR CONSTANT ArrayLength : Int := 16; Zero : Word := 16#0; END_VAR BEGIN #StrLen := LEN(#Stringa); FOR #i := 1 TO #ArrayLength DO IF #i > #StrLen THEN #Stringa[#i] := #Zero; END_IF; END_FOR; #RetVal := FILL(BVAL := #Stringa, //sorgente BLK => #IndirizzoAreaMemoria); //destinazione END_FUNCTION Questo è ad esempio l'area di memoria che passo alla variabile "IndirizzoAreaMemoria": P#Q1105.0 BYTE 16 Modificato: 4 ottobre 2019 da albertid Link al commento Condividi su altri siti More sharing options...
Livio Orsini Inserita: 4 ottobre 2019 Segnala Share Inserita: 4 ottobre 2019 33 minuti fa, albertid scrisse: pensavo fosse SCL il "futuro", forse AWL è più a basso livello? AWL può essere paragonato ad un linguaggio tipo assembler, mentre SCL è paragonabile ad un linguaggio come il "C". Con lo AWL sei più a contatto con la macchina. Link al commento Condividi su altri siti More sharing options...
albertid Inserita: 4 ottobre 2019 Autore Segnala Share Inserita: 4 ottobre 2019 38 minuti fa, Livio Orsini scrisse: AWL può essere paragonato ad un linguaggio tipo assembler, mentre SCL è paragonabile ad un linguaggio come il "C". Con lo AWL sei più a contatto con la macchina. Io infatti conoscendo un pochino di C, mi trovo più a mio agio con SCL, però capisco il consiglio di Batta Link al commento Condividi su altri siti More sharing options...
batta Inserita: 4 ottobre 2019 Segnala Share Inserita: 4 ottobre 2019 Il mio consiglio, a dire il vero, non è quello di usare awl, ma di cercare una strada, se possibile, che ti permetta di lavorare senza usare gli indirizzi. Per esempio, non capisco perché tu voglia passare l'indirizzo della variabile dove andrai a scrivere, e non direttamente la variabile. Poi dichiari la variabile Stringa come STRING. Ricorda che se nel tipo String non dichiari la lunghezza, viene impostata la lunghezza massima di 254 caratteri. La funzione FILL è in una cartella chiamata Legacy. Queste istruzioni sono presenti per mantenere la compatibilità con versioni precedenti ma, se possibile, meglio non usarle. Per lavorare con le stringhe, guarda piuttosto le funzioni dedicate. Per esempio, una funzione che ti potrebbe fare comodo è Str_TO_Chars. Ribadisco che non ho capito perché vuoi lavorare con l'indirizzo della variabile anziché direttamente con la variabile. Link al commento Condividi su altri siti More sharing options...
albertid Inserita: 7 ottobre 2019 Autore Segnala Share Inserita: 7 ottobre 2019 Ciao Batta, ho utilizzato l'indirizzo e non direttamente la variabile perchè le variabili che devo scrivere sono dei Byte di uscita di un dispositivo profinet. Ho 16 Byte di uscita, non una stringa, quindi per andare a scriverli dovrei andare a metterli nella mia funzione uno ad uno tutti e 16 (correggetemi se sbaglio) per questo ho pensato di puntare solo l'indirizzo del primo Byte e scrivere automaticamente quelli che vengono dopo. Condivido i dubbi sulla variabile di ingresso di tipo stringa, l'ho utilizzata perchè ancora non so bene quanti Byte andrò a scrivere, potrebbero essere anche 32, però hai ragione forse sarebbe meglio usare un array. Link al commento Condividi su altri siti More sharing options...
batta Inserita: 7 ottobre 2019 Segnala Share Inserita: 7 ottobre 2019 (modificato) 1 ora fa, albertid scrisse: Ho 16 Byte di uscita, non una stringa, quindi per andare a scriverli dovrei andare a metterli nella mia funzione uno ad uno tutti e 16 (correggetemi se sbaglio) Ti basta dichiarare i 16 byte come un array, e passi alla funzione tutto l'array. Anche nel caso questi 16 byte siano direttamente nell'area delle uscite, ti basta creare un Tipo di Dati che sia un array di 16 byte, e usarlo sia nella funzione, sia nella tabella delle variabili. 1 ora fa, albertid scrisse: forse sarebbe meglio usare un array Dipende da come componi la stringa. Se la imposti da un pannello operatore Siemens, dichiararla come String è la soluzione più comoda. Modificato: 7 ottobre 2019 da batta Link al commento Condividi su altri siti More sharing options...
albertid Inserita: 7 ottobre 2019 Autore Segnala Share Inserita: 7 ottobre 2019 33 minuti fa, batta scrisse: Ti basta dichiarare i 16 byte come un array, e passi alla funzione tutto l'array. Anche nel caso questi 16 byte siano direttamente nell'area delle uscite, ti basta creare un Tipo di Dati che sia un array di 16 byte, e usarlo sia nella funzione, sia nella tabella delle variabili. Grazie per il consiglio, avevo proceduto esattamente in questo modo, ma non so per quale motivo facendo così mi si è allungato il tempo di ciclo di 2ms (!!!) possibile che questo crei qualche noia alla comunicazione, rallentando il ciclo? io non ho saputo darmi una risposta Link al commento Condividi su altri siti More sharing options...
batta Inserita: 7 ottobre 2019 Segnala Share Inserita: 7 ottobre 2019 1 ora fa, albertid scrisse: possibile che questo crei qualche noia alla comunicazione, rallentando il ciclo? Non credo proprio. Anzi, dato che non utilizzando l'istruzione FILL si possono usare blocchi ottimizzati, dovrebbe essere più veloce. Una domanda: sei sicuro che sia corretto scrivere 00Hex nei byte corrispondenti ai caratteri vuoti della stringa? Te lo chiedo perché, di solito, se si lavora con caratteri e stringhe, il carattere vuoto non è 00Hex. 00Hex, tradotto in carattere, viene visualizzato come '$00'. Mi pare strano che il dispositivo dove vai a scrivere riceva dei caratteri, e voglia 00Hex per i caratteri vuoti. Qui sotto, solo per fare un esempio, ho implementato una funzione usando il tipo "Variant". In questo modo, la variabile INOUT potrebbe essere un array di char di dimensioni diverse. In realtà, nel caso specifico, dove la lunghezza è definita (16 caratteri) non ha senso complicarsi la vita con il formato Variant. È da prendere solo come esempio, buttato lì anche per far vedere l'uso di istruzioni di controllo come "IS_ARRAY", "CountOfElements", "TypeOfElements", ecc. FUNCTION_BLOCK "TestStringToArray" { S7_Optimized_Access := 'TRUE' } VERSION : 0.1 VAR_INPUT Stringa : String[32]; END_VAR VAR_IN_OUT ArrayOut : Variant; END_VAR VAR_TEMP Buffer : Array[1..#BufferElements] of Char; ArrayOutSize : UDInt; StrLen : Int; i : Int; RetVal : Int; END_VAR VAR CONSTANT BufferElements : Int := 254; END_VAR BEGIN // Esegui solo se la variabile passata come parametro è un array di Char IF IS_ARRAY(#ArrayOut) THEN IF TypeOfElements(#ArrayOut) = Char THEN // Leggi dimensione array variabile passata come parametro #ArrayOutSize := CountOfElements(#ArrayOut); // Leggi lunghezza effettiva stringa #StrLen := LEN(#Stringa); // Copia caratteri della stringa in "Buffer" (per caratteri vuoti, scrivere 00Hex) FOR #i := 1 TO UDINT_TO_INT((#ArrayOutSize)) DO IF #i <= #StrLen THEN #Buffer[#i] := #Stringa[#i]; ELSE #Buffer[#i] := b#16#00; END_IF; END_FOR; // Copia un numero di byte pari alla lunghezza della variabile da "Buffer" alla variabile #RetVal := MOVE_BLK_VARIANT(SRC := #Buffer, COUNT := #ArrayOutSize, SRC_INDEX := 0, DEST_INDEX := 0, DEST => #ArrayOut); END_IF; END_IF; END_FUNCTION_BLOCK Link al commento Condividi su altri siti More sharing options...
albertid Inserita: 7 ottobre 2019 Autore Segnala Share Inserita: 7 ottobre 2019 I byte del dispositivo (è una camera Cognex) di default contengono 0x0, se metto ad esempio uno spazio questo viene interpretato come tale (giustamente), ho pensato quindi di reimpostarli al valore che avevano per default in modo da non avere problemi. Grazie mille per l'esempio, mi sarà molto utile, ad un primo sguardo mi sembra proprio fare al caso mio. Link al commento Condividi su altri siti More sharing options...
batta Inserita: 7 ottobre 2019 Segnala Share Inserita: 7 ottobre 2019 5 ore fa, albertid scrisse: ad un primo sguardo mi sembra proprio fare al caso mio Ma se la dimensione dell'array da scrivere è fissa, ti conviene fare qualcosa di più semplice. Esempio: FUNCTION_BLOCK "Test" { S7_Optimized_Access := 'TRUE' } VERSION : 0.1 VAR_INPUT MyString : String[#ArrayDim] := 'abcdefghijklmnop'; END_VAR VAR_OUTPUT MyArray : Array[1..#ArrayDim] of Char; END_VAR VAR_TEMP StringLen : Int; i : Int; END_VAR VAR CONSTANT ArrayDim : Int := 16; END_VAR BEGIN #StringLen := LEN(#MyString); FOR #i := 1 TO #ArrayDim DO IF #i <= #StringLen THEN #MyArray[#i] := #MyString[#i]; ELSE #MyArray[#i] := '$00'; END_IF; END_FOR; END_FUNCTION_BLOCK Link al commento Condividi su altri siti More sharing options...
albertid Inserita: 8 ottobre 2019 Autore Segnala Share Inserita: 8 ottobre 2019 Grazie, non sapevo come si potessero dimensionare gli array con delle costanti in TIA Portal Link al commento Condividi su altri siti More sharing options...
batta Inserita: 8 ottobre 2019 Segnala Share Inserita: 8 ottobre 2019 1 ora fa, albertid scrisse: non sapevo come si potessero dimensionare gli array con delle costanti in TIA Portal In SCL si faceva già anche con il Simatic Manager. 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