Skip to content

Commit

Permalink
Updated examples and README
Browse files Browse the repository at this point in the history
  • Loading branch information
timyhac committed Jul 26, 2024
1 parent 515beff commit f379a6f
Show file tree
Hide file tree
Showing 13 changed files with 161 additions and 374 deletions.
4 changes: 2 additions & 2 deletions docs/libplctag.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@ var myTag = new Tag()

// Read the value from the PLC and output to console
myTag.Read();
int originalValue = myTag.GetInt32();
int originalValue = myTag.GetInt32(0);
Console.WriteLine($"Original value: {originalValue}");

// Write a new value to the PLC, then read it back, and output to console
int updatedValue = 1234;
myTag.SetInt32(updatedValue);
myTag.SetInt32(0, updatedValue);
myTag.Write();
Console.WriteLine($"Updated value: {updatedValue}");
```
Expand Down
1 change: 0 additions & 1 deletion examples/CSharp DotNetCore/CSharp DotNetCore.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="5.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="5.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="5.0.0" />
<PackageReference Include="RandomTestValues" Version="2.0.5.1" />
</ItemGroup>

</Project>
187 changes: 0 additions & 187 deletions examples/CSharp DotNetCore/ExampleAsync.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,7 @@

using libplctag;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Threading;
using System.Threading.Tasks;

Expand Down Expand Up @@ -44,190 +41,6 @@ public static async Task Run()
}


public static void SyncAsyncComparison()
{

Console.WriteLine("This method measures the speed of synchronous vs asynchronous reads");

List<Tag> myTags;

for (int ii = 0; ii < 10; ii++)
{
myTags = Enumerable.Range(0, 10)
.Select(i => {
var myTag = new Tag()
{
Name = $"MY_DINT_ARRAY_1000[{i}]",
Gateway = "10.10.10.10",
Path = "1,0",
PlcType = PlcType.ControlLogix,
Protocol = Protocol.ab_eip,
};
myTag.Initialize();
return myTag;
})
.ToList();

int repetitions = 100;

//Console.Write($"Running {repetitions} Read() calls...");
//var syncStopWatch = Stopwatch.StartNew();
//for (int ii = 0; ii < repetitions; ii++)
//{
// // We know that it takes less than 1000ms per read, so it will return as soon as it is finished
// myTag.Read(1000);
//}
//syncStopWatch.Stop();
//Console.WriteLine($"\ttook {(float)syncStopWatch.ElapsedMilliseconds / (float)repetitions}ms on average");


Console.Write($"Running {repetitions} ReadAsync() calls...");
var asyncStopWatch = Stopwatch.StartNew();
for (int jj = 0; jj < repetitions; jj++)
{
Task.WaitAll(
myTags[0].ReadAsync(),
myTags[1].ReadAsync(),
myTags[2].ReadAsync(),
myTags[3].ReadAsync(),
myTags[4].ReadAsync(),
myTags[5].ReadAsync(),
myTags[6].ReadAsync(),
myTags[7].ReadAsync(),
myTags[8].ReadAsync(),
myTags[9].ReadAsync()
);
//await myTag.ReadAsync();
}
asyncStopWatch.Stop();
Console.WriteLine($"\ttook {(float)asyncStopWatch.ElapsedMilliseconds / (float)repetitions}ms on average");
}


}

public static void ParallelBlockingReads()
{

Console.WriteLine("This method measures the speed of synchronous vs asynchronous reads");
var myTag = new Tag()
{
Name = "PROGRAM:SomeProgram.SomeDINT",
Gateway = "10.10.10.10",
Path = "1,0",
PlcType = PlcType.ControlLogix,
Protocol = Protocol.ab_eip,
};
myTag.Initialize();

int repetitions = 100;

Console.Write($"Running {repetitions} calls...");
var sw = Stopwatch.StartNew();
for (int ii = 0; ii < repetitions; ii++)
{
Task.WaitAll(
Task.Run(() => myTag.Read()),
Task.Run(() => myTag.Read())
);
}
sw.Stop();

Console.WriteLine($"\ttook {(float)sw.ElapsedMilliseconds / (float)repetitions}ms on average");

}

public static void SyncAsyncMultipleTagComparison(int repetitions = 1000)
{
Console.WriteLine("This method measures the speed of synchronous vs asynchronous reads for multiple tags simultaneously");

SyncAsyncMultipleTagComparisonSingleRun(1, repetitions);
SyncAsyncMultipleTagComparisonSingleRun(2, repetitions);
SyncAsyncMultipleTagComparisonSingleRun(3, repetitions);
SyncAsyncMultipleTagComparisonSingleRun(4, repetitions);
SyncAsyncMultipleTagComparisonSingleRun(5, repetitions);
SyncAsyncMultipleTagComparisonSingleRun(6, repetitions);
SyncAsyncMultipleTagComparisonSingleRun(7, repetitions);
SyncAsyncMultipleTagComparisonSingleRun(8, repetitions);
SyncAsyncMultipleTagComparisonSingleRun(9, repetitions);
SyncAsyncMultipleTagComparisonSingleRun(10, repetitions);
SyncAsyncMultipleTagComparisonSingleRun(11, repetitions);
SyncAsyncMultipleTagComparisonSingleRun(12, repetitions);
SyncAsyncMultipleTagComparisonSingleRun(13, repetitions);
SyncAsyncMultipleTagComparisonSingleRun(14, repetitions);
SyncAsyncMultipleTagComparisonSingleRun(15, repetitions);
SyncAsyncMultipleTagComparisonSingleRun(16, repetitions);
SyncAsyncMultipleTagComparisonSingleRun(17, repetitions);
SyncAsyncMultipleTagComparisonSingleRun(18, repetitions);
SyncAsyncMultipleTagComparisonSingleRun(19, repetitions);
SyncAsyncMultipleTagComparisonSingleRun(20, repetitions);
//SyncAsyncMultipleTagComparisonSingleRun(25, repetitions);
//SyncAsyncMultipleTagComparisonSingleRun(30, repetitions);
//SyncAsyncMultipleTagComparisonSingleRun(35, repetitions);
//SyncAsyncMultipleTagComparisonSingleRun(40, repetitions);
//SyncAsyncMultipleTagComparisonSingleRun(45, repetitions);
//SyncAsyncMultipleTagComparisonSingleRun(50, repetitions);
//SyncAsyncMultipleTagComparisonSingleRun(60, repetitions);
//SyncAsyncMultipleTagComparisonSingleRun(70, repetitions);
//SyncAsyncMultipleTagComparisonSingleRun(80, repetitions);
//SyncAsyncMultipleTagComparisonSingleRun(90, repetitions);
//SyncAsyncMultipleTagComparisonSingleRun(100, repetitions);
//SyncAsyncMultipleTagComparisonSingleRun(200, repetitions);
//SyncAsyncMultipleTagComparisonSingleRun(300, repetitions);
//SyncAsyncMultipleTagComparisonSingleRun(400, repetitions);
//SyncAsyncMultipleTagComparisonSingleRun(500, repetitions);
//SyncAsyncMultipleTagComparisonSingleRun(600, repetitions);
//SyncAsyncMultipleTagComparisonSingleRun(700, repetitions);
//SyncAsyncMultipleTagComparisonSingleRun(800, repetitions);
//SyncAsyncMultipleTagComparisonSingleRun(900, repetitions);
//SyncAsyncMultipleTagComparisonSingleRun(1000, repetitions);
}

private static void SyncAsyncMultipleTagComparisonSingleRun(int maxTags, int repetitions = 10)
{

Console.Write($"Running {repetitions} ReadAsync() calls on {maxTags} tags simultaneously...");

var myTags = Enumerable.Range(0, maxTags)
.Select(i => {
var myTag = new Tag()
{
Name = "PROGRAM:SomeProgram.SomeDINT",
Gateway = "10.10.10.10",
Path = "1,0",
PlcType = PlcType.ControlLogix,
Protocol = Protocol.ab_eip,
Timeout = TimeSpan.FromMilliseconds(1000),
};
myTag.Initialize();
return myTag;
})
.ToList();

var asyncStopWatch = Stopwatch.StartNew();

Task.WaitAll(myTags.Select(tag =>
{
return Task.Run(async () =>
{
for (int ii = 0; ii < repetitions; ii++)
{
await tag.ReadAsync();
}
});
}).ToArray());

asyncStopWatch.Stop();
Console.WriteLine($"\ttook {(float)asyncStopWatch.ElapsedMilliseconds / (float)repetitions}ms on average");

foreach (var tag in myTags)
{
tag.Dispose();
}

}


public static void AsyncParallelCancellation(int maxTags = 20, int repetitions = 100)
{

Expand Down
1 change: 0 additions & 1 deletion examples/CSharp DotNetCore/ExampleILogger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

using libplctag;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
Expand Down
138 changes: 138 additions & 0 deletions examples/CSharp DotNetCore/ExampleRaw.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
// Copyright (c) libplctag.NET contributors
// https://github.com/libplctag/libplctag.NET
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using libplctag;

namespace CSharp_DotNetCore
{
class ExampleRaw
{
public static void Run()
{
var lister = new LogixTagListing()
{
Gateway = "192.168.0.1",
Path = "1,0",
Timeout = TimeSpan.FromMilliseconds(1000),
};

var tags = lister.ListTags();

foreach (var tag in tags)
Console.WriteLine($"Id={tag.Id} Name={tag.Name} Type={tag.Type} Length={tag.Length}");
}

class LogixTagListing
{
readonly Tag _rawCip = new Tag()
{
PlcType = PlcType.ControlLogix,
Protocol = Protocol.ab_eip,
Name = "@raw",
};

public string Gateway { get => _rawCip.Gateway; set => _rawCip.Gateway = value; }
public string Path { get => _rawCip.Path; set => _rawCip.Path = value; }
public TimeSpan Timeout { get => _rawCip.Timeout; set => _rawCip.Timeout = value; }

public List<TagInfo> ListTags()
{
// This payload is taken from https://github.com/libplctag/libplctag/blob/release/src/examples/test_raw_cip.c
// but others can be found by analysing the Rockwell or other manufacturer's documentation
// https://literature.rockwellautomation.com/idc/groups/literature/documents/pm/1756-pm020_-en-p.pdf pg 39

var raw_payload = new byte[] {
0x55,
0x03,
0x20,
0x6b,
0x25,
0x00,
0x00,
0x00,
0x04,
0x00,
0x02,
0x00,
0x07,
0x00,
0x08,
0x00,
0x01,
0x00
};

_rawCip.Initialize();
_rawCip.SetSize(raw_payload.Length);
_rawCip.SetBuffer(raw_payload);
_rawCip.Write();

var responseSize = _rawCip.GetSize();

var tagInfos = new List<TagInfo>();
int offset = 0;
while (offset < responseSize)
tagInfos.Add(DecodeOneTagInfo(ref offset));

return tagInfos;
}

public class TagInfo
{
public uint Id { get; set; }
public ushort Type { get; set; }
public string Name { get; set; }
public ushort Length { get; set; }
public uint[] Dimensions { get; set; }
}

TagInfo DecodeOneTagInfo(ref int offset)
{

var tagInstanceId = _rawCip.GetUInt32(offset);
var tagType = _rawCip.GetUInt16(offset + 4);
var tagLength = _rawCip.GetUInt16(offset + 6);
var tagArrayDims = new uint[]
{
_rawCip.GetUInt32(offset + 8),
_rawCip.GetUInt32(offset + 12),
_rawCip.GetUInt32(offset + 16)
};

var apparentTagNameLength = (int)_rawCip.GetUInt16(offset + 20);
const int TAG_STRING_SIZE = 200;
var actualTagNameLength = Math.Min(apparentTagNameLength, TAG_STRING_SIZE * 2 - 1);

var tagNameBytes = Enumerable.Range(offset + 22, actualTagNameLength)
.Select(o => _rawCip.GetUInt8(o))
.Select(Convert.ToByte)
.ToArray();

var tagName = Encoding.ASCII.GetString(tagNameBytes);

offset = 22 + actualTagNameLength;

return new TagInfo()
{
Id = tagInstanceId,
Type = tagType,
Name = tagName,
Length = tagLength,
Dimensions = tagArrayDims
};

}

}

}

}
Loading

0 comments on commit f379a6f

Please sign in to comment.