Member 12292743 Ответов: 3

Как прочитать более 1 байта из последовательного порта


 Dim outData As Byte() = New Byte(0) {}

Private Function HextoByte(ByVal msg As String) As Byte()
        msg = msg.Replace(" ", "")

        Dim combuffer As Byte() = New Byte(msg.Length \ 2 - 1) {}
        For i As Integer = 0 To msg.Length - 1 Step 2
            combuffer(i \ 2) = CByte(Convert.ToByte(msg.Substring(i, 2), 16))
        Next

        Return combuffer
    End Function

Private Function BytetoHex(ByVal comByte As Byte()) As String
        Dim builder As New StringBuilder(comByte.Length * 3)
        For Each data As Byte In comByte
            builder.Append((Convert.ToString(data, 16).PadLeft(2, "0")))
        Next
        Return builder.ToString().ToUpper()
    End Function

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        lblDataValue.Text = ScrollData.Value.ToString()
        ScrollData.Enabled = False
        ScrollData.Maximum = 255
        ScrollData.LargeChange = 1
        btnDisconnect.Enabled = False
        tbRx.Text = "00"

        Dim Portnames as String() = SerialPOrt.GetPortNames
        IF Portnames is nothing then
            msgbox("No ports detected")
            me.close()
        End If
        cbComPort.Items.AddRange(Portnames)
        cbComPort.Text = Portnames(0)
    End Sub

Private Sub btnConnect_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnConnect.Click

        outData(0) = Convert.ToByte(lblDataValue.Text)

        Try
            SerialPort1.PortName = cboCOMPorts.Items(cboCOMPorts.SelectedIndex).ToString()
            SerialPort1.BaudRate = 9600
            SerialPort1.Open()
            SerialPort1.Write(outData, 0, 1)
            btnDisconnect.Enabled = True
            ScrollData.Enabled = True
            btnConnect.Enabled = False
        Catch ex As Exception
            btnDisconnect.PerformClick()
        End Try
    End Sub

 Private Sub btnDisconnect_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnDisconnect.Click
        Try
            SerialPort1.DiscardInBuffer()
            SerialPort1.DiscardOutBuffer()
            SerialPort1.Close()
            ScrollData.Value = 0
            ScrollData.Enabled = False
            btnConnect.Enabled = True
            btnDisconnect.Enabled = False
        Catch ex As Exception

        End Try
    End Sub

Private Sub ScrollData_Scroll(ByVal sender As System.Object, ByVal e As System.Windows.Forms.ScrollEventArgs) Handles ScrollData.Scroll
        lblDataValue.Text = ScrollData.Value.ToString("X")

        outData(0) = Convert.ToByte(ScrollData.Value)
        SerialPort1.Write(outData, 0, 1)
    End Sub

Private Delegate Sub DisplayDelegate(ByVal displayChar As String)

    Private Sub DisplayCharacter(ByVal displayChar As String)
        tbRx.Text = displayChar
    End Sub

    Private Sub serialPort1_DataReceived(ByVal sender As Object, ByVal e As SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
        Dim rx As Integer
        rx = SerialPort1.BytesToRead
        Dim comBuff As Byte() = New Byte(rx - 1) {}
        SerialPort1.Read(comBuff, 0, rx)
        tbRx.Invoke(New DisplayDelegate(AddressOf DisplayCharacter), New Object() {BytetoHex(comBuff)})
    End Sub


код взят с этого сайта


[^]

Что я уже пробовал:

http://www.codeproject.com/Tips/341405/Read-n-bytes-from-the-serial-port-in-NET

В приведенной выше ссылке объясняется, как читать n байт, что я и думал сделать, так как ожидаю 2 байта в соответствии с руководством по командам от производителя:

https://www.google.co.uk/url?sa=t&rct=j&q=&esrc=s&source=web&cd=3&cad=rja&uact=8&ved=0ahUKEwj8xNS2-Z3PAhVDD8AKHQotAIIQFgg0MAI&url=http%3A%2F%2Fwww.optris.co.uk%2Finterfaces%3Ffile%3Dtl_files%2Fdownloads%2FManuals%2Faddendums-de-en%2Fct-ctlaser-commands.pdf&usg=AFQjCNEkEtwUoiM6jsJYOnGD4-8Yo2Cprg&bvm=bv.133387755,bs.2,d.d2s

Member 12292743

но ничего не меняется в tbRx, в котором я хочу видеть временное значение

Member 12292743

если я прав насчет чтения более 1 байта, как мне реализовать это в своем коде

3 Ответов

Рейтинг:
2

Ralf Meier

Если вы хотите прочитать более 1 байта (этот ответ является дополнительным к решению от OG), то вы можете/должны подождать до "SerialPort1.BytesToRead "имеет то значение ,которое вы хотите иметь - возможно, с помощью цикла или" Do... до того момента" ... или в методе "serialPort1_DataReceived" вы сначала проверяете, имеет ли BytesToRead правильное значение - в другом случае вы оставляете метод, ничего не делая ...

например :

Private Sub serialPort1_DataReceived(ByVal sender As Object, ByVal e As SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
    Dim rx As Integer
    rx = SerialPort1.BytesToRead
    if rx >= 2 then
       Dim comBuff As Byte() = New Byte(rx - 1) {}
       SerialPort1.Read(comBuff, 0, rx)
       tbRx.Invoke(New DisplayDelegate(AddressOf DisplayCharacter), New Object() {BytetoHex(comBuff)})
    end if
End Sub


Member 12292743

как проверить, имеет ли BytesToRead правильное значение?

Ralf Meier

у вас есть строка в коде, где вы написали "rx = SerialPort1.BytesToRead".
если теперь вы ждете 2 байта, а значение "rx" не равно 2, то вы прерываете метод (например, " Exit Sub")

Member 12292743

извините, что причиняю вам боль, ребята, но я реализовал ваше предложение, и все равно ничего не происходит.

Я заметил что-то странное, я поставил точку останова в функции scrolldata, и когда я шагаю и иду строка за строкой, на этой строке появляется сообщение об ошибке:

SerialPort1. Write(outData, 0, 1)

говорит, что порт закрыт.

Я пытался вставить SerialPort1.open() раньше, но появилось еще одно сообщение об ошибке, говорящее, что порт уже открыт?

Что мне делать

Ralf Meier

Содержит ли ваш ComboBox-Selection допустимый COM-порт при использовании метода Btn_Connect ?
Возможно, вам следует сначала отладить (complete) SerialPort-настройки (путем установки точки останова в строке " SerialPort1. Write(outData, 0, 1)".
Изменения кода, которые я внес в это решение, не могут повлиять на такое поведение ...

Рейтинг:
1

CPallini

Вы можете использовать буфер для добавления полученных байтов (по одному за раз). Затем, когда накопленных байтов в буфере достаточно, вы обрабатываете их, чтобы получить значимую информацию.


Member 12292743

не могли бы вы показать мне пример того, что вы имеете в виду?

Рейтинг:
0

OriginalGriff

Последовательные порты, как правило, не являются "быстрыми устройствами" - и когда вы используете 9600 бод, вы говорите: "этот порт передает не более 9600 бит информации в секунду". Это примерно 960 байт в секунду (чуть меньше, чем из - за старта, остановки и битов четности на самом деле) - что с точки зрения вычислительной мощности вашего ПК положительно ледяное. И событие DataReceived сигнализируется каждый раз, когда байт принимается аппаратным обеспечением. Таким образом, если ваше удаленное устройство отправляет пять байтов, вы, вероятно, получите пять хорошо разнесенных событий: по одному на каждый байт.

И каждый раз, когда вы получаете байт, вы перезаписываете то, что находится в textbox...so вы никогда не увидите только последний байт, ни один из других.