Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - bobbh95

Pages: [1] 2
1
I got a good night's sleep and did a bit of Googling -

Perhaps these threads from... nine years ago may be of interest to you.

https://www.advancedhmi.com/forum/index.php?topic=829.0
https://www.advancedhmi.com/forum/index.php?topic=765.0 Specifically the 2nd response from Godra - beginning with "For those who might be interested"

2
According to the User Manual for that Converter - pages 3 and 4 of the document - a flashing light on the TXD LED indicates that it is successfully transmitting data.

Without knowing anything else about your setup, I can only spit a few links at you and hope one of them is helpful.

https://forums.mrplc.com/index.php?/topic/20120-fx3u-as-modbus-slave/ Modbus RTU and FX3U
https://forum.arduino.cc/t/how-to-use-modbus-rtu-to-communicate-esp8266-with-plc-fx3u-slave/1062509 Same as above, but also with arduino/C-ish language
https://www.daudin.co/uploads/images/Download/Connection%20Operation%20Manual_EN/M/iO-GRID_M_Modbus_RTU_Connection_Operating_Manual(FX3U)_EN.pdf An actual MODBUS RTU manual for the FX3U PLCfrom a maybe kindasketchyplace

But as far as data transfer is concerned - it is happening. The flashing TXD light indicates as much.

Here, from the document in question:

Quote
 LED indicators:
 PWR: red power indicator, light up when there is USB connection and voltageis detected
 TXD: green TX indicator, light up when the USB port sends data
 RXD: blue RX indicator, light up when the device ports

3
What converter are you using?

4
Hey Godra!

Thanks for chiming in~ I always love seeing anything you say, it's always on point.

I get what you're saying in the other thread about it being... not necessarily necessary. I think in this case it is, though. That said, I also see the two examples you provided.

Am I to understand that the basic idea is to make the constructor create a bunch of Friend WithEvent objects to represent all of the sub-components of the NewControl, as well as assigning all of the appropriate default properties to all of the said components? Also adding those objects to the Controls collection of the NewControl, and setting up all of the Public Property (in the format of your examples) to make them viewable in the Properties pane of the Design Window?

If so, you're top tier. I love that you've not only given me everything I need to solve this problem, but you haven't given me the solution directly. Edit: <- To be perfectly clear, THIS IS NOT SARCASM, I AM BEING PERFECTLY HONEST HERE, PLEASE DON'T TAKE THIS WRONGLY

I'll be back.

Edit 2: I've also already (short term) solved this problem by doing a mix of what you prescribed initially in the other thread and what I was trying to do. I made a control with the layout I wanted, then in the MainForm assigned all of the necessary values (including the ComComponent values) and then added them to the necessary Controls collection.

Sometimes I have to make a form with 300+ similar controls though, and going through and manually assigning all of the tag values for 1k+ LEDs is... painful.

(Right now I have something to the effect of

Code: [Select]
For Each tag in TagList
    control.SimpleLED1.PLCAddress = tag_base & tag_ending1
    control.SimpleLED2.PLCAddress = tag_base & tag_ending2
    control.SevenSegment21.PLCAddress = tag_base & whimsical_ending

5
For example:

Say I put both this PilotLight3Color and this ChartByLogging control into a new user control. As soon as I add either of them via the GUI, the EthernetIPforCLXcom1 component is automatically created in the Control Design window. How can I go about making the PilotLight3Color and the ChartByLogging automatically look at and subscribe to the ComComponent that is already created in the parent window?



Would I do something to the effect of:

Code: [Select]
    Private m_ComComponent As MfgControl.AdvancedHMI.Drivers.IComComponenet
    Public Property ComComponent As MfgControl.AdvancedHMI.Drivers.IComComponent
        Get
            Return m_ComComponent
        End Get
        Set(value As IComComponent)
            PilotLight3Color1.ComComponent = value
            ChartByLogging1.ComComponent = value
            ' ... until necessary for all sub-controls
            m_ComComponent = value
        End Set
    End Property

and then that would just be the end of the story? Would that automatically set all of the ComComponents for all the sub-controls inside of the UserControl?

Thanks again!



Edit:= Do I need to delete the automatically generated EthernetIPforCLXcom1 inside of the UserControl? If so, how do I refer to the one that I'm pointing to? Do I use reflection? Or do I pass it in as an argument to the class?

6
Hey Archie, thanks for responding once again!

I can see that that's possible - but is there a way to override multiple controls simultaneously, and also automatically?

When I am creating a UserControl, and I insert a PilotLight3Color, for example, it automatically creates a ComComponent for me. It then automatically routes all of the individual "sub-controls" to the automatically generated ComComponent.

This is similar to how you can graphically add a PilotLight3Color to the Design window of a WinForm, and it will automatically route to the ComComponent (if already available) in the Form. I would like to be able to make a new component that contains multiple PilotLight3Color (simply as an example) and have them all point to the same tag.

I can upload an example here shortly.

7
As an example:

New user control, with both a SevenSegment2 and also a PilotLight3Color. I want both of these (the SevenSegment2 and the PilotLight3Color) to be both settable via the GUI/code, but also to automatically override the defaults, if/how possible.

Thank you all!

8
Support Questions / Adding Existing Controls as Members of New Control
« on: October 18, 2024, 07:37:42 PM »
Howdy all!

Say I have a brand new AdvancedHMI project. I have a MainForm.

From here, I go to the AdvancedHMIControls section of the solution, and I make a new directory. Inside of that directory, I make a new User Control. Inside of that new User Control, I add a PilotLight3Color.

That PilotLight3Color has a ComComponent (settable via GUI or tt) that automatically gets inherited from whatever is available when placed by GUI. That ComComponent is also automatically created if I use the GUI to add a new PilotLight3Color to my new UserControl. How can I make that automatically generated ComComponent be the same object as something I pass in via the GUI?

Say that my UserControl instead has five PilotLight3Colors - how can I make "ComComponent" a member that is both accessible from the GUI interface, but also "overrides" all member versions of the ComComponent. Better than that, how can I make a Control that combines multiple AdvancedHMI controls that all require a PLCAddress and/or PLCAddressItem?

Thank you all for your time! I hope this makes any kind of sense. Please let me know if you need any clarification about what I'm asking!


9
Open Discussion / Re: DataSubscriber won't except text value
« on: October 12, 2024, 10:06:24 AM »
When this happens, a potential solution that doesn't require rebooting your entire computer may be
  • Close all open code, design, and project property windows
  • Select Build > Clean Solution
  • Select Build > Rebuild Solution

This should allow you to modify the properties of objects again.

10
If your PLCAddressValueItems collection looks something like this picture (if made via the GUI) then you'll likely either want to consolidate everything to a singular DataSubscriber2 instance, and get the values from each PLCAddressValueItem with code to the effect of:

Code: [Select]
Private Sub DataSubHandler(sender As Object, e As Drivers.Common.PlcComEventArgs) Handles StaErrors.DataReturned

     ' Insert your code here


     Select Case e.PLCAddress
          Case "Sta1Error.PLCAddress"
               i = 103
               q = 105
          Case "Sta2Error.PLCAddress"
               i = 121
               q = 123
          ' ... and so on from here on out
     End Select

     ' Insert your code here too!

End Sub

If your DataSubscriber2 isn't made with the GUI, but instead purely through code

  • You probably already know (roughly) how many PLCAddressValueItems are in the object without needing to look at the GUI
  • If not, you can disconnect from the network that you're communicating to the PLC on, add a button with a .Click event with Debug.WriteLine(DataSub2.PLCAddressValueItems.Count()), launch the program in debug mode, and hit the button you made. It will tell you how -  in the Output pane of Visual Studio - many items are contained in the Collection of PLCAddressValueItems at the time you clicked the button

Otherwise, if you want to keep it as a bunch of separate objects, you'd change them to DataSubscribers instead of DataSubscriber2s, and keep the rest of your code more or less the same.



11
My apologies!! I was remembering incorrectly - I didn't have Visual Studio open in front of me at the time. The event we're looking for is going to be the DataReturned event!


That's 100% my bad.


Edit: Darn, I just went back and re-read, and it seems I lost the plot somewhere.

Does each DataSubscriber2 have multiple tags that it is looking at? Or is does each DataSubscriber2's PLCAddressValueItems only contain a single PLCAddressValueItem inside of it? If there's only a single PLCAddressValueItem, then you'll probably be better served with a DataSubscriber as it is a bit simpler to use, and only works on a single tag in a PLC.

Another possibility for why the DataSubscriber2 events aren't all firing off might be: Are all of these looking at the same PLC? Even if it's (for example) a rack with an A-B L83ES and several L83 PLCs sharing a single IP Address, you'll need a separate EthernetIPforCLXCom object for each separate PLC, and you'd set the Chassis Slot accordingly.

12
Support Questions / Re: Extending BasicTrendChart to trend BOOLs
« on: October 09, 2024, 07:52:01 PM »
Okay, so if that's the case, then when the BasicTrendChart is updating the underlying Collection of Points, it does so by calling the Value.Set() method from BasicChart?

If so, that is the bit I was missing out on! I assumed that was the situation, but I couldn't see where it was explicitly called. If that's all it would take, then I'll go ahead and attempt that tomorrow when I'm back at work.

Thank you again Archie! I'll try that out tomorrow, and I have no doubt it'll work phenomenally. Maybe someday I'll understand VB/AdvHMI enough to be able to track down where edits are necessary for my desired functionality.

For the time being, I suppose I'll simply have to rely on your magnanimity.

I'll drop in a screenshot of the HMI page in question tomorrow, so you'll at least be able to see how you've helped me here!

13
Support Questions / Re: Extending BasicTrendChart to trend BOOLs
« on: October 09, 2024, 07:09:47 PM »
Hmm, then I suppose that part isn't what is a mystery to me, it would be where in BasicTrendChart it deals with the information coming back from the Subscription.
ch
I can see where BasicTrendChart creates a ComComponent as m_ComComponent if it doesn't already exist, then subscribes to it with SubscribeToComDriver()

I also see the Public Property for Value, which I (assume) to be where a point is added, by an added value.
s
I then see there's a SubscribeAutoProperties contained within the SubscriptionHandler class, as well as event handlers such as SubscribedDataReturned(BV s A o, BC e A PlcComEventArgs)



I'm just struggling to find where exactly I'd want to make a change for my desired behavior. I have a suspicion that in SubscribedDataReturned, I'd want to do something such as the following, but I just really don't know for sure (and I've spent a pretty substantial amount of time fiddling around with things trying to get them working as intended to no avail.)


Code: [Select]
    Private Sub SubscribedDataReturned(ByVal sender As Object, ByVal e As MfgControl.AdvancedHMI.Drivers.Common.PlcComEventArgs)
        For Each Subscript In m_SubscriptionList
            Dim address As String = Subscript.PLCAddress
            If Subscript.Invert Then
                address = Subscript.PLCAddress.Substring(4)
            End If

            If e.ErrorId = 0 Then

                'If (e.PlcAddress Is Nothing) OrElse (String.Compare(address, e.PlcAddress, True) = 0) Then
                If (e.PlcAddress Is Nothing) OrElse (e.SubscriptionID = Subscript.NotificationID) Then
                    Dim a As New SubscriptionHandlerEventArgs
                    a.PLCComEventArgs = e
                    a.SubscriptionDetail = Subscript

                    If e.Values IsNot Nothing AndAlso e.Values.Count > 0 Then
                        '* Check if the value should be inverted
                        If Subscript.Invert Then
                            '* Try to invert a boolean value
                            Try
                                Dim ea As MfgControl.AdvancedHMI.Drivers.Common.PlcComEventArgs
                                '* Clone the EventArgs for the inversion because there may be another subscription that doesn't need inverted
                                ea = CType(e.Clone, MfgControl.AdvancedHMI.Drivers.Common.PlcComEventArgs)
                                Dim x As New System.Collections.ObjectModel.Collection(Of String)


                                ' HERE IS MY CHANGED CODE


                                If e.Values(0) = True Then
                                    Dim s As String = "1"
                                ElseIf e.Values(0) = False Then
                                    Dim s As String = "0"
                                Else
                                    Dim s As String = (Convert.ToString(Not CBool(e.Values(0))))
                                End If

                                ' EVERYTHING AFTER THIS UNCHANGED


It seems like this would be the most logical place for me to make a change to an existing class, but it would have to be *specific* to this particular application. But, from how you understand AdvancedHMI to function - as the creator - does this look like it would work? Or am I entirely off base here?

14
Support Questions / Re: Extending BasicTrendChart to trend BOOLs
« on: October 09, 2024, 05:50:20 PM »
Awesome! Thank you for throwing out the base source code; it's a lot better (for someone like me) to see the actual source, rather than trying to ponder on how it works when it has been decompiled into C# - a language I know significantly less than VB.net.



Perhaps (and I suspect this to be the case) I'm simply missing something? I don't see anywhere in that file where a Subscription is made to the PLC, nor where it handles the returned data? Is that encapsulated in the actual BasicTrendChart file? Or would it make more sense for me to extend the DataSubscriber class, and modify how it returns Boolean values to upstream controls? Because if the implementation were to happen purely in the BasicTrendChart class, I'm 1000% lost.


Thank you again for your time! You're a saint, Archie!

15
Sorry for the super late response (and I hope you found an answer before this) but you'll probably want to use the DataUpdated event instead of DataChanged.

Quote
    Private Sub Sta1Error_DataUpdated(sender As Object, e As MfgControl.AdvancedHMI.Drivers.Common.PlcComEventArgs) Handles _
        Sta1Error.DataUpdated, Sta2Error.DataUpdated, Sta3Error.DataUpdated, Sta4Error.DataUpdated, Sta5Error.DataUpdated _
        , Sta6Error.DataUpdated, Sta7Error.DataUpdated, Sta8Error.DataUpdated



DataChanged event only fires when the first item in DataSubscriber2 updates; DataUpdated event fires if ANY of them update.

Pages: [1] 2