Tecniche di programmazione

per i PLC S7 300

 

   

Nulla di nuovo sotto l’albero, in questo articolo viene descritto in modo “il più chiaro possibile” come utilizzare strutture indicizzate nella programmazione dei PLC S7 300 della Siemens [1] . Questo articolo è dedicato a chiunque sia alle prime armi con l’ambiente di sviluppo in oggetto.

 

Il seguente materiale è frutto dell’esperienza dell’autore.

 

L’utilizzo del seguente materiale o parte di esso è consentito se e solo se viene citata la fonte, l’autore, nonché l’autore stesso venga messo al corrente dell’uso che se ne intende fare (eventualmente con diritto di veto J ).

 

© Copyright – Federico Milan, 2004 / PLC Forum ®

 

Qualunque FeedBack è sempre apprezzato.

 

L’autore non è responsabile di false citazioni, errori, danni a cose e/o persone derivanti dalla lettura del seguente materiale.

 

Gli indirizzi di riferimento per contattare l’autore sono:

 

                milan1@interfree.it

                federico@plcforum.it

 

 

                                                                                                                             Federico Milan

                                                                                                                             Cittadella, PD

 

 

Indice

 

0.0         Introduzione                                                                      

1.0         Giocando con le strutture dati

1.1         Inserimento di una DB

1.2         Inserimento dati e loro utilizzo nel programma

1.3         Gli UDT

2.0         Gli Array

3.0         Funzioni per strutture indicizzate

4.0         Conclusioni

 

 

 

 

 

 
 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

0.0           Introduzione

 

Il seguente articolo pur essendo dedicato a chi è alle prime armi presuppone una certa dimestichezza con l’utilizzo dell’ambiente integrato ©SIMATIC Manager. L’ambiente di riferimento è la versione 5.2 + SP1.

 

Per una lettura efficiente il lettore dovrebbe avere assimilato il concetto di struttura dati su di un DB, l’utilizzo degli UDT, nonché saper utilizzare gli operatori di caricamento e trasferimento dati.

È necessario anche una piccola conoscenza di aritmetica e delle basi numeriche.

In questo articolo si prende in considerazione una delle possibili tecniche di indicizzazione dei dati. Si prenderanno in considerazione quindi gli array [2] e le strutture dati e gli UDT [3] .

 

 

1.0           Giocando con le strutture dati

 

Prima di entrare nel vivo della problematica vediamo come si costruiscono le strutture dati, e facciamo un piccolo confronto tra le strutture dati e gli UDT, sempre in termini molto “terra a terra” senza pretese di onniscienza J.

 

 

1.1            Inserimento di una DB

 

Sebbene si dovrebbe gia sapere utilizzare l’ambiente di sviluppo vediamo brevemente come inserire le DB

 

Figura 1 – Inserimento di un DataBlock (DB).

 

A questo punto verrà data la possibilità di associare un nome simbolico alla DB creata, così come visualizzato dalla Figura 2.

 

Figura 2 – Inserimento di un DataBlock; nome simbolico

 

Non resta che premere il pulsante OK. La figura seguente da un’idea di cosa abbiamo creato J.

 

Figura 3 – Il DB è inserito J.

 

 

 

 

 

 

 

 

1.2            Inserimento dati e loro utilizzo nel programma

 

Iniziamo a inserire la prima struttura dati sulla DB creata. Iniziamo subito “alla grande”; inseriamo una struttura in grado di rappresentare uno spazio e un tempo, e ovviamente una velocità J.

 

 

Figura 4 – Ecco come si presenta la DB

 

Se volessimo a questo punto eseguire un calcolino della velocità, ecco quello che dovremmo fare:

 

Figura 5 – Nomi simbolici e effettivo indirizzo fisico delle variabili

 

Tutta la nostra fatica ovviamente non è sul ripasso delle leggi fisiche, ma su come vengono rappresentati i dati e la loro relazione con l’indirizzo fisico.

 

Il codice leggibile per gli esseri umani, potrebbe anche essere riscritto come segue, il che mette in luce che il simbolico utilizzato è solo utile alla compressione del testo, ma niente di utile per realizzare programmi “funzionanti”.

 

Figura 6 – Nomi simbolici e effettivo indirizzo fisico delle variabili

 

Fino a qui tutto dovrebbe essere chiaro. Le strutture dati servono solo a noi programmatori, al compilatore/interprete/PLC non interessano, a queste entità non servono a nulla! Ritornando ad uno dei mie primi articoli potremmo giocare con il codice, complicandolo come segue:

 

Figura 7 – come complicarsi la vita … Riferimento a dati tramite puntatore a 32bit.

 

Bene, a questo punto, oltre a giocare per farsi “male” L, potremmo giocare per semplificarci la vita J. Prima di fare questo è opportuno vedere brevemente gli UDT.

 

 

 

 

 

 

 

 

 

1.3            GLI UDT

 

Gli UDT sono dati creati dall’utente, si generano allo stesso modo delle DB, solo che non sono dati residenti in memoria, ma una loro descrizione.

Un esempio chiarificatore potrebbe essere il seguente.

 

Figura 8 – UDT1

 

Apriamo l’ UDT1 e inseriamo la nostra relazione fisica:

 

Figura 9 – Descrizione dei dati dell’UDT1

 

Notare che l’UDT presenta già il costrutto STRUCT. Ora, però, questi dati li possiamo solo rappresentare, ma per il momento non possiamo farci niente; i dati per essere usti devono essere prima mappati su di una DB.

 

È necessario quindi inserire in una nostra DB un nome e come tipo di dato il nome della UDT creata. Di seguito l’esempio.

 

 

 

Figura 10 – come si trasforma il codice

 

Come si vede il simbolico è cambiato (di poco), ma l’indirizzo fisico no! Ancora una volta il simbolico serve solo per gli esseri umani, ma al PLC non serve a nulla.

 

L’utilizzo delle UDT è molto utile per descrivere dati di uso generico, ovviamente in questo articolo non se ne apprezzerà il vantaggio, ma con il passare del tempo, si apprezzerà la potenza descrittiva degli UDT.

 

 

2.0           Gli array

 

Ora introduciamo gli array, e iniziamo a fare sul serio. Anzi iniziamo a divertirci veramente J.

Per essere semplice e chiaro vediamo subito come inserire un array di 10 elementi nella nostra solita DB.

 

L’array dichiara un “insieme” di elementi indicizzati, tutti delle stesso tipo. È importante ricordare che gli elementi di un array devono essere dello stesso tipo, questo perché ogni elemento occupa una zona ben precisa di memoria.

 

 

 

Figura 11 – array di UDT

 

Nel simbolico ogni elemento vene indicizzato, osservate la Figura 11.

 

Ancora una volta il simbolico è cambiato, ma l’indirizzo fisico è rimasto lo stesso (almeno per il primo elemento). Ora osservate la seguente figura (Figura 12) e capirete la relazione che esiste tra gli elementi dell’array.

 

 

 

 

Figura 12 – Relazione tra indirizzi …

 

Come risulta chiaro dalla figura il primo elemento Fisica [4] : Fisica[1] è a offset 0, il secondo (Fisica[2]) è a offset 6 e così via.

La cosa interessante è che lo Spazio  di Fisica[] si trova a offset 0 rispetto a Fisica[] mentre Tempo si trova a offset 2 rispetto a Fisica[]. A questo punto tutto diventa banale. Il puntamento a strutture, per quanto complesse siano, si basa su un calcolo di offset e su di uno di spiazzamento.

 

Per fare un esempio a parole, diciamo che se vogliamo puntare alla Velocità di Fisica[4] dovremmo trovare l’inizio di Fisica[4] che è alla WORD 18, e a questo sommare i 4 Byte di offset, ottenendo l’indirizzo DBW 22.

 

 

 

 

3.0           Funzioni per strutture indicizzate

 

Quello che si è detto sul paragrafo 2.0 consente già di per sé di trovare una soluzione al problema. Non ci resta che mettere sul fuoco un po’ di codice, e il gioco è fatto.

 

 

 

Figura 13 – Il codice per l’indiccizzazione

 

 

Il codice che abbiamo scritto, mostra come andare a puntare ad un qualunque elemento dell’array. In questo caso il MW100 (ma poteva essere una qualunque memoria intera) rappresenta l’indice a cui puntare, oppure detto in altre parole, l’elemento desiderato dell’array.

 

Vediamo come lavora il codice:

 

Ipotiziamo di voler puntare all’elemento 2.

 

MW100 = 2;

                        calcoliamo l’offset:

 

                        (2 – 1) * 6 = 6 à       l’inizio della struttura del secondo elemento è sul

sesto byte.

                        Trasformiamo il numero 6 in puntatore [5] e lo carichiamo sul registro

AR1. Ora tramite la sintassi L DBW[AR1,P#x.y] possiamo puntare all’indirizzo caricato su AR1, eventualmente sommando l’offset indicato da P#x.y [6] .

 

 

A questo punto tutto dovrebbe essere chiaro. Spesso, però non siamo fortunati, e non possiamo partire da offset 0. Questo non dovrebbe preoccuparci, perché, così come calcoliamo lo “spiazzamento” degli elementi dell’array, allo stesso modo possiamo calcolare anche l’offset dell’inizio array. Come fare? Semplice:

 

            Aprendo il DB si guarda a che byte inizia l’array.

 

Nel calcolo del puntatore, all’inizio basta sommare il numero di byte a cui inizia l’array.

 

 

4.0           Conclusioni

 

Abbiamo visto come utilizzare gli array, come indicizzarli. Ora siamo in grado di programmare strutture in modo “dinamico”.

 

Solo una precisazione, abbiamo lavorato con interi, ma nulla toglie di utilizzare DINT, o Bit, basta slo utilizzare i rispettivi “operatori” DBD[], DBX[]. Ma ovviamente non ci possiamo solo limitare alla memoria delle DB, possiamo anche puntare anche puntare alle variabili locali, ampliando ulteriormente le nostre possibilità … a voi l’immaginazione.

 

E se l’array è multidimensionale? Del tipo  una matrice? Ancora una volta un po’ di algebra ci aiuta:

 

es:

M[5][4]         :           immaginiamo che la matrice sia composta da 4

colonne e 5 righe.

 

            Come puntare all’elemento M[2][3]?

            Seguiamo il ragionamento:

           

            dobbiamo puntare alla colonna 3 riga 2, quindi matematicamente

significa puntare alla zona di memoria indicata da:

 

(3-1) +( 2-1)*4 [trasformato in puntatore secondo la regola [7] ]

 

Quindi generalizzando (y-1)*N_Colonne + (x-1).

 

 

Buon divertimento!



[1] Per maggiori dettagli consultare il sito www4.ad.siemens.de

[2] L’array può essere visto come un vettore mono o multidimensionale contenente degli oggetti di tipo bit, byte, word,… o addirittura strutture dati molto complesse. Gli oggetti devono essere tutti dello stesso tipo.

[3] Con la sigla UDT viene indicato un tipo di dati definito dall’utente.

[4] Fisica è il nome della struttura. È importante non confondere la struttura array con l’elemento di array che indichiamo come Fisica[4](ossia il quarto elemento dell’array).

[5] Il calcolo di puntatore viene eseguito con uno shift a sinistra del numero.

[6] Il puntatore è indicato con P#x.y dove x rappresenta il byte e y il bit. Per maggiori dettagli consultare la documentazione in linea.

[7] Il puntatore si trova moltiplicando l’indice del suo indirizzo per la dimensione dei dati in byte, quindi “shiftando” di 3 bit a sinistra.