Beckhoff / TF6000_ADS_DOTNET_V5_Samples

Sample code for the Version 6.X series of the TwinCAT ADS .NET Packages
https://infosys.beckhoff.com/content/1033/tc3_ads.net/9407515403.html?id=6770980177009971601
BSD Zero Clause License
37 stars 15 forks source link

How to find out if an interface object is assinged or null in the PLC #55

Closed maxxie85 closed 5 months ago

maxxie85 commented 6 months ago

In our PLC projects we rely quite heavy on the OOP extensions in TwinCAT. However I'm facing a challenge which I still don't have a perfect solution for.

For example I have the following FB, which contains 2 variables that will be set during an Initialize() call. However depending on the physical configuration they will be set conditionally, so they may be null.

FUNCTION_BLOCK Cylinder IMPLEMENTS ICylinder
VAR
  _workSensor : IDigitalInput 
  _homeSensor : IDigitalInput
END_VAR

In our HMI application I have an engineering screen that scans all the symbols from the SymbolLoader, and finds known ISymbol implementations, like IDigitalInput. However in the HMI I need to check if they are null, of when looking at them in TcXaeShell they are either

Is there a method in TwinCAT.Ads to allow evaluation if it's null. I used to call TryReadValue and evaluate the result. And this worked in TwinCAT.ADS 6.0.194, because I would then get some big value, or 0. However in the latest release 6.1.197 i'm getting the following exception

System.ArgumentOutOfRangeException: Specified argument was out of the range of valid values. (Parameter 'value')
   at TwinCAT.TypeSystem.PrimitiveTypeMarshaler.Unmarshal(AnyTypeSpecifier typeSpec, Boolean bitSize, ReadOnlySpan`1 data, Object& val)
   at TwinCAT.TypeSystem.PrimitiveTypeMarshaler.Unmarshal(AnyTypeSpecifier typeSpecifier, ReadOnlySpan`1 data, Object& val)
   at TwinCAT.TypeSystem.PrimitiveTypeMarshaler.Unmarshal(Type type, ReadOnlySpan`1 data, Encoding encoding, Object& val)
   at TwinCAT.TypeSystem.PrimitiveTypeMarshaler.Unmarshal(IDataType dataType, ReadOnlySpan`1 source, Type valueType, Encoding encoding, Object& value)
   at TwinCAT.TypeSystem.PrimitiveTypeMarshaler.Unmarshal(IDataType dataType, ReadOnlySpan`1 source, Type valueType, Object& value)
   at TwinCAT.TypeSystem.SymbolicAnyTypeMarshaler.Unmarshal(IDataType dataType, Encoding encoding, ReadOnlySpan`1 data, Type valueType, Object& value)
   at TwinCAT.TypeSystem.SymbolicAnyTypeMarshaler.Unmarshal(IAttributedInstance symbol, ReadOnlySpan`1 source, Type valueType, Object& value)
   at TwinCAT.TypeSystem.InstanceValueMarshaler.Unmarshal(IAttributedInstance symbol, ReadOnlySpan`1 source, Type valueType, Object& value)
   at TwinCAT.ValueAccess.ValueFactory.CreateValue(ISymbol symbol, Memory`1 source, IValue parent, DateTimeOffset timeStamp)
   at TwinCAT.ValueAccess.ValueAccessor.TryReadValue(ISymbol symbol, Object& value, Nullable`1& timeStamp)
   at TwinCAT.Ads.TypeSystem.Symbol.OnTryReadValue(Int32 timeout, Object& value)
   at TwinCAT.Ads.TypeSystem.Symbol.TryReadValue(Int32 timeout, Object& value)
RalfHeitmann commented 6 months ago

Hi maxxie85, I have added the Version 6.1.203 to nuget.org

https://www.nuget.org/packages/Beckhoff.TwinCAT.Ads/6.1.203

That should solve your problem. Be aware there was a breaking change compared to version 6.0.194 on Pointer/Interface values in Versions >= 6.1.125:

BreakingChange: Implementation and Support of TwinCAT.TypeSystem.UInt32Ptr and TwinCAT.TypeSystem.UInt64Ptr as values instead of raw 'uint' and 'ulong' as Pointer Value representation

This change was the reason for your ArgumentOutOfRangeException and should be fixed now. These UIntXXPtr types are allowing the NULL check also.

maxxie85 commented 5 months ago

Hi Ralf,

Thank you for the update. The IsNull property if perfect.