Author Topic: Expose register that triggers datachanged event  (Read 1237 times)

MrPike

  • Sr. Member
  • ****
  • Posts: 297
    • View Profile
Expose register that triggers datachanged event
« on: March 21, 2019, 10:35:19 PM »
Hi guys. I am working with a device over Modbus TCP and I am creating my own register map since I don’t have access to one. I am thinking I can use a DS2 and set the element range to about 100 and populate a textbox with the register that triggers the datachanged event. I dont care about the value in the register just the register number itself.  How would I go about writing this code? I guess I could set a breakpoint but i was hoping to avoid this to make multiple executions quicker. Thanks.

Phrog30

  • Guest
Re: Expose register that triggers datachanged event
« Reply #1 on: March 22, 2019, 07:50:30 AM »
Something like this:
Code: [Select]
Private Sub DS_DataChanged(sender As Object, e As Drivers.Common.PlcComEventArgs) Handles DS.DataChanged

        textbox1.text = e.PlcAddress

End Sub

Where DS is the name of your data subscriber.

If you set element size to greater than one, then I'm pretty sure only the first element will trigger the event.  If you want all to trigger the event then you will need to add each address individually.  If I'm wrong hopefully Archie will let me know.

Archie

  • Administrator
  • Hero Member
  • *****
  • Posts: 5269
    • View Profile
    • AdvancedHMI
Re: Expose register that triggers datachanged event
« Reply #2 on: March 22, 2019, 03:08:43 PM »
If you set element size to greater than one, then I'm pretty sure only the first element will trigger the event.  If you want all to trigger the event then you will need to add each address individually.  If I'm wrong hopefully Archie will let me know.
It actually will trigger if any of the elements in the array changes. It works by creating a comma separated list of all the values, then compares it as a string to the previous list of values returned. It will not indicate which value changed, this is where you would need to write the code to check each value in the e.Values array.

Code: [Select]
    Private PreviousValues As String()
    Private Sub BasicDataLogger21_DataChanged(sender As Object, e As Drivers.Common.PlcComEventArgs) Handles BasicDataLogger21.DataChanged
        '* Is this the first returb of data?
        If PreviousValues Is Nothing Then
            PreviousValues = New String(e.Values.Count - 1) {}
            For index = 0 To e.Values.Count - 1
                PreviousValues(index) = e.Values(index)
            Next
        Else
            Dim index As Integer
            While index < PreviousValues.Length And e.Values(index) = PreviousValues(index)
                index += 1
            End While
            If index < PreviousValues.Length Then
                TextBox1.Text = "Register Number " & index & " has changed."
            End If
        End If
    End Sub

This code should actually be used with a DataSubscriber (not 2) because if more than one register value is returned, it will not work.
« Last Edit: March 22, 2019, 03:11:13 PM by Archie »

MrPike

  • Sr. Member
  • ****
  • Posts: 297
    • View Profile
Re: Expose register that triggers datachanged event
« Reply #3 on: March 27, 2019, 09:11:50 AM »
So I am turning this into a troubleshooting tool and would like to give the user the ability to assign the starting register and the number of registers to search.  A couple things, the DataSubscriber1(not 2) does not provide a number of elements property.  Second, if I were to use the DS2, how do I assign the .Add method a user input value for PLCAddress and Numberof Elements from a textbox?  I tried string, int,double and none are accepted by the driver.  Not sure how to change the DS2 properties during runtime with the code below for a button click. 

Thanks Archie!

  Private Sub btnScan_Click(sender As Object, e As EventArgs) Handles btnScan.Click

        ds21.PLCAddressValueItems.Add()               

    End Sub

Archie

  • Administrator
  • Hero Member
  • *****
  • Posts: 5269
    • View Profile
    • AdvancedHMI
Re: Expose register that triggers datachanged event
« Reply #4 on: March 27, 2019, 09:41:04 AM »
Here is a useful hint when you are not sure how to code something that can be done in the designer, such as adding a DataSubscriver2 and adding PLCAddressItems to it.

First you add the item to a form in designer like you would normally do. Then in Solution Explorer at the top you will see an icon for Show All Files, select that icon. Now you can drill down into your form and you will see a file with the form name and appended to it is designer.vb  .  This is the code that Visual Studio has written for you when you added the items to the designer. Open that file and scroll down until you see where it sets the properties for the item (DataSubscriber in this case). You will see how to write the code to do the task.

For the DataSubscriber2 you are not going to see what would you expect, so it may not be very useful. I will explain why not.... In some cases Visual Studio will write out all of the code and in other cases it will put things into a resource file, which is the case for a PLCAddressItem. Now if you look at Solution Explorer you will also see a file with the name of the form and an extension of resx. This is where the resources are stored. You can double click that to see the resources. When it first opens you still will not see your PLCAddressItems. In the resource display the first drop down selection at the top is probably set to String. You will need to change that to Other.

Now that I explained a bunch of stuff that is not completely useful, I will tell you the answer you were looking for.

The PLCAddressItem is an object, so you need to create a new instance in order to add it to the PLCAddresValueItems of the DataSubscriber2. Fortunately there is a constructor that takes parameters directly to make this easy:

MfgControl.AdvancedHMI.Drivers.PLCAddressItem("40001", 1)

So now you can use that to create the instance and add it to the DataSubscriber like this:
Code: [Select]
ds21.Add(New MfgControl.AdvancedHMI.Drivers.PLCAddressItem("40001", 1))

Now let me jump back to the Visual Studio designer code and tell you where it is important.... If you look toward the top of the code, you will find this line of code:

Code: [Select]
        CType(Me.DataSubscriber21, System.ComponentModel.ISupportInitialize).BeginInit()

This code is important because the DataSubscriber implements an interface called ISupportInitialize. The purpose of the is to let the DataSubscriber set all of its properties before it starts trying to subscribe to the driver. You can think of calling BeginInit as a "pause". To remove the "pause", you will need to call EndInit. Visual Studio handles any kind of object and must adapt so it adds the Ctype() which in your case you will not need.

So here is the final required code to add items to the DataSubscriber2:
Code: [Select]
ds21.BeginInit()
ds21.Add(New MfgControl.AdvancedHMI.Drivers.PLCAddressItem("40001", 1))
ds21.EndInit()

MrPike

  • Sr. Member
  • ****
  • Posts: 297
    • View Profile
Re: Expose register that triggers datachanged event
« Reply #5 on: April 02, 2019, 02:14:19 PM »
Thanks Archie, this was very helpful, I will try to implement this once I get free time.  Much appreciated!

Godra

  • Hero Member
  • *****
  • Posts: 1438
    • View Profile
Re: Expose register that triggers datachanged event
« Reply #6 on: September 19, 2019, 06:34:20 PM »
Here is another example of exposing the register that triggered DataChagend event for DataSubscriber2:

https://www.advancedhmi.com/forum/index.php?topic=2451.msg15112#msg15112