AdvancedHMI Software
General Category => Support Questions => Topic started by: Tped on June 08, 2019, 07:31:43 AM
-
I have my udt class created, and a tag defined to it (TestData as UDT_Results). When i run this line
TestData = EthernetIPforCLXCom1.ReadUDT(Of UDT_Results)("TestResults", 1)
i get this back
System.NullReferenceException
HResult=0x80004003
Message=Object reference not set to an instance of an object.
Source=MfgControl.AdvancedHMI.Drivers
StackTrace:
at MfgControl.AdvancedHMI.Drivers.UDTBytesToClass.a[a]()
at MfgControl.AdvancedHMI.Drivers.UDTBytesToClass.GetObjectFromBytes[t](Byte[] data, Int32 startIndex)
at MfgControl.AdvancedHMI.Drivers.EthernetIPforCLX.ReadUDT[t](String startAddress, Int32 numberOfElements)
at MfgControl.AdvancedHMI.FormMain.Subscription_DataReceived(Object sender, PlcComEventArgs e) in D:\Documents\Advanced HMI\3120 Pentair Data Management\AdvancedHMI\FormMain.vb:line 61
at AdvancedHMIDrivers.EthernetIPforCLXCom.DataRecSync(Object e) in D:\Documents\Advanced HMI\3120 Pentair Data Management\AdvancedHMIDrivers\AllenBradley\EthernetIPforCLXCom.vb:line 291
Not sure what i'm doing wrong, I'm a PLC guy, this vb stuff is pretty new to me.
-
There is an issue with ReadUDT in 3.99y Beta 31, this is going to be fixed in Beta 32
-
Beta 32 is now available. Try this version to see if it works for ReadUDT:
https://www.advancedhmi.com/forum/index.php?topic=2058.180
-
I'm also experiencing this null reference exception. Upgrading to Beta 32 does not appear to have resolved the issue, at least not for my scenario.
//readData = ethernetIPforCLXCom1.ReadUDT<CompleteUDT>("TestData");
at MfgControl.AdvancedHMI.Drivers.UDTBytesToClass.a[a]()
at MfgControl.AdvancedHMI.Drivers.UDTBytesToClass.GetObjectFromBytes[t](Byte[] data, Int32 startIndex)
at MfgControl.AdvancedHMI.Drivers.EthernetIPforCLX.ReadUDT[t](String startAddress, Int32 numberOfElements)
at MfgControl.AdvancedHMI.Drivers.EthernetIPforCLX.ReadUDT[t](String startAddress)
at MainForm.PLC_Read(String element) in C:\Project\MainForm.cs:line 363
//readData = ethernetIPforCLXCom1.ReadUDT<CompleteUDT>("TestData", 1)[0];
at MfgControl.AdvancedHMI.Drivers.UDTBytesToClass.a[a]()
at MfgControl.AdvancedHMI.Drivers.UDTBytesToClass.GetObjectFromBytes[t](Byte[] data, Int32 startIndex)
at MfgControl.AdvancedHMI.Drivers.EthernetIPforCLX.ReadUDT[t](String startAddress, Int32 numberOfElements)
at MainForm.PLC_Read(String element) in C:\Project\MainForm.cs:line 363
I have a feeling this may be caused by having a nested UDT, similar to the following:
public class CompleteUDT
{
public PartUDT PartOne;
public PartUDT PartTwo;
public PartUDT PartThree;
public CompleteUDT()
{
PartOne = new PartUDT();
PartTwo = new PartUDT();
PartThree = new PartUDT();
}
public class PartUDT
{
public string DetailOne;
public short DetailTwo;
public float DetailThree;
public short[] DetailFour;
public float[] DetailFive;
public PartUDT()
{
DetailOne = string.Empty;
DetailTwo = 0;
DetailThree = 0f;
DetailFour = new short[64];
DetailFive = new float[64];
}
}
}
WriteUDT works fine, but ReadUDT on the root UDT returns the null reference exception.
CompleteUDT completeData = new CompleteUDT();
// Assign values
PartUDT partData = new PartUDT();
dynamic value = "0";
// Repeat following for DetailOne, DetailTwo, and DetailThree
value = "some string";
partData.DetailOne = Convert.ChangeType(value, partData.DetailOne.GetTypeCode());
// Repeat following for DetailFive (Array types)
for (int i = 0; i < partData.DetailFour.Length; i++) {
value = i;
partData.DetailFour = Convert.ChangeType(value, partData.DetailFour[i].GetTypeCode());
}
completeData.PartOne = partData;
// Repeat the block above for PartTwo and PartThree
// Write CompleteUDT to tag "TestData"
ethernetIPforCLXCom1.WriteUDT("TestData", completeData);
// Read CompleteUDT from tag "TestData"
CompleteUDT readData = new CompleteUDT();
// Cause null reference exceptions:
//readData = ethernetIPforCLXCom1.ReadUDT<CompleteUDT>("TestData");
//readData = ethernetIPforCLXCom1.ReadUDT<CompleteUDT>("TestData", 1)[0];
// Current workaround:
readData.PartOne = ethernetIPforCLXCom1.ReadUDT<CompleteUDT.PartUDT>("TestData.PartOne");
readData.PartTwo = ethernetIPforCLXCom1.ReadUDT<CompleteUDT.PartUDT>("TestData.PartTwo");
readData.PartThree = ethernetIPforCLXCom1.ReadUDT<CompleteUDT.PartUDT>("TestData.PartThree");
-
There was an issue that would let it work in the development solution, but not in the release package.
Attached is a patched file that should work.
- Download the attached file
- In Solution Explorer, expand down the AdvancedHMIDrivers project
- Right click the Support folder and select Add->Existing Item
- Browse to the location the attached file was downloaded to
- Change the file types to All Files
- Select the MfgControl.AdvancedHMI.Drivers.DLL file
- Make sure it asks to replace the file, if not you missed a step some where
- Rebuild the Solution
-
Awesome! That appears to have resolved the ReadUDT issue, thank you Archie.