ErrorUnsupported in .NET ControlLogix

169 views
Skip to first unread message

AZ Software Solutions

unread,
Jan 20, 2021, 9:38:43 AM1/20/21
to libplctag
Hello and Well Done! Great work! 
Thanks to your library I'm able to learn about AB PLC tags without having the device on hand.
I'm using version 1.0.3 from nuget, I'm running the code on my machine with the ab_server  simulator that I found.
Tags that I'm using:
tag1, tag2 = new Tag<DintPlcMapper, int[]>() {}
tag1.Value = new int[10] - only for reading
tag2.Value = new int[10] - only for writing

I wrote some code based on the examples. I have a simple loop to establish and maintain the connection:

if(!Connected)
{
try
{
CreateTags();
InitializeTags();
//Verify if can read/write
tag1.Read();
tag2.Write();
Connected = true;
}
catch(LibPlcTagException lptex)
Connected = false;
DestroyTags();
}

}

Then I read and write tags as follows:

while(Connected)
{
sr = tag1.GetStatus();
sw = tag2.GetStatus();

if( sr== Status.Ok)
{
tag1.ReadAsync();
//decide how to set outputs
}

if(sw == Status.Ok)
{
Thread.Sleep(4);  
//write outputs
tag2.WriteAsync();
}

if (sr == Status.Pending || sw == Status.Pending) 
Thread.Sleep(11); 
}
Thread.Sleep(4);   
}
The Sleep right before calling WriteAsync() and the one at the end I had to add because without this I'm getting  ErrorUnsupported  (8/-35). Attached dump from this. I guessed it needs some time between operations so I added sleep.

When testing further testing with those timeouts I noticed that the tags are getting stuck in Pending state after a while and only re-connecting fixes this issue. Added another sleep in case of Pending state, which helped a bit. This happens in Release mode outside Visual Studio, I suspect without VS overhead the performance is different. Does tag timeout not work at all in async?

One inconvenience is that the tag takes more time to establish connection than for RW operations so I have to set a high Timeout (>100ms) which doesn't makes sense to me as then for tag RW I'd expect to timeout much faster than connection takes. Can I change tag timeout after successfully connected?

I think I'm doing something wrong, as I shouldn't use these timeouts, please give me some advice.

ab_server command for my tags is:
Snippet ab_server --plc=ControlLogix --path=1,0 --tag=tag1:DINT[10] --tag=tag2:DINT[10]

ErrorUnsupported_libplctagDump1.txt

Jody Koplo

unread,
Jan 20, 2021, 11:51:05 AM1/20/21
to AZ Software Solutions, libplctag
If you're going to use the ReadAsync and the WriteAsync methods then they need to be awaited. Or at least you need to do something with the Tasks they return... You shouldn't need to be doing any thread sleeping either.

I'd remove all the sleeps and try Reading/Writing with the synchronous methods first.

Jody 

--
You received this message because you are subscribed to the Google Groups "libplctag" group.
To unsubscribe from this group and stop receiving emails from it, send an email to libplctag+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/libplctag/0355de69-4e97-4361-b928-68647a8d8277n%40googlegroups.com.

tim...@gmail.com

unread,
Jan 20, 2021, 4:29:54 PM1/20/21
to libplctag

AZ Software Solutions

unread,
Jan 21, 2021, 4:44:46 AM1/21/21
to libplctag
Just tested synchronous read/write, and also tested async with await, looks ok not falling into pending state and not throwing errors. But the reason I first switched to async was the speed.
Now with synchronous RW that loop rate is around 60, but funny thing is that this is inside Visual Studio, if I run it outside the rate goes down to 8 (  in both Debug and Release ) is it possible that Visual Studio is doing some on the fly optimizations ?
I'm running the same .exe file, same location, how is this possible?

Any advantages if I try to create and use each tag on separate thread?

Alex 

Kyle

unread,
Jan 21, 2021, 5:06:35 AM1/21/21
to libplctag
Note that the simulator is very basic.  I would not use it to determine speed.  It is purely single threaded and does only the bare minimum to be used as a test for the CI system when I do code check-ins of the C core library.   It does not support UDTs or anything other than a few basic types.

For use with a real PLC, the core library uses the least resources and performs best when using a small number of threads (e.g. one) and using the C async functions.  That may not be the case with the .Net wrappers.   Jody and Tim will be the best guides there!

Best,
Kyle

Jody Koplo

unread,
Jan 21, 2021, 4:07:17 PM1/21/21
to Kyle, libplctag
The .net lib implements async in a very poor way. It's basically a placeholder at this point. Strictly speaking you should get better performance out of the sync calls with your application.

That said, hardware is absolutely the bottleneck. You have to test against actual PLCs in real applications. The same PLC model will give different performance depending on what code is running on it, what network it's on, and what else is requesting data from it (HMI, OPC server, etc).

Jody

tim...@gmail.com

unread,
Jan 21, 2021, 8:26:02 PM1/21/21
to libplctag
The only thing I would add here is that instead of setting up different threads for each tag, you can use the async functionality to await many tags at once. This scenario would give you "better performance" than synchronous versions - something like this should take advantage of libplctags request packing functionality, reducing the total number of network calls.

await Task.WhenAll(tags.Select(tag => tag.ReadAsync());

AZ Software Solutions

unread,
Jan 22, 2021, 10:44:05 AM1/22/21
to libplctag
Ok, could possibly someone test this for me on a real AB PLC ?
When I do this with simulator:
SnippetTask.WaitAll(new Task[] { tag1.ReadAsync(), tag2.WriteAsync() }); 
I get ErrorUnsupported
Same if I do this:
Snippet var t1= tag1.ReadAsync(); var t2 = tag2.ReadAsync(); await t1; await t2;
or even this
Snippet var t1= tag1.ReadAsync(); var t2 = tag1.ReadAsync(); await t1; await t2;  

Can someone just check for me that this only happens with the simulator?
Thanks

tim...@gmail.com

unread,
Jan 22, 2021, 4:05:27 PM1/22/21
to libplctag
Try using one of the examples with the simulator: https://github.com/libplctag/libplctag.NET/blob/master/src/Examples/CSharp%20DotNetCore/ExampleAsync.c which have been tested on a real PLC.

Its hard to know what your code is exactly but I haven't seen the tags configured with appropriate values (Protocol for example).

tim...@gmail.com

unread,
Jan 22, 2021, 6:06:33 PM1/22/21
to libplctag
...and Name, PlcType, Path, Gateway, Timeout.

Clearly you have configured those because you said that it worked with the synchronous versions, but the code you've submitted here doesn't show that.

For some reason the URL didn't copy properly before, its missing the s in .cs:

AZ Software Solutions

unread,
Jan 23, 2021, 3:13:10 AM1/23/21
to libplctag
Ok here's the tag config ( I believe I didn't messed this one up)

PLC_IP ="127.0.0.1";
devpath = "1,0"; 
tagplcType = PlcType.ControlLogix; 
tagproto = Protocol.ab_eip; 
tagTimeout =120;

tag1 = new Tag<DintPlcMapper, int[]>() {     Name = "tag1",     Gateway = PLC_IP,     Path = devpath,     PlcType = tagplcType,     Protocol = tagproto,     ArrayDimensions = new int[] { 10 },     Timeout = TimeSpan.FromMilliseconds(tagTimeout), }; tag1.UseConnectedMessaging = true; 
tag1.Value = new int[10]; 
... and same for tag2
then I initialize tags with this sync method:
tag1.Initialize ();

If I get timeout I dispose both tags and create them again.
And that's really it, the code is running on a Backgroundworker dedicated for this. 
I ran ExampleAsync.cs as is and got ErrorUnsupported , I guess it has to do with the simulator I will have to wait until I can grab an actual PLC.

I will try with nativeImport methods.



Reply all
Reply to author
Forward
0 new messages