locked
Byte array and byte converter RRS feed

  • Question

  • Hi,

    i have several numberical text boxes that i need to convert into a bit array using te BitConverter

    i have the following code:-


        
    Code Block

        Dim i As Integer
            Dim limits(0 To 12) As Byte

            limits = BitConverter.GetBytes(Convert.ToInt16(GFPLowntxb.Value))
            limits = BitConverter.GetBytes(Convert.ToInt16(GFPHighntxb.Value))


            For i = 0 To limits.Length - 1
                SerialDatartb.AppendText(limits(i) & vbCrLf)
            Next


    but making limits =BitConverter.GetBytes(Convert.ToInt16(GFPHighntxb.Value)) will just save data to Limits(0) and limits (1), how do i make

    GFPLowntxb.value get converted into limits(0) and limits(1) and GFPHighntxb.value into limits(2) and limits(3) and so on for another 4 numberical box's

    I am sure there is a simple answer.

    Regards,

    Andy
    Wednesday, January 16, 2008 1:16 PM

Answers

  • Hi,

     

    I've cracked it.

     

    I put in the decimal equivalents of the values.>>

     

    FF

    EE

    DD

    CC

    BB

    AA

     

    which are;

     

    • 255
    • 238
    • 221
    • 204
    • 187
    • 170

     

    Extracting the low byte first you get.>>

     

    • 15 + 240
    • 14 + 224
    • 13 + 208
    • 12 + 192
    • 11 + 176
    • 10 + 160

     

    If you add either of those pairs of values together you will see this is correct.

     

    I have used 6 textboxes with the names;

     

    • txt1
    • txt2
    • txt3
    • txt4
    • txt5
    • txt6

     

    and the default button name in this code.

     

    The Try Catch End Try block is there in case values of 256 or more are entered.

     

    0 to 11 inclusive is 12 items in the array.

     

     

     

     

    Regards,

     

    John

    ( A student at Teesside University, England. ).

     

     

    Code Block

     

    Option Strict On

    Public Class Form1

     

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

     

    Dim i As Integer

    Dim limits(11) As Byte

    'limits = BitConverter.GetBytes(Convert.ToInt16(GFPLowntxb.Value))

    'limits = BitConverter.GetBytes(Convert.ToInt16(GFPHighntxb.Value))

    Dim textBoxNumber As Integer

    Try

    For Each ctrl In Me.Controls

    If TypeOf (ctrl) Is TextBox Then

    If CType(ctrl, TextBox).Name.Substring(0, 3) = "txt" Then

    textBoxNumber = Convert.ToInt32(CType(ctrl, TextBox).Name.Substring(3, 1))

     

    limits((textBoxNumber * 2) - 2) = Convert.ToByte(CLng(CType(ctrl, TextBox).Text) And &HF)

     

    limits((textBoxNumber * 2) - 1) = Convert.ToByte(CLng(CType(ctrl, TextBox).Text) And &HF0)

     

    End If

    End If

    Next

    Catch

    End Try

     

    Dim outputString As String = ""

    For i = 0 To limits.GetUpperBound(0)

    outputString &= limits(i).ToString & vbCrLf

    SerialDatartb.AppendText(limits(i) & vbCrLf)

    Next

    MessageBox.Show(outputString)

    End Sub

    End Class

     

     

     

     

    Wednesday, January 16, 2008 10:58 PM

All replies

  • Hi,

     

    I've cracked it.

     

    I put in the decimal equivalents of the values.>>

     

    FF

    EE

    DD

    CC

    BB

    AA

     

    which are;

     

    • 255
    • 238
    • 221
    • 204
    • 187
    • 170

     

    Extracting the low byte first you get.>>

     

    • 15 + 240
    • 14 + 224
    • 13 + 208
    • 12 + 192
    • 11 + 176
    • 10 + 160

     

    If you add either of those pairs of values together you will see this is correct.

     

    I have used 6 textboxes with the names;

     

    • txt1
    • txt2
    • txt3
    • txt4
    • txt5
    • txt6

     

    and the default button name in this code.

     

    The Try Catch End Try block is there in case values of 256 or more are entered.

     

    0 to 11 inclusive is 12 items in the array.

     

     

     

     

    Regards,

     

    John

    ( A student at Teesside University, England. ).

     

     

    Code Block

     

    Option Strict On

    Public Class Form1

     

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

     

    Dim i As Integer

    Dim limits(11) As Byte

    'limits = BitConverter.GetBytes(Convert.ToInt16(GFPLowntxb.Value))

    'limits = BitConverter.GetBytes(Convert.ToInt16(GFPHighntxb.Value))

    Dim textBoxNumber As Integer

    Try

    For Each ctrl In Me.Controls

    If TypeOf (ctrl) Is TextBox Then

    If CType(ctrl, TextBox).Name.Substring(0, 3) = "txt" Then

    textBoxNumber = Convert.ToInt32(CType(ctrl, TextBox).Name.Substring(3, 1))

     

    limits((textBoxNumber * 2) - 2) = Convert.ToByte(CLng(CType(ctrl, TextBox).Text) And &HF)

     

    limits((textBoxNumber * 2) - 1) = Convert.ToByte(CLng(CType(ctrl, TextBox).Text) And &HF0)

     

    End If

    End If

    Next

    Catch

    End Try

     

    Dim outputString As String = ""

    For i = 0 To limits.GetUpperBound(0)

    outputString &= limits(i).ToString & vbCrLf

    SerialDatartb.AppendText(limits(i) & vbCrLf)

    Next

    MessageBox.Show(outputString)

    End Sub

    End Class

     

     

     

     

    Wednesday, January 16, 2008 10:58 PM
  • Hi John

    There is a utility that somebosy has made. that converts a number MSB first then LSB and it can be found here: -

    http://www.yoda.arachsys.com/csharp/miscutil/

    basically i have six numerical text box's that can hold a 16bit int (uShort) and i need to collect them into a byte array MSB first followed by LSB. so i would have :-

    limits0) = numerical box 1 - MSB
    limits(0) = numerical box 1 - LSB
    limits(0) = numerical box 2 - MSB
    limits(0) = numerical box 2 - LSB
    and so on

    then i can call

     SerialPort.Write(Data, 0, 11) to send the data through the serial port. so my question is: -

    as

     limits = MiscUtil.Conversion.BigEndianBitConverter.Big.GetBytes(Convert.ToInt16(GFPLowntxb.Value))

    will on each call place the MSB into limits(0) and the LSB into limits(1) ho do i make it so i can call 

    limits = MiscUtil.Conversion.BigEndianBitConverter.Big.GetBytes(Convert.ToInt16(GFPLowntxb.Value))

    say six times and get it to fill my array?

    i think i need something like : -


    Code Block

    limits As New List(Of Byte)

    limits .AddRange(MiscUtil.Conversion.BigEndianBitConverter.Big.GetBytes(Convert.ToInt16(GFPLowntxb.Value)) )


     
    not sure if that will work as i have not got time to test it

    Andy
    Wednesday, January 16, 2008 11:28 PM
  • Hi Andy,

     

    Your original post seemed to indicate you wanted the LSB first not the MSB

     as you had a line with the word Low in the early part of your code before the line with the word High.

     

    Anyway, here is my code again putting the MSB first.>>

     

    Code Block

     

    Option Strict On

    Public Class Form1

     

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

     

    Dim i As Integer

    Dim limits(11) As Byte

    Dim textBoxNumber As Integer

     

    Dim MSB, LSB As Byte

     

    Try

    For Each ctrl In Me.Controls

    If TypeOf (ctrl) Is TextBox Then

    If CType(ctrl, TextBox).Name.Substring(0, 3) = "txt" Then

    textBoxNumber = Convert.ToInt32(CType(ctrl, TextBox).Name.Substring(3, 1))

     

    MSB = Convert.ToByte(CLng(CType(ctrl, TextBox).Text) And &HF0)

     

    limits((textBoxNumber * 2) - 2) = MSB

     

    LSB = Convert.ToByte(CLng(CType(ctrl, TextBox).Text) And &HF)

     

    limits((textBoxNumber * 2) - 1) = LSB

     

    End If

    End If

    Next

    Catch

    End Try

    Dim outputString As String = ""

    For i = 0 To limits.GetUpperBound(0)

    outputString &= limits(i).ToString & vbCrLf

    SerialDatartb.AppendText(limits(i) & vbCrLf)

    Next

    MessageBox.Show(outputString)

    End Sub

    End Class

     

     

     

     

     

     

    Regards,

     

    John

     

    Thursday, January 17, 2008 2:22 PM
  • Hi john,

    Thanks for your post.

    Here is another way of doing it with the utility i mentioned:-


    Code Block

    Dim mReadBytes As New List(Of Byte)
    Dim buffer(0 To 11) As Byte

            mReadBytes.AddRange(MiscUtil.Conversion.BigEndianBitConverter.Big.GetBytes(Convert.ToInt16(GFPLowntxb.Value)))
            mReadBytes.AddRange(MiscUtil.Conversion.BigEndianBitConverter.Big.GetBytes(Convert.ToInt16(GFPHighntxb.Value)))

            mReadBytes.AddRange(MiscUtil.Conversion.BigEndianBitConverter.Big.GetBytes(Convert.ToInt16(GDPLowntxb.Value)))
            mReadBytes.AddRange(MiscUtil.Conversion.BigEndianBitConverter.Big.GetBytes(Convert.ToInt16(GDPHighntxb.Value)))

            mReadBytes.AddRange(MiscUtil.Conversion.BigEndianBitConverter.Big.GetBytes(Convert.ToInt16(GFLLowntxb.Value)))
            mReadBytes.AddRange(MiscUtil.Conversion.BigEndianBitConverter.Big.GetBytes(Convert.ToInt16(GFLHighntxb.Value)))

    mReadBytes.CopyTo(buffer)

    Transmitt(":G")

    SerialPort.Write(buffer, 0, 12)


    Thursday, January 17, 2008 2:39 PM
  • Hi Andy,

     

    If you can think of bitwise operations.

     

    FE in hex can be split into the MSB and the LSB

     

    E being the LSB and F the MSB

     

    FE as you know is 254

     

    If you do the following.>>

     

    &HFE AND &HF0 the MSB value is found.

     

    If you do

     

    &HFE AND &HF the LSB is found.

     

    This is all to do with bit-masking using the AND operator.

     

    That is all that my code is doing above, apart from directing the right textbox values to the correct array elements.

     

    Try this bit of code to see what I mean. Just add 1 button to a FORM please.

     

    This is not complicated. To use a utility to split the MSB and the LSB seems a bit  O-T-T  to me.

     

     

    Code Block

     

    Option Strict On

    Public Class Form1

     

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

     

    Dim MSB, LSB As Byte

    'Result is 240

    MSB = &HFE And &HF0

    MessageBox.Show(MSB.ToString)

    'Above in decimal is.>>

    MSB = 254 And 240

    MessageBox.Show(MSB.ToString)

     

    'Result is 14

    LSB = &HFE And &HF

    MessageBox.Show(LSB.ToString)

    'Above in decimal is.>>

    LSB = 254 And 15

    MessageBox.Show(LSB.ToString)

     

    End Sub

    End Class

     

     

     

    By the way the lowerbound of an array has to be zero.>>

     

    Dim buffer(0 To 11) As Byte

     

    it can not be say 1 To 12

     

     

     

     

    Regards,

     

    John

     

    Thursday, January 17, 2008 2:41 PM
  • Hi Andy,

     

    You could also have used

     

    buffer = mReadBytes.ToArray

     

     

     

     

    Regards,

     

    John

     

    Thursday, January 17, 2008 2:56 PM
  • You could use Array.Reverse on the array you get from the bitconverter. Also, if the textboxes hold ushorts, dont covert to int16, use uint16.

    Code Block

     

    Option Strict On
    Option
    Explicit On

    Public
    Class Form1

        
    Private uInt16Boxes(5) As TextBox
        
    Private WithEvents b As New Button
        
    Private result As New TextBox

        
    Sub New()
            InitializeComponent()
            
    Dim testVals() As String = {&H1234.ToString, &H5678.ToString, &H90AB.ToString, _
                                        &HCDEF.ToString, &H1122.ToString, &H3344.ToString}
            
    For i As Integer = 0 To uInt16Boxes.Length - 1
                uInt16Boxes(i) =
    New TextBox
                uInt16Boxes(i).Location =
    New Point(10, (uInt16Boxes(i).Height + 5) * i)
                uInt16Boxes(i).Text = testVals(i)
            
    Next
            Me.Controls.AddRange(uInt16Boxes)
            
    With uInt16Boxes(uInt16Boxes.Length - 1)
                b.Location =
    New Point(.Right - b.Width, .Bottom + 5)
            
    End With
            b.Text = "go"
            Me.Controls.Add(b)
            result.Location =
    New Point(10, b.Bottom + 5)
            result.Width =
    Me.Width - 20
            
    Me.Controls.Add(result)
        
    End Sub

        Private Sub b_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles b.Click
            
    Dim bytes(11) As Byte
            For i As Integer = 0 To uInt16Boxes.Length - 1
                
    Dim value As UShort
                If UShort.TryParse(uInt16Boxes(i).Text, value) = False Then
                    Me.Text = "bad data"
                    Exit Sub
                End If
                ' convert the ushorts to bytes
                Dim ushortBytes() As Byte = BitConverter.GetBytes(value)
                
    ' swap the endianness
                Array.Reverse(ushortBytes)
                
    ' copy to final array
                Array.Copy(ushortBytes, 0, bytes, i * 2, 2)
            
    Next
            Me.Text = "ok"
            ' display bytes
            Dim sb As New System.Text.StringBuilder
            
    For Each b As Byte In bytes
                sb.Append(Convert.ToString(b, 16).PadLeft(2, "0"c))
                sb.Append(
    ",")
            
    Next
            sb.Remove(sb.Length - 1, 1)
            result.Text = sb.ToString
        
    End Sub

    End
    Class

     

     

    Friday, January 18, 2008 12:21 AM