-
May 23rd, 2017, 04:54 AM
#1
Thread Starter
Junior Member
Hex to serial
Hey,
I try to do the following:
I send to the serial port the following bytes:
Code:
View plaincopy to clipboardprint?
Dim Data (5) As Byte
Data (0) = & H12
Data (1) = & HAF
Data (2) = & HAA
Data (3) = & HBB
Data (4) = Manual.Text
As you can see, I want to use an User input with Data (4). Now it's about the following.
For example, if I import Decimal 9999.0 into manual.Text, I can convert it to Hex 18696. But it seems to me that this should be written as follows.
Code:
View plaincopy to clipboardprint?
Dim Data (7) As Byte
Data (0) = & H12
Data (1) = & HAF
Data (2) = & HAA
Data (3) = & HBB
Data (4) = & H96
Data (5) = & H86
Data (6) = & H01
The result should therefore be as follows in my opinion: 12 AF AA BB 96 86 01
Now my question, How do I get bytes 4, 5 and 6 now? As above example. Or do I get this wrong? Or is there a other approach?
Thanks in advance.
Gr. Ray
Last edited by Ray1972; May 23rd, 2017 at 08:22 AM.
-
May 23rd, 2017, 08:24 AM
#2
Thread Starter
Junior Member
Re: Hex to serial
I tried with following also but that doesnt get me anywhere if i use more then 2 bytes.
Code:
Dim input As String = "10 AA BB " + TextBox7.Text + " 60 10 03"
Dim process_CMD() As Byte = input.Split(" "c).Select(Function(x) Convert.ToByte(x, 16)).ToArray()
SerialPort1.Write(process_CMD, 0, process_CMD.Length)
Maybe i am on the wrong track, but if anyone can give a me a direction it would be much appreciated.
-
May 23rd, 2017, 09:01 AM
#3
Re: Hex to serial
Are you trying to send the bytes to the serial port or are you trying to send a hexadecimal string representation of the bytes to the serial port?
-
May 23rd, 2017, 09:14 AM
#4
Thread Starter
Junior Member
Re: Hex to serial
I am trying to send it as byte as in the above example Dim Data (7) As Byte. So as Byte's the String was just a test. i dont know if i am on the right track.
Gr. Ray
-
May 23rd, 2017, 02:39 PM
#5
Re: Hex to serial
I am not sure I fully understand what you are trying to do in your first post you had
Code:
Dim Data (5) As Byte
Data (0) = & H12
Data (1) = & HAF
Data (2) = & HAA
Data (3) = & HBB
Data (4) = Manual.Text
but you said that if the text was 9999.0 you would be converting it to 18696, firstly 18696 is actually 99990 and not 9999.0 - so which of the numbers should it be? Do you want to get the bytes of the integer 9999 or actually the decimal 9999.0?
If you are after the underlying bytes there is no need to convert the number to hex anyway, just convert the number.
Code:
Dim val = Decimal.Parse("9999.0")
Dim res = BitConverter.GetBytes(val)
'that gives
' (0): 0
' (1): 60
' (2): 28
' (3): 70
or if you meant integer then
Code:
Dim val = Integer.Parse("9999")
Dim res = BitConverter.GetBytes(val)
'that gives
' (0): 15
' (1): 39
' (2): 0
' (3): 0
those are the respective bytes for the number 9999 as a decimal or integer respectively. There is no need to convert the original number to hex to make this work.
If you really need to display things as hex then you could just display each byte as hex.
Have I misunderstood your aim?
-
May 24th, 2017, 02:32 AM
#6
Thread Starter
Junior Member
Re: Hex to serial
Hello plausiblydamp,
What i am doing is making a program that where users can enter values for different features.
the string i need to send is : <DLE> <id> <data string bytes> <DLE> <ETX>. The data string bytes is based on user input.
I have 1 combobox with 3 items, When they select one item for example item 3 the value will be 03.
Then in the 2nd Combobox i have 12 items. When they select for example 5 then this will result in 05 byte.
With this selected item i get 5 Textboxes and they must enter a value in those textboxes. those values will represent also bytes.
Textbox1 value = 50
Textbox2 value = 60
Textbox3.value = 70
Textbox4.value = 80
Textbox5.value = 50
So the packet that will be send is: <12> <AA> <50 60 70 80 50> <12> <03>
------------------------------------------DLE -- ID -- Data string bytes -- DLE -- ETX -----------------------------------------
So for example if Textbox1 has value 99990 then the send packet string is:
<12> <AA> <18 69 06 50 60 70 80 50> <12> <03>
But if i send it like this value 99990 will not be read correctly because the packet string should look like:
<12> <AA> <96 81 01 50 60 70 80 50> <12> <03>
I can use little-endian to change this.
But my biggest question is how do i program it as in my example below
Code:
Dim Data(4) As Byte
Data(0) = &H12
Data(1) = &HAA
Data(2) = Textbox1.text
Data(3) = Textbox2.Text
And from here i am lost because what if Textbox1.text has more then 2 bytes Like for example the 99990?
How does the program know this and how should it split up and add this per 2 bytes to the array?
Hope you understand my meaning
-
May 24th, 2017, 04:37 AM
#7
Re: Hex to serial
Will the users always be entering numbers into the text boxes or could it be any string at all?
If the user enters something longer than a single byte then use code similar to what I posted above to convert the contents into a byte array, you could then append this to the existing byte array rather than assuming a fixed size.
-
May 24th, 2017, 05:11 AM
#8
Thread Starter
Junior Member
Re: Hex to serial
Yes, users always enter numbers.
So if i understand you correct it should be something like this?
Code:
Dim vOut As Byte() = BitConverter.GetBytes(Convert.ToDouble(TextBox1.Text))
Dim Data (5) As Byte
Data (0) = & H12
Data (1) = & HAF
Data (2) = vOut
Is this right?
-
May 24th, 2017, 05:39 AM
#9
Re: Hex to serial
Hi Ray,
'Convert.ToDouble' produces a floating point value, and the original example you gave of 9999.0 was also a float. However, the byte values you showed corresponded to an integral value of 99990.
Can you confirm if you are expecting to work against integral values or floats?
Also, how do you know how many bytes to convert the user entered number into?
You showed 3 earlier, but also talked about the TextBox containing a value that needed 2 bytes to hold it. Isn't the number of data bytes you need to send determined by the <id> value? Wouldn't you need to know that before adding the byte values to the output Data array? PlausiblyDamp's example in Post#5 converted the user input into a 32bit integral value, and BitConverter.GetBytes will always return 4 bytes in that case. In your example above, you convert to a Double before calling BitConverter.GetBytes, so you will get an array with 8 bytes returned. So my question is, once you create the bytes from the String number in the TextBox, how many of those will you need to add to your output array?
Finally,
Code:
Dim vOut As Byte() = BitConverter.GetBytes(Convert.ToDouble(TextBox1.Text))
Dim Data (5) As Byte
Data (0) = & H12
Data (1) = & HAF
Data (2) = vOut
isn't going to work because you can't add a Byte Array to a single element of another Byte Array.
It would be better to work with a List(Of Byte) in order to build your output, and convert that List(Of Byte) to a Byte Array if necessary:
Code:
Dim bytes As New List(Of Byte)
Dim vOut As Byte() = <conversion from String in the TextBox>
bytes.Add(&H12)
bytes.Add(&HAF)
bytes.AddRange(vOut)
dim data() as byte = bytes.ToArray
-
May 24th, 2017, 05:56 AM
#10
Thread Starter
Junior Member
Re: Hex to serial
Thank alot Inferrd,
I understand now. I changed the code to convert to Int16.
Code:
Dim vOut As Byte() = BitConverter.GetBytes(Convert.ToInt16(TextBox7.Text))
bytes.Add(&H12)
bytes.Add(&HAF)
bytes.AddRange(vOut)
Dim data() As Byte = bytes.ToArray
SerialPort1.Write(data, 0, data.Length)
Now the output is with value 300 = 12 AF 2C 01
So that is what i need.
Now for a other question, If user decided to fill in 5 Textboxes can i just do following?
Code:
bytes.AddRange(vOut, vOut1, vOut2.... And so on?)
Gr. Ray
-
May 24th, 2017, 06:15 AM
#11
Re: Hex to serial
Originally Posted by Ray1972
I understand now. I changed the code to convert to Int16.
Note that Convert.ToInt16 will raise an exception if the user enters anything other than a 16 bit number into the textbox. You may want to use Int16.TryParse to prevent your program from crashing. See https://msdn.microsoft.com/en-us/lib...vs.110%29.aspx
Or use a NumericUpDown instead of a TextBox.
Originally Posted by Ray1972
Code:
bytes.AddRange(vOut, vOut1, vOut2.... And so on?)
Not quite. It would be more like:
Code:
bytes.Add(&H12)
bytes.Add(&HAF)
bytes.AddRange(vOut)
bytes.AddRange(vOut1)
bytes.AddRange(vOut2)
' And so On
See the documentation for List(Of T) at https://msdn.microsoft.com/en-us/lib...vs.110%29.aspx
-
May 24th, 2017, 06:23 AM
#12
Thread Starter
Junior Member
Re: Hex to serial
Ok got it, Thanks alot for your help!
-
May 24th, 2017, 07:28 AM
#13
Thread Starter
Junior Member
Re: Hex to serial
Can i ask 1 more question ?
I also need to get the checksum from the data byte string.
So the check sum of vOut and lets say vOut1.
I now try this:
Code:
Dim bytes As New List(Of Byte)
Dim vOut As Byte() = BitConverter.GetBytes(Convert.ToInt16(TextBox7.Text))
bytes.Add(&H10)
bytes.Add(&H8E)
bytes.Add(&HAA)
bytes.AddRange(vOut)
Dim checksum As Byte
For I As Byte = 3 To 3
checksum += bytes(I) Mod &HFF
Next
bytes.Add(checksum)
bytes.Add(&H12)
bytes.Add(&H3)
Dim data() As Byte = bytes.ToArray
SerialPort1.Write(data, 0, data.Length)
Is this the correct way?
Gr. Ray
Last edited by Ray1972; May 24th, 2017 at 08:04 AM.
-
May 24th, 2017, 07:55 AM
#14
Re: Hex to serial
Originally Posted by Ray1972
Can i ask 1 more question ?
You just did
-
May 24th, 2017, 08:04 AM
#15
Thread Starter
Junior Member
Re: Hex to serial
see edited
-
May 24th, 2017, 08:22 AM
#16
Re: Hex to serial
Originally Posted by Ray1972
I also need to get the checksum from the data byte string.
So the check sum of vOut and lets say vOut1.
I now try this:
Code:
Dim bytes As New List(Of Byte)
Dim vOut As Byte() = BitConverter.GetBytes(Convert.ToInt16(TextBox7.Text))
bytes.Add(&H10)
bytes.Add(&H8E)
bytes.Add(&HAA)
bytes.AddRange(vOut)
Dim checksum As Byte
For I As Byte = 3 To 3
checksum += bytes(I) Mod &HFF
Next
bytes.Add(checksum)
bytes.Add(&H12)
bytes.Add(&H3)
Dim data() As Byte = bytes.ToArray
SerialPort1.Write(data, 0, data.Length)
Is this the correct way?
Gr. Ray
Pretty much so. A few minor points though:
Always work with Option Strict turned on. The IDE will then give you some helpful pointers as to what might go wrong with your code.
You are adding your user data bytes to the list at indexes 3 and 4, so your For Loop should loop from '3 To 4', shouldn't it?
I would declare the loop variable as Integer, not Byte, because that's the Type that Arrays use as indexes.
So your code would become:
Code:
Dim bytes As New List(Of Byte)
' Dim vOut As Byte() = BitConverter.GetBytes(Convert.ToInt16(TextBox7.Text))
bytes.Add(&H10)
bytes.Add(&H8E)
bytes.Add(&HAA)
bytes.AddRange(vOut)
Dim checksum As Byte
For I As Integer = 3 To 4
checksum += CByte(bytes(I) Mod &HFF)
Next
bytes.Add(checksum)
bytes.Add(&H12)
bytes.Add(&H3)
Dim data() As Byte = bytes.ToArray
SerialPort1.Write(data, 0, data.Length)
All minor points though.
If you felt it appropriate, you could also calculate the checksum directly against the vOut array, and save worrying about indexes within the List:
Code:
For Each value As Byte In vOut
checksum += CByte(value Mod &HFF)
Next
-
May 24th, 2017, 09:19 AM
#17
Thread Starter
Junior Member
-
May 24th, 2017, 10:25 AM
#18
Re: Hex to serial
Rather than copy and paste the code for each textbox you could turn it into a function that has a string as a parameter and returns a List(Of Byte) - you would then just need to call this function once for each textbox.
-
May 24th, 2017, 12:50 PM
#19
Re: Hex to serial
I agree with PlausiblyDamp. Where you have repeated code, it's better to make a method out of it and just make a call to that method instead of typing out the code all over again.
But before that, I have to point out a problem with the code I gave you earlier and your subsequent code. The following is almost guaranteed to give you problems:
Code:
Dim checksum As Byte
checksum += bytes(I) Mod &HFF
and:
Code:
Dim checksum0 As Byte
Dim checksum1 As Byte
Dim checksum2 As Byte
bytes.Add(checksum0 + checksum1 + checksum2)
That's because repeatedly adding byte values is bound to exceed the maximum value for the Byte Type (255) and you'll get an overflow exception. I think the simplest (and hopefully least confusing) solution is to add a helper method that adds 2 Byte values together by converting to Int32's, and returns the least significant byte as the result:
Code:
Private Function Add2Bytes(b1 As Byte, b2 As Byte) As Byte
Return CByte((CInt(b1) + CInt(b2)) And &HFF)
End Function
OK, back to PlausiblyDamp's suggestion for reducing the amount of repetition. I don't know what you have in your ComboBox2, but it looks like you are using its SelectedIndex Property to return a number between 0 and 5, and that number refers to the count of the input TextBoxes that you want to take values from. You could use that number to index an array of your TextBoxes, looping through the correct number of TextBoxes for the ComboBox's SelectedIndex. It also appears that you always have the same lead byte values of 0x10, 0x8E, 0xAA, 0xBB and the same tail byte values of 0x12, 0x03 so you could in theory write your code something like:
VB.NET Code:
Dim inputBoxes() As TextBox = {TextBox7, TextBox8, TextBox9, TextBox10, TextBox11, TextBox12} Dim inputsUpperBound As Integer = ComboBox2.SelectedIndex Dim bytes As New List(Of Byte) bytes.Add(&H10) bytes.Add(&H8E) bytes.Add(&HAA) bytes.Add(&HBB) Dim checksum0 As Byte = CalculateChecksum(bytes.GetRange(3, 1).ToArray) Dim inputsChecksum As Byte = 0 For index As Integer = 0 To inputsUpperBound Dim inputTextBox As TextBox = inputBoxes(index) Dim vOut As Byte() = BitConverter.GetBytes(Convert.ToInt16(inputTextBox.Text)) bytes.AddRange(vOut) inputsChecksum = Add2Bytes(inputsChecksum, CalculateChecksum(vOut)) Next bytes.Add(Add2Bytes(checksum0, inputsChecksum)) bytes.Add(&H12) bytes.Add(&H3) Dim data() As Byte = bytes.ToArray SerialPort1.Write(data, 0, data.Length)
with the 2 additional methods: one for calculating the checksum of the input box number, and the other for adding the checksum values without overflow:
VB.NET Code:
Private Function CalculateChecksum(arrayOfBytes() As Byte) As Byte Dim checksum As Byte = 0 For Each value As Byte In arrayOfBytes checksum = Add2Bytes(checksum, CByte(value Mod &HFF)) Next Return checksum End Function Private Function Add2Bytes(b1 As Byte, b2 As Byte) As Byte Return CByte((CInt(b1) + CInt(b2)) And &HFF) End Function
Saves a lot of Copy and Pasting, and should be easier to maintain and debug.
-
May 24th, 2017, 01:40 PM
#20
Thread Starter
Junior Member
Re: Hex to serial
Thanks alot guys for al your help and information.
I am going to work on this, will report back
Thnx again!
Gr. Ray
-
May 26th, 2017, 08:58 AM
#21
Thread Starter
Junior Member
Re: Hex to serial
Works like a charm, Tnx alot for the help guys.
Gr. Ray
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|