Ereignisgesteuertes Lesen

Download

Voraussetzungen

Sprache / IDE

Beispielprogram auspacken

C# / Visual Studio

Sample03.zip

Aufgabe

In der SPS befinden sich 7 globale Variablen. Jede SPS-Variable ist von einem anderen Datentyp. Die Werte der Variablen sollen auf möglichst effektive Weise ausgelesen und der Wert mit Zeitstempel auf einer Form in Visual Basic dargestellt werden.

Beschreibung

In dem Load-Ereignis der Form wird mit der Methode TcAdsClient.AddDeviceNotification() eine Verbindung zu jeder Variablen in der SPS erzeugt. Das Handle dieser Verbindung wird in einem Array gespeichert. Der Parameter TransMode spezifiziert die Art des Datenaustausches. In diesem Fall wird mit AdsTransMode.OnChange festgelegt, dass die SPS-Variable nur übermittelt wird falls sich der Wert in der SPS geändert hat(siehe AdsTransMode ). Der Parameter cycleTime bestimmt, wie oft die PLC checken soll, ob sich die entsprechende Varaiable geändert hat. MaxDelay ermöglicht es die Notifications für einen Zeitraum zu sammeln und nach Ablauf des Intervall im Block zu verschicken.

Wenn die SPS-Variable sich geändert hat, wird das TcAdsClient.AdsNotification() gefeuert. Der Parameter e der Eventhandler-Methode ist vom Typ AdsNotificationEventArgs und enthält die Zeit, das Handle, den Wert und das Textfeld, das die Daten anzeigen soll. In dem Closing-Ereignis werden die Verbindungen wieder mit der Methode TcAdsClient.DeleteDeviceNotification() freigegeben. Dieses sollten Sie umbedingt beachten, da jede Verbindung die mit TcAdsClient.AddDeviceNotification() hergestellt wurde Resourcen verbraucht. Setzen Sie außerdem die CycleTime auf angemessene Werte, da zu viele Schreib / Leseoperationen das System so stark auslasten kann, dass die Bedieneroberfläche stark verlangsamt wird.

Hinweis: Im Callback (OnNotification()) dürfen keine zeitintensiven Aktionen ausgeführt werden.

Ereignisgesteuertes Lesen 1:

C# Programm


using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.IO;
using TwinCAT.Ads;

namespace Sample03
{
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.Label label4;
private System.Windows.Forms.Label label5;
private System.Windows.Forms.Label label6;
private System.Windows.Forms.Label label7;
private System.Windows.Forms.Label label8;
private System.Windows.Forms.Label label9;
private System.Windows.Forms.Label label10;
private System.Windows.Forms.TextBox tbInt;
private System.Windows.Forms.TextBox tbDint;
private System.Windows.Forms.TextBox tbSint;
private System.Windows.Forms.TextBox tbLreal;
private System.Windows.Forms.TextBox tbReal;
private System.Windows.Forms.TextBox tbString;
private System.Windows.Forms.Label label11;
private System.Windows.Forms.TextBox tbBool;
private System.ComponentModel.Container components = null;

private TcAdsClient tcClient;
private int[] hConnect;
private AdsStream dataStream;
private BinaryReader binRead;

public Form1()
{
InitializeComponent();
}

protected override void Dispose( bool disposing ) ...

private void InitializeComponent() ...

[STAThread]
static void Main()
{
Application.Run(new Form1());
}

private void Form1_Load(object sender, System.EventArgs e)
{
dataStream = new AdsStream(31);
//Encoding is set to ASCII, to read strings
binRead = new BinaryReader(dataStream, System.Text.Encoding.ASCII);
// Creaste instance of class TcAdsClient
tcClient = new TcAdsClient();

// PLC1 Port - TwinCAT 3=851
tcClient.Connect(851);

hConnect = new int[7];

try
{
hConnect[0] = tcClient.AddDeviceNotification("MAIN.boolVal",dataStream,0,1,
AdsTransMode.OnChange,100,0,tbBool);
hConnect[1] = tcClient.AddDeviceNotification("MAIN.intVal",dataStream,1,2,
AdsTransMode.OnChange,100,0,tbInt);
hConnect[2] = tcClient.AddDeviceNotification("MAIN.dintVal",dataStream,3,4,
AdsTransMode.OnChange,100,0,tbDint);
hConnect[3] = tcClient.AddDeviceNotification("MAIN.sintVal",dataStream,7,1,
AdsTransMode.OnChange,100,0,tbSint);
hConnect[4] = tcClient.AddDeviceNotification("MAIN.lrealVal",dataStream,8,8,
AdsTransMode.OnChange,100,0,tbLreal);
hConnect[5] = tcClient.AddDeviceNotification("MAIN.realVal",dataStream,16,4,
AdsTransMode.OnChange,100,0,tbReal);
hConnect[6] = tcClient.AddDeviceNotification("MAIN.stringVal",dataStream,20,11,
AdsTransMode.OnChange,100,0,tbString);

tcClient.AdsNotification += new AdsNotificationEventHandler(OnNotification);
}
catch(Exception err)
{
MessageBox.Show(err.Message);
}
}

private void OnNotification(object sender, AdsNotificationEventArgs e)
{
DateTime time = DateTime.FromFileTime(e.TimeStamp);
e.DataStream.Position = e.Offset;
string strValue = "";

if( e.NotificationHandle == hConnect[0])
strValue = binRead.ReadBoolean().ToString();
else if( e.NotificationHandle == hConnect[1] )
strValue = binRead.ReadInt16().ToString();
else if( e.NotificationHandle == hConnect[2] )
strValue = binRead.ReadInt32().ToString();
else if( e.NotificationHandle == hConnect[3] )
strValue = binRead.ReadSByte().ToString();
else if( e.NotificationHandle == hConnect[4] )
strValue = binRead.ReadDouble().ToString();
else if( e.NotificationHandle == hConnect[5] )
strValue = binRead.ReadSingle().ToString();
else if( e.NotificationHandle == hConnect[6] )
{
strValue = new String(binRead.ReadChars(11));
}

((TextBox)e.UserData).Text = String.Format("DateTime: {0},{1}ms; {2}",time,time.Millisecond,strValue);
}

private void Form1_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
try
{
for(int i=0; i<7; i++)
{
tcClient.DeleteDeviceNotification(hConnect[i]);
}
}
catch(Exception err)
{
MessageBox.Show(err.Message);
}
tcClient.Dispose();
}

}
}

PLC Programm


PROGRAM MAIN
VAR
boolVal : BOOL;
intVal : INT;
dintVal : DINT;
sintVal : SINT;
lrealVal : LREAL;
realVal : REAL;
stringVal : STRING(10);
END_VAR

PROGRAM MAIN
VAR
;
END_VAR