marcob1984 Inserito: 10 febbraio 2015 Segnala Share Inserito: 10 febbraio 2015 (modificato) Buongiorno a tutti, ho sempre trovato le risposte che cercavo ma questa volta richiedo il vostro aiuto perchè non sono a riuscito a trovare una soluzione al mio "problema". In parte è spiegata qui http://www.plcforum....li-locali-fc/#1,manon del tutto. Mi spiego: ho un impianto da automatizzare composto da 6 motori con inverter ABB e scheda RPBA01 (profibusDP) tutti uguali. Ho la necessità quindi, di creare un FB univoco per tutti i motori e ad ogni motore associo una DB di istanza diversa. La logica di comando in profibus per questi motori necessita di 2 word di lettura (che chiameremo: StatusWord e RD_SpdRef) e 2 word di scrittura (che chiameremo ControlWord e WR_SpdRef) che opportunamente lette/scritte mi fanno lo start/stop/riferimento velocità. Il mio "problema" è che se nell'FB dichiaro così le variabili: IN: StatusWord TYPE: Word OUT: ControlWord TYPE: Word quando devo scrivere il codice non riesco a puntare i singoli bits che mi servono. Per fare funzionare il tutto, devo dichiarare le variabili splittate (quindi bit per bit). Qualcuno sa aiutarmi? PS: appoggiando tali word in variabili TEMP (es: L #StatusWord T LW0 L LW2 T #ControlWord) non posso richiamare simultaneamente 2 o più blocchi FB altrimenti le variabili locali vengono sovrascritte e succede un casino Grazie . Modificato: 10 febbraio 2015 da Giuseppe Signorella Completata discussione con parte del testo mancante Link al commento Condividi su altri siti More sharing options...
batta Inserita: 10 febbraio 2015 Segnala Share Inserita: 10 febbraio 2015 Sbaglio, o manca la domanda? Link al commento Condividi su altri siti More sharing options...
JumpMan Inserita: 10 febbraio 2015 Segnala Share Inserita: 10 febbraio 2015 (modificato) L #StatusWord T LW0 L LW2 T #ControlWord)non posso richiamare simultaneamente 2 o più blocchi FB altrimenti le variabili locali vengono sovrascritte e succede un casino Non è vero che succede un casino Bisogna avere qualche accortezza: L #StatusWordT LW0 L ControlWord T LW2 Queste sopra devono essere le prime istruzioni dell'FB Dopodichè puoi interrogare i bit L0.0 - L1.7 ed è come se interrogassi i bit della #StatusWord Nei vari segmenti dell'FB puoi settare o resettare i bit di LW2 Alla fine dell'FB riscrivi la controlword: L LW2 T #ControlWord Devo dire però che non amo molto questo sistema perchè basta poco per far casini... devi essere sicuro che non sposti le Word locali perchè poi le vai a interrogare a bit in maniera assoluta. Però ammetto che qualche volta non ho avuto il tempo di far fiorellini e l'ho usato (tra l'altro credo proprio in una circostanza simile) ========================================================================================================================== Un altro modo è quello di interrogare direttamente i bit della DB d'istanza, la apri nell'editor, controlli l'indirizzo della #StatusWord e della #ControlWord, supponiamo siano 10.0 e 20.0, nell'FB interrogherai i bits DIX10.0-11.7 per la status e scriverai nei bits DIX20.0-21.7 per la control. Ma questo sistema mi piace ancora meno ! ========================================================================================================================== Il modo più elegante, più sicuro e corretto è quello di usare i puntatori: L P##StatusWord LAR1 U DIX [AR1,P#1.0] // interroga il 1° bit (quello meno significativo) della status word L P##ControlWord LAR1 = DIX [AR1,P#0.7] // Imposta il 16° bit (quello più significativo) della status word Modificato: 10 febbraio 2015 da JumpMan Link al commento Condividi su altri siti More sharing options...
marcob1984 Inserita: 11 febbraio 2015 Autore Segnala Share Inserita: 11 febbraio 2015 Batta: hai ragione, ero di fretta ed è ho dimenticato di formulare esplicitamente la domanda. Comuque la risposta di JumpMan ha centrato l'obiettivo. Scusatemi ancora. Adesso provo e poi vi faccio sapere. Grazie mille. Link al commento Condividi su altri siti More sharing options...
STEU Inserita: 11 febbraio 2015 Segnala Share Inserita: 11 febbraio 2015 (modificato) Jumpman ma con l' offset P#1.0 dell' istruzione: U DIX[AR1,P#1.0] vado ad interrogare il bit 0 del byte più significativo, quindi l'ottavo bit e non quello meno significativo. giusto? Modificato: 11 febbraio 2015 da STEU Link al commento Condividi su altri siti More sharing options...
JumpMan Inserita: 11 febbraio 2015 Segnala Share Inserita: 11 febbraio 2015 (modificato) La domanda l'ho intuita dal titolo... vado ad interrogare il bit 0 del byte più significativo, quindi l'ottavo bit e non quello meno significativo. giusto? No, nel Siemens i bytes sono swappati. Se hai dubbi fai questa prova, vai in stato variabili: nella riga 1 scrivi MW100 con visualizzazione intera nella riga 2 scrivi MW100 con visualizzazione binaria nella riga 3 metti M100.0 nella riga 4 metti M101.0 Ora attiva lo stato e forza MW100 = 1 (intero) nella prima riga Modificato: 11 febbraio 2015 da JumpMan Link al commento Condividi su altri siti More sharing options...
STEU Inserita: 11 febbraio 2015 Segnala Share Inserita: 11 febbraio 2015 Lo so che sono "swappati" infatti esistono le istruzioni TAW e TAD proprio per questo. Se però carichi il valore del puntatore L ##StatusWord e StatusWord è il primo parametro di ingresso dell' FB in AR1 carici il "valore" DI 0.0 quindi U DIX[AR1, P#1.0] è rindondante bastava scrivere U [AR1, P1.0] però se nel puntatore AR1 carichi il valore DI 0.0 (praticamente Link al commento Condividi su altri siti More sharing options...
batta Inserita: 11 febbraio 2015 Segnala Share Inserita: 11 febbraio 2015 C'è anche un sistema che richiede un piccolo lavoro in più ma che, a mio avviso, rende il codice molto più comprensibile, perché permette di assegnare un nome ad ogni singolo bit della status word e della control word. Esempio: FUNCTION "ProvaPuntatori" : VOID TITLE = VERSION : 0.1 VAR_INPUT StatusWord : WORD ; END_VAR VAR_OUTPUT CtrlWord : WORD ; END_VAR VAR_TEMP tmpSTW : STRUCT bit_08 : BOOL ; bit_09 : BOOL ; bit_10 : BOOL ; bit_11 : BOOL ; bit_12 : BOOL ; bit_13 : BOOL ; bit_14 : BOOL ; bit_15 : BOOL ; bit_00 : BOOL ; bit_01 : BOOL ; bit_02 : BOOL ; bit_03 : BOOL ; bit_04 : BOOL ; bit_05 : BOOL ; bit_06 : BOOL ; bit_07 : BOOL ; END_STRUCT ; tmpCTW : STRUCT bit_08 : BOOL ; bit_09 : BOOL ; bit_10 : BOOL ; bit_11 : BOOL ; bit_12 : BOOL ; bit_13 : BOOL ; bit_14 : BOOL ; bit_15 : BOOL ; bit_00 : BOOL ; bit_01 : BOOL ; bit_02 : BOOL ; bit_03 : BOOL ; bit_04 : BOOL ; bit_05 : BOOL ; bit_06 : BOOL ; bit_07 : BOOL ; END_STRUCT ; END_VAR BEGIN NETWORK TITLE = //Appoggio valore della Status Word su variabile locale LAR1 P##tmpSTW; L #StatusWord; T LW [AR1,P#0.0]; //Qui puoi interrogare i singoli bit dichiarati nella struttura "tmpSTW" //Puoi assegnare lo stato desiderato ai singoli bit della struttura "tmpCTW" //Scrittura dello stato dei singoli bit nella Control Word LAR1 P##tmpCTW; L LW [AR1,P#0.0]; T #CtrlWord; END_FUNCTION Link al commento Condividi su altri siti More sharing options...
STEU Inserita: 11 febbraio 2015 Segnala Share Inserita: 11 febbraio 2015 scasate il post precedente ma l'ho inviato per errore prima che finissi di scriverlo tutto Link al commento Condividi su altri siti More sharing options...
STEU Inserita: 11 febbraio 2015 Segnala Share Inserita: 11 febbraio 2015 Lo so che sono "swappati" infatti esistono le istruzioni TAW e TAD proprio per questo.Se però carichi il valore del puntatore L ##StatusWorde StatusWord è il primo parametro di ingresso dell' FBin AR1 carici il "valore" DI 0.0quindi U DIX[AR1, P#1.0] è rindondantebastava scrivere U [AR1, P#1.0]Inoltre prova il sorgente qui sotto e vedrai che l'uscita A0.0 va a 1 quando forzi a 1 M1.0 FUNCTION_BLOCK FB 1TITLE =VERSION : 0.1VAR_INPUTstatusword : WORD ;END_VARVAR_OUTPUTcontrolword : WORD ;END_VARBEGINNETWORKTITLE =L P##statusword;LAR1 ;U [AR1,P#1.0];= A 0.0;END_FUNCTION_BLOCKDATA_BLOCK DB 1TITLE =VERSION : 0.0FB 1BEGINstatusword := W#16#0;controlword := W#16#0;END_DATA_BLOCKORGANIZATION_BLOCK OB 1TITLE = "Main Program Sweep (Cycle)"VERSION : 0.1VAR_TEMPOB1_EV_CLASS : BYTE ; //Bits 0-3 = 1 (Coming event), Bits 4-7 = 1 (Event class 1)OB1_SCAN_1 : BYTE ; //1 (Cold restart scan 1 of OB 1), 3 (Scan 2-n of OB 1)OB1_PRIORITY : BYTE ; //Priority of OB ExecutionOB1_OB_NUMBR : BYTE ; //1 (Organization block 1, OB1)OB1_RESERVED_1 : BYTE ; //Reserved for systemOB1_RESERVED_2 : BYTE ; //Reserved for systemOB1_PREV_CYCLE : INT ; //Cycle time of previous OB1 scan (milliseconds)OB1_MIN_CYCLE : INT ; //Minimum cycle time of OB1 (milliseconds)OB1_MAX_CYCLE : INT ; //Maximum cycle time of OB1 (milliseconds)OB1_DATE_TIME : DATE_AND_TIME ; //Date and time OB1 startedEND_VARBEGINNETWORKTITLE =CALL FB 1 , DB 1 (statusword := MW 0,controlword := MW 50);END_ORGANIZATION_BLOCK Link al commento Condividi su altri siti More sharing options...
marcob1984 Inserita: 11 febbraio 2015 Autore Segnala Share Inserita: 11 febbraio 2015 Batta, come sempre hai azzeccato alla grande e mi hai risolto il problema. Ho provato e funziona. Ed è proprio un lavoro pulito pulito, come volevo io, perchè si riesce ad nominare bit per bit. Io di solito programmo l'800xA di ABB ed ha già in libreria una funzione che splitta la word in bit singoli. L'idea del tuo codice ce l'avevo in testa, ma non riuscivo a buttarla giù, perchè mi mancava il passaggio di dichiarazione delle 2 word come strutture. Alla fine la soluzione alternativa l'avevo trovata (evitare le word locali nell'FB, e dichiarare tutti i parametri d'ingresso e uscita booleani che mi servivano), ma tua soluzione è di gran lunga più elegante e pulita. Grazie mille a tutti voi, siete sempre un libro aperto, perchè ho imparato di più leggendo le vostre discussioni che non i manuali dell'S7 300. Link al commento Condividi su altri siti More sharing options...
JumpMan Inserita: 11 febbraio 2015 Segnala Share Inserita: 11 febbraio 2015 (modificato) quindi U DIX[AR1, P#1.0] è rindondantebastava scrivere U [AR1, P#1.0] Hai ragione, mi è sfuggito, funziona lo stesso ma è meglio senza DIX e anche L P##StatusWordLAR1 Si possono ridurre a: LAR1 P##StatusWord Inoltre prova il sorgente qui sotto e vedrai che l'uscita A0.0 va a 1 quando forzi a 1 M1.0 è ovvio che l'offset ,P#1.0 riferito a MW0 va a puntare sul bit M1.0 ci mancherebbe altrimenti diventeremmo scemi ma..... DIX [AR1,P#1.0] // interroga il 1° bit (quello meno significativo) della status word .... la status Word è composta da 16 bit e ribadisco che P#1.0 punta al 1° bit (quello meno significativo) della status word Se la status Word la visualizzi in esadecimale e la imposti = W#16#0001 quel bit andrà a 1 ! Comunque il codice di Batta è elegante e leggibile, è il miglior modo per risolvere il problema Modificato: 11 febbraio 2015 da JumpMan 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