W&T Interfaces
for TCP/IP, Ethernet, RS-232, RS-485, USB, 20mA
Glass and plastic fiber optic, http, SNMP, OPC, I/O digital, I/O analog, ISA, PCI, ...?
      Products
Home Contact   Distributors worldwide
Languages:
DE

US

ES

IT

RU
Climate measurement
Web-Thermograph
WuTooth
Web-IO
Digital
Analog
Special
Data Server
Motherbox 2
pure.box 2
Network Memory
TCP/IP-Ethernet servers
Com-Server (serial)
USB Server
Serial interfaces
USB, RS232, RS485, 20mA
Isolators & fiber optics
USB, RS232, RS485, 20mA
PC cards
PCI Express, PCI and
ISA bus
...
Printer interfaces
Accessories
Downloads
Old
Shopping basket Your shopping basket

 
      Technical knowledge
Books, articles, glossaries...
Technical background info
Applications for Com-Server,
USB Server
, Web-IO,
Web Thermometer,
Motherbox and pure.box
 
Application for the Web-IO Digital:

Control and monitor the Web-IO Digital with Visual C#




 Additional links: Product overview Application overview Print version


Visual C++ was until recently one of the most widely used development platforms for creating Windows applications. But in the meantime, more and more programmers are working with the .Net Framework and creating their applications in C#.

Controlling Web-IO Digital with C Sharp

Using the following C# program example you can represent your Web-IO Digital with its inputs and outputs in a Windows application. You can also switch the Web-IO outputs.


You don’t have a Web-IO® yet but would like to try the example out sometime?

No problem: We will be glad to send you the Web-IO Digital 2xInput, 2xOutput at no charge for 30 days. Simply fill out a sample ordering form, and we will ship the Web-IO for testing on an open invoice. If you return the unit within 30 days, we will simply mark the invoice as paid.

To sample orders   To sample orders  

Preparations
You have already provided your Web-IO Digital
1. Combine the various operating elements and display objects in the form


2. Import resources and declarations from member variables
  • Firstly, all classes required for the network connection and the GUI are imported.
    using System;
    using System.Drawing;
    using System.Collections;
    using System.ComponentModel;
    using System.Windows.Forms;
    using System.Data;
    using System.Net;
    using System.Net.Sockets;
    using System.Text;

  • Then the application components and important variables for a TCP connection are declared as member variables, thereby making them accessible to the class methods.

    private System.Windows.Forms.CheckBox cb_Output0;
    private System.Windows.Forms.CheckBox cb_Output1;
    private System.Windows.Forms.CheckBox cb_Input0;
    private System.Windows.Forms.CheckBox cb_Input1;
    private System.Windows.Forms.CheckBox cb_Polling_Counter;
    private System.Windows.Forms.CheckBox cb_Polling_Outputs;
    private System.Windows.Forms.CheckBox cb_Polling_Inputs;
    private System.Windows.Forms.Button bt_Readall_Outputs;
    private System.Windows.Forms.Button bt_Readall_Inputs;
    private System.Windows.Forms.Button bt_Clear_Counter0;
    private System.Windows.Forms.Button bt_Clear_Counter1;
    private System.Windows.Forms.Button bt_Clearall_Counter;
    private System.Windows.Forms.Button bt_Read_Counter0;
    private System.Windows.Forms.Button bt_Read_Counter1;
    private System.Windows.Forms.Button bt_Readall_Counter;
    private System.Windows.Forms.Label lb_Counter0;
    private System.Windows.Forms.Label lb_Counter1;
    private System.Windows.Forms.Label lb_Intervall;
    private System.Windows.Forms.TextBox tb_Counter0;
    private System.Windows.Forms.TextBox tb_Counter1;
    private System.Windows.Forms.TextBox tb_Intervall;
    private System.Windows.Forms.Button bt_Connect;
    private System.Windows.Forms.Button bt_Disconnect;
    private System.Windows.Forms.TextBox tb_Password;
    private System.Windows.Forms.TextBox tb_Port;
    private System.Windows.Forms.TextBox tb_IP;
    private System.Windows.Forms.GroupBox gb_ioControlBox;
    private System.Windows.Forms.GroupBox gb_conControlBox;
    private System.Windows.Forms.StatusBar statusBar;
    private System.ComponentModel.Container components = null;
    private System.Windows.Forms.Timer counter;
    private System.Windows.Forms.Timer outputs;
    private System.Windows.Forms.Timer inputs;

    private Socket client;
    private string rcv;
    private int intervall;
    private byte[] buffer = new byte[256];

3. Starting the program
  • Setting up the operating elements
    The group with the operating elements for the Web-IO is first blocked from operation. As soon as a connection is established, all elements are enabled which have a meaningful format.

  • The name of the respective operating element is derived from the element itself depending on the context. The first two characters in the name stand for the element type (cb -> Checkbox, bt -> Button, gb -> Groupbox and
    tb-> TextBox).


public mainWindow()
{
  InitializeComponent();

  gb_ioControlBox.Enabled = false;
  bt_Disconnect.Enabled = false;
  cb_Input0.Enabled = false;
  cb_Input1.Enabled = false;
  tb_Counter0.Enabled = false;
  tb_Counter1.Enabled = false;
}

4. Connection control
  • Establishing the connection
    After entering the IP address for the Web-IO in the text field tb_IP and Port 80 in the text field tb_port, clicking on the bt_connect button allows a connection to be opened. If no IP address or port is entered, a message is displayed in the status bar

  • Opening the connection
    Now to be able to open a TCP connection, the already declared socket variable is initialized. It is given a stream and the connection type. In addition, a variable is generated which saves the port and IP address.

    So that the program can run asynchronous, it does not wait for events, but rather uses callback routines. Callback methods are initialized when a process is started and invoked when the corresponding event occurs, i.e. for example when a connection is opened, for sending or receiving.

private void bt_Connect_Click(object sender, System.EventArgs e)
{
  try
  {
    if((tb_IP.Text != "") && (tb_Port.Text == "80"))
    {
      client = new Socket(AddressFamily.InterNetwork, SocketType.Stream,                           ProtocolType.Tcp);
      IPEndPoint ipep = new IPEndPoint(IPAddress.Parse(tb_IP.Text),                                        int.Parse(tb_Port.Text));
      client.BeginConnect(ipep, new AsyncCallback(connectCallback), client);
    }
    else
      statusBar.Text = "IP and Port needed!";
  }
  catch(SocketException)
  { statusBar.Text = "Connection not possible!"; }
}

  • In the following the callback routine is shown which is invoked when the connection is established.
    After successfully opening a connection, all useful operating elements for the application are enabled and the Connect button deactivated. In addition, the application immediately begins to go into receive ready mode. For this the callback routine "receivecallback" is initialized, which is explained in greater detail below.

private void connectCallback(IAsyncResult ar)
{
  try
  {
    client = (Socket) ar.AsyncState;
    client.EndConnect(ar);
    statusBar.Text = "Connected!";

    gb_ioControlBox.Enabled = true;
    bt_Disconnect.Enabled = true;
    bt_Connect.Enabled = false;

    intervall = 1000;
    client.BeginReceive(buffer, 0, 255, SocketFlags.None, new                         AsyncCallback(receiveCallback), client);
  }
  catch(Exception)
  { disconnect(); statusBar.Text = "Error while connecting!"; }
}



  • Disconnecting
    The connection remains open until the user clicks on the Disconnect button or until it is ended by the Web-IO. After clicking on the button a message is displayed that the connection has been ended.
private void bt_Disconnect_Click(object sender, System.EventArgs e)
{
  disconnect();
}

 

  • When the connection is ended all elements must be returned to their initial state. It should then no longer be possible to actuate the Disconnect button.
private void disconnect()
{
  try
  {
    client.Shutdown(SocketShutdown.Both);
    client.Close();
    statusBar.Text = "Disconnected!";

    gb_ioControlBox.Enabled = false;
    bt_Disconnect.Enabled = false;
    bt_Connect.Enabled = true;
  }
  catch(Exception)
  { statusBar.Text = "Not able to disconnect!"; }
}

 

  • Now the connection is closed again and the application reset to its initial state.
5. Operation and communication from the client side

As soon as a connection is made with the Web-IO, the user can use the corresponding program elements to send commands to the Web-IO.

  • When sending a message to the Web-IO, a callback routine is invoked just as in the case of receiving.


    private void sendCallback(IAsyncResult ar)
    {
      try
      {
        Socket tmp_client = (Socket) ar.AsyncState;
        int bytessend = tmp_client.EndSend(ar);
      }
      catch(Exception)
      { statusBar.Text = "Error while sending"; }
    }


  • Setting the outputs
    The outputs on the Web-IO can be switched using the two checkboxes IDC_OUTPUT0 and IDC_OUTPUT1. The checkbox notes when it was clicked and then triggers an action. Depending on whether the checkbox is already set, the output is either set to ON or OFF.

private void cb_Output0_CheckedChanged(object sender, System.EventArgs e)
{
if(cb_Output0.Checked)
  send("GET /outputaccess0?PW=" + tb_Password.Text + "&State=ON&");
else
  send("GET /outputaccess0?PW=" + tb_Password.Text + "&State=OFF&");
}

private void cb_Output1_CheckedChanged(object sender, System.EventArgs e)
{
if(cb_Output1.Checked)
  send("GET /outputaccess1?PW=" + tb_Password.Text + "&State=ON&");
else
  send("GET /outputaccess1?PW=" + tb_Password.Text + "&State=OFF&");
}

  • Query output/input status
private void bt_Readall_Outputs_Click(object sender, System.EventArgs e)
{
  send("GET /output?PW=" + tb_Password.Text + "&");
}
private void bt_Readall_Inputs_Click(object sender, System.EventArgs e)
{
  send("GET /input?PW=" + tb_Password.Text + "&");
}
  • Query counters
    The following method sends a request to a particular counter and requests a reply containing the current state of the counter.
private void bt_Read_Counter0_Click(object sender, System.EventArgs e)
{
  send("GET /counter0?PW=" + tb_Password.Text + "&");
}
private void bt_Read_Counter1_Click(object sender, System.EventArgs e)
{
  send("GET /counter1?PW=" + tb_Password.Text + "&");
}
  • Of course all the counter states can also be polled using one command.

    private void bt_Readall_Counter_Click(object sender, System.EventArgs e)
    {
      send("GET /counter?PW=" + tb_Password.Text + "&");
    }

  • Reset counter
private void bt_Clear_Counter0_Click(object sender, System.EventArgs e)
{
  send("GET /counterclear0?PW=" + tb_Password.Text + "&");
}
private void bt_Clear_Counter1_Click(object sender, System.EventArgs e)
{
  send("GET /counterclear1?PW=" + tb_Password.Text + "&");
}

  • Of course all the counters can be reset together using a single command.

    private void bt_Clearall_Counter_Click(object sender, System.EventArgs e)
    {
      send("GET /counterclear?PW=" + tb_Password.Text + "&");
    }

  • Since all counter states can be read or reset using one command, there must be a method implemented which processes the reply string from the Web-IO and assigns each counter in the application its specific state.

    private void readAndClearCounter(string data)
    {
      int j = 0;
      string[] counter = new string[12];
      for(int i = 0; i < data.Length-1; i++)
      {
        if((data[i].CompareTo(';')) == 0)
          j++;
        else
          counter[j] += data[i].ToString();
      }
      tb_Counter0.Text = counter[0];
      tb_Counter1.Text = counter[1];
    }
6. Data reception from the Web-IO
  • Process and display the received data

    All commands and requests to the Web-IO are acknowledged with a reply string. The replies have a specific structure depending on the type:

    For the outputs: output;<binary value of the output status in hexadecimal format>
    For a special output: outputx;<ON or OFF>

    For the inputs: input;<binary value of the input status in hexadecimal format>
    For a special input inputx;<ON or OFF>

    Then there is the reply string for a counter, which looks as follows.

    Counter: counterx;<decimal counter state>

    or counter;<decimal counter state 0 >; <decimal counter state 0 >; ... if you want to read all the counters at one time.

    All reply strings are finished off with a 0 byte.

    In our application the method receiveCallback() is invoked to receive such a message. In this method the reply string from the Web-IO is read and processed. The unique feature here is the event-driven invoking, which takes place as soon as the Web-IO sends data to the application.
private void receiveCallback(IAsyncResult ar)
{
  int bytesRead;
  try
  {
    bytesRead = client.EndReceive(ar);
    rcv = string.Empty;
    rcv = Encoding.ASCII.GetString(buffer);

    client.BeginReceive(buffer, 0, 255, SocketFlags.None , new                         AsyncCallback(receiveCallback), client);
  }
  catch(Exception)
  { bytesRead = 0; }

  if(bytesRead == 0 && client.Connected)
    disconnect();
  else if(rcv != null)
  {
    if(rcv[0] == 'o')
    {
      int i = Int32.Parse(rcv.Substring(7),                           System.Globalization.NumberStyles.HexNumber);
      if((i & 1) == 1)
        cb_Output0.Checked = true;
      else
        cb_Output0.Checked = false;
      if((i & 2) == 2)
        cb_Output1.Checked = true;
      else
        cb_Output1.Checked = false;
    }
    if(rcv[0] == 'i')
    {
      int i = Int32.Parse(rcv.Substring(6),                           System.Globalization.NumberStyles.HexNumber);
      if((i & 1) == 1)
        cb_Input0.Checked = true;
      else
        cb_Input0.Checked = false;
      if((i & 2) == 2)
        cb_Input1.Checked = true;
      else
        cb_Input1.Checked = false;
    }
    if(rcv[0] == 'c')
    {
      if(rcv[7] == '0')
      tb_Counter0.Text = rcv.Substring(9);
      if(rcv[7] == '1')
        tb_Counter1.Text = rcv.Substring(9);
      if(rcv[7] == ';')
        readAndClearCounter(rcv.Substring(8));
    }
  }
}
 
7. Polling
  • Cyclical polling of particular values
    It is desirable that the status of an individual component be updated by the component itself, so that the application always shows the current status. For this the program uses a timer which sends cyclical queries to the Web-IO at a user-defined time interval.

    The time interval can be specified in the field IDC_POLLINGTEXT.

    Of course this also catches cases where the user enters a nonsense value, such as a negative time value.
private void tb_Intervall_TextChanged(object sender, System.EventArgs e)
{
  try
  {
    if(Convert.ToInt32(tb_Intervall.Text) > 0)
    {
      intervall = Convert.ToInt32(tb_Intervall.Text);
      statusBar.Text = "New range: " + intervall.ToString() + " ms!";
    }
    else
      statusBar.Text = "Only positive Integer allowed!";
  }
  catch(Exception)
  { statusBar.Text = "Only positive Integer allowed!"; }
}
  • To carry out cyclical polling of the Web-IO states, you can select from among polling the outputs, the inputs or the counters.

    Each polling variant has its own timer initialized.

    Actuating the checkbox cb_Polling_Outputs causes polling to be applied to the outputs. The corresponding timer is initialized.
private void cb_Polling_Outputs_CheckedChanged(object sender, System.EventArgs e)
{
  if(cb_Polling_Outputs.Checked)
  {
    outputs = new System.Windows.Forms.Timer();
    outputs.Interval = intervall;
    outputs.Start();

    outputs.Tick += new EventHandler(timer_handler);
  }
  else
    outputs.Stop();
}
  • The same applies to inputs and counters
private void cb_Polling_Inputs_CheckedChanged(object sender, System.EventArgs e)
{
  if(cb_Polling_Inputs.Checked)
  {
    inputs = new System.Windows.Forms.Timer();
    inputs.Interval = intervall;
    inputs.Start();
    inputs.Tick += new EventHandler(timer_handler);
  }
  else
    inputs.Stop();
}

private void cb_Polling_Counter_CheckedChanged(object sender, System.EventArgs e)
{
  if(cb_Polling_Counter.Checked)
  {
    counter = new System.Windows.Forms.Timer();
    counter.Interval = intervall;
    counter.Start();

    counter.Tick += new EventHandler(timer_handler);
  }
  else
    counter.Stop();
}
  • In this method the respective event of the time which is currently reporting is captured and assigned to a particular action.
private void timer_handler(object sender, System.EventArgs e)
{
  if(sender == counter) bt_Readall_Counter_Click(sender, e);
  if(sender == outputs) bt_Readall_Outputs_Click(sender, e);
  if(sender == inputs) bt_Readall_Inputs_Click(sender, e);
}

 
The sample program supports all common functions of the Web-IO in command string mode, optimized for the Web-IO 2x Digital Input, 2x Digital Output. For the other Web-IO models you may have to adapt the program. Additional program examples for socket programming can be found on the Tool pages for the Web-IO. A detailed description for the socket interface of the Web-IO Digital models can be found in the reference manual.

To sample orders   To sample orders Download program example   To download area

 
    Additional application examples for Web-IO Digital
Web techniques
     
     
     
     
  Your own web pages
       
        PHP and AJAX - dynamic web pages also for multiple Web-IOs
        Mashup web pages - displaying values in Google Maps
        Java-Applet - use the integrated applet
        Java-Applet - Example: display in- and outputs
        Java-Applet: Example: display in- and outputs and control the outputs
        Java-Applet - Example: display counters
        Java-Applet - Example: Open doors and switch lights from the browser
        Web-IO with iPhone: visualize and control
        Web-IO with iPhone example: control shutter blinds
        Web-IO with iPhone example: monitor room climate
        Web-IO with iPhone example: display measurement values
System integration
     
     
     
     
     
      Box-to-Box
Data acquisition
     
      FTP data logger - example
Timer
     
      CRON timer (Linux)
      Task planner as timer
Individual programming
     
      Visual Basic.Net 2005/2008/2010
      Visual Basic.Net 2005/2008/2010 with WuTdevice.dll
      Visual C++
      Visual C#
      Visual C# with WuTdevice.dll
      Visual C++ (Linux with QT-Designer)
      Visual Delphi
      Visual Delphi.Net (2005)
      Lazarus / FreePascal
      Java
      control using VBScript
Web-IO system
     
     
      Motherbox - Access multiple Web-IOs
      Motherbox - Logically link Web-IOs
      Limit monitoring
  Web-IO - Options for network linking
       
        DSL
        UMTS/GPRS/mobile phone network
        Satellite radio

 
  • Mister Wong
  • Google Bookmarks
  • Twitter
  • Facebook
  • Digg
   Imprint
We are here for you personally! Wiesemann & Theis GmbH Tel.: +49 202/2680-110 (M-F 8:00 - 5:00)
Porschestr. 12 fax: +49 202/2680-265
42279 Wuppertal Individual e-mail

© Wiesemann & Theis GmbH, subject to error and alteration: Since we can make errors, none of our statements should be used without verification. Please report any mistakes or misunderstandings so that we can be aware of them and respond appropriately as quickly as possible.