AdvancedHMI Software
General Category => Support Questions => Topic started by: Aviraj on September 11, 2015, 03:38:16 PM
-
This might actually be an extremely easy question for a majority of you here, but I haven't really coded much with VB so I am not quite aware. Here is what I am trying to establish:
I have an Advanced HMI form with some objects that are connected to different PLCs and different addresses. I also have a Date and Time Display object there. What I want to do is turn on/off a PLC function (related to some object) based purely on the date and time.
I know I need to add code to the DateTime1 object (or maybe somewhere else) but what do I exactly do ? For the beginning, lets just assume I want to turn on a pilot light at a particular time and then turn it off at some other time.
Thanks in advance for the help :)
Aviraj
-
This is how DateTime control shows on my computer: "09/11/15 17:48:00"
You would have to use the format that shows on your screen when you run AHMI.
Here is a simple way of doing what you've asked for: besides for the DateTime control that you have also place a BasicIndicator control on the form then switch to code view and copy this subroutine:
Private Sub DateTime1_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles DateTime1.TextChanged
If Me.DateTime1.Text = "09/11/15 17:48:00" Then ' Adjust the format to match the format on your computer
Me.BasicIndicator1.SelectColor2 = True ' BasicIndicator light should turn Green
End If
If Me.DateTime1.Text = "09/11/15 17:48:15" Then
Me.BasicIndicator1.SelectColor2 = False ' 15 seconds later turn the Green light OFF and also
Me.BasicIndicator1.SelectColor3 = True ' turn the Red light ON
End If
End Sub
Make necessary adjustments to fit names of your controls and the DateTime format.
-
Keep in mind the DateTime control is updated based on a timer. Since Windows is not a real time operating system, a timer can get delayed if the OS is doing something else, therefore updates can skip a few seconds. This will mean looking for an exact time such as 12:00:00 may not work because it may skip putting every second into a DateTime control.
-
In that case specifying a range for seconds might work better. Maybe a code like this:
Private Sub DateTime1_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles DateTime1.TextChanged
Dim DateTime() As String = Me.DateTime1.Text.Split(" "c) 'Store Date and Time separately as strings
Dim HoursMinSec() As String = DateTime(1).Split(":"c) 'Store hours, minutes and seconds separately as strings
If CInt(HoursMinSec(0)) = 23 Then 'Check if the hours value is equal to specific hours
If CInt(HoursMinSec(1)) = 57 Then 'Check if the minutes value is equal to specific minutes
If CInt(HoursMinSec(2)) > 0 AndAlso CInt(HoursMinSec(2)) < 15 Then 'Check if the seconds value is within a specific seconds range (0 to 15)
If Not Me.BasicIndicator1.SelectColor2 Then Me.BasicIndicator1.SelectColor2 = True ' Turn the Green BasicIndicator light ON if not already ON
End If
End If
End If
If CInt(HoursMinSec(0)) = 23 Then 'Check if the hours value is equal to specific hours
If CInt(HoursMinSec(1)) = 57 Then 'Check if the minutes value is equal to specific minutes
If CInt(HoursMinSec(2)) > 45 AndAlso CInt(HoursMinSec(2)) < 59 Then 'Check if the seconds value is within a specific seconds range (45 to 59)
If Me.BasicIndicator1.SelectColor2 Then Me.BasicIndicator1.SelectColor2 = False ' If ON then turn the Green BasicIndicator light OFF
If Not Me.BasicIndicator1.SelectColor3 Then Me.BasicIndicator1.SelectColor3 = True ' Turn the Red BasicIndicator light ON if not already ON
End If
End If
End If
End Sub
Initially any text would have to be removed from the DateTime1's text property at Design Time.
Specifying hours and minutes only would eliminate checking for seconds and would reduce the code (this would give a 60 sec range).
Using this same logic a specific Date could be used as well.
-
Here is a clever way to see if the date is within 1 minute of target:
Private Sub DateTime1_TextChanged(sender As Object, e As EventArgs) Handles DateTime1.TextChanged
Dim CurrentDateTime As Date
If Date.TryParse(DateTime1.Text, CurrentDateTime) Then
Dim DifferenceOfTime As TimeSpan = CurrentDateTime.Subtract("12:08")
If DifferenceOfTime.Minutes = 0 Then
'* Our time is on the same minute as target
End If
End If
End Sub
-
Hopefully all these posts did not introduce too much of coding for Aviraj and that at least one of the answers can work for him.
For the sake of BasicIndicator example mentioned above, here is Archie's code slightly modified:
Private Sub DateTime1_TextChanged(ByVal sender As Object, ByVal e As EventArgs) Handles DateTime1.TextChanged
Dim CurrentDateTime As Date
If Date.TryParse(DateTime1.Text, CurrentDateTime) Then
Dim DifferenceOfTimeGreen As TimeSpan = CurrentDateTime.Subtract("13:27")
If DifferenceOfTimeGreen.Minutes = 0 Then
'* Our time is on the same minute as target
If Not Me.BasicIndicator1.SelectColor2 Then Me.BasicIndicator1.SelectColor2 = True ' Turn the Green BasicIndicator light ON if not already ON
End If
Dim DifferenceOfTimeRed As TimeSpan = CurrentDateTime.Subtract("13:28")
If DifferenceOfTimeRed.Minutes = 0 Then
'* Our time is on the same minute as target
If Me.BasicIndicator1.SelectColor2 Then Me.BasicIndicator1.SelectColor2 = False ' Turn the Green BasicIndicator light OFF if not already OFF
If Not Me.BasicIndicator1.SelectColor3 Then Me.BasicIndicator1.SelectColor3 = True ' Turn the Red BasicIndicator light ON if not already ON
End If
End If
End Sub
-
Thanks a lot Godra and Archie for the help. I got it working. The code wasn't too hard to understand either ! Just had a small question. What does the Me. prefix signify ? Why is that necessary (if it is) ?
-
.NET is an object oriented programming and Me is a VB concept of OOP. It essentially means to refer to the instance of the current object/class. If there is no prefix, it is assumed to mean "Me" therefore the Me is optional most of the time.
-
Thanks for the clarification Archie
Avi
-
I again have a little bit of an issue with manipulating the VB code. The question kind of has 2 parts, 1 specific to a problem I am trying to solve at this moment and the second is a more general question about having to do similar manipulations in the future:
1. I have a ThreeButtonPLC object on my form with the 3 states being Hand, Auto and Off. What I want to do is that some other PLC control turns on/off when I click on one of these options. Or also something like the level in a tank changes to some value when I click one of these options. It sounds simple enough but I cant seem to get my head around it. When I double click on the ThreeButtonPLC object, the code windows shows the subroutine generated as "ThreeButtonPLC1_Load" which only gets called once when the form is loaded. I also do not see any relevant properties related to this object that I can use ! I know I'll have to create a separate subroutine which gets called when one of those buttons are clicked, but cant figure it out. This leads me to the second question !
2. Speaking on a general level, can I create separate subroutines for any object ? If so, are there some specific things that I need to take care of. I am looking to control some more PLC values based on the state/value of some other objects. Is there a general way to do this which will be applicable to a majority of the objects ? Also, I am guessing the properties of the objects remain fixed (defined set of properties that are available and they can t be changed). Please correct me on that if I am wrong.
Thanks for the patience to read through that !
Avi
-
Aviraj,
When you double click the control it seems to take you straight to Load which somehow seems to be the default event. You don't have to use it and can just delete the sub.
If you look at the attached picture there you can see ThreeButtonPLC1 selected on the left side and its list of events on the right side. From this list you can select any of the available events. If you don't see the event that you want then you can eventually try to create it in the base class, which in the case of ThreeButtonPLC.vb is actually ThreeButtons.vb class.
I have attached a modified ThreeButtons.vb class which now includes 3 public events: AutoButtonClick, HandButtonClick and OffButtonClick. The attached picture shows the subs for 2 of these events, each sub containing multiple write statements. For example, the sub for AutoButtonClick, when put in plain language, it says: "When I click the Auto button the 4 write statements will be executed". You also need to remember that this button has been assigned PLCAddressClickAuto property, so if you have an address placed in that property it will also get executed.
You should be able to add the attached vb file as ExistingItem to Controls folder and replace the existing file.
Archie might suggest whether these new public events could create any conflict.