Author Topic: Have a control respond to either True or False bit  (Read 6028 times)

Godra

  • Hero Member
  • *****
  • Posts: 1447
    • View Profile
Have a control respond to either True or False bit
« on: December 19, 2014, 02:43:38 PM »
This would be related to SquareIlluminatedButton control but might apply to other controls as well.

Is it possible to have the PLCAddressValue property, or if incorrect then some other property, be specified as either True or False? Since I am a newbie at this, if the option already exists could someone point me in the right direction?

Quick example would be to have 2 buttons read the same bit and illuminate depending on whether the bit is True or False (attached is a picture of START and STOP buttons and if the bit is True then START button would be illuminated while if that same bit is False the STOP button would be illuminated).

Currently I have been using alternative where I create a new rung in ladder logic and place the condition where the wanted bit False value activates a new bit and then use that new bit address in the mentioned STOP control. I guess it is possible to write a VB statement that examines the state of the wanted bit and then, when False, somehow illuminates the button.

Archie

  • Administrator
  • Hero Member
  • *****
  • Posts: 5322
    • View Profile
    • AdvancedHMI
Re: Have a control respond to either True or False bit
« Reply #1 on: December 19, 2014, 03:48:23 PM »
I think what you are looking for is the "NOT"  modifier. For example in PLCAddressValue you can put

NOT B3/0
NOT MyTag
NOT 10001

Godra

  • Hero Member
  • *****
  • Posts: 1447
    • View Profile
Re: Have a control respond to either True or False bit
« Reply #2 on: December 19, 2014, 04:09:26 PM »
Thank you.

That is exactly what I wasn't aware of and it works just fine.

Godra

  • Hero Member
  • *****
  • Posts: 1447
    • View Profile
Re: Have a control respond to either True or False bit
« Reply #3 on: June 12, 2015, 11:05:56 PM »
Archie,

There seems to be an issue with a single control using combination of True and False of the same PLCAddress but on 2 or more different fields.
Some odd behavior is exhibited and on some other controls there is flicker.

What I just tried was using PilotLight and populated the following fields with Modbus addresses (using MOD RSSim):

PLCAddressText - NOT 40001
PLCAddressValue - 40001
PLCAddressVisible - 40001      <---  tried without this field as well

On "0" value the control is still visible, showing "True" and with the Green light turned on (check the attached picture).

Also tried OPC simulator and still odd behavior.

Archie

  • Administrator
  • Hero Member
  • *****
  • Posts: 5322
    • View Profile
    • AdvancedHMI
Re: Have a control respond to either True or False bit
« Reply #4 on: June 13, 2015, 06:52:23 AM »
This problem is in SubscriptionHandler.vb between lines 191 and 202. I will come up with a fix for it later this evening.

Godra

  • Hero Member
  • *****
  • Posts: 1447
    • View Profile
Re: Have a control respond to either True or False bit
« Reply #5 on: June 13, 2015, 04:28:39 PM »
I made some changes and it seems to be working fine for now.

Here is what I did, on Line188 introduced 2 strings to record both original value as well as inverted:

Code: [Select]
                        If Subscript.Invert Then
                            '* Try to invert a boolean value
                            Try
                                Dim x As New System.Collections.ObjectModel.Collection(Of String)
                                Dim s1 As String = Convert.ToString(CBool(e.Values(0)))
                                Dim s2 As String = Convert.ToString(Not CBool(e.Values(0)))
                                x.Add(s1)
                                x.Add(s2)
                                e.Values = x
                            Catch ex As Exception
                                Dim dbg = 0
                            End Try
                        End If

and then on Line224 write one of these values dependent on "NOT " prefix:

Code: [Select]
                                    '* Write the value to the property that came from the end of the PLCAddress... property name
                                    If Subscript.Invert Then
                                        m_Parent.GetType().GetProperty(a.SubscriptionDetail.PropertyNameToSet). _
                                                    SetValue(m_Parent, Utilities.DynamicConverter(a.PLCComEventArgs.Values(1), m_Parent.GetType().GetProperty(a.SubscriptionDetail.PropertyNameToSet).PropertyType), Nothing)
                                    Else
                                        m_Parent.GetType().GetProperty(a.SubscriptionDetail.PropertyNameToSet). _
                                            SetValue(m_Parent, Utilities.DynamicConverter(a.PLCComEventArgs.Values(0), m_Parent.GetType().GetProperty(a.SubscriptionDetail.PropertyNameToSet).PropertyType), Nothing)
                                    End If

Archie

  • Administrator
  • Hero Member
  • *****
  • Posts: 5322
    • View Profile
    • AdvancedHMI
Re: Have a control respond to either True or False bit
« Reply #6 on: June 13, 2015, 06:21:07 PM »
What I end up doing was to clone the PLCComEventArgs when it was to be inverted. That way it didn't alter the values of the original e object instance.

Godra

  • Hero Member
  • *****
  • Posts: 1447
    • View Profile
Re: Have a control respond to either True or False bit
« Reply #7 on: June 13, 2015, 09:12:55 PM »
With you there is always something new to learn.

I will check the code once you are to post it, guess in the next version of AHMI.

In the meantime I might try to figure it out myself.

Archie

  • Administrator
  • Hero Member
  • *****
  • Posts: 5322
    • View Profile
    • AdvancedHMI
Re: Have a control respond to either True or False bit
« Reply #8 on: June 13, 2015, 09:20:02 PM »
I'm hoping to get a new version posted tomorrow. But here is the code I hacked together:
Code: [Select]
                            '* 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)

                                Dim s As String = (Convert.ToString(Not CBool(e.Values(0))))
                                x.Add(s)
                                ea.Values = x
                                a.PLCComEventArgs = ea
                            Catch ex As Exception
                                Dim dbg = 0
                            End Try

Godra

  • Hero Member
  • *****
  • Posts: 1447
    • View Profile
Re: Have a control respond to either True or False bit
« Reply #9 on: June 13, 2015, 10:27:12 PM »
I had to make small changes to make your code work (move creation of "a" before the main If loop and also add "Else" to the Invert loop):

Code: [Select]
            Dim a As New SubscriptionHandlerEventArgs '* Move these 2 lines before the "If" statement
            a.SubscriptionDetail = Subscript          '*

            If (e.PlcAddress Is Nothing) OrElse (String.Compare(address, e.PlcAddress, True) = 0) Then
                If e.ErrorId = 0 Then
                    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)

                                Dim s As String = (Convert.ToString(Not CBool(e.Values(0))))
                                x.Add(s)
                                ea.Values = x
                                a.PLCComEventArgs = ea
                            Catch ex As Exception
                                Dim dbg = 0
                            End Try
                        Else
                            a.PLCComEventArgs = e '* Include the "Else" along with this line since NullException was being thrown
                        End If
                    Else
                        '* No data returned from driver
                        e.ErrorId = -999
                        e.ErrorMessage = "No Values Returned from Driver"
                    End If

                    If Subscript.CallBack IsNot Nothing Then
                        Subscript.CallBack.Invoke(sender, a)
                    End If

                    '********************************************
                    '* Process the AutoProperty subscribed items
                    '********************************************
                    If Me.Parent IsNot Nothing And a.SubscriptionDetail.PropertyNameToSet IsNot Nothing AndAlso (String.Compare(a.SubscriptionDetail.PropertyNameToSet, "") <> 0) Then
                        If e.ErrorId = 0 Then
                            Try
                                '* Does this property exist?
                                If m_Parent.GetType().GetProperty(a.SubscriptionDetail.PropertyNameToSet) IsNot Nothing Then
                                    '* Write the value to the property that came from the end of the PLCAddress... property name
                                    m_Parent.GetType().GetProperty(a.SubscriptionDetail.PropertyNameToSet). _
                                        SetValue(m_Parent, Utilities.DynamicConverter(a.PLCComEventArgs.Values(0), m_Parent.GetType().GetProperty(a.SubscriptionDetail.PropertyNameToSet).PropertyType), Nothing)
                                End If
                            Catch ex As Exception
                                OnDisplayError("INVALID VALUE RETURNED!" & a.PLCComEventArgs.Values(0))
                            End Try
                        Else
                            OnDisplayError("Com Error " & a.PLCComEventArgs.ErrorId & "." & a.PLCComEventArgs.ErrorMessage)
                        End If
                    End If
« Last Edit: June 13, 2015, 10:35:59 PM by Godra »

Godra

  • Hero Member
  • *****
  • Posts: 1447
    • View Profile
Re: Have a control respond to either True or False bit
« Reply #10 on: June 15, 2015, 12:49:42 AM »
Archie,

I can see in 3.98p that you did it in a simpler way by moving all 3 lines at the same time and to a slightly different position, instead of introducing the Else part.

Nice work (I can only learn from it).