W&T collega
Adattatori per TCP/IP, Ethernet, RS-232, RS-485, USB, 20 mA, Fibra ottica di vetro e plastica, http, SNMP, OPC, Modbus TCP, I/O digitale, I/O analogico, ISA, PCI

Applicazione relativa al Web-IO digitale:

Web-IO digitali controllo e monitoraggio con Lazarus/Free Pascal


Lazarus è un ambiente di sviluppo open source che emula Delphi e che utilizza Free Pascal. L’aspetto interessante di Lazarus è che questo ambiente di sviluppo è disponibile per Windows, Linux e alcuni sistemi MAC e può essere utilizzato attraverso vari progetti. All’indirizzo https://www.lazarus.freepascal.org/ Lazarus può essere scaricato gratuitamente.

Come linguaggio di alto livello di facile apprendimento Lazarus offre tutto ciò che è necessario per la programmazione di applicazioni Web-IO®. Per lo svolgimento della comunicazione TCP/IP deve tuttavia essere installato l’ elemento di controllo LNET supplementare come pacchetto di componenti.

Web-IO controllo con Delphi

Con il seguente esempio di programma potete riprodurre il vostro Web-IO digitale con i suoi input e output in un’applicazione Windows. Inoltre potete collegare gli output del Web-IO.

Preparativi

Avete già alimentato con corrente

1. Collocazione dei diversi elementi di comando e oggetti di visualizzazione nel modulo Lazarus

Elementi di comando Delphi

Nella denominazione dei singoli oggetti è utile utilizzare nomi che ne riprendono il significato. In questo esempio la prima parte del nome descrive il tipo di oggetto e la seconda parte la funzione.

2. Controllo del collegamento

Inizializzazione del collegamento

Immettendo l’indirizzo IP del Web-IO nel campo di testo ed_ip e facendo clic sul pulsante bt_connect viene avviata la creazione del collegamento.


			procedure TForm1.bt_connectClick(Sender: TObject);
			begin
				if ed_ip.Text <> ’’ then
				begin
					bt_connect.Enabled := false;
					LTCPComponent1.Connect(ed_ip.Text, strtoint(ed_port.Text));
				end;
			end;
		
Collegamento realizzato

Non appena il Web-IO accetta il collegamento, l’elemento di controllo ClintSocket esegue la corrispondente procedura. Nella riga di stato viene visualizzata la realizzazione del collegamento, gli elementi di comando vengono abilitati per l’utilizzo e il pulsante Disconnect risulta utilizzabile.


			procedure TForm1.LTCPComponent1Connect(aSocket:TLSocket);
			begin
				StatusBar1.SimpleText :=’Connected to ’ + ed_ip.Text;
				bt_connect.Enabled := False;
				bt_disconnect.Enabled := True;
				gb_io.Enabled := True;
			end;
		
Disinserzione del collegamento

Il collegamento rimane fino a quando non viene terminato dall’utente facendo clic sul pulsante Disconnect oppure il Web-IO termina il collegamento.


			procedure TForm1.bt_disconnectClick(Sender:TObject);
			begin
				StatusBar1.SimpleText :=’No Connection’;
				bt_connect.Enabled := True;
				bt_disconnect.Enabled := False;
				gb_io.Enabled := False;
				LTCPComponent1.Disconnect;
			end;
		

Anche in questo caso l’elemento di controllo ClientSocket richiama la corrispondente procedura


			procedure TForm1.LTCPComponent1Disconnect(aSocket:TLSocket);
			begin
				StatusBar1.SimpleText :=’No Connection’;
				bt_connect.Enabled := True;
				bt_disconnect.Enabled := False;
				gb_io.Enabled := False;
				LTCPComponent1.Disconnect;
			end;
		
Errore di collegamento

Anche nel caso di un errore di collegamento l’elemento di controllo ClientSocket esegue una corrispondente procedura che corrisponde a grandi linee alla procedura di disconnessione. Nella riga di stato viene inoltre visualizzato il numero di errore Winsock e l’ErrorCode viene alla fine impostato su 0, affinché non si arrivi ad un errore di run-time.


			procedure TForm1.LTCPComponent1Error(const msg: string; aSocket: TLSocket);
			begin
				StatusBar1.SimpleText :=’Error: ’+ msg;
				bt_connect.Enabled := True;
				bt_disconnect.Enabled := False;
				gb_io.Enabled := False;
				LTCPComponent1.Disconnect;
			end;
		

3. Utilizzo e comunicazione del lato client

Non appena viene realizzato un collegamento con il Web-IO, l’utente può inviare comandi al Web-IO utilizzando i corrispondenti elementi del programma.

Impostazione degli output

L’impostazione degli output è resa possibile all’utente da due caselle di spunta cb_outputx. Il programma utilizza a tale scopo l’evento MouseUP di questo oggetto. Se viene registrato un MouseUp, ossia un abbandono della casella di spunta degli output, il programma esegue la corrispondente procedura e inoltra al Web-IO, in base all’eventuale impostazione della casella di spunta, il comando adatto.


			procedure TForm1.cb_output0MouseUp(Sender:TOBject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
			begin
				if cb_output0.Checked then
				LTCPComponent1.SendMessage(’GET/outputaccess0?PW=’ + ed_password.Text+ ’&State=ON&’,nil)
				else
				LTCPComponent1.SendMessage(’GET/outputaccess0?PW=’ + ed_password.Text + ’&State=OFF&’,nil)
			end;
		

			procedure TForm1.cb_output1MouseUp(Sender:TOBject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
			begin
				if cb_output1.Checked then
				LTCPComponent1.SendMessage(’GET/outputaccess1?PW=’ + ed_password.Text + ’&State=ON&’,nil)
				else
				LTCPComponent1.SendMessage(’GET/outputaccess1?PW=’ + ed_password.Text + ’&State=OFF&’,nil)
			end;
		
Interrogazione dello stato degli output/input

L’utente può richiedere lo stato degli output e degli input facendo clic sul relativo pulsante.


			procedure TForm1.bt_outputs_readClick(Sender:TObject);
			begin
				LTCPComponent1.SendMessage(’GET/output?PW=’ + ed_password.Text + ’&’,nil);
			end;
		

			procedure TForm1.bt_inputs_readClick(Sender:TObject);
			begin
				LTCPComponent1.SendMessage(’GET/input?PW=’ + ed_password.Text + ’&’,nil);
			end;
		
Interrogazione/cancellazione dei counter

È possibile interrogare o cancellare anche gli stati dei counter degli input.


			procedure TForm1.bt_counter_read0Click(Sender:TObject);
			begin
				LTCPComponent1.SendMessage(’GET/counter0?PW=’ + ed_password.Text + ’&’,nil);
			end;
		

			procedure TForm1.bt_counter_read1Click(Sender:TObject);
			begin
				LTCPComponent1.SendMessage(’GET/counter1?PW=’ + ed_password.Text + ’&’,nil);
			end;
		

			procedure TForm1.bt_counter_clear0Click(Sender: TObject);
			begin
				LTCPComponent1.SendMessage(’GET/counterclear0?PW=’ + ed_password.Text + ’&’,nil);
			end;
		

				procedure TForm1.bt_counter_clear1Click(Sender:TObject);
				begin
					LTCPComponent1.SendMessage(’GET/counterclear1?PW=’ + ed_password.Text + ’&’,nil);
				end;
		

Naturalmente è possibile leggere o cancellare contemporaneamente anche tutti i counter.


			procedure TForm1.bt_counter_readallClick(Sender:TObject);
			begin
				LTCPComponent1.SendMessage(’GET/counter?PW=’ + ed_password.Text + ’&’,nil);
			end;
		

			procedure TForm1.bt_counter_clearallClick(Sender:TObject);
			begin
				LTCPComponent1.SendMessage(’GET/counterclear?PW=’ + ed_password.Text + ’&’,nil);
			end;
		

4. Ricezione dei dati dal Web-IO

Analisi e visualizzazione dei dati ricevuti
  • Tutti i comandi e le richieste al Web-IO vengono confermati con una stringa di risposta. Le risposte hanno una struttura specifica in base al tipo.
  • Per gli output: output;<valore binario dello stato degli output in formato esadecimale>
  • Per gli input: input;<valore binario dello stato degli input in formato esadecimale>
  • Per i counter: counterx;<stato del conteggio decimale>
  • oppure counter;<stato del conteggio decimale 0 >; <stato del conteggio decimale 0 >; ... se tutti i counter devono essere letti in un’unica volta.
  • Tutte le stringe di risposta terminano con 0 byte.
  • Se l’elemento di controllo ClientSocket riceve dati, esso richiama la corrispondente procedura

			procedure TForm1.LTCPComponent1Receive(aSocket:TLSocket);
			var ReceiveString : String;
			SemiPosition : integer;
			OutputValue : word;
			InputValue : word;
			begin
				aSocket.GetMessage(ReceiveString);
				if Receivestring[1] = ’o’ then
				begin
					OutputValue := HextoInt(copy(ReceiveString, pos(’;’,ReceiveString)+1,length(ReceiveString)-pos(’;’,ReceiveString)-1));
				if OutputValue and 1 = 1 then
					cb_output0.Checked := True
				else
					cb_output0.Checked := False;
				if OutputValue and 2 = 2 then
					cb_output1.Checked := True
				else
					cb_output1.Checked := False;
				end;
				if Receivestring[1] = ’i’ then
				begin
					InputValue := HextoInt(copy(ReceiveString, pos(’;’,ReceiveString)+1, length(ReceiveString)-pos(’;’,ReceiveString)-1));
				if InputValue and 1 = 1 then
					cb_input0.Checked := True
				else
					cb_input0.Checked := False;
				if InputValue and 2 = 2 then
					cb_input1.Checked := True
				else
					cb_input1.Checked := False;
				end;
				if Receivestring[1] = ’c’ then
				begin
				if copy(ReceiveString, 8, 1) = ’0’ then
					ed_counter0.Text := copy(ReceiveString, 10,length(ReceiveString)-10);
				if copy(ReceiveString, 8, 1) = ’1’ then
					ed_counter1.Text := copy(ReceiveString, 10,length(ReceiveString)-10);
				if copy(ReceiveString, 8, 1) = ’;’ then
				begin
					ReceiveString[8] := ’ ’;
					ed_counter0.Text := copy(ReceiveString, 9, pos(’;’,ReceiveString)-9);
					ed_counter1.Text := copy(ReceiveString, pos(’;’,ReceiveString)+1, length(ReceiveString)-pos(’;’,ReceiveString)-1);
				end;
				end;
			end;
			

La procedura di ricezione controlla, sulla base del primo carattere dei dati ricevuti, se si tratta di messaggi degli input, degli output o dei counter. In base a ciò viene ad es. stabilito quale stato ha quale output. Poiché lo stato degli output viene fornito in formato esadecimale, è innanzitutto necessaria una trasformazione in un valore intero per calcolare ulteriori fasi. Per la trasformazione è stata integrata nel programma una corrispondente funzione. Nei counter è possibile sia interrogare i valori dei singoli contatori che leggere tutti i counter contemporaneamente. Gli stati dei singoli contatori vengono visualizzati in una stringa in decimali separati mediante punto e virgola


			function HexToInt(HexString :String) : longWord;
			var CharCount : integer;
				HexCharValue : longWord;
				HexValue : longWord;
			begin
				HexValue := 0;
				HexString := UpperCase(HexString);
				for CharCount := 1 to length(HexString)
			do
				begin
				HexCharValue := ord(HexString[CharCount]);
				if HexCharValue > 57 then
					HexCharValue := HexCharValue - 55
				else
					HexCharValue := HexCharValue - 48;
					HexCharValue := HexCharValue
			shl ((length(HexString) - CharCount) * 4);
					HexValue := HexValue or HexCharValue;
				end;
				HexToInt := HexValue;
			end;
			
Interrogazione ciclica di determinati valori

Per permettere anche un aggiornamento automatico della visualizzazione, viene utilizzato un timer.

In base alle caselle di spunta per il polling degli output, degli input e dei counter le corrispondenti informazioni vengono richiamate dal Web-IO nell’intervallo impostato.

5. Polling

L’intervallo desiderato può essere immesso nel corrispondente campo di testo.


				procedure TForm1.timer_pollingTimer(Sender:TObject);
				begin
					if LTCPComponent1.Connected and cb_output_polling.Checked then
						LTCPComponent1.SendMessage(’GET/output?PW=’ + ed_password.Text + ’&’,nil);
					if LTCPComponent1.Connected and cb_input_polling.Checked then
						LTCPComponent1.SendMessage(’GET/input?PW=’ + ed_password.Text + ’&’,nil);
					if LTCPComponent1.Connected and cb_counter_polling.Checked then
						LTCPComponent1.SendMessage(’GET/counter?PW=’ + ed_password.Text + ’&’,nil);
				end;
			

In caso di modifica l’intervallo del timer viene adattato automaticamente.


			procedure TForm1.ed_intervalChange(Sender:TObject);
			begin
				timer_polling.Interval:= strtoint(ed_interval.text);
			end;
			

Il programma esempio supporta tutte le comuni funzioni del Web-IO nella modalità stringa di comando, ottimizzata per il Web-IO 2x input digitale, 2x output digitale Per gli altri modelli di Web-IO devono essere eventualmente apportati adattamenti al programma. Ulteriori esempi di programma per la programmazione socket sono riportati nelle pagine dei tool relative al Web-IO. Una descrizione dettagliata relativa all’interfaccia socket dei modelli Web-IO digitali è riportata nel manuale di riferimento.

Download esempio di programma

Non disponete ancora di un Web-IO e desiderate semplicemente provarne il funzionamento come nell’esempio illustrato?

Nessun problema: vi mettiamo a disposizione gratuitamente per 30 giorni il Web-IO digitale 2x input, 2x output. Non dovete far altro che compilare l’ordinazione del campione e vi forniremo il Web-IO in prova in conto aperto. Se ci restituite l’apparecchio entro 30 giorni, vi accreditiamo completamente la fattura.

All’ordinazione del campione