AdvancedHMI Software
General Category => Support Questions => Topic started by: rbelknap on June 05, 2017, 02:20:12 PM
-
I'm looking to use a (2) Do-More processors in a build and need to be able to send ASCII strings to them from AdvancedHMI, mainly model/serial numbers.
My original plan was to use Modbus TCP, but in looking at the manuals I don't see a way to send ASCII strings.
Am I seeing this wrong? or will it just work.
I have the hardware already, but haven't had a chance to hook anything up yet.
Is my only other option to go through the serial port?
-
Since Modbus does not natively support strings, you have to do a bit of a work around to convert a string to words, then write:
'* Convert the string to words stored in an array of integers
Dim w() As Integer
w = MfgControl.AdvancedHMI.Drivers.Common.CalculationsAndConversions.StringToWords("ABC")
'* Convert the array of integers into an array a strings so it can be send to the driver as data
Dim s(w.Length - 1) As String
For index = 0 To s.Length - 1
s(index) = w(index).ToString
Next
'* Write it to the PLC
ModbusTCPCom1.Write("40001", s)
-
Archie,
That works great!.
Thanks,
Rich
-
It's very nice that it can do the string conversion with one line from the driver.
Just wondering if you have a few liners to do StringTowords in a case when driver is not present.
-
This is the actual code:
'**********************************************************
'* Convert a string to an array of words
'* Can be used when writing a string to an Integer file
'**********************************************************
Public Shared Function StringToWords(ByVal source As String) As Int32()
If source Is Nothing Then
Return Nothing
' Throw New ArgumentNullException("input")
End If
Dim ArraySize As Integer = Convert.ToInt32(Math.Ceiling(source.Length / 2)) - 1
Dim ConvertedData(ArraySize) As Int32
Dim i As Integer
While i <= ArraySize
ConvertedData(i) = Convert.ToInt32(Convert.ToChar(source.Substring(i * 2, 1))) * 256
'* Check if past last character of odd length string
If (i * 2) + 1 < source.Length Then ConvertedData(i) += Convert.ToInt32(Convert.ToChar(source.Substring((i * 2) + 1, 1)))
i += 1
End While
Return ConvertedData
End Function
-
Archie
Sorry to bring this post back to life, but I have been trying to do the opposite, read a string (an array of characters indeed) using your WordsToString function from the PLC to the VB app.
So far I have not quite really understand how the function works, because I just get syntax errors.
Dim str(4) As String
'* Read it from the PLC
str = ModbusTCPCom1.Read("40009", str.Length)
Dim ResultString(4) As String
ResultString = MfgControl.AdvancedHMI.Drivers.Common.CalculationsAndConversions.WordsToString(str)
And I still have to figure how to pass the results to a string...
I made my own processing sub, but I want to understand and use the one you created, my code is still very basic and you need to know the lenght of the character array in the PLC by advance... see below:
Private Sub btnRead_Click(sender As Object, e As EventArgs) Handles btnRead.Click
Dim length As Integer = 6
Dim i As Integer = 0
Dim StartAddress As Integer
Dim Buffer As String = Nothing
While i < length
StartAddress = 40009 + i
val = ModbusTCPCom1.Read(StartAddress)
Dim BufferBytes As Byte() = BitConverter.GetBytes(val)
Dim SingleChar() As Char = {"", ""}
'From integer to ascii
SingleChar(0) = Chr(BufferBytes(1))
SingleChar(1) = Chr(BufferBytes(0))
Buffer = Buffer & SingleChar(0) & SingleChar(1)
i += 1
End While
tbxRead.Text = Buffer
End Sub
-
I cannot find this code in the project, I assume is inside of your DLL?
This is the actual code:
'**********************************************************
'* Convert a string to an array of words
'* Can be used when writing a string to an Integer file
'**********************************************************
Public Shared Function StringToWords(ByVal source As String) As Int32()
If source Is Nothing Then
Return Nothing
' Throw New ArgumentNullException("input")
End If
Dim ArraySize As Integer = Convert.ToInt32(Math.Ceiling(source.Length / 2)) - 1
Dim ConvertedData(ArraySize) As Int32
Dim i As Integer
While i <= ArraySize
ConvertedData(i) = Convert.ToInt32(Convert.ToChar(source.Substring(i * 2, 1))) * 256
'* Check if past last character of odd length string
If (i * 2) + 1 < source.Length Then ConvertedData(i) += Convert.ToInt32(Convert.ToChar(source.Substring((i * 2) + 1, 1)))
i += 1
End While
Return ConvertedData
End Function
-
I finally found out. I was declaring the result string as an array, my mistake. So this works pretty good!
Private Sub btnReadArchie_Click(sender As Object, e As EventArgs) Handles btnReadArchie.Click
Dim str(4) As String
'* Read it from the PLC
str = ModbusTCPCom1.Read("40009", str.Length)
Dim ResultString As String
ResultString = MfgControl.AdvancedHMI.Drivers.Common.CalculationsAndConversions.WordsToString(str)
tbxReadArchie.Text = ResultString
End Sub
-
Archie. How would I implement writing strings over Modbus with the new 3.99y version? Thank you
-
Archie. How would I implement writing strings over Modbus with the new 3.99y version? Thank you
ModbusTCPCom1.Write("40001@S10", "StringVal")
Or you can use a BasicLabel and put 40001@S10 in PLCAddressKeypad
-
Great news Archie! The ability to write strings with Modbus simplifies it a lot!
What about for reading? Just ModbusTCPCom1.Read("40001@S10")?
-
Great news Archie! The ability to write strings with Modbus simplifies it a lot!
What about for reading? Just ModbusTCPCom1.Read("40001@S10")?
Nothing like doing it by myself. I picked up my project with reading and writing strings using modbus to Siemens 1200 PLC. It works with your new method, but still I do not find a way to write the string length value. If the string is empty (zero lentgh) in the PLC you can't see any change. If the string length is the same o higher than the value you are trying to write, then the value you write is visible. I tried to write the length value directly, but seems to write an incorrect value (hex instead integer). I will keep trying.