ADS-Summenkommando: Lesen oder Schreiben von mehreren Variablen

Download

Voraussetzungen

Sprache / IDE

Beispielprogram auspacken

C# / Visual Studio

Sample09.zip

Dieses Beispiel zeigt, wie man unter Zuhilfenahme des ADS-Summenkommandos, viele Variablen lesen oder schreiben kann. Aufgebaut als TcAdsClient.ReadWrite dient es als Behälter, in dem die Unterkommandos in einem ADS-Stream transportiert werden.

ADS-Summenkommando: Lesen oder Schreiben von mehreren Variablen 1:
TwinCAT.Ads_Sample8

Wichtig ist vor Beginn, dass die 'TwinCAT.Ads.dll' eingebunden wird! Hierfür einfach den 'Solution Explorer' öffnen und 'Add References...' unter 'References' auswählen. Auf den Reiter 'Browse' klicken und die DLL aus dem 'TwinCAT -> ADS API -> .NET' Verzeichnis hinzufügen.

C# Programm

1. Variablen lesen

Zu Beginn werden zwei Strukturen definiert

namespace AdsBlockRead
{
// Structure declaration for values
internal struct MyStruct
{
public ushort uintValue;
public int dintValue;
public bool boolValue;
}

// Structure declaration for handles
internal struct VariableInfo
{
public int indexGroup;
public int indexOffset;
public int length;
}

und ein paar Variablen global deklariert.

public classForm1 : System.Windows.Forms.Form
{
[...]

privateTcAdsClient adsClient;
private string[] variableNames;
private int[] variableLengths;
VariableInfo[] variables;

Beim Start der Anwendung wird eine Verbindung mit der PLC hergestellt und Handle Parameter in die Struktur geschrieben.

private void Form1_Load(object sender, System.EventArgs e)
{
try
{
// Connect to PLC
adsClient = newTcAdsClient();
adsClient.Connect(851);

// Fill structures with name and size of PLC variables
variableNames = new string[] { "MAIN.uintValue", "MAIN.dintValue", "MAIN.boolValue" };
variableLengths = new int[] { 2, 4, 1 };

// Write handle parameter into structure
variables = newVariableInfo[variableNames.Length];
for (int i = 0; i < variables.Length; i++)
{
variables[i].indexGroup = (int)AdsReservedIndexGroups.SymbolValueByHandle;
variables[i].indexOffset = adsClient.CreateVariableHandle(variableNames[i]);
variables[i].length = variableLengths[i];
}
}
catch (Exception err)
{
MessageBox.Show(err.Message);
adsClient = null;
}
}

Nach einem Klick auf den 'Read' Button, gibt die 'BlockRead' Methode einen ADS Stream zurück. Es folgt das Prüfen der ADS Return Codes (Err), bevor die restlichen Daten aus dem Stream gelesen und in die Textboxen geschrieben werden.

private void button1_Click(object sender, System.EventArgs e)
{
if (adsClient == null)
return;

try
{
// Get the ADS return codes and examine for errorsBinaryReader reader = newBinaryReader(BlockRead(variables));
for (int i = 0; i < variables.Length; i++)
{
int error = reader.ReadInt32();
if (error != (int)AdsErrorCode.NoError)
System.Diagnostics.Debug.WriteLine(
String.Format("Unable to read variable {0} (Error = {1})", i, error));
}

// Read the data from the ADS streamMyStruct myStruct;
myStruct.uintValue = reader.ReadUInt16();
myStruct.dintValue = reader.ReadInt32();
myStruct.boolValue = reader.ReadBoolean();

// Write data from the structure into the text boxes
tbUint.Text = myStruct.uintValue.ToString();
tbDint.Text = myStruct.dintValue.ToString();
tbBool.Text = myStruct.boolValue.ToString();
}
catch (Exception err)
{
MessageBox.Show(err.Message);
}
}

Die 'BlockRead' Methode nimmt ein Objekt vom Typ 'VariableInfo[]' entgegen, in dem die Handle Parameter enthalten sind. Nach der Reservierung von Speicher, für die zu lesenden und schreibenden Werte, wird ein ADS Stream mit den Parametern vom 'VariableInfo[]' Objekt beschrieben. Am Ende überträgt das Summenkommando die Subkommandos und ein ADS Stream wird zurückgegeben.

privateAdsStream BlockRead(VariableInfo[] variables)
{
// Allocate memoryint rdLength = variables.Length * 4;
int wrLength = variables.Length * 12;

// Write data for handles into the ADS StreamBinaryWriter writer = newBinaryWriter(newAdsStream(wrLength));
for (int i = 0; i < variables.Length; i++)
{
writer.Write(variables[i].indexGroup);
writer.Write(variables[i].indexOffset);
writer.Write(variables[i].length);
rdLength += variables[i].length;
}

// Sum command to read variables from the PLCAdsStream rdStream = newAdsStream(rdLength);
adsClient.ReadWrite(0xF080, variables.Length, rdStream, (AdsStream)writer.BaseStream);

// Return the ADS error codesreturn rdStream;
}

Die Parameter für das Summenkommando bestehen aus IndexGroup (0xF080) - Aufruf des Summenkommandos, IndexOffset (variables.Length) - Anzahl der Unterkommandos, rdDataStream (rdStream) - Speicher, der gelesene Daten entgegen nimmt, wrDataStream (writer.BaseStream) - Speicher, der zu sendende Daten enthält.

Subkommandos in wrDataStream

ADS-Summenkommando: Lesen oder Schreiben von mehreren Variablen 2:
TwinCAT.Ads_Sample9


Response in rdDataStream
ADS-Summenkommando: Lesen oder Schreiben von mehreren Variablen 3:

2. Variablen schreiben Nach einem Klick auf den 'Write' Button, gibt die 'BlockRead2' Methode einen ADS Stream zurück. Es folgt das Prüfen der ADS Return Codes (Err).

private void button2_Click(object sender, EventArgs e)
{
if (adsClient == null)
return;

try
{
// Get the ADS return codes and examine for errorsBinaryReader reader = newBinaryReader(BlockRead2(variables));
for (int i = 0; i < variables.Length; i++)
{
int error = reader.ReadInt32();
if (error != (int)AdsErrorCode.NoError)
System.Diagnostics.Debug.WriteLine(
String.Format("Unable to read variable {0} (Error = {1})", i, error));
}
}
catch (Exception err)
{
MessageBox.Show(err.Message);
}
}

Die 'BlockRead2' Methode nimmt ein Objekt vom Typ 'VariableInfo[]' entgegen, in dem die Handle Parameter enthalten sind. Nach der Reservierung von Speicher, für die zu lesenden und schreibenden Werte, wird das 'MyStruct' Objekt mit den Werten der Textboxen gefüllt. Anschließend wird ein ADS Stream mit den Parametern vom 'VariableInfo[]' Objekt und den Werten vom 'MyStruct' Objekt beschrieben. Am Ende überträgt das Summenkommando die Subkommandos und ein ADS Stream wird zurück gegeben.

privateAdsStream BlockRead2(VariableInfo[] variables)
{
// Allocate memoryint rdLength = variables.Length * 4;
int wrLength = variables.Length * 12 + 7;

BinaryWriter writer = newBinaryWriter(new AdsStream(wrLength));
MyStruct myStruct;
myStruct.uintValue = ushort.Parse(tbUint2.Text);
myStruct.dintValue = int.Parse(tbDint2.Text);
myStruct.boolValue = bool.Parse(tbBool2.Text);

// Write data for handles into the ADS streamfor (int i = 0; i < variables.Length; i++)
{
writer.Write(variables[i].indexGroup);
writer.Write(variables[i].indexOffset);
writer.Write(variables[i].length);
}

// Write data to send to PLC behind the structure
writer.Write(myStruct.uintValue);
writer.Write(myStruct.dintValue);
writer.Write(myStruct.boolValue);

// Sum command to write the data into the PLCAdsStream rdStream = newAdsStream(rdLength);
adsClient.ReadWrite(0xF081, variables.Length, rdStream, (AdsStream)writer.BaseStream);

// Return the ADS error codesreturn rdStream;
}

Die Parameter für das Summenkommando bestehen aus IndexGroup (0xF081) - Aufruf des Summenkommandos, IndexOffset (variables.Length) - Anzahl der Unterkommandos, rdDataStream (rdStream) - Speicher, der gelesene Daten entgegen nimmt, wrDataStream (writer.BaseStream) - Speicher, der zu sendende Daten enthält.

Subkommandos in wrDataStream

ADS-Summenkommando: Lesen oder Schreiben von mehreren Variablen 4:
TwinCAT.Ads_Sample11


Response in rdDataStream
ADS-Summenkommando: Lesen oder Schreiben von mehreren Variablen 5: