AdvancedHMI Software
General Category => Support Questions => Topic started by: Jesse on September 11, 2013, 09:29:31 AM
-
Is it possible to use a standard combo box and have it send values to different locations such as different N files depending on what option the operator selects, and I'm pretty new to coding so if it is what would that look like?
-
Yes. Sometimes it involves a bit of coding. In the Tips & Tricks section is a short tutorial on turning a standard windows control into an AdvancedHMI control.
-
Ok so I have my Combobox made and I have a 3 "items" in it. I used the code from a basic label for it and in the properties its has PLCaddress, value, keypad etc.
Now all my experience is with PLCs I have barley any with structured text. My 3 Items are Heat, Soak, and Carbon. If you could show me the code that would give me a properties option of PLCaddressHeat I think I could figure out the rest.
Thanks.
-
Do you want the control to write the values to the PLC when the selection is changed, or do you want it to read from the PLC and update the value based on what it read from the PLC?
-
If the operator selects the item heat I will need the textbox to pop up where operator will enter a number it will then write that value to an N file
at the same time when heat is selected it needs to also write a 3 to another N file
The 3 will be a constant it will never change.
-
or instead of a plcaddressheat option could you should me the code that would be like..
If Combobox1.text = "heat" Then
TextBox1.Visible = True
' here is the part I don't know how to do (sending a value to slc/clx)
Else
TextBox1.Visible = False
'........
End If
-
If Combobox1.text = "heat" Then
TextBox1.Visible = True
' here is the part I don't know how to do (sending a value to slc/clx)
Else
TextBox1.Visible = False
'........
End If
EthernetIPforCLXCom1.Write("MyTag",3)
or
EthernetIPforPLCSLCMicroCom1.Write("N7:0",3)
-
Works just like I was hoping for, Thank you! you made a great program!
-
I apologize in advance for asking so many questions, but as i said I'm new at VB programing.
Heres the deal: in the image I attached to this there are 40 comboboxes and 40 text boxes and each line represents a step so there for instance line 1 has a label step one then a combobox then a text box, so 40 lines, in each text box there will be 13 items (heat, soak, ramp, .. etc.) dependend on what step it is and on what item was selected it is going to send a value 1-13 (heat= 1, soak = 2, ramp = 3, etc.) to an N file N20[0] through N20[39] (step 1 = n20[0], step 2= n20[1], etc.).
And on top of that the value of the text box will be sent to a F file corresponding to it's step so (step 1 textbox.text = F21[0], and so on..)
Once the operator has entered in all of these items and values they will click the send to PLC button. Now I wrote a piece of code to test it and it worked with an If statement.
That code is only for the first step and there are 40 and doing this with an if statement just seems like the wrong way of doing it to me because its going to be so long and messy. So I was wondering if you could put me on the right track of writing this code if you know of a better way?
Thanks.
Private Sub btnPLC_Click(sender As System.Object, e As System.EventArgs) Handles btnPLC.Click
If OpCodeBox1.Text = "HEAT" Then
EthernetIPforCLXCom1.Write("F21[0]", OpText1.Text)
EthernetIPforCLXCom1.Write("N20[0]", 1)
ElseIf OpCodeBox1.Text = "CARBON" Then
EthernetIPforCLXCom1.Write("F21[0]", OpText1.Text)
EthernetIPforCLXCom1.Write("N20[0]", 2)
ElseIf OpCodeBox1.Text = "NULL OPCODE" Then
EthernetIPforCLXCom1.Write("F21[0]", 0)
EthernetIPforCLXCom1.Write("N20[0]", 0)
ElseIf OpCodeBox1.Text = "RAMP" Then
EthernetIPforCLXCom1.Write("F21[0]", OpText1.Text)
EthernetIPforCLXCom1.Write("N20[0]", 3)
ElseIf OpCodeBox1.Text = "SOAK" Then
EthernetIPforCLXCom1.Write("F21[0]", OpText1.Text)
EthernetIPforCLXCom1.Write("N20[0]", 4)
ElseIf OpCodeBox1.Text = "TEMP LIMIT TIME" Then
EthernetIPforCLXCom1.Write("F21[0]", OpText1.Text)
EthernetIPforCLXCom1.Write("N20[0]", 5)
ElseIf OpCodeBox1.Text = "CARBON LIMIT TIME" Then
EthernetIPforCLXCom1.Write("F21[0]", OpText1.Text)
EthernetIPforCLXCom1.Write("N20[0]", 6)
ElseIf OpCodeBox1.Text = "AMMONIA EVEN" Then
EthernetIPforCLXCom1.Write("F21[0]", OpText1.Text)
EthernetIPforCLXCom1.Write("N20[0]", 7)
ElseIf OpCodeBox1.Text = "END OF CYCLE EVENT" Then
EthernetIPforCLXCom1.Write("F21[0]", OpText1.Text)
EthernetIPforCLXCom1.Write("N20[0]", 8)
ElseIf OpCodeBox1.Text = "SPARE EVENT" Then
EthernetIPforCLXCom1.Write("F21[0]", OpText1.Text)
EthernetIPforCLXCom1.Write("N20[0]", 9)
ElseIf OpCodeBox1.Text = "PROBE BURNOFF EVEN" Then
EthernetIPforCLXCom1.Write("F21[0]", OpText1.Text)
EthernetIPforCLXCom1.Write("N20[0]", 10)
ElseIf OpCodeBox1.Text = "TEMP DEVIATION" Then
EthernetIPforCLXCom1.Write("F21[0]", OpText1.Text)
EthernetIPforCLXCom1.Write("N20[0]", 11)
ElseIf OpCodeBox1.Text = "CARBON DEVIATION" Then
EthernetIPforCLXCom1.Write("F21[0]", OpText1.Text)
EthernetIPforCLXCom1.Write("N20[0]", 12)
End If
End Sub
-
How about something like this.... In your drop down boxes put a value in parentheses after the text
HEAT (1)
CARBON (2)
NULL OPCode (0)
Then extract that value to write to PLC. Your code always writes OpText1.Text to F21[0], so that line only needs to be there once.
Dim ValueToWrite as integer
Dim StartOfValue As Integer = ComboBox1.Text.LastIndexOf("(") + 1
Dim LengthOfValue As Integer = ComboBox1.Text.LastIndexOf(")") - StartOfValue
ValueToWrite = CInt(ComboBox1.Text.Substring(StartOfValue, LengthOfValue))
EthernetIPforCLXCom1.Write("N20[0]", ValueToWrite)
EthernetIPforCLXCom1.Write("F21[0]", OpText1.Text)
-
Thank you, took me a little bit of research to see what you're doing there but I figured it out, that will probably work though 2 of my items are actually going to have numbers in parenthesis already but I don't think it would cause a problem, is there possibly another solution though?
-
You can get a little more advanced and populate the combobox in code and use a dictionary collection to cross reference the integer value to the string:
'* Declare a class scope dictionary object
Private d As New Dictionary(Of String, Integer)
'*** Double click a blank spot on the form to get to this load event
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
d.Add("Null OpCode", 0)
d.Add("Heat", 1)
d.Add("Carbon", 2)
For Each item In d
ComboBox1.Items.Add(item.Key)
Next
End Sub
'* When the button is clicked, look up in the dictionary collection (d)
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
EthernetIPforCLXCom1.Write("N20[0]", CStr(d(ComboBox1.Text)))
End Sub
-
So I decided to go with the dictionary way. It works really well and saved me a lot of code, although there's still something I'm not sure how to do now. Sorry this VB has really been a learning curve for me. But if the operator/user ever selects NULL OPCODE in a combobox that will be the last step and after that the rest of the comboboxes and text boxes will just be blank and i plan for their visibility to go false and the N and F files that they're linked to, to receive values of zero. How would I go about that? I tried if statements for the visibility but then the blank combos only go invisible if you try to change the index.
-
This is once again an advanced technique that will seem overwhelming until you get a very good understanding of .NET, never the less it is more compact than brute forcing it.
The code takes advantage of the Tag property, which is a general purpose property only there for the programmers use. First you must go into each ComboBox on the form and set a value in the Tag property to tell the code which order they are in (1,2,3,...). This also build on the dictionary lookup code from above. I tried to comment it in detail to help you understand how it works.
'* After the next line, add the full list of comboboxes on your form so this event will fire when any of them are changed
Private Sub ComboBox1_SelectedIndexChanged(sender As System.Object, e As System.EventArgs) Handles ComboBox1.SelectedIndexChanged, ComboBox2.SelectedIndexChanged, ComboBox3.SelectedIndexChanged
'* First we must find the lowest Tag value of the box with a null value selected
Dim NullBoxTagValue As Integer = 9999
'* Go through each control on the form
For Each ControlOnForm As Control In Me.Controls
'* only process comboboxes with something in the Tag property
If TypeOf (ControlOnForm) Is ComboBox Then
If ControlOnForm.Tag <> "" Then
'* Did we find a ComboBox with a value of null?
If ControlOnForm.Text <> "" AndAlso d(ControlOnForm.Text) = 0 Then
'* is this Tag value less than what we already found?
If ControlOnForm.Tag < NullBoxTagValue Then
NullBoxTagValue = ControlOnForm.Tag
End If
End If
End If
End If
Next
'* Now we can go through and enable/disable boxes that are higher than the null
For Each ControlOnForm As Control In Me.Controls
'* only process comboboxes with something in the Tag property
If TypeOf (ControlOnForm) Is ComboBox AndAlso ControlOnForm.Tag <> "" Then
'* If we are greater than the null box, then disable
If ControlOnForm.Tag > NullBoxTagValue Then
ControlOnForm.Text = ""
ControlOnForm.Enabled = False
Else
ControlOnForm.Enabled = True
End If
End If
Next
End Sub
-
So I used your code except changed one thing:
If ControlOnForm.Text <> "" AndAlso d(ControlOnForm.Text) = 0 Then
If ControlOnForm.Text <> "" AndAlso d(ControlOnForm.Text) = 8 Then (only changed the 0 to 8)
the 8 is for End of Cycle Event but now that I did that say I make the 5th combobox an end of cycle event i get an error on the sixth for "The given key was not present in the dictionary." The error is always on the combobox after the End of Cycle Event one.
-
Ended up not using that code to disable text boxes and I got my program working for the most part except now when I run it the first time I put in values and send to CLX and it works fine, though if I try to change anything and send a new set of values I get an error in your code from the CLXethernet driver code
SyncLock (ReadLock)
DLL(MyDLLInstance).WriteTagValue(tag, StringVals, 1, TNS)
End SyncLock
There Error I get here says Send que full, may have lost connection or data request too fast.
Any idea why I would be getting that?
-
That generally means that over 30 read/write requests are being sent faster than the PLC can respond to them. If you are using a lot of back to back read or writes, try putting this in between about every 10
System.threading.thread.sleep(50)