Next revision | Previous revision |
en:appnote:an007 [2017/04/27 17:25] – created qem103 | en:appnote:an007 [2019/08/29 17:01] (current) – external edit 127.0.0.1 |
---|
In the following examples, the device will always be dvHMI. | In the following examples, the device will always be dvHMI. |
| |
==== Attendere la pressione di un tasto o più tasti per un certo tempo ==== | ==== Wait for a KeyPress or more keys for some time ==== |
| |
Si voglia scrivere un programma Qcl che attenda la pressione del tasto F per eseguire una subroutine. È sufficiente verificare che il parametro //key// abbia il bit relativo al tasto F attivo: | You want to write a Qcl program wait for the keystroke F for executing a subroutine. Simply verify that the //key// parameter having the bit for the F key active: |
| |
<code QCL> | <code QCL> |
SUB MyFUNC | SUB MyFUNC |
;------------------------- | ;------------------------- |
;codice subroutine | ;subroutine code |
;------------------------- | ;------------------------- |
ENDSUB | ENDSUB |
</code> | </code> |
| |
questo codice non assicura che sia premuto solamente il tasto F: la funzione MyFUNC potrebbe essere chiamata anche se fossero premuti assieme al tasto F anche altri tasti. Per assicurare l'esclusività della pressione di F il codice diventa: | This code does not ensure that it is only pressed the F button: the MyFUNC function may also be called if they were pressed together with F key also other keys. To ensure the exclusivity of the pressure of F the code becomes: |
| |
<code QCL> | <code QCL> |
</code> | </code> |
| |
Si voglia ora scrivere un codice che attenda la pressione contemporarea dei tasti CLEAR ed ENTER per almeno 2 secondi: | You want now write code that listens for the both pressure of the CLEAR and ENTER keys for at least 2 seconds: |
| |
<code QCL> | <code QCL> |
IF ( dvHMI:key EQ (KEY_ENTER+KEY_CLEAR) ) | IF ( dvHMI:key EQ (KEY_ENTER+KEY_CLEAR) ) |
IF tm01:remain EQ 0 ;verifica timer scaduto | IF tm01:remain EQ 0 ;check expired timer |
CALL MyFUNC | CALL MyFUNC |
ENDIF | ENDIF |
ELSE | ELSE |
tm01=2000 ;timer viene ricaricato | tm01=2000 ;timer is reloaded |
ENDIF | ENDIF |
</code> | </code> |
| |
==== Creare una visualizzazione ricorsiva ==== | ==== Create a recursive view ==== |
| |
Si voglia scrivere un programma Qcl che abiliti una visualizzazione ricorsiva sui 4 display più a sinistra con segno e 2 cifre decimali. Decidiamo per comodità di utilizzare la screenA. Dobbiamo innanzitutto impostare il numero di caratteri che vogliamo visualizzare tenendo presente che il segno occupa un carattere; possiamo quindi dire che il numero di caratteri rappresenta il numero di digit del display che vengono occupati e manipolati dalla visualizzazione stessa. I valori massimo e minimo che potremo visualizzare saranno rispettivamente 9999 e -999. Se il dato da visualizzare è inferiore a tale valore minimo oppure superiore a tale valore massimo, il display visualizzerà i caratteri di out of range ''$$$$''.\\ | You want to write a program that enables a Qcl recursive view on the leftmost 4 display with sign and 2 decimal places. We decide for ease to use screenA. We must first set the number of characters you want to shown bearing in mind that the sign is a character; we can therefore say that the number of characters is the number of digits of the display that are occupied and manipulated by the view. The maximum and minimum values that will allow us to shown are 9999 and -999. If the data to be showed is less than this minimum value or greater than this maximum value, the display shows the out of range characters ''$$$$''.\\ |
Imposteremo quindi: | We'll set: |
| |
<code QCL> | <code QCL> |
</code> | </code> |
| |
Metteremo la nostra visualizzazione nei display più a sinistra impostando il valore di offset pari a: | We will put our view on the leftmost display setting the offset value to: |
| |
<code QCL> | <code QCL> |
</code> | </code> |
| |
Settiamo la posizione del punto decimale a 2: | We set decimal point position to 2: |
| |
<code QCL> | <code QCL> |
</code> | </code> |
| |
Abilitiamo la visualizzazione ricorsiva screenA settando il corrispondente bit di abilitazione della variabile scflags: | Enable recursive view screenA by setting the corresponding enable of the scflags variable: |
| |
<code QCL> | <code QCL> |
</code> | </code> |
| |
Eseguendo l'istruzione di cui sopra abbiamo automaticamente disabilitato le altre due visualizzazioni ricorsive ed abbiamo abilitato la visualizzazione del segno sulla screenA. Nel caso avessimo voluto preservare gli stati delle altre visualizzazioni screenB e screenC avremmo dovuto scrivere: | Executing the above statement We automatically disabled the other two recursive views and we have enabled the display of the sign on screenA. In case we wanted to preserve the States of other screenB and screenC views we should have written: |
| |
<code QCL> | <code QCL> |
dvHMI:scflags = dvHMI:scflags ORB SCRA_ENABLE ;abilitazione screenA | dvHMI:scflags = dvHMI:scflags ORB SCRA_ENABLE ;screenA enable |
dvHMI:scflags = dvHMI:scflags ANDB SCRA_DISSIGN ;abilitazione segno screenA | dvHMI:scflags = dvHMI:scflags ANDB SCRA_DISSIGN ;screenA sign enable |
</code> | </code> |
| |
Infine è sufficiente aggiornare la variabile screenA con il valore che vogliamo visualizzare e normalmente contenuto in un'altra variabile del nostro programma (nell'esempio supponiamo di utilizzare una variabile con il nome //count//): | Finally, you can simply update the screenA variable with the value you want to shown and normally contained in another variable of our program (in the example, suppose we use a variable with the //count// name): |
| |
<code QCL> | <code QCL> |
</code> | </code> |
| |
L'operazione di aggiornamento di screenA dovrà essere continuamente eseguita dal nostro programma con il refresh rate più opportuno in ragione della funzionalità che il programmatore ha previsto per tale variabile. | The update operation of screenA must be continuously performed by our program with the refresh rate more appropriate for reasons of functionality that the programmer has planned for that variable. |
| |
==== Creare una visualizzazione di testo ==== | ==== Create a text view ==== |
| |
Si voglia scrivere un programma Qcl che scriva sul display "HELLO" allineato a destra. Per fare ciò è sufficiente impostare nelle variabili associate ai digit del display il codice del carattere che si vuole visualizzare. Avremo quindi: | You want to write a Qcl program that writes on display "HELLO" right-aligned. To do this, just set the variables associated with the digit of the display the code of the character that you want to shown. We will therefore have: |
| |
<code QCL> | <code QCL> |
;Stampa "HELLO" | ;Print "HELLO" |
dvHMI:dis6 = CHAR_ | dvHMI:dis6 = CHAR_ |
dvHMI:dis5 = CHAR_ | dvHMI:dis5 = CHAR_ |
</code> | </code> |
| |
<WRAP center round info 60%>Nota:\\ Per poter funzionare correttamente, non devono essere attive visualizzazioni ricorsive che sovrascriverebbero tutti o parte dei digit interessati dal nostro "HELLO". Controllare quindi che nel parametro //scflags// i bits 0,1 e 2 siano a 0 oppure forzarli a tale valore.</WRAP> | ^:info:^Note:\\ In order to work properly, must not be active recursive views that overwrite all or part of interested digit by our "HELLO". Check that in the//scflags// parameter the 0,1 and 2 bits are to 0 or force them to that value.^ |
| |
==== Creare più visualizzazioni ricorsive miste a visualizzazioni di testo ==== | ==== Create multiple recursive views mixed with text displays ==== |
| |
Si voglia creare una visualizzazione composta da due testi fissi e due valori ricorsivi. A titolo di esempio si pensi di visualizzare un tempo espresso in secondi ed un numero di programma. La visualizzazione voluta potrebbe essere: "t51 Pr2" dove "t" indica il tempo, "51" è il valore del tempo, "Pr" è un testo che indica il programma, "2" indica il numero del programma.\\ | You want to create a view consists of two fixed texts and two recursive values. As an example, you shown a time in seconds and a program number. The desired show might be: "t51 Pr2" where "t" indicates the time, "51" is the time value, "Pr" it's a text that indicates the program, "2" indicates the program number.\\ |
Innanzitutto stampiamo i testi: | First we print the texts: |
| |
<code QCL> | <code QCL> |
</code> | </code> |
| |
Impostiamo poi i dati per la visualizzazione numerica del tempo tramite la screenA. | Then we set the data for the numerical display of the time through the screenA. |
| |
<code QCL> | <code QCL> |
</code> | </code> |
| |
Impostiamo poi i dati per la visualizzazione numerica del programma tramite la screenB. | We then the data for the numerical display of the program using the screenB. |
| |
<code QCL> | <code QCL> |
</code> | </code> |
| |
Abilitiamo le due visualizzazioni: | We enable the two views: |
| |
<code QCL> | <code QCL> |
</code> | </code> |
| |
Poi ricorsivamente aggiorneremo i dati della visualizzazione: | Then recursively we will update the view data: |
| |
<code QCL> | <code QCL> |
</code> | </code> |
| |
==== Creare una introduzione dati semplice ==== | ==== Create a simple data input ==== |
| |
Si voglia scrivere un programma Qcl che permetta all'utente di introdurre un valore su una variabile, ad esempio una utilizzata per memorizzare un conta pezzi. Innanzitutto dovremo dichiarare tale variabile, ad esempio //cntPieces// nell'apposita sezione della unit di configurazione. Supponiamo che si voglia visualizzare il messaggio "CP" sulla parte sinistra del display ad indicare l'introduzione del conta pezzi, e che il valore da introdurre sia di 4 caratteri e posizionato sulla parte più a destra del display. Il data entry occuperà i display dis0, dis1, dis2, dis3 mentre il messaggio verrà scritto in dis5 e dis6. | You want to write a Qcl program that allows the user to input a value to a variable , for example, one used to store a pieces counting. First we will declare that variable, for example //cntPieces// in the section of the configuration unit. Suppose you want to view the "CP" message on the left side of the display to indicate the introduction of pieces counting, and that the value to be introduced is 4 charactersand positioned on the far right of the display. The data entry will occupy the dis0, dis1, dis2, dis3 display while the message is written in dis5 and dis6. |
| |
<code QCL> | <code QCL> |
</code> | </code> |
| |
La posizione del punto decimale sarà ovviamente posta a 0 ed eseguiremo la copia del valore del conta pezzi attuale nel parametro //devalue// per far sì che all'ingresso dell'introduzione dati compaia tale valore sul display. | The position of the decimal point will be placed to 0 and we will copy the value of the current pieces in the //devalue// parameter count to ensure that data appears at the entrance of the introduction that value on the display. |
| |
<code QCL> | <code QCL> |
</code> | </code> |
| |
Infine abiliteremo l'introduzione dati con l'apposito flag, disabiliteremo il segno (un conta pezzi non potrà essere negativo) e attiveremo la procedura d'introduzione con il comando //DATAENTRY//: | Finally we will enable the data input using the appropriate flag, we will disable the sign (a pieces counter cannot be negative) and activate the introduction with the //DATAENTRY// command: |
| |
<code QCL> | <code QCL> |
</code> | </code> |
| |
A questo punto comincerà a lampeggiare sul display il digit più significativo del valore di //cntPieces// e sarà necessario attendere che l'utente introduca il dato e lo confermi con il tasto ENTER. Successivamente si dovrà leggere il dato introdotto (nel parametro //devalue//) e copiarlo nella nostra variabile del conta pezzi //cntPieces//. Lo stato //st_dentry// ci permette di sapere se il data entry è attivo quindi attendiamo che questo vada a 0 per poi fare le operazioni di copia: | At this point the most significant digit on the display will start flashing the value of //cntPieces// and you will have to wait for the user to enter the data and confirm with the ENTER button. Then you must read the introduced data (in the //devalue// parameter) and copy it into our variable //cntPieces// of pieces counting. The //st_dentry// state lets us know if data entry is active o expect this go to 0 before copying: |
| |
<code QCL> | <code QCL> |
</code> | </code> |
| |
A questo punto la variabile //cntPieces// è aggiornata con il valore introdotto dall'utente. | At this point the//cntPieces// variable is updated with the value entered by the user. |
| |
==== Creare una introduzione dati complessa ==== | ==== Create a complex data introduction ==== |
| |
Si voglia scrivere un programma Qcl che permetta all'utente di introdurre un valore su una variabile, come già fatto nell'esempio precedente, ma con le seguenti caratteristiche aggiuntive: | You want to write a Qcl program that allows the user to input a value to a variable, as in the previous example, but with the following additional features: |
| |
* controllare che il dato sia compreso tra 1 e 1000 ed in caso contrario visualizzare "Error" per 1 secondo e ripetere l'introduzione dati | * check that the figure is between 1 to 1000 and otherwise show "Error" for 1 second and repeat the data entry |
* se viene premuto il tasto F si esca dall'introduzione dati senza memorizzare il dato introdotto e venga stampato per un secondo il messaggio "Exit F" | * if the F key is pressed you step out of the data input without storing the data introduced and may be printed for a second the "Exit F" message |
* se viene premuto il tasto CLEAR si esca dall'introduzione dati senza memorizzare il dato introdotto e venga stampato per un secondo il messaggio "Exit C" | * If the CLEAR key is pressed you step out of the data input without storing the data introduced and may be printed for a second the "Exit C" message |
* stampare per un secondo il messaggio "MOdiFY" se il dato in introduzione è stato modificato | * print for a second the "MOdiFY" message if the introduced data has been modified |
| |
=== Controllo limiti dato === | === Control data limits === |
Per abilitare il controllo dei limiti del dato introdotto è necessario abilitare tale funzionalità ponendo a 1 l'apposito bit del parametro //deflags// ed impostare nei parametri //deuplim// e //delowlim// i valori dei limiti superiore ed inferiore. Rispetto al codice del precedente esempio dovremo aggiungere, prima del comando //DATAENTRY//, le seguenti istruzioni Qcl: | |
| To enable bounds checking of the introduced data you must enable this feature putting to 1 the relevant bits of the //deflags// parameter and set in //deuplim// and //delowlim// parameters the values of the upper and lower limits. Compared to the previous example code we will add, before the //DATAENTRY// command, the following Qcl instructions: |
| |
<code QCL> | <code QCL> |
</code> | </code> |
| |
e sostituire l'istruzione di impostazione del parametro deflags con: | and replace the setting instruction of the deflags parameter: |
| |
<code QCL> | <code QCL> |
</code> | </code> |
| |
=== Configurare uno o più tasti di uscita dal data entry === | === Configure one or more keys to exit from data entry === |
Per abilitare l'uscita dal data entry con un tasto è necessario impostare il parametro //deExKeymask// cioè la maschera per i tasti di uscita. Per abilitare un tasto a funzionare come tasto di uscita dal data entry, è sufficiente attivare il bit corrispondente del parametro sopracitato. Quindi se vogliamo far si che si esca dal data entry con i tasti F e CLEAR serve inserire la seguente istruzione Qcl prima del comando //DATAENTRY//: | |
| To enable the output from data entry with a key You must set the //deExKeymask// parameter that is the form to exit buttons. To enable a button to function as data entry exit key, simply activate the corresponding bit of the above mentioned parameter. So if we want to ensure that you exit from data entry with the F and CLEAR keys you must insert the following //DATAENTRY// command instruction Qcl: |
| |
<code QCL> | <code QCL> |
</code> | </code> |
| |
=== Verificare se il dato introdotto è nei limiti === | === Check if the introduced data is within limits === |
All'uscita dal data entry (quindi con lo stato //st_dentry// = 0), è sufficiente controllare il valore degli stati //st_uplim// e //st_lowlim// per sapere se il dato introdotto è superiore ai limiti impostati. Se //st_uplim// vale 1 significa che il valore introdotto è maggiore del limite superiore, mentre se //st_lowlim// vale 1 significa che il valore introdotto è minore del limite inferiore. Quindi controlleremo tali stati e faremo una chiamata alla subroutine ERROR (che si occuperà di visualizzare il messaggio di errore per 1 secondo) nel caso di superamento dei limiti. | |
| When you exit from the data entry (then with the //st_dentry// = 0 State), check the value of the //st_uplim// and //st_lowlim// states to know if the data introduced is in excess of the limits set. If //st_uplim// vale 1 means that the input value is greater than the upper limit, while if //st_lowlim// vale 1 means that the input value is less than the lower limit. Then we will check those states, and we will make a call to the ERROR subroutine (that will display the error message for 1 second) if the limits are exceeded. |
| |
<code QCL> | <code QCL> |
;Controllo limiti dati | ;Data limits control |
IF ( dvHMI:st_uplim OR dvHMI:st_lowlim ) | IF ( dvHMI:st_uplim OR dvHMI:st_lowlim ) |
CALL ERROR ;stampa messaggio d'errore | CALL ERROR ;print error message |
JUMP Dentry ;ritorno introduzione datai | JUMP Dentry ;return datai introduction |
ENDIF | ENDIF |
</code> | </code> |
| |
=== Controllare il tasto di uscita dal data entry === | === Check the output key from data entry === |
Controllando il parametro //deExitKey// e gli stati //st_modified// ed //st_exitcmd//, è possibile capire in quale modo si è usciti dal data entry. La seguente tabella riassume le possibili condizioni:\\ | |
^//deExitKey//^//st_exitcmd//^Descrizione| | Checking the//deExitKey// parameter and the //st_modified// and //st_exitcmd// states, you can understand in what way you are signed out from data entry. The following table summarizes the possible conditions:\\ |
|0|0|Uscita con conferma tramite pressione del tasto ENTER o tramite comando //EXITDEC//| | ^//deExitKey//^//st_exitcmd//^Description| |
|0|1|Uscita senza conferma tramite domando //EXITDE//| | |0|0|Exit with confirmation by pressing the ENTER key or by //EXITDEC// command| |
|!=0|X|Uscita senza conferma tramite pressione del tasto identificato dal valore del parametro //deExitKey//| | |0|1|Exit without confirmation by //EXITDE// command| |
| |!=0|X|Exit without confirmation by pressing the button identified by the value of the //deExitKey// parameter| |
| |
| === Check if the data has been modified === |
| |
=== Verificare se il dato è stato modificato === | To check if the introduced data has changed, simply check the //st_modified// status. It takes the 1 value If the input value is different from the previous value of the devalue parameter befor of the //DATAENTRY// command.\\ |
Per verificare se il dato introdotto è stato modificato basta semplicemente controllare lo stato //st_modified//. Esso assume valore 1 se il valore introdotto è diverso dal valore che aveva il parametro devalue prima del comando //DATAENTRY//.\\ | The full program will then: |
Il programma completo sarà quindi: | |
| |
<code QCL> | <code QCL> |
| |
IF dvHMI:deExitKey | IF dvHMI:deExitKey |
;--Uscita da data entry con tasti d'uscita | ;--Output from data entry with output keys |
dvHMI:dis6 = CHAR_E | dvHMI:dis6 = CHAR_E |
dvHMI:dis5 = CHAR_H | dvHMI:dis5 = CHAR_H |
dvHMI:dis1 = CHAR_ | dvHMI:dis1 = CHAR_ |
IF dvHMI:deExitKey EQ KEY_F | IF dvHMI:deExitKey EQ KEY_F |
dvHMI:dis0 = CHAR_F ;Pressione tasto F | dvHMI:dis0 = CHAR_F ;F key press |
ELSE | ELSE |
IF dvHMI:deExitKey EQ KEY_CLEAR | IF dvHMI:deExitKey EQ KEY_CLEAR |
dvHMI:dis0 = CHAR_C ;Pressione tasto CLEAR | dvHMI:dis0 = CHAR_C ;CLEAR key press |
ENDIF | ENDIF |
ENDIF | ENDIF |
ELSE | ELSE |
;--Uscita da data entry con conferma | ;--Output from data entry with confirm |
;--Controllo limiti | ;--Limits control |
IF ( dvHMI:st_uplim OR dvHMI:st_lowlim ) | IF ( dvHMI:st_uplim OR dvHMI:st_lowlim ) |
CALL ERROR ;stampa mesaggio d'errore | CALL ERROR ;print error message |
JUMP LABEL0 ;ritorna all'introduzione dati | JUMP LABEL0 ;return to data entry |
ENDIF | ENDIF |
;--Verifica se i dati sono stati modificati | ;--Checks if the data has changed |
IF dvHMI:st_modified | IF dvHMI:st_modified |
dvHMI:dis6 = CHAR_ ;stampa messaggio "MODIFY" | dvHMI:dis6 = CHAR_ ;print "MODIFY" message |
dvHMI:dis5 = CHAR_M | dvHMI:dis5 = CHAR_M |
dvHMI:dis4 = CHAR_O | dvHMI:dis4 = CHAR_O |
WAIT tm01 | WAIT tm01 |
ENDIF | ENDIF |
cntPieces = dvHMI:devalue ;memorizza valore introdotto | cntPieces = dvHMI:devalue ;stores entered value |
ENDIF | ENDIF |
| |
| |
SUB ERROR | SUB ERROR |
dvHMI:dis6 = CHAR_ ;stampa messaggio "ERROR" | dvHMI:dis6 = CHAR_ ;print "ERROR" message |
dvHMI:dis5 = CHAR_E | dvHMI:dis5 = CHAR_E |
dvHMI:dis4 = CHAR_R | dvHMI:dis4 = CHAR_R |
</code> | </code> |
| |
==== Creare una visualizzazione mista non ricorsiva ==== | ==== Create a mixed non-recursive visualization ==== |
| |
Si voglia creare una visualizzazione di un messaggio composto dalla stringa "Error" e da un numero identificativo dell'errore che appaia quando si verifica un errore, mentre normalmente venga visualizzato, in maniera ricorsiva, il valore di un conteggio. Per realizzare questo, sfruttiamo il funzionamento di sola visualizzazione di un valore numerico presente nella funzionalità del comando //DATAENTRY// ed abilitata impostando a 0 il bit //DE_ENABLE// del parametro //deflags//. Per semplicità, realizzeremo una condizione fittizia di errore tramite la fine di un timer caricato a 5 sec. Come vedremo, sarà importante ricordarsi di disabilitare la visualizzazione ricorsiva prima di visualizzare il messaggio di errore, altrimenti il risultato non sarà quello che ci si aspetta.\\ | You want to create a view of a message consisting of the "Error" string and an identification number of the error that appears when occurs an error, while normally appears, recursively the counter value. To achieve this, we exploit the functioning can only be displayed by a numerical value present in //DATAENTRY// command functionality and enabled by setting to 0 the //DE_ENABLE// bits of the //deflags// parameter. For simplicity, we'll create a fictitious error condition by the end of a timer uploaded to 5 sec. As will see, It will be important to remember to disable recursive view before showing the error message, otherwise the result will not be what you expect.\\ |
Il codice risulta essere: | The code is: |
| |
<code QCL> | <code QCL> |
dvHMI:dis6 = CHAR_C | dvHMI:dis6 = CHAR_C |
| |
;configura e abilita screenA | ;Configure and enable screenA |
dvHMI:ncharA = 6 | dvHMI:ncharA = 6 |
dvHMI:offsA = 0 | dvHMI:offsA = 0 |
dvHMI:scflags = dvHMI:scflags ORB SCRA_ENABLE | dvHMI:scflags = dvHMI:scflags ORB SCRA_ENABLE |
| |
tm01 = 5000 ;utilizzo del timer per causare un errore | tm01 = 5000 ;how to use the timer to cause an error |
| |
LOOP: | LOOP: |
;Errore? | ;Errore? |
IF tm01 | IF tm01 |
;disabilita screenA | ;disable screenA |
dvHMI:scflags = dvHMI:scflags ANDB ( NOT SCRA_ENABLE ) | dvHMI:scflags = dvHMI:scflags ANDB ( NOT SCRA_ENABLE ) |
CALL ERROR | CALL ERROR |
| |
SUB ERROR | SUB ERROR |
;stampa "ERROR" | ;print "ERROR" |
dvHMI:dis6 = CHAR_E | dvHMI:dis6 = CHAR_E |
dvHMI:dis5 = CHAR_R | dvHMI:dis5 = CHAR_R |
| |
| |
;stampa errore con identificativo | ;printing error with the ID |
dvHMI:deoffs = 0 | dvHMI:deoffs = 0 |
dvHMI:denchar = 2 | dvHMI:denchar = 2 |
DATAENTRY dvHMI | DATAENTRY dvHMI |
| |
;attesa 2 secondi | ;wait 2 seconds |
tm01 = 2000 | tm01 = 2000 |
WAIT tm01 | WAIT tm01 |
</code> | </code> |
| |
==== Diagnostica Ingressi ==== | ==== Diagnostic Inputs ==== |
| |
Si voglia creare una visualizzazione che rappresenti lo stato di 9 ingressi digitali. Lo stesso esempio potrà essere poi utilizzato per la rappresentazione di uscite digitali. Assegneremo perciò, ad ogni ingresso, uno dei segmenti di ciascuno dei tre digit più a destra e lo attiveremo quando il corrispondente ingresso sarà attivo.\\ | You want to create a view that represents the State of 9 digital inputs. The same example can be used for the representation of digital outputs. We will assign to each input, one of the segments of each of the three rightmost digit and we will activate when the corresponding input will be active.\\ |
La figura mostra l'assegnamento scelto per gli ingressi ed i segmenti dei digit del display: | The figure shows the assignment chose for the inputs and segments of the digits of the display: |
| |
{{:software:devices:hmi:an007:an_hmi2_01.png?nolink400|}} | {{:software:devices:hmi:an007:an_hmi2_01.png?nolink400|}} |
| |
Innanzitutto dichiareremo, nella unit di configurazione, 9 variabili di dimensione FLAG il cui valore simulerà lo stato dei 9 ingressi digitali. | First we will declare, in the configuration unit, 9 variables of FLAG dimensions whose value will simulate the condition of 9 digital inputs. |
| |
<code QCL> | <code QCL> |
</code> | </code> |
| |
Dichiareremo poi anche un array global da 8 elementi che servirà per contenere i codici dei caratteri da stampare per ogni combinazione degli ingressi. | We will declare a global array to 8 items that will serve to hold character codes to print for each combination of inputs. |
| |
<code QCL> | <code QCL> |
ARRGBL | ARRGBL |
diagnTab B 8 ;tabella caratteri per diagnostica | diagnTab B 8 ;character table for Diagnostics |
</code> | </code> |
| |
Infatti per ogni gruppo di tre ingressi associati ad uno dei tre digit sul display avremo 8 possibili combinazioni. La tabella riassume, ad esempio, per la combinazione degli ingressi I7,I8 ed I9, i possibili lo stati del digit associato: | In fact, for each group of three inputs associated with one of the three digits on the display we will have 8 possible combinations. For example, the table summarizes the possible States of the digit associated with, the combination of inputs I7,I8 ed I9: |
| |
^I7^I8^I9^Display^ | ^I7^I8^I9^Display^ |
|1|1|1|$| | |1|1|1|$| |
| |
Servirà infine anche la definizione di alcune costanti da utilizzare come maschera per bit generici di un byte: | Will finally also defining some constants to be used as a mask for generic bits of a byte: |
| |
<code QCL> | <code QCL> |
</code> | </code> |
| |
Il codice completo per ottenere la funzione di diagnostica è: | The complete code to obtain the diagnostic function is: |
| |
<code QCL> | <code QCL> |
;inizializza tabella | ;Initializes table |
diagnTab[1] = CHAR_ | diagnTab[1] = CHAR_ |
diagnTab[2] = CHAR_UP | diagnTab[2] = CHAR_UP |
diagnTab[8] = CHAR_LOWUPCE | diagnTab[8] = CHAR_LOWUPCE |
| |
;stampa messaggio "INP." | ;print "INP." message |
hmi:dis6 = CHAR_I | hmi:dis6 = CHAR_I |
hmi:dis5 = CHAR_N | hmi:dis5 = CHAR_N |