Professional OPC
Development Tools

logos

Online Forums

Technical support is provided through Support Forums below. Anybody can view them; you need to Register/Login to our site (see links in upper right corner) in order to Post questions. You do not have to be a licensed user of our product.

Please read Rules for forum posts before reporting your issue or asking a question. OPC Labs team is actively monitoring the forums, and replies as soon as possible. Various technical information can also be found in our Knowledge Base. For your convenience, we have also assembled a Frequently Asked Questions page.

Do not use the Contact page for technical issues.

[Bug] Reading an SByte from the server gives an Int16 as result.

More
20 Oct 2017 07:20 - 20 Oct 2017 07:20 #5601 by support
The attributes that each node has depend on its NodeClass, and are defined in the OPC UA specifications. You normally work with the "Value" attribute of the node, but there are more of them. Displaying attributes with each node during browsing would be possible, but in most cases it brings more confusion than good, because the number of items the user ends up seeing increases roughly ten-fold.

In order to determine the data type, it is necessary to read the DataType and possibly ValueRank attributes of the node. The DataType is a Node ID that tell you the element type; ValueRank is used with arrays. For simple types like SByte, the DataType will be one of the pre-defined OPC UA DataType node. We have a list of them in QuickOPC in the UADataTypeIds class. The type system in UA is complex, and is different from the .NET type system.
Last edit: 20 Oct 2017 07:20 by support.

Please Log in or Create an account to join the conversation.

More
19 Oct 2017 13:41 - 19 Oct 2017 13:49 #5594 by Erik

support wrote: If, for any reason, your code does not know that the underlying value has just 8 bits: In such case you need to read and interpret the DataType attribute of the node.


Is that the UAAtributeData returned from a Read? Because that says Int16. When discovering a node with client.BrowseDataNodes I dont find any DataType attribute.

And sure, for the progressbar case this doesn't realy worry me to much. But if we wanted to make a discovery client (for debugging purposes) we would have an rather big challange.

Anyway, thanks for putting up with me on this. Managed to find a bug that allowed -1 to overflow. Anyway. looks like i'll have to special case these occurrences.
Last edit: 19 Oct 2017 13:49 by Erik.

Please Log in or Create an account to join the conversation.

More
19 Oct 2017 13:16 #5593 by support
-1 in an Int16 converts to -1 an an SByte just fine. SByte is from -128 to +127.

256 cannot be stored in an SByte, that's true. If you are manipulating bits and you know their semantics, you should never obtain 256, because to do that you would need to turn on bit 8. So if you are writing code that knows the meaning of the bits, it knows that there are just bits 0 to 7, and manipulating these in an Int16 gives precisely the same results as doing so in an SByte, and the resulting value can be written back and will be converted to an SByte first, automatically. You just must not turn on bits that semantically are "not there".

If, for any reason, your code does not know that the underlying value has just 8 bits: In such case you need to read and interpret the DataType attribute of the node.

You also wrote that you use SByte to represent values from -100 to 100. I understand it in such way that you already have some code that assures that the value falls in this range. The code will look precisely the same, no matter if it compares SByte or Int16 values: Something like "(-100 <= value) && (value <= 100)".

Regards

Please Log in or Create an account to join the conversation.

More
19 Oct 2017 12:58 - 19 Oct 2017 13:09 #5592 by Erik
How do I use OPClabs to detect if the server type is an Int16 or an SByte?

This matters, because writing 256 to reported Int16 will overflow when the underlying type is SByte. Likewise, converting -1 presented as Int16 to SByte will overflow.

Conversions between integers in the UInt32 range and System.Decimal are precise.

And for UInt64?
Last edit: 19 Oct 2017 13:09 by Erik.

Please Log in or Create an account to join the conversation.

More
19 Oct 2017 12:54 - 19 Oct 2017 12:54 #5591 by support
OK, my understanding of your answer is that there actually isn't any problem with Int16 being returned for an SByte; it was just unexpected.

System.Decimal has enough precision (mantissa bits) to precisely represent any integer that UInt32 can hold, therefore no information is lost in this case either. Conversions between integers in the UInt32 range and System.Decimal are precise.

Regards
Last edit: 19 Oct 2017 12:54 by support.

Please Log in or Create an account to join the conversation.

More
19 Oct 2017 12:06 - 19 Oct 2017 12:52 #5590 by Erik
We utilize SByte for values ranging from -100 to 100%. This is used for devices that can operate on both sides, or to show progressbars that indicate progress in a direction for positive, and in the oposite direction for negative.

We are also utilizing Uint32 for status words. Meaning each single bit has a boolean meaning. Thankfully you utilize Int64 for this and not a floating point like for UInt64, as any floating point data type will inevetably destroy the values meaning.

As for Int16, it poses the challange of correctly detecting that what should be an Sbyte is now an Int16 and correctly convert its values while avoiding overflows and correctly converting back avoiding overflows.
Last edit: 19 Oct 2017 12:52 by Erik.

Please Log in or Create an account to join the conversation.

More
19 Oct 2017 10:56 #5589 by support
Hello,

this behavior is by design, and is explained here: opclabs.doc-that.com/files/onlinedocs/QuickOpc/Latest/User%2...ata%20Types%20in%20OPC-UA.html . It has to do with the fact that not all .NET tools are required to support SByte, and we need to make sure we are "consumable" from all the tools. QuickOPC therefore converts all values to so-called CLS-compliant types, if possible.

Can you please tell me why receiving Int16 instead of SByte presents any problem, I am curious as to what the use cases are.

Best regards

Please Log in or Create an account to join the conversation.

More
19 Oct 2017 10:16 #5588 by Erik
Hello,

When trying to read an SByte[] from our OPC UA server, the OPClabs client returns a type of Int16[].
The code used in a console app:
using (EasyUAClient client = new EasyUAClient())
{
    var result = client.Read(new UAEndpointDescriptor(UAAddress), new UANodeDescriptor($"{UANodeDescriptor}{Tag}"));
    Console.WriteLine($"#{result.ValueType} ==> {result.Value}");
}
Console.ReadKey();

Checking for a simple SByte tag results in an Int16 as well.

Is there any reason as to why we can't read Sbytes? How do I get the correct result?

Windows 7
.Net Framework version: 4.5.2
OPCLabs version: 5.40.462.1

Please Log in or Create an account to join the conversation.

Moderators: support
Time to create page: 0.058 seconds