Example: Machine with Microsoft Expression Blend in Microsoft Windows Vista Media Center
Microsoft Expression Blend is a program for creating program interfaces for C# and Visual Basic. In this example an interface created with the program is linked with the Machine example and subsequently integrated in the Microsoft Windows Vista Media Center. The programming language C# was used.
Target platform:
-Windows Vista
Implementation
-Visual C#
Required software:
- Microsoft .NET Framework Version 3.0
- Microsoft Expression Blend
- Microsoft Visual Studio 2005
- Microsoft Windows Vista Media Center
- Microsoft Windows SDK for .Net Framework 3.0
- Microsoft Visual Studio 2005 extensions for .Net Framework 3.0 (November 2006 CTP)
- TwinCAT 2.10
- Notepad or other text editor
First steps ...
Step by step familiarisation with the development of a program with Microsoft Visual Studio and Microsoft Expression Blend, integration of the TwinCAT ADS .NET component based on an example, and integration in the Microsoft Windows Vista Media Center.
1. Create new project:
Start Microsoft Visual Studio and create new XAML browser application. Proceed via the menu 'File -> New -> Project...' . The dialog box 'New Project' opens.
First select the project type: 'Project types -> Visual C# -> Net Framework 3.0'. The project type templates appear on the right. Select 'XAML Browser Application'. Enter a name for your project (in this case Machine) and specify the location.
2. Creating a user interface
Now change to Microsoft Expression Blend and open the project you just created in order to create the user interface.
In the upper left you see the two outputs that are also output to the Bus Terminals. The bottom left shows the variable for counting the workpieces. The cycle speed of the motor can be changed via the 'Speed' field on the right. The 'Steps' display shows the number of cycles that are output on output 1.
To make the user interfaces constantly adapt their size, copy the upper grid and insert a view box instead of the grid. Now insert the grid into the view box. Now set the size of the page, the view box and the grid to 'Auto'. This may result in shifting of elements, in which case you have to reposition them. Please ensure that the size of the page, the view box and the grid is not inadvertently reset to "fixed".
3. Adding a reference
Once the interface has been created, add a reference called 'TwinCAT.Ads.dll'. This can be done in Visual Studio or Expression Blend. In both cases proceed via the menu 'Project --> Add Reference'.
4. Security activation
Select 'Project -> <Project Name> Properties....' from the menu . .
A tab opens, in which you can specify the project properties. Select 'Security' and then 'this is a full trust application'.
5. Edit source text
You can now start creating the source text in C#.
The required namespaces 'System.IO' and 'TwinCAT.Ads' are added in the top row of the source text.
using System.IO;
using TwinCAT.Ads;
The next step involves the declarations.
privateTcAdsClient tcClient;
privateAdsStream dataStream;
privateBinaryReader binReader;
private int hEngine;
private int hDeviceUp;
private int hDeviceDown;
private int hSteps;
private int hCount;
private int hSwitchNotify;
private int hSwitchWrite;
The first method is the 'Load' method. It is used to generate instances of different classes and create a link to port 801.
//-----------------------------------------------------// Wird als erstes beim Starten des Programms aufgerufen// Is activated first when the program is started//-----------------------------------------------------private void Load(object sender, EventArgs e)
{
try
{
// Eine neue Instanz der Klasse AdsStream erzeugen// Create an new instance of the AdsStream class
dataStream = new AdsStream(7);
// Eine neue Instanz der Klasse BinaryReader erzeugen// Create a new instance of the BinaryReader class
binReader = new BinaryReader(dataStream);
// Eine neue Instanz der Klasse TcAdsClient erzeugen// Create an new instance of the TcAdsClient class
tcClient = new TcAdsClient();
// Verbinden mit lokaler SPS - Laufzeit 1 - Port 801// Connecting to local PLC - Runtime 1 - Port 801
tcClient.Connect(801);
}
catch
{
MessageBox.Show("Fehler beim Laden");
}
//...
The variables in the 'Load' method are then linked and linked with a method (that still has to be written), which is called when a variable changes.
try
{
// Initialisieren der Überwachung der SPS-Variablen// Initalizing the monitoring of the PLC variables
hEngine = tcClient.AddDeviceNotification(".engine", dataStream, 0, 1, AdsTransMode.OnChange, 10, 0, null);
hDeviceUp = tcClient.AddDeviceNotification(".deviceUp", dataStream, 1, 1, AdsTransMode.OnChange, 10, 0, null);
hDeviceDown = tcClient.AddDeviceNotification(".deviceDown", dataStream, 2, 1, AdsTransMode.OnChange, 10, 0, null);
hSteps = tcClient.AddDeviceNotification(".steps", dataStream, 3, 1, AdsTransMode.OnChange, 10, 0, null);
hCount = tcClient.AddDeviceNotification(".count", dataStream, 4, 2, AdsTransMode.OnChange, 10, 0, null);
hSwitchNotify = tcClient.AddDeviceNotification(".switch", dataStream, 6, 1, AdsTransMode.OnChange, 10, 0, null);
// Holen des Handles von 'switch' - wird für das Schreiben des Wertes benötigt// Getting the handle for 'switch' - needed for writing the value
hSwitchWrite = tcClient.CreateVariableHandle(".switch");
// Erstellen eines Events für Änderungen an den SPS-Variablen-Werten // Creating an event for changes of the PLC variable value
tcClient.AdsNotification += newAdsNotificationEventHandler(tcClient_OnNotification);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
6. Definition
Linking PLC variables:
The method AddDeviceNotification was used for linking the variables.
public int AddDeviceNotification(string variableName, AdsStream dataStream, int offset, int length, AdsTransMode transMode, int cycleTime, int maxDelay, object userData);
- variableName: Name of the PLC variable.
- dataStream: Data stream receiving the data.
- offset: Interval in the data stream.
- length: Length in the data stream.
- transMode: Event if the variable changes.
- cycletime: Time (in ms) after which the PLC server checks whether the variable has changed.
- maxDelay: Latest time (in ms) after which the event has finished.
- userData: Object that can be used for storing certain data.
The method CreateVariableHandle was used for linking the variable 'hSwitchWrite'.
int TcAdsClient.CreateVariableHandle(string variableName);
- variableName: Name of the PLC variable.
7. Write method:
A method that does not exist yet was referred to above. This method ('tcClient_OnNotification') is written next. The method is called if one of the PLC variables has changed.
//------------------------------------------------// wird bei Änderung einer SPS-Variablen aufgerufen// is activated when a PLC variable changes//------------------------------------------------private void tcClient_OnNotification(object sender, AdsNotificationEventArgs e)
{
try
{
// Setzen der Position von e.DataStream auf die des aktuellen benötigten Wertes// Setting the position of e.DataStream to the position of the current needed value
e.DataStream.Position = e.Offset;
// Ermittlung welche Variable sich geändert hat// Detecting which variable has changedif(e.NotificationHandle == hDeviceUp)
{
// Die Farben der Grafiken entsprechened der Variablen anpassen// Adapt colors of graphice according to the variablesif (binReader.ReadBoolean() == true)
{
DeviceUp_LED.Foreground = newSolidColorBrush(Colors.Red);
}
else
{
DeviceUp_LED.Foreground = newSolidColorBrush(Colors.White);
}
}
else if(e.NotificationHandle == hDeviceDown)
{
if (binReader.ReadBoolean() == true)
{
DeviceDown_LED.Foreground = newSolidColorBrush(Colors.Red);
}
else
{
DeviceDown_LED.Foreground = newSolidColorBrush(Colors.White);
}
}
else if(e.NotificationHandle == hSteps)
{
// Einstellen der ProgressBar auf den aktuellen Schritt// Setting the ProgressBar to the current step
prgSteps.Value = binReader.ReadByte();
}
else if(e.NotificationHandle == hCount)
{
// Anzeigen des 'Zähler'-Wertes// Displaying the 'count' value
lblCount.Text = binReader.ReadUInt16().ToString();
}
else if(e.NotificationHandle == hSwitchNotify)
{
// Markieren des korrekten RadioButtons// Checking the correct RadioButtonif (binReader.ReadBoolean() == true)
{
optSpeedFast.IsChecked = true;
}
else
{
optSpeedSlow.IsChecked = true;
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Lastly, we require two methods for setting the machine to fast or slow. They are used to switch a virtual switch by writing a value to the PLC variable 'switch'.
//------------------------------------------------------// wird aufgerufen, wenn das Feld 'schnell' markiert wird// is activated when the 'fast' field is marked//------------------------------------------------------private void optSpeedFast_Click(object sender, EventArgs e)
{
try
{
tcClient.WriteAny(hSwitchWrite, true);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
//------------------------------------------------------// wird aufgerufen, wenn das Feld 'langsam' markiert wird// is activated when the 'slow' field is marked//------------------------------------------------------private void optSpeedSlow_Click(object sender, EventArgs e)
{
try
{
tcClient.WriteAny(hSwitchWrite, false);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
8. Delete notifications and handles:
In the Close event of the window the links are activated again with the method DeleteDeviceNotification().
//------------------------------------------------------// wird beim Beenden des Programms aufgerufen// is activated when ending the program//------------------------------------------------------private void Close(object sender, EventArgs e)
{
try
{
// Löschen der Notifications und Handles// Deleting of the notification and handles
tcClient.DeleteDeviceNotification(hEngine);
tcClient.DeleteDeviceNotification(hDeviceUp);
tcClient.DeleteDeviceNotification(hDeviceDown);
tcClient.DeleteDeviceNotification(hSteps);
tcClient.DeleteDeviceNotification(hCount);
tcClient.DeleteDeviceNotification(hSwitchNotify);
tcClient.DeleteVariableHandle(hSwitchWrite);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
tcClient.Dispose();
}
Last but not least we need to ensure that the methods are called for the right event. To this end open Expression Blend, select Page, change to Events in Properties and enter 'Load' under 'Loaded' and 'Close' under 'Unloaded'. Proceed accordingly for the two radio buttons, except that the 'Click' event should be selected and the method 'optSpeedFast_Click' or 'optSpeedSlow_Click'.
The Machine_Final.pro PLC machine program must run in runtime system 1, and the program can be tested in Internet Explorer 7.
9. Integration in Vista Media Center
Once you have tested your project sufficiently and no errors were detected, you can integrate it in the Microsoft Windows Vista Media Center.
In Visual Studio call up the project properties again, but this time select 'Publish'. Click on 'Publish Now'. This creates an xbap file which you subsequently call up in the Media Center. This step is always required whenever the program has been modified and the change is to be transferred to the Media Center.
Now open a text editor (e.g. Notepad) and enter:
<application
URL = "C:\Users\<User>\Documents\Visual Studio 2005\Projects\Machine\Machine\Publish\Machine.xbap">
</application>
Save this under: 'C:\Users\<User>\AppData\Roaming\Media Center Programs\Machine.mcl'. If you now start your Media Center you will find your program under 'Online Media -> program library -> programs by name -> Machine'.
This is the simplest form of integration in the Microsoft Windows Vista Media Center. Further information on integration in the Media Center can be found here.