W&T connects
Interfaces for TCP/IP, Ethernet, RS-232, RS-485, USB, 20mA, glass and plastic fiber optic cable, http, SNMP, OPC, Modbus TCP, I/O digital, I/O analog, ISA, PCI

Tutorial for the Web-IO Digital:

Control Web-IO Digital from your own web page using AJAX

The Web-IO Digital 4.0 make it possible to create your own web page and load it to the Web-IO. Then you can construct the interface for switching and monitoring just as you need to.

The core of such dynamic (self-refreshing) web pages is to use JavaScript and HTTP requests to call information from the Web-IO and adjust the already loaded web page content to the process image of the Web-IO.

This programming technique is referred to as Asynchronous JavaScript and XML, abbreviated as AJAX.

Controlling Web-IO using AJAX

The following example shows the structure of a very simple web page and the functions needed for displaying the IO states for the Web-IO Digital 4.0 2xIn, 2xOut.


Basic construction of your own web page

Web-IO with AJAX

The HTML basic structure of this page looks as follows:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<meta http-equiv="Content-Type" content="text/html; charset=windows-1250">
<title>Web-IO Digital, User</title>
<style type="text/css">
  * { font-family:arial; }
  table { font-size:14px; text-align:center; padding-left:5px; padding-right:5px;}
  .borderLeft { border-left:1px solid #000000; }
  .button { font-size:9px; width:40px; }
  .name { font-size:20px; font-weight:bold; text-align:center }
  .table { background-color:#d6e8ff; border-collapse:collapse; border:1px solid #000000; }
  .whiteBack { background-color:#ffffff; }
<script language="JavaScript" type="text/javascript">


<body onload="CommandLoop()">
  <div align="center">
    <h2>Web-IO 0</h2>
    <span>Password: </span>
    <input id="pw" type="password" maxlength="31" size="20"">
  <table align="center" class="table">
    <td>input 0</td>
    <td id="input0">OFF</td>
    <td id="counter0">0</td>
      <input class="button" onclick="clearCounter(0);" type="button" value="Clear">
    <td class="borderLeft">output 0</td>
    <td id="output0">OFF</td>
      <input class="button" onclick="setOutput(0,1);" type="button" value="ON">
      <input class="button" onclick="setOutput(0,0);" type="button" value="OFF">
  <tr class="whiteBack">
    <td>input 1</td>
    <td id="input1">OFF</td>
    <td id="counter1">0</td>
      <input class="button" onclick="clearCounter(1);" type="button" value="Clear">
    <td class="borderLeft">output 1</td>
    <td id="output1">OFF</td>
      <input class="button" onclick="setOutput(1,1);" type="button" value="ON">
      <input class="button" onclick="setOutput(1,0);" type="button" value="OFF">

The head area and style information will not be covered here. The contents of the script area are described in the following. Important in the body area are the id nomenclatures by means of which the objects and table cells are accessed in the JavaScript functions. Using onclick you determine the function called by the buttons. As a parameter the number of the counters and outputs is passed. For the outputs the second parameter indicates the status (0=OFF, 1=ON).

By maintaining this system the example can be adapted to other Web-IO models without changing the JavaScript functions simply by adding additional table lines.

Global variables and functions in JavaScript

First a few global variables need to be declared.

var MaxI = 2;
var MaxO = 2;
var ApplicationStep = 0;
var Interval = 500;

// Converting hexadecimal string to Integer
function HexToInt(HexStr)
{ var TempVal;
  var HexVal=0;
  for( var i=0; i<HexStr.length;i++)
  { if (HexStr.charCodeAt(i) > 57)
    { TempVal = HexStr.charCodeAt(i) - 55;
    { TempVal = HexStr.charCodeAt(i) - 48;
    HexVal=HexVal+TempVal*Math.pow(16, HexStr.length-i-1);
  return HexVal;

Sending HTTP requests and receiving HTTP replies

// Sending command lines to Web-IO and receiving IO State
function DataRequest(SendString)
{ var xmlHttp;
  if( window.ActiveXObject )       // Internet Explorer
  { xmlHttp = new ActiveXObject( "Microsoft.XMLHTTP" );
  else if(window.XMLHttpRequest )  // Mozilla, Opera und Safari
  {	xmlHttp = new XMLHttpRequest();
  if (xmlHttp)
  { xmlHttp.onreadystatechange = function()
    { if (xmlHttp.readyState == 4)
      { if (xmlHttp.status == 200)
        { if (xmlHttp.responseText.length > 0)
          { updateDisplay(xmlHttp.responseText);
    xmlHttp.open("GET", SendString, true);
    xmlHttp.setRequestHeader("If-Modified-Since", "Thu, 1 Jan 1970 00:00:00 GMT");

Processing of HTTP Request and HTTP Reply is handled by the function DataRequest. Unfortunately Internet Explorer uses different mechanisms for processing HTTP requests than other browsers. Therefore the function first checks in which browser the web page is being opened in. The HTTP Request sent as SendString is then sent to the server and to the Web-IO from which the web page was loaded. The reply, that is the HTTP reply, is then passed to the UpdateDisplay function.

Cyclical querying of inputs, outputs and counters

// Preparing command lines for cycle sending
function CommandLoop()
{ var CommandString =’’;
  var IOPassword = document.getElementById(’pw’).value;
  { case 1:
      CommandString = ’input’;
    case 2:
      CommandString = ’output’;
    case 3:
      CommandString = ’counter’;
      ApplicationStep = 0;
  DataRequest(CommandString + ’?PW=’ + IOPassword + ’&’);
  maintimer = setTimeout("CommandLoop()", Interval);

The CommandLoop function is started using the parameter onload in the body tag as soon as the web page is fully loaded. The function uses the DataRequest function for alternatingly sending HTTP requests to the Web-IO for polling inputs, outputs and counters and automatically calls itself again after a time delay. In this way the IO states are continually refreshed at a fixed interval.

Switching the outputs

// Set Output to ON (requested from User)
function setOutput(OutNo, OutVal)
{ var IOPassword = document.getElementById(’pw’).value;
  var CommandString = ’outputaccess’+OutNo+’?PW=’+IOPassword+’&State=OFF&’;
  { CommandString = ’outputaccess’+OutNo+’?PW=’+IOPassword+’&State=ON&’;

Clicking on the corresponding buttons calls the setOutput function and the number of the output and transmits which state should be assumed. Using the DataRequest function the necessary HTTP Request is sent to the Web-IO.

Clearing the counters

// Set Counter to 0 (requested from display)
function clearCounter(CounterNo)
{ var IOPassword = document.getElementById(’pw’).value;

Clicking on the corresponding buttons calls the clearCounter function and transfers the input number.

Refreshing the web page contents

// Dynamic update of the display depending on IO State
function updateDisplay(ReceiveStr)
{ var HexVal;
  var State;
  var ReceiveData = ReceiveStr.split(’;’)
  // Display Intput State
  if (ReceiveData[ReceiveData.length - 2].substring(0, 1) == ’i’)
  { HexVal = HexToInt(ReceiveData[ReceiveData.length - 1]);
    for (var i = 0; i < MaxI; i++)
    { State = false;
      if ((HexVal & Math.pow(2, i)) == Math.pow(2, i))
      { State = true;
      document.getElementById(’input’+i).firstChild.data = ( !State ) ? ’OFF’ : ’ON’;
  // Display Output State
  if (ReceiveData[ReceiveData.length - 2].substring(0, 1) == ’o’)
  { HexVal = HexToInt(ReceiveData[ReceiveData.length - 1]);
    for (var i = 0; i < MaxO; i++)
    { State = false;
      if ((HexVal & Math.pow(2, i)) == Math.pow(2, i))
      { State = true;
      document.getElementById(’output’+i).firstChild.data = ( !State ) ? ’OFF’ : ’ON’;
  //Display Counter
  if (ReceiveData.length - MaxI - 1 >= 0)
  { if (ReceiveData[ReceiveData.length - MaxI - 1].substring(0, 1) == ’c’)
    { for (var i = 0; i < MaxI; i++)
      { document.getElementById(’counter’ + i).innerHTML = ReceiveData[ReceiveData.length - MaxI + i]
  //Display cleared Counter
  if (ReceiveData[ReceiveData.length - 2].substring(0, 1) == ’c’)
  { document.getElementById(’counter’+ ReceiveData[ReceiveData.length - 2].substring(7, ReceiveData[ReceiveData.length - 2].length)).innerHTML = ReceiveData[ReceiveData.length - 1];

In reply to an HTTP request the Web-IO always sends the actual command and, separated by a semicolon, one or more parameters.

For an input query this is for example input;1.

The function UpdateDisplay uses split to break down the passed string into a string array. For the input example the result is an array with the first field variable input and the second 1. The first letter of the first field variable determines whether the reply affects an input, output or the counters.

The second field variable contains for input and output the bit pattern for the switching state of the IOs (Bit0=Input0, Bit1=Input1, .....). Since the value is sent in hexadecimal format, it must first be converted using the function HexToInt into a decimal number.

Using an AND operation on the input value with the power of 2, which corresponds to the bit value of the individual inputs and outputs, the determination is made whether the affected input (output) is 0 or 1, i.e. OFF or ON. This is done in a loop which runs depending on the number of IOs.

Using the JavaScript function document.getElementById the display object to be refreshed is identified and adjusted correspondingly to the current switching state.

The same mechanisms are used for refreshing the counters, except that there is no hex to decimal conversion since the counter states are already passed in decimal format.

The example supports the most important functions of the Web-IO which are available using HTTP requests, optimized for the Web-IO Digital 4.0 2xIn, 2xOut. For the other Web-IO models you may have to make changes to the program. A detailed description of the binary structures can be found in the JavaScript section. A detailed description for using HTTP requests for the Web-IO Digital models can be found in the Request command overview or in the programming manual for the Web-IO.

Download program example