Vai al contenuto
PLC Forum


S7-200 - Utilizzo le librerie utente


sfinge

Messaggi consigliati

Salve a tutti ho un quesito da porvi.

Vediamo se riesco a farmi capire..

Sto effettuando alcune prove di utilizzo delle biblioteche utente provando cosi' a creare dei blocchi da poter importare in altri progetti.

Ho fatto una prova costruendomi un blocco che all'interno utilizza la funzione bgn_time e cal_time per andare a accendre e spegnere un'uscita a tempo (per esempio 0,5s on 0,5s off).

Vi è un'ingresso di start (IN) un'uscita (OUT) il valore di preload timer (IN).Il blocco importandolo da un'altro progetto funziona perfettamente anche modificando il valore di preload.

Quando vado ad inserire 2 blocchi identici all'interno del MAIN si blocca tutto (naturalmente con parameto d'uscita diverso).

Non capisco davvero dove sbaglio visto che all'interno vengono usate variabili di tipo temporale (percui non dovrebbero esservi conflitti).

Ho scaricato una libreria dal sito S7-200.NET (la timer) e in questo caso invece impiantando il blocco TP si ha la possibilità di lavorare anche con 4-5 blocchi dello stesso tipo richiamati dal main (con uscite diverse naturalmente)e tutte le uscite funzionano perfettamente anche con tempi di clock diversi l'una dall'altra.

Non capisco davvero cosa vi è di diverso o quale sistema viene utilizzato.

Qualcuno puo' aiutarmi??Sarei molto grato!

Ciao a tutti e buon lavoro.

Link al commento
Condividi su altri siti


Credo tu abbia dimenticato qualche parametro...

Le funzioni bgn_itime e cal_itime necessitano di 2 dword:

- una dword per la memorizzazione dell’ istante in cui parte il timer (bgn_itime)

- una dword per il calcolo del tempo trascorso (cal_itime)

Poi ti serve una dword con il tuo “preload” o soglia di impostazione del timer (e questa l’hai messa, spero però che tu abbia usato una dword).

Altre avvertenze:

bgn_itime devi lanciarlo con un fronte, non ciclarlo sempre.

Il controllo del tempo trascorso devi realizzarlo con un confronto tra il “preload” e la DWORD che esce da “cal_itime”

Ricapitolando, in OB1 quando lanci la tua SBR devi passare:

1 bit (IN) per lo start del timer

2 DWORD (IN/OUT) di appoggio per il controllo del tempo iniziale e trascorso

1 DWORD (IN) per il setpoint del timer

1 bit (OUT) per l’uscita del timer.

Link al commento
Condividi su altri siti

  • 2 weeks later...

Ciao JumpMan

grazie della risposta e scusami se ho avuto tempo soltanto adesso di risponderti ma sono stato parecchio impegnato.Adesso ho un po di tempo libero e ho ripreso le prove con le librerie utente.

Ho seguito il tuo consiglio alla lettera ma purtroppo si ripete il fenomeno di prima, ovvero:

Se inserisco nel Main un blocco soltanto creato precedentemente con le librerie utente, il blocco funziona perfettamente.Se ne inserisco 2 si blocca il tutto. (naturalmente i due blocchi anno parametri con indirizzi diversi)Mi piacerebbe inviarti il file per fartelo esaminare.Come faccio ad inviartelo??Adesso provo ad iserirtelo in allegati!

Ciao e grazie della disponibilità!

Link al commento
Condividi su altri siti

Se non ho capito male hai creato un blocco con variabili locali e questo blocco è stato poi messo in una libreria che puoi facilmente richiamere dell'albero delle istruzione di MICROWIN, a me è capitata una cosa simile alla tua alcune variabili che erano dichiarate come tipo in ingresso "IN" le ho dovute mettere come "INOUT" anche se comunque erano degli ingressi del mio blocco.

Me ne sono accorto quando andavo in stato di esecuzione mi andavano in errore.

Non so se sia il tuo caso del tuo problema , io sono andato matto mezza giornata e poi con un pò di C..O l'ho trovato.

Ciao

Link al commento
Condividi su altri siti

Salve a tutti!

Forse non mi sono spiegato bene...

Il problema non è sul singolo blocco che se impiantato nel Main funziona perfettamente.

Il problema insorge quando inserisco nel Main + di un blocco (ad esempio 2)con parametri aventi indirizzi

diversi naturalmente. Si blocca tutto come se vi fosse un'interferenza fra le variabili locali dei 2 blocchi.

L'indirizzamento secondo me è esatto come consigliatomi da Jump Man.

Sono riuscito a far funzionare due blocchi contemporaneamente che hanno la funzione di temporizzatore come i TON risoluz. 1Ms che però internamente hanno soltanto una operazione bgn_itime call_itime.

Ho notato che se all'interno vi è più di una operazione bgn_itime call_itime mi da questo problema.

Non vi è nessuno che può aiutarmi (eventualmente posso mandare un'esempio)?.

Vorrei proprio capire dove sbaglio o se oppure, la cosa non è fattibile.

Ciao Grazie!

Link al commento
Condividi su altri siti

Prova a fare File>Esporta: “tuo_programma.awl” (sul desktop)

Poi apri “tuo_programma.awl” (sul desktop) con notepad, seleziona tutto, copia e incolla qui sul forum....

Link al commento
Condividi su altri siti

Ciao a tutti!

Ecco il listato del blocco in oggetto.

Se impiantato una sola volta nel Main e fatto girare funziona perfettamente.

Se impiantato due volte con parametri aventi indirizzi differenti naturalmente,sia il primo blocco

che il secondo blocco non funzionano piu'. Io non so più che pesci pigliare.

Secondo voi perchè accade questo? Quale è la soluzione?

Ciao a tutti e grazie per l'attenzione!

SUBROUTINE_BLOCK PULSE:SBR3

TITLE=COMMENTI SUL SOTTOPROGRAMMA

VAR_INPUT

Enable:BOOL;

PT_ON:DWORD; // Valore di ON imposto all'uscita

PT_OFF:DWORD; // Valore di OFF imposto all'uscita

END_VAR

VAR_IN_OUT

Output:BOOL;

CV_ON:DWORD; // Valore ad ON dell'uscita

CV_OFF:DWORD; // Valore ad OFF dell'uscita

END_VAR

VAR

INIT_1:DWORD;

INIT_2:DWORD;

END_VAR

BEGIN

Network 1 // Imposto uscita sull'attivazione di enable.

// Commento del segmento

LD L0.0

AD>= LD14, LD5

EU

LD L0.0

EU

OLD

S L9.0, 1

Network 2 // Rilevo istante di On.

LD L0.0

A L9.0

EU

BITIM LD18

Network 3 // Calcolo tempo di uscita ad On.

LD L0.0

A L9.0

CITIM LD18, LD10

Network 4 // Spengo l'uscita dopo il tempo trascorso di On.

LD L0.0

AD>= LD10, LD1

EU

R L9.0, 1

Network 5 // Rilevo istante di Off.

LD L0.0

A L9.0

ED

BITIM LD22

Network 6 // Calcolo tempo di uscita ad Off.

LD L0.0

AN L9.0

CITIM LD22, LD14

Network 7 // Spengo uscita al cadere di enable

LDN L0.0

R L9.0, 1

END_SUBROUTINE_BLOCK

Link al commento
Condividi su altri siti

Come ti avevo già detto prima:

Ricapitolando, in OB1 quando lanci la tua SBR devi passare:

1 bit (IN) per lo start del timer

2 DWORD (IN/OUT) di appoggio per il controllo del tempo iniziale e trascorso

1 DWORD (IN) per il setpoint del timer

1 bit (OUT) per l’uscita del timer.

Le tue DWORD INIT_1 e INIT_2 che usi per la memorizzazione tel tempo iniziale (BGN_ITIME) sono locali (TEMP) e quindi la tua SBR non può funzionare se la richiami 2 volte!

Ti ricordo che l’area TEMP è una zona di memoria condivisa che quando esci dalla SBR, viene “liberata” (per modo di dire) e resa disponibile alle SBR richiamate successivamente.

Dall’. in linea:

Variabile temporanea salvata provvisoriamente nello stack dei dati locali. Una volta conclusa l'esecuzione dell'unità di programma, il valore della variabile temporanea non è più disponibile. Le variabili di questo tipo non mantengono il valore tra un'esecuzione e l'altra dell'unità di programma.

Metti INIT_1 e INIT_2 su 2 DWORD IN_OUT e “spreca” 2 variabili per ogni richiamo della SBR, vedrai che funziona ! (anche se non ho capito a cosa ti serve quella specie di timer a “intermittenza”)

;)

Link al commento
Condividi su altri siti

Ciao!

Spiacente di deluderti JumpMan ma con 2 chiamate non funziona nemmeno cosi'.

Non so piu' che dire.

SUBROUTINE_BLOCK PULSE:SBR3

TITLE=COMMENTI SUL SOTTOPROGRAMMA

VAR_INPUT

Enable:BOOL;

PT_ON:DWORD; // Valore di ON imposto all'uscita

PT_OFF:DWORD; // Valore di OFF imposto all'uscita

END_VAR

VAR_IN_OUT

INIT_1:DWORD;

INIT_2:DWORD;

CV_ON:DWORD; // Valore ad ON dell'uscita

CV_OFF:DWORD; // Valore ad OFF dell'uscita

END_VAR

VAR_OUTPUT

Output:BOOL;

END_VAR

BEGIN

Network 1 // Imposto uscita sull'attivazione di enable.

// Commento del segmento

LD L0.0

AD>= LD21, LD5

EU

LD L0.0

EU

OLD

S L25.0, 1

Network 2 // Rilevo istante di On.

LD L0.0

A L25.0

EU

BITIM LD9

Network 3 // Calcolo tempo di uscita ad On.

LD L0.0

A L25.0

CITIM LD9, LD17

Network 4 // Spengo l'uscita dopo il tempo trascorso di On.

LD L0.0

AD>= LD17, LD1

EU

R L25.0, 1

Network 5 // Rilevo istante di Off.

LD L0.0

A L25.0

ED

BITIM LD13

Network 6 // Calcolo tempo di uscita ad Off.

LD L0.0

AN L25.0

CITIM LD13, LD21

Network 7 // Spengo uscita al cadere di enable

LDN L0.0

R L25.0, 1

END_SUBROUTINE_BLOCK

Link al commento
Condividi su altri siti

Ci ho buttato ancora un occhiatina veloce.... la variabile #Output , visto che la interroghi anche in lettura non sarebbe il caso di metterla IN_OUT ? :rolleyes:

Link al commento
Condividi su altri siti

Ciao!

Ho provato anche in questo modo (output come IN_OUT) niente da fare

se richiamato 2 volte i blocchi non funzionano piu' (ne il primo ne il secondo).

Provare per credere.

Non ho la più pallida idea di come possano funzionare certe librerie che si trovano in rete o quelle che vengono fornite da Siemens (che sono richiamate da un enable sempre On) anche se vengono inserite e richiamate più volte nel Main;Ma la mia impressione è che se gli indirizzi della memoria locale sono identici sia per il primo che per il secondo blocco e se richiamati da un sempre "on" entrambi, i blocchi non funzioneranno mai.

Se invece il mio 1° sottoprogramma puo' funzionare e essere abilitato (enable) da un fronte e il 2° sottoprogramma essere richiamato da un uscita di "Done" su fronte provenienete dal 1° il tutto girerebbe.

Cosi facendo però certe funzioni come call_time non possono funzionare dovendo essere sempre attraversate dal flusso di corrente.

Cosa ne pensate??

Link al commento
Condividi su altri siti

Non ho la più pallida idea di come possano funzionare certe librerie che si trovano in rete o quelle che vengono fornite da Siemens (che sono richiamate da un enable sempre On) anche se vengono inserite e richiamate più volte nel Main;Ma la mia impressione è che se gli indirizzi della memoria locale sono identici sia per il primo che per il secondo blocco e se richiamati da un sempre "on" entrambi, i blocchi non funzioneranno mai.

Che stai addi! (hei Romani, come si scrive?)

Le SBR sono fatte apposta per essere richiamate anche 1000 volte, è prassi comune di ogni programmatore di crearsi qualche funzione da richiamare più volte all’interno dello stesso programma.

I dati locali dichiarati come TEMP vanno usati solo per appoggiare TEMPoraneamente i valori all’interno della SBR e sono validi solo fino all’ultima istruzione della SBR, quando il programma esce e torna al MAIN, l’area viene liberata e resa disponibile per il blocco successivo, ma questo solo per i dati TEMP!

I dati dichiarati come IN_OUT appoggiano il valore sulla variabile dichiarata nel richiamo della SBR, e, a meno che tu non usi le stesse variabili anche altrove, nessuno si permette di “sporcarle”!

Ti assicuro che le funzioni ITIME le ho usate molte volte e con richiami ripetuti, prova a fare qualche esperimento con qualcosa di più semplice, magari metti una sola funzione anziché 2 e ti crei un timer normale anziché intermittente (che non ho ancora capito a cosa diavolo ti serve, magari ci sono anche modi migliori per ottenere quel risultato...) così ti fai un po’ di esperienza.

Scrivendo da casa, senza poter provare, per me è difficile trovare il baco, a volte questo essere subdolo si nasconde in un piccolo pertugio del programma, e quando lo trovi dici: ma guarda che **** !

Per finire ricordati che ha (quasi) sempre ragione lui !

Modificato: da JumpMan
Link al commento
Condividi su altri siti

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 account

Accedi

Hai già un account? Accedi qui.

Accedi ora
×
×
  • Crea nuovo/a...