AdvancedHMI Software
General Category => Support Questions => Topic started by: Gene T. on March 26, 2019, 11:27:14 PM
-
I have been reading up on how to construct loops.
I have made numerous attempts but not making much progress.
Here is what I have done....
Added a datasubsriber.
Added this code to form.....
If Alarm_Data.PLCAddressValueItems(0).LastValue = True Then
ModbusTCPCom1.Write(40300.0, 1)
Else
ModbusTCPCom1.Write(40300.0, 0)
End If
If Alarm_Data.PLCAddressValueItems(1).LastValue = True Then
ModbusTCPCom1.Write(40300.1, 1)
Else
ModbusTCPCom1.Write(40300.1, 0)
End If
etc.....
etc.....
If Alarm_Data.PLCAddressValueItems(15).LastValue = True Then
ModbusTCPCom1.Write(40300.15, 1)
Else
ModbusTCPCom1.Write(40300.15, 0)
End If
etc.....
etc.....
If Alarm_Data.PLCAddressValueItems(31).LastValue = True Then
ModbusTCPCom1.Write(40301.15, 1)
Else
ModbusTCPCom1.Write(40301.15, 0)
End If
This code works as expected.
Can This be converted to loops, or am I just spinning my wheels?
Thanks,
Gene
-
If you are looking to decrease your amount of code, you could do something like this:
Dim WordValue, index As Integer
While index < 15 AndAlso index < Alarm_Data.PLCAddressValueItems.Count
If String.Compare(Alarm_Data.PLCAddressValueItems(index).LastValue, "True", True) = 0 Then
WordValue += (2 ^ index)
End If
index += 1
End While
ModbusTCPCom1.Write("40300", WordValue)
-
Archie, the code you referenced will not work for him as he's writing to a different address for each item.
-
Archie, the code you referenced will not work for him as he's writing to a different address for each item.
You are absolutely correct. It was going to be my first question asked before posting code, but after seeing his example indexed through the bits of the same word, I went ahead and posted code based on the assumption that was the only goal.
-
If you need to dynamically write to different registers, assuming they "line" up with the index:
Dim Binary_Length As Integer = 16
Dim Word As Integer
Dim Bit As Integer
Word = Math.Floor(NumericUpDown1.Value / Binary_Length)
Bit = NumericUpDown1.Value Mod Binary_Length
Label1.Text = "4003" & Word & "." & Bit
Replace the NumericUpDown1 with your index and instead of using a label use in your address write.
-
Another trick is to put the address to write to in the Name property of each PLCAddressItem then use this code:
Dim index As Integer
While index < Alarm_Data.PLCAddressValueItems.Count
If String.Compare(Alarm_Data.PLCAddressValueItems(index).LastValue, "True", True) = 0 Then
ModbusTCPCom1.Write(Alarm_Data.PLCAddressValueItems(index).Name, "1")
Else
ModbusTCPCom1.Write(Alarm_Data.PLCAddressValueItems(index).Name, "0")
End If
index += 1
End While
-
Another trick is to put the address to write to in the Name property of each PLCAddressItem then use this code:
Dim index As Integer
While index < Alarm_Data.PLCAddressValueItems.Count
If String.Compare(Alarm_Data.PLCAddressValueItems(index).LastValue, "True", True) = 0 Then
ModbusTCPCom1.Write(Alarm_Data.PLCAddressValueItems(index).Name, "1")
Else
ModbusTCPCom1.Write(Alarm_Data.PLCAddressValueItems(index).Name, "0")
End If
index += 1
End While
Nice!
-
Yes Archie I would like to force myself to learn this method to reduce the amount of code.My project has many places this would be very helpful and a lot cleaner.
Needles to say not one of my 15 attempts look anything like the examples you gentleman posted. Thanks for the guidance. You help is very much appreciated.
Gene
-
Well I kept plugging until I finally figured out a way to do a loop that worked for me.
@ Archie and James, I know that I could copy and paste the code you posted and saved a lot of
time but I had to figure out what I was missing in my attempts. Here is what I came up with...
Dim y
Dim counter = 0
For index = 0 To Alarm_Data.PLCAddressValueItems.Count - 1
Dim i = Alarm_Data.PLCAddressValueItems(index).LastValue
If index <= 15 Then
y = "40300." + Convert.ToString(counter)
ElseIf index <= 31 Then
y = "40301." + Convert.ToString(counter)
ElseIf index <= 47 Then
y = "40302." + Convert.ToString(counter)
ElseIf index <= 63 Then
y = "40303." + Convert.ToString(counter)
ElseIf index <= 79 Then
y = "40304." + Convert.ToString(counter)
ElseIf index <= 95 Then
y = "40305." + Convert.ToString(counter)
ElseIf index <= 111 Then
y = "40306." + Convert.ToString(counter)
ElseIf index <= 127 Then
y = "40307." + Convert.ToString(counter)
ElseIf index <= 143 Then
y = "40308." + Convert.ToString(counter)
ElseIf index <= 159 Then
y = "40309." + Convert.ToString(counter)
End If
If i = "True" Then
ModbusTCPCom1.Write(y, 1)
Else
ModbusTCPCom1.Write(y, 0)
End If
If counter = 15 Then
counter = 0
Else
counter = counter + 1
End If
Next
I then moved on to the code that James posted and implemented it and as expected works as advertised.
I haven't had time to get to the code Archie posted yet. I have noticed that when this code is used "both" what is posted and the code from James, the application slows to a crawl on loading the application and changing to the form that has the datasubscriber on it. Am I still missing something in this loop that could/would cause this problem?