AdvancedHMI Software
General Category => Support Questions => Topic started by: opmal7 on June 05, 2017, 11:32:04 PM
-
I am using AdvancedHMI 3.98t with a Micrologix 1100.
I am working with a sensor that outputs a Hex string message. The message contains multiple pieces of data, using different units for each piece of data. Some pieces of data are 2 bytes, some pieces of data are 8+ bytes. In the Micrologix PLC, the entire message gets imported to an integer array. In RsLogix, if I open the integer array and change the 'Radix' option to "Hex/BCD" then I can see the Hex data that is equal to the message being sent from the sensor. So, for example, N1:0=AAAA, N1:1=BBBB, N1:2=CCCC, etc.
One of the pieces of information I am interested in is made up of 8 bytes of data, meaning it is spread across 4 consecutive integer values. For example, N1:0=4151, N1:1=8AFC, N1:2=7FFC, N1:3=BADE. The actual value I'm interested in is a SP Float with the hex string value "41518AFC7FFCBADE," or a decimal equivalent of "4598769.99."
I currently have the program set up to where I can click a button, and the decimal value is displayed in a text box. The code for the button press is shown below:
Private Sub Button1_Click_1(sender As Object, e As EventArgs) Handles Button1.Click
Dim Value1() As Integer = EthernetIPforSLCMicroCom1.ReadInt("N1:0", 2)
Dim Value1Hex As String = Value1(0).ToString("X4")
Dim Value2() As Integer = EthernetIPforSLCMicroCom1.ReadInt("N1:1", 2)
Dim Value2Hex As String = Value2(0).ToString("X4")
Dim Value3() As Integer = EthernetIPforSLCMicroCom1.ReadInt("N1:2", 2)
Dim Value3Hex As String = Value3(0).ToString("X4")
Dim Value4() As Integer = EthernetIPforSLCMicroCom1.ReadInt("N1:3", 2)
Dim Value4Hex As String = Value4(0).ToString("X4")
Dim Value14digithex As String = Value1Hex.Substring(Value1Hex.Length - 4, 4)
Dim Value24digithex As String = Value2Hex.Substring(Value2Hex.Length - 4, 4)
Dim Value34digithex As String = Value3Hex.Substring(Value3Hex.Length - 4, 4)
Dim Value44digithex As String = Value4Hex.Substring(Value4Hex.Length - 4, 4)
Dim ValueHex As String = Value14digithex & Value24digithex & Value34digithex & Value44digithex
Dim I64 As Int64 = Int64.Parse(ValueHex, Globalization.NumberStyles.HexNumber)
Dim Value As Double = BitConverter.Int64BitsToDouble(I64)
TextBox1.Text = Value.ToString("#.##")
End Sub
This approach has worked so far, but it takes a few seconds for the value to show up in the textbox. I'm guessing the delay is due to the fact that the program has to read each value from the PLC, and then convert the values into a form that is meaningful (in this case, a decimal value). I would like to eliminate the button, and have the value continuously update on one of the screens with as minimal delay as possible. Does anyone have any tips on how to approach this?
-
Use a data subscriber. Do a search for that and you will find plenty of examples.
-
Your code should take no more than 50ms to execute unless your network is extremely busy. You can reduce your code to a single read like this:
Dim data() As Integer = EthernetIPforSLCMicroCom1.ReadInt("N7:0", 4)
Dim ValueHex As String = ""
For index = 0 To 3
ValueHex &= Convert.ToInt16(data(index)).ToString("X4")
Next
To get continuous updates, as Phrog mentioned, you can use a DataSubscriber2
-
Ok, so I set up a DataSubscriber2 for each PLC address I am wanting to continuously update. Now how would I convert those values from integer, to hex, and then combine them to display a floating point value? I assume I would put the code in the DataSubscriber21_DataChanged event, but how would I address each value?
-
http://advancedhmi.com/documentation/index.php?title=DataSubscriber
-
Thanks Archie, I didn't know that page existed. Good info on there!
-
Do you plan to add something similar for Datasubscriber2?
-
Is it possible to test multiple addresses using the e.PLCaddress condition?
My program is giving me an error when I run it, pointing to the following line of code:
ElseIf e.PlcAddress = "N20:33" Or "N20:34" Or "N20:35" Or "N20:36" Then ...
The error is attached
-
Try it like this:
e.PlcAddress = "N20:33" Or e.PlcAddress = "N20:34" Or e.PlcAddress = "N20:35" Or e.PlcAddress = "N20:36" Then
-
Thanks Archie, that worked. Now, how would I pull each value from the DataSubscriber?
Basically, the code should work like this:
ElseIf e.PlcAddress = "N20:33" Or e.PlcAddress = "N20:34" Or e.PlcAddress = "N20:35" Or e.PlcAddress = "N20:36" Then
Value1 = 'whatever is in N20:33
Value2 = 'whatever is in N20:34
Value3 = 'whatever is in N20:35
Value4 = 'whatever is in N20:36
I tried using Value1 = e.Values(0), Value2=e.values(1)... but got an error saying the index is out of range, so I don't think that is the correct way to do it.
-
Are you subscribing to each element individually or subscribing to the first element and specifying the number of elements?
-
I believe I'm subscribing to each element individually. I just noticed the "NumberOfElements" option.
-
If you are subscribing individually, then they will be returned one at a time:
If e.PlcAddress = "N20:33" then
value1=e.Values(0)
ElseIf e.PlcAddress = "N20:34" then
value2=e.Values(0)
ElseIf e.PlcAddress = "N20:35" then
value3=e>Values(0)
End if
-
Archie,
Is either way, subscribing individually, or using NumberOfElements, better than the other?
ie, is there a performance hit one way vs the other?
And what would the difference in the datachanged event code look like if you use NumberOfElements?
Rich
-
Is either way, subscribing individually, or using NumberOfElements, better than the other?
ie, is there a performance hit one way vs the other?
And what would the difference in the datachanged event code look like if you use NumberOfElements?
The driver automatically optimizes the communication, so there will be little to no performance difference.
This is how it would look like if done the other way:
If e.PLCAddress = "N20:33" then
value1=e.values(0)
if e.Values.Count>1 then value2=e.Values(1)
if e.Values.Count>2 then value2=e.Values(2)
End if
-
ok, That makes sense.
My other question on this, is there a reason you wouldn't use a Select Case statement?
Something like this:
Select Case e.PlcAddress
Case "N20:33"
value1 = e.Values(0)
Case "N20:34"
value2 = e.Values(0)
Case "N20:35"
value3 = e > Values(0)
Case Else
MsgBox " No handler for " & e.plcaddress
End Select
-
The Select-Case works just as well.