2013-06-15 2 views
1

У меня есть приложение VB.NET 4, которое получает 10 байтов данных ASCII от микроконтроллера PIC24 по UART. Это моя функция приема:Неполный последовательный RX в VB

Private Sub mySerialPort_DataReceived(ByVal sender As Object, ByVal e As SerialDataReceivedEventArgs) 
     'Handles serial port data received events 
     UpdateFormDelegate1 = New UpdateFormDelegate(AddressOf UpdateDisplay) 
     Dim n As Integer = mySerialPort.BytesToRead 'find number of bytes in buf 
     comBuffer = New Byte(n - 1) {} 're dimension storage buffer 
     mySerialPort.Read(comBuffer, 0, n) 'read data from the buffer 
     Me.Invoke(UpdateFormDelegate1) 'call the delegate 
    End Sub 

Here is where I got this block of code

я анализирую и присвоить полученные данные, где он должен пойти с этим кодом:

Private Sub UpdateDisplay() 
     Dim i As Integer 
     Dim RX_String(15) As String 
     Dim RX_String_Hex(15) As String 
     Dim Message As String 

     For i = 0 To comBuffer.Length - 1 
      RX_String(i) = Chr(comBuffer(i)) 
     Next 
     Message = String.Join("", RX_String) 
     TextBox1.Text = Message 
    End Sub 

Когда я запускаю мое приложение, я открываю последовательный порт. Затем я указываю микроконтроллеру на отправку данных, т. Е. 1234567890, в моем приложении VB будут отображаться такие вещи, как 12, 4567890 и т. Д., Пока в конце концов он не отобразит полную строку данных после случайного числа передач от микроконтроллера. Я никогда не делал сериала в VB, поэтому я должен пропустить очевидное. Я пропускаю то, что мешает мне получать все 10 байт каждый раз?

+0

В дисплее обновления вы могли бы сделать уровень класса сообщений, то сообщение + = string.join («», RX_String). Используйте условие, чтобы подождать, пока оно не достигнет нужной длины, а затем отобразит строку. – tinstaafl

+0

Вы делаете классическую ошибку, игнорируя возвращаемое значение метода Read(). Это будет ** не ** быть «n», как правило, всего несколько байтов. Что бы ни случилось в буфере приема, не так много, поскольку последовательные порты работают медленно. Не вызывайте BeginInvoke, пока не получите их всех. –

+0

Вам следует подумать о том, чтобы сделать процедуру «UpdateDisplay» взятием буфера в качестве параметра, чтобы избежать условий гонки, если другое серийное событие получено до того, как основной поток обработает предыдущий. Кроме того, 'System.Text.Encoding.ASCII.GetString' хорош для преобразования байт-массивов в строки. –

ответ

1

Вот некоторые универсальный код для обработчика событий DataReceived

Dim dataByts As New List(Of Byte) 
Dim dataLock As New Object 
Dim datarcvd As New Threading.AutoResetEvent(False) 

Private Sub SerialPort1_DataReceived(sender As Object, _ 
            e As IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived 
    Dim br As Integer = SerialPort1.BytesToRead '# of bytes to read 
    If br > 0 Then 
     Dim b(br - 1) As Byte 'create buffer to read into 
     Try 
      br = SerialPort1.Read(b, 0, b.Length) 'read the bytes 
      If br < b.Length Then 'adjust length if required 
       Array.Resize(b, br) 
      End If 
      'add bytes just read to list 
      Threading.Monitor.Enter(dataLock) 
      dataByts.AddRange(b) 
      Threading.Monitor.Exit(dataLock) 
      datarcvd.Set() 'signal event fired 
      ' 
      'check for a condition 
      ' 
      If dataByts.Count >= 10 Then 
       'condition met <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 
      End If 
      ' 
      'fine tune exception handling 
      ' 
     Catch ex As Exception 
      Debug.WriteLine(ex.Message) 
     End Try 
    End If 
End Sub 

Private Sub SerialPort1_ErrorReceived(sender As Object, _ 
             e As IO.Ports.SerialErrorReceivedEventArgs) _ 
            Handles SerialPort1.ErrorReceived 
    Debug.WriteLine(e.EventType) 
End Sub 

Если у вас есть 10 байт (или больше), то Invoke делегат и декодировать строку. Обратите внимание на блокировку при размещении байтов в буфере. Делегат должен выглядеть следующим образом

Dim s As String = "" 
    Threading.Monitor.Enter(dataLock) 'yes 
    s = SerialPort1.Encoding.GetChars(dataByts.ToArray, 0, 10) 
    dataByts.RemoveRange(0, 10) 'remove the bytes processed 
    Threading.Monitor.Exit(dataLock) 
    TextBox1.Text = s 
+0

Большое значение. Я могу честно сказать, что никогда бы не подумал об этом. – KZ5EE