Sample Machine with Microsoft Silverlight and JavaScript

Microsoft Silverlight is a web-presentation-technology.

Target platform

-Windows XP, XPE, WES

-Windows Vista

-Windows 7

Implementation

-JavaScript

Required Software:

- runtime:
- Microsoft Silverlight 1.0 / 1.1
- developer tools:
- Microsoft Visual Studio 2008 Beta 2
- Microsoft Silverlight Tools Alpha Refresh for Visual Studio (July 2007)
or

- Microsoft Visual Studio 2005
- Microsoft Silverlight 1.0 Software Development Kit
For this sample Microsoft Visual Studio 2005 was used.

- designer tools:
- Expression Blend 2

- others:
- TwinCAT 2.10
- Browser (for example Internet Explorer 7 or Mozilla Firefox 2)
- Microsoft .NET Framework Version 3.0

The first steps...

Step for step you learn to develop a Silverlight-Application and include the TwinCAT ADS Web Service on a sample.

1. Create new Project:

Start the Microsoft Expression Blend 2 and create a new user interface over 'Menu->File -> new Project...' . If the Dialog 'Create New Project' open, now you can edit the type, the name, the location and the language. In this sample choose the type 'Silverlight Application (JavaScript)' and the name 'Machine'.

Sample Machine with Microsoft Silverlight and JavaScript 1:

2. Create user interface:

A few controls are available for the development of the user interfaces in Silverlight applications. You can create a RadioButton with a Textbox and two Ellipses, whitch are grouped into a Canvas. The Progressbar can be created with three Rectangles which are grouped into a separate Canvas again.
The properties of the interface are described in the Page.xaml file.
Note that you can not set the object size to 'Auto'. This may lead to errors later.

Sample Machine with Microsoft Silverlight and JavaScript 2:

You can see the two outputs in the upper left corner. The variable, which counts the work pieces, is placed below. You can change the engine speed with the two RadioButtons on the right side. The displayed steps are equivalent to the number of clocks that are returned to output 1.

3. Add XMLHTTP.JS

In Visual Studio over 'Project → Add Existing Item...' add the file 'XMLHTTP.JS'. This file contains general methods for reading and writing of PLC variables and converting data types.

Sample Machine with Microsoft Silverlight and JavaScript 3:

4. Edit source code

Open the file 'Default.html' in Visual Studio and include the 'XMLHTTP.JS' file into the header.

<scripttype="text/javascript"src="xmlhttp.js"></script>

Add a JavaScript-range in the HEAD-field of the HTML page. You find the following source code in it:

The global variables has to be declared first.

<script type="text/javascript">//enter URL to webservice here:var url = "http://localhost/TcAdsWebService/TcAdsWebService.dll";
     //enter netId here:var netId = "172.16.2.63.1.1"; 
     //enter the port here:var port = 811;
     //send soap request every x seconds:var refresh = 1000;
     
     var inuse = false;var b64s, success, errors, req;
     
     var vUp, vDown, vProgressbar, vCount, vFast, vSlow;
     
... 

You have to adapt the url of the TcAdsWebService, the netID and the port.

The GUI objects can not be accessed directly. In order to do this the objects will be assigned to already declared variables after the start of the application.

function Load(sender, eventArgs)
{
     vUp = sender.findName("pathUp");
     vDown = sender.findName("pathDown");
     vProgressbar = sender.findName("recProgressbar");
     vCount = sender.findName("txbCount");
     vFast = sender.findName("ellPointFast");
     vSlow = sender.findName("ellPointSlow");

The loading method contains the assignation of the variables. For executing the Load method Loaded="Load" has to be added to the Canvas on top of the Page.xaml.

<Canvasxmlns="http://schemas.microsoft.com/client/2007"
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     Width="368" Height="256"
     x:Name="Page"
     Loaded="Load"
>
... 
function loop(x)
{
     Read(netId, port, '16416', '0', '86'); //send soap read request via xmlhttprequest
     window.setTimeout("loop("+x+")", x); 
}

Read PLC variable

Read(netId, nPort, indexGroup, indexOffset, cbLen)
function init()
{
     b64s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
     success = 0;
     errors = 0; 
     loop(refresh); //send request every x seconds

Add onload="init()" into <body>, so that the method will be executed during loading.

<body onload="init()" >

The next function reads values and displays them. It is important that the address of the variable in Machine.pro is correctly.

function processReqChange() 

    /*
    readyStates:
    0 = uninitialized
    1 = loading
    2 = loaded
    3 = interactive
    4 = complete
    */ if (req.readyState == 4)
    {
    // only if "OK"if (req.status == 200)
    { 
        response = req.responseXML.documentElement;

        inuse = false; 

        try//check if there was an error in the request
        {
        errortext = response.getElementsByTagName('faultstring')[0].firstChild.data;
        try
        {
            errorcode = response.getElementsByTagName('errorcode')[0].firstChild.data;
        }
        catch (e){errorcode="-";}
            alert(errortext + " ("+errorcode+")");
        return;
        }
        catch (e)
        {
        errorcode=0;
        } 

        var data;
        try//if the server returns a <ppData> element decode it, otherwise (write request) do nothing
        {
        data = response.getElementsByTagName('ppData')[0].firstChild.data;
        mode = "read";
        }
        catch (e)
        {
        data = "";
        mode = "";
        }

        if (mode=="read")
        {
        try
        { 
            data = b64t2d(data); //decode result string

            steps = toInt(data.substr(1, 2));

            bool = toInt(data.substr(5,2));
            bool2 = toInt(data.substr(4,2));

            count = toInt(data.substr(3, 2)); 

            speed = toInt(data.substr(6, 2));
        }
        catch (e)
        {
            alert("Parsing Failed:" + e);
            return;
        } 

        vProgressbar.Width = 306.321/100*steps*4;

        if (bool2 != "1")
            { vCount.Text = count.toString();} 

        if (bool == "1")
            { vUp.Opacity=1.0;
              vDown.Opacity=0.0; }
        else if (bool2 == "1")
            { vUp.Opacity=0.0;
              vDown.Opacity=1.0; }
        else 
            { vUp.Opacity=0.0;
              vDown.Opacity=0.0; } 

        if (speed == "0")
           { vFast.Opacity=1.0;
             vSlow.Opacity=0.0; }
        else 
           { vSlow.Opacity=1.0;
             vFast.Opacity=0.0; }

        } 
    }
    else alert(req.statusText+" "+req.status); //cannot retrieve xml data
    }

With the last two methods the PLC variable, which controls the speed of the machine, is set to zero or one.

function Fast_MouseLeftButtonDown(sender, eventArgs) 
{
     Write(netId, port, '16416', '6', '2', '0', 'int');
}
function Slow_MouseLeftButtonDown(sender, eventArgs) 
{
     Write(netId, port, '16416', '6', '2', '1', 'int');

Write SPS Variables

Write(netId, port, indexGroup, indexOffset, cbLen, pwrData, type)

It has to be changed to 'Expression Blend 2' as it has been done with the 'Load' function for declaring the according rows as 'Click' event for both buttons.

<Canvas x:Name="canvasFast" MouseLeftButtonDown="Fast_MouseLeftButtonDown" ... 
<Canvas x:Name="canvasSlow" MouseLeftButtonDown="Slow_MouseLeftButtonDown" ... 

5. Testing:

By debugging the application you will recognize that it will not work as expected. To prevent this got to 'Build -> Publish'.

Sample Machine with Microsoft Silverlight and JavaScript 4:

Choose the 'Target location' in the dialog window and then 'All project files' under 'Copy'.

Sample Machine with Microsoft Silverlight and JavaScript 5:

If the statusbar says 'Publish succeded', you can run and test the application in the browser.

Download:

Silverlight-Sample