W&T conecta
Interfaces para TCP/IP, Ethernet, RS-232, RS-485, USB, 20mA, fibra óptica de vidrio y de plástico, http, SNMP, OPC, Modbus TCP, I/O digital, I/O analógico, ISA, PCI

Aplicación al Web-IO digital:

Dirigir y supervisar Web-IO digital con Lazarus/Free Pascal


Lazarus es un ambiente de desarrollo OpenSource, que emula Delphi y se conecta en Free Pascal. Lo interesante en Lazaus es que este ambiente de desarrollo está disponible para Windows, Linux y algunos sistemas MAC y los proyectos son utilizables de forma superior. En http://www.lazarus.freepascal.org/ se puede descargar Lazarus gratis.

Como idioma fácil de aprender Lazarus ofrece casi todo lo que es necesario para programar aplicaciones Web-IO®. Para el desarrollo de la comunicación TCP/IP, sin embargo, tiene que instalarse el elemento adicional de mando LNET como paquete de componentes.

Dirigir Web-IO con Delphi

Con el ejemplo siguiente de programa puede representar su Web-IO Digital con sus Inputs y Outputs en una aplicación Windows. Además de ello puede conmutar los Outputs del Web-IO.

Preparativos

Ya ha abastecido su Web-IO Digital

1. Recopilación de los diferentes elementos de manejo y objetos de visualización en formato Lazarus

Elementos de manejo Delphi

Al denominar cada uno de los objetos, es de gran ayuda usar nombres con sentido. En este ejemplo la primera parte del nombre describe la clase de objeto y la segunda la función.

2. El control de conexión

Introducir la conexión

La conexión se arranca entrando la dirección IP del Web-IO en el campo de texto ed_ip y chasqueando el botón bt_connect.


			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;
		
Se establece la conexión

Tan pronto como el Web-IO acepta la conexión, el elemento de mando ClintSocket ejecuta el procedimiento correspondiente. En la línea de estado aparece la realización de la conexión, los elementos de manejo se liberan para el uso y puede manejarse el botón Disconnect.


			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;
		
Separar la conexión

La conexión permanece tanto tiempo hasta que el usuario la finalice chasqueando el botón Disconnect o el Web-IO finalice la conexión.


			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;
		

En este caso el elemento de mando ClientSocket también llama un procedimiento correspondiente


			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;
		
Error de conexión

En el caso de un error de conexión el elemento de mando ClientSocket también ejecuta un correspondiente procedimiento, que corresponde en general al del Disconnect. En la línea de estado se visualiza adicionalmente el número de error Winsock y el ErrorCode se pone finalmente a 0 para que no se dé un error de funcionamiento.


			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. Manejo y comunicación por parte del cliente

Tan pronto como se ha establecido la conexión con el Web-IO, el usuario puede enviar comandos al Web-IO manejando los correspondientes elementos de programa

Poner Outputs

El usuario puede poner los Outputs a través de dos casillas de verificación cb_outputx. El programa utiliza para ello el suceso de MouseUP de este objeto. Si se registra un Mouse Up, es decir soltar la caja de chequeo Output, el programa realiza el correspondiente procedimiento y transmite el adecuado comando al Web-IO - según si está puesta la casilla o no.


			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;
		
Solicitar estado de Output/Input

El usuario puede solicitar el estado de los Outputs e Inputs chasqueando el botón correspondiente.


			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;
		
Preguntar/borrar contadores

También se pueden preguntar o borrar los estados de contador de los Input-Counter.


			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 también se pueden leer o borrar al mismo tiempo todos los contadores.


			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. Recepción de datos del Web-IO

Evaluar e indicar los datos recibidos
  • Todos los comandos y solicitudes al Web-IO se confirman con un String de respuesta. Aquí las respuestas presentan una estructura específica según el tipo.
  • Para los Outputs: output;<valor binario del estado de salida en formato hexadecimal>
  • Para los Inputs: input;<valor binario del estado de salida en formato hexadecimal>
  • Para los contadores: counterx;<estado decimal de contador >
  • o counter;<estado decimal de contador 0 >; <estado decimal de contador 0 >; ...... si todos los contadores se deben leer de una sola vez.
  • Todos los Strings de respuesta se finalizan con un Byte 0.
  • Si el elemento de mando ClientSocket recibe datos, éste llama al procedimiento correspondiente

			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;
			

El procedimiento de recepción verifica según el primer signo de los datos de recepción, si se trata de un Input, Output o de mensajes del contador. Dependiendo de ello se constata p. ej. qué Output tiene qué estado. Puesto que el estado de Output se transmite hexadecimal, primero es necesario una conversión en un valor íntegro para calcular otros pasos más. Para la conversión se integró una función correspondiente en el programa. En los contadores es posible tanto preguntar valores de contador separados como también leer todos los contadores de un viaje. Cada uno de los estados de contador se emiten decimalmente separados por punto y coma en una cadena (String)


			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;
			
Solicitud cíclica de determinados valores

A fin de posibilitar una actualización automática de la indicación, se utiliza un Timer.

Dependiendo de las casillas de verificación para el Polling de Output, Input y Counter se llaman las informaciones correspondientes a un intervalo ajustado del Web-IO.

5. Polling

El intervalo deseado puede entrarse en el campo correspondiente de texto.


				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;
			

En caso de un cambio el intervalo del Timer se adapta automáticamente.


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

El programa ejemplo asiste todas las funciones corrientes del Web-IO en el modo String de comando, optimado para el Web-IO 2x Entradas digitales, 2x Salidas digitales. Para los otros modelos Web-IO tienen que realizarse en caso necesario adaptaciones en el programa. Otros ejemplos de programa para la programación del zócalo los encontrarán en las páginas de herramientas al Web-IO. Una descripción detallada de la interfaz del zócalo de los modelos Web-IO digitales la encontrarán en el manual de referencia.

Descargar el programa ejemplo

¿No tiene todavía un Web-IO y quiere probar el ejemplo presentado?

No hay problema: Le ponemos a disposición el Web-IO Digital 2xInput, 2xOutput gratis durante 30 días. Rellene sencillamente un pedido muestra y le enviaremos el Web-IO para probar a cuenta abierta. Si nos devuelve el aparato dentro de los 30 días, le abonamos la factura completa.

Al pedido muestra