Frank681 Inserito: 7 aprile 2015 Segnala Share Inserito: 7 aprile 2015 Salve Dovre spostare dei valori da un puntatore di 48 dw in memoria a delle struct composte da 48 dword in un db , tutto questo devo ripeterlo x 20 volte e' possibile fare un fb in scl ? Mi date un indizio che poi lo sviluppo.. Grazie mille Link al commento Condividi su altri siti More sharing options...
batta Inserita: 7 aprile 2015 Segnala Share Inserita: 7 aprile 2015 (modificato) Puoi usare l'istruzione MOVE. Questa istruzione non copia solo byte, word e dword, ma anche timer, counter, stringhe, array e strutture. Unica cosa importante è che l'area sorgente e quella di destinazione devono essere identiche, ovvero non basta che abbiano la stessa dimensione, ma devono avere anche la stessa identica struttura. Ora non ho ben capito cosa tu intenda con "memorizzare dei valori 48 dword di un puntatore in memoria" ma, se queste 48 dword possono essere dichiarate all'interno di una STRUCT, ti basta dichiarare come area di destinazione un array di 20 STRUCT identiche a quella sorgente. Nell'istruzione MOVE, in uscita, puoi usare all'interno delle parentesi quadre una variabile (di tipo INT o DINT) con la quale vai ad indicare in quale struttura dell'array scrivere. Modificato: 7 aprile 2015 da batta Link al commento Condividi su altri siti More sharing options...
STEU Inserita: 7 aprile 2015 Segnala Share Inserita: 7 aprile 2015 potresti fare un un esempio? devi spostare 48 DW da un db ad altri 20? non ho capito bene il tuo problema Link al commento Condividi su altri siti More sharing options...
Frank681 Inserita: 7 aprile 2015 Autore Segnala Share Inserita: 7 aprile 2015 Ciao STEU Chiedo aiuto poiché e' la prima volta che lavoro con i puntatori Leggo dei valori da degli strumenti modbus tcp ( ne ho 20 ) , ogni strumento mi restituisce i valori in un puntatore P#M1000.0 DWROD 120 , vorrei alla fine della lettura spostare i valori delle variabili , in una struct di un db , parlo di 20 perché; ho 20 strumenti che mi restituiscono i valori nello stesso puntatore per cui prima di passare alla lettura successiva devo salvare i valori letti nel db . Spero di essere stato chiaro , e mi scuso per la confusione Link al commento Condividi su altri siti More sharing options...
STEU Inserita: 7 aprile 2015 Segnala Share Inserita: 7 aprile 2015 Scusami ma non ho capito moltissimo,comunque esiste sfc 20 "Blockmove" , che ti copia il i valori dal parametro dove vuoi tuCALL "BLKMOV"SRCBLK :=P#M 100.0 DWORD 150RET_VAL:=MW10DSTBLK :=P#DB10.DBX 0.0 DWORD 150la risposta mi sembra troppo facile per aver capito esattamente cosa vuoi. Link al commento Condividi su altri siti More sharing options...
STEU Inserita: 7 aprile 2015 Segnala Share Inserita: 7 aprile 2015 scusa mi sono accorto adesso che e un 1200,e quindi awl non è permesso, e non so se questo blocco di sistema è presente in quel PLC. Link al commento Condividi su altri siti More sharing options...
Frank681 Inserita: 7 aprile 2015 Autore Segnala Share Inserita: 7 aprile 2015 (modificato) Infatti Amche nel 1200 esiste un bloc_move ma mi Sto arrivando! Diverso Forse trovato usando poke_move , devo verificare esattamente i settaggi e gli offset fatte prove al volo su cpu di test ok , domani provo su cpu di progetto. Modificato: 7 aprile 2015 da Frank681 Link al commento Condividi su altri siti More sharing options...
Frank681 Inserita: 7 aprile 2015 Autore Segnala Share Inserita: 7 aprile 2015 (modificato) Ciao Batta Le variabile che leggo via modbus TCP , sono di tipo Real , ho provato a memorizzarle direttamente nel DB ma non mi funziona , per fare delle prove ho provato a leggere i dati con CAS modbus scanner e ho notato una cosa strana , leggo gli indirizzi 40001 ma il primo valore Real è nel registro 40002 , à normale ? Chiedo poichè non ho mai letto direttamente le dword . Può essere per questo che se provo a memorizzare i dati direttamente nell struct del db ho valori incomprensibili . Ho paura che ci sia uno sfasamento nella lettura , domani provo a leggere il registro 40002 e vedere se i dati si allineano . La cosa mi è poco chiara... forse trovato usando poke_move devo verificare i settaggi da effettuare Modificato: 7 aprile 2015 da Frank681 Link al commento Condividi su altri siti More sharing options...
batta Inserita: 8 aprile 2015 Segnala Share Inserita: 8 aprile 2015 leggo gli indirizzi 40001 ma il primo valore Real è nel registro 40002 , à normale ? I registri Modbus sono a 16 bit (2 byte). Una REAL è composta da 4 byte. Una REAL quindi occupa due registri. Forse devi scambiare tra loro i registri 40001 e 40002. Per quanto riguarda poi la copia delle 48 variabili dall'area in cui vengono depositate dalla funzione MB_MASTER, devi solo procedere come ti ho indicato nel precedente post. Per fare questo, devi apportare una piccola modifica: anziché depositare i registri letti nell'area di memoria M (P#M1000.0 DWROD 120), utilizzi un DB. Il DB in questione deve essere "non ottimizzato" (tasto destro sul DB --> Proprietà --> Attributi --> Togli il segno di spunta da "accesso ottimizzato al blocco"). In questo DB crei una STRUCT con le tue 48 REAL. Nel DB dove andrai a scrivere i dati di ogni singolo strumento crei un ARRAY di 20 STRUCT identiche (potresti anche creare un "Tipo di dati" da usare in entrambi i DB). Poi ti basta usare l'istruzione MOVE, con un indice per indicare in quale struttura dell'array andare a scrivere. In base al numero di nodo dal quale hai appena fatto la lettura dei registri, imposti questo indice ed hai già risolto, senza complicarti la vita con poke ed altro. Link al commento Condividi su altri siti More sharing options...
Frank681 Inserita: 8 aprile 2015 Autore Segnala Share Inserita: 8 aprile 2015 Grazie Batta Provo e ti faccio sapere , infatti ho sperimentato la scrittura diretta in un DB partendo da 40002 e funziona ora devo solo capire la lunghezza da leggere che dipende dagli strumenti. Grazie mille Link al commento Condividi su altri siti More sharing options...
Frank681 Inserita: 8 aprile 2015 Autore Segnala Share Inserita: 8 aprile 2015 Ciao Batta Ho provato ad usare un db , non ottimizzato con dentro le struct che mi servono e la seguente procedura di lettura modbus ma i dati nelle struct mi cambiano sempre ad ogni lettura . Ho provato a cambiare MB_UNIT_ID del db di istanza per puntare ad ogni singolo slave TCP poiché ne ho piu' di uno con lo steppo indirizzo IP uso il done e error per avanzare , il segnmento che vedi e' una lettura per ogni lettura cambio MB_UNIT_ID e struct dove scrivere , ma si influenzano .... Dove sbaglio ? Link al commento Condividi su altri siti More sharing options...
batta Inserita: 9 aprile 2015 Segnala Share Inserita: 9 aprile 2015 A quanto vedo tu stai trasferendo 67 registri letti dallo strumento con indirizzo IP 192.168.1.110 in "MOD_TCP_PARK".GEN Non capisco perché l'indirizzo IP sia fisso e non capisco perché tu vada a caricare un valore in "MB_CLIENT".MB_UNIT_ID. Dalla guida in linea: Un server Modbus TCP viene indirizzato dall'indirizzo IP. Per questo motivo il parametro MB_UNIT_ID non viene utilizzato per l'indirizzamento Modbus TCP. Quindi per puntare ai diversi strumenti non devi modificare MB_UNIT_ID ma l'indirizzo IP (a meno che tu non stia usando un qualche gateway per comunicare in MODBUS RTU). Per quanto riguarda il DB non ottimizzato (e qui penso di aver detto una cavolata, perché sono quasi sicuro che potrebbe anche essere ottimizzato) mi riferivo al DB dove vai ad appoggiare i dati letti, ovvero "MOD_TCP_PARK".GEN In questo DB, GEN dovrebbe essere una struttura di dimensioni adatte a contenere il numero più alto di registri letti da uno strumento (non so se leggi lo stesso numero di registri da ogni strumento. Se torniamo al discorso delle 48 REAL, i registri dovrebbero essere 96). Poi dovrai fare un altro DB (ma potrebbe anche essere lo stesso DB) con un array di 20 strutture identiche a GEN. A seconda del ciclo di lettura MODBUS completato, copierai i dati parcheggiati in "MOD_TCP_PARK".GEN nell'area definitiva impostando opportunamente l'indice dell'array. Link al commento Condividi su altri siti More sharing options...
Frank681 Inserita: 10 aprile 2015 Autore Segnala Share Inserita: 10 aprile 2015 Ciao Batta In effetti il GAVAZZI VMUC-EM è un accentratore concentratore gateway , a cui sono collegati gli strumenti in RTU , lo "SCATOLOTTO" me li rende disponibili in TCP , per cui ho piu' slave TCP da leggere tramite un unico IP , cambiando il valore MB_UNIT_ID , trovato nel manuale di sistema del 1200 pag 759. Mi permane il problema che mi cambiano tutti i dati . Fatto prove assegnando ad ogni MB_UNIT_ID un MB_CLIENT con db di istanza diversa e un CONNECT_ID diverso , ora tutto funziona , ma se faccio cosi' per 20 strumenti saturo le connessioni del PLC. qualche suggerimento Usando un gateway , devo programmare in modo diverso ? Link al commento Condividi su altri siti More sharing options...
batta Inserita: 10 aprile 2015 Segnala Share Inserita: 10 aprile 2015 Mi permane il problema che mi cambiano tutti i dati . Non capisco cosa intendi. Cambiando il numero di nodo (MB_UNIT_ID) dovresti leggere i dati dallo strumento interessato. Questi dati vengono scritti dalla funzione MB_CLIENT in "MOD_TCP_PARK".GEN. Ovviamente, ad ogni ciclo di lettura in "MOD_TCP_PARK".GEN troverai dati diversi perché è cambiato lo strumento dal quale sono stati letti. Alla fine della lettura, prima di iniziare la lettura successiva, dovrai copiare i dati dall'area di "parcheggio" "MOD_TCP_PARK".GEN nell'area definitiva utilizzando l'istruzione MOVE. Oppure, se devi leggere valori da strumenti con numero di nodo da 1 a 20 potresti creare un DB con un array di 20 strutture (array[1..20]of struct) con le variabili di cui hai bisogno. I dati letti da MB_CLIENT li potresti scrivere direttamente nella struttura desiderata, collegando al parametro MD_DATA_PTR la struttura con tanto di indice dell'array (esempio: "DB_ProvaModbus".Strumento[#id]). Non ti serve nemmeno usare l'istruzione MOVE. Il DB credo debba essere di tipo "non ottimizzato", ma non ne sono del tutto sicuro. Link al commento Condividi su altri siti More sharing options...
Frank681 Inserita: 10 aprile 2015 Autore Segnala Share Inserita: 10 aprile 2015 Ciao Batta Confermo il db non vuole ottimizzato il mio problema e che anche se copio i dati con il move dalla struct di parcheggio alla struct del DB definitivo con il done della lettura , alla lettura sucessiva con MB|_UNIT_ID divers oi dati mi cambiano tutti nel db definitivo non so come far si che i dati vengano copiati una sola volta dalla zona di parcheggio al db definitivo . per ogni diverso MV_UNIT_ID nel db definitivo mi cambiano tutti i dati Link al commento Condividi su altri siti More sharing options...
batta Inserita: 10 aprile 2015 Segnala Share Inserita: 10 aprile 2015 Per darti indicazioni dovrei vedere tutto il codice. Comunque, puoi sempre eseguire il MOVE su un fronte di salita. Link al commento Condividi su altri siti More sharing options...
Frank681 Inserita: 11 aprile 2015 Autore Segnala Share Inserita: 11 aprile 2015 Ciao BAtta Provato niente da fare , se vuoi posso fare upload del codice che mi da problemi , lo sto testando anche su una cpu di scorta Link al commento Condividi su altri siti More sharing options...
batta Inserita: 11 aprile 2015 Segnala Share Inserita: 11 aprile 2015 Me lo puoi inviare anche per e-mail. Gli darò di sicuro un'occhiata. Link al commento Condividi su altri siti More sharing options...
walterword Inserita: 11 aprile 2015 Segnala Share Inserita: 11 aprile 2015 (modificato) il problema e ' che stai sovrascrivendo i dati ad ogni ciclo O usi dei fronti di salita per fare le operazioni solo una volta sola oppure usi dei bit di memoria tipo macchina a stati finiti per tenere traccia di cosa stai facendo e di cosa devi fare Se la comunicazione e' asincrona basta che guardi bene cosa fai quando leggi i dati e dove li metti , se invece e' sincrona puo darsi che mentre stai salvando i dati da qualche parte , la comunicazione te li sovrascrive .Ma comunque queste comunicazioni sono del tipo asincrono per cui usa dei bit per tenere traccia delle operazioni da fare e per sincronizzare un po il tutto Per i puntatori ne puoi usare migliaia , asta che siano varaibili DWORD , l'accesso e' piu lento rispetto ai registri della cpu dedicati ma non importa .Puoi copiare quindi il contenuto di un puntatore su variabili globali , usane altri e poi ripescarli Modificato: 11 aprile 2015 da walterword Link al commento Condividi su altri siti More sharing options...
Frank681 Inserita: 11 aprile 2015 Autore Segnala Share Inserita: 11 aprile 2015 Ciao walterword Le operazioni le faccio solo se ho un indice che vado ad incrementare quando ho il done della lettura , ma niente da fare , quando ho il done faccio il move della struct dal db di parcheggio a quello definitivo ma niente da fare.. non so dove sbaglio Link al commento Condividi su altri siti More sharing options...
batta Inserita: 11 aprile 2015 Segnala Share Inserita: 11 aprile 2015 Per ora ho dato solo un'occhiata veloce al codice che mi hai inviato. Ho subito notato un piccolo errore: la struttura dove vai a scrivere i dati è formata da 34 REAL, ma tu leggi solo 67 registri (che sono da 16 bit). Ne manca uno. Non è comunque questo il problema. Mi lascia molto perplesso piuttosto il fatto che a REQ hai linkato un TRUE. Praticamente cambi al volo il nodo, senza mai interrompere un ciclo di lettura. Non ne sono completamente sicuro ma, secondo me, potrebbe essere questa l'origine del problema. Di certo è difficile capire quando il DONE è veritiero. Non capisco poi come tu riesca ad incrementare l'indice dello strumento dal quale leggere i dati. Io ho visto scritture in questa variabile solo se viene rilevato un errore, mai nel caso di lettura ok (DONE). Domani o lunedì, se trovo un po' di tempo, provo a buttare giù un esempio di come farei io. Link al commento Condividi su altri siti More sharing options...
walterword Inserita: 12 aprile 2015 Segnala Share Inserita: 12 aprile 2015 il done lo resetti tu ? o si resetta da solo? Link al commento Condividi su altri siti More sharing options...
Frank681 Inserita: 12 aprile 2015 Autore Segnala Share Inserita: 12 aprile 2015 Ciao Batta Hai ragione nel cancellare ho cancellato troppo , nel segmento 4 vi era anche il move dell'indice. Il done va via da solo poichè quando ho il done cambio indice , all'inizio avevo provato anche il REQ con l'eguaglianza dell'indice ma il problema persiste.. Grazie mille Link al commento Condividi su altri siti More sharing options...
batta Inserita: 13 aprile 2015 Segnala Share Inserita: 13 aprile 2015 Hai provato l'esempio che ti ho inviato? Link al commento Condividi su altri siti More sharing options...
Giuseppe Signorella Inserita: 13 aprile 2015 Segnala Share Inserita: 13 aprile 2015 (modificato) Hai provato l'esempio che ti ho inviato? Perchè non condividerlo sul forum, e due parole pse spiegarlo? Modificato: 13 aprile 2015 da Giuseppe Signorella 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