如何从串口读取超过1个字节 [英] How to read more than 1 bytes from serial port
问题描述
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
the代码来自本网站
>
[ ^ ]
我的尝试:
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德烯%2Fct-ctlaser -commands.pdf& usg = AFQjCNEkEtwUoiM6jsJYOnGD4-8Yo2Cprg& bvm = bv.133387755,bs.2,d.d2s
the code is from this website
[^]
What I have tried:
http://www.codeproject.com/Tips/341405/Read-n-bytes-from-the-serial-port-in-NET
In the link above, it explains how to read n bytes which is what i was thinking I should do since I am expecting 2 bytes as per the commands manual from the manufacturer:
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
推荐答案
串口通常不是快速设备 - 当你使用9600波特时,你说这个端口最多每秒传输9600位信息。这大约是每秒960字节(略低于实际上由于启动,停止和奇偶校验位) - 就PC处理能力而言,这是积极的冰川。每次硬件接收到一个字节时,都会发出DataReceived事件的信号。因此,如果您的远程设备发送五个字节,您可能会得到五个间距很大的事件:每个字节一个。
每次收到一个字节时,都会覆盖文本框中的内容...所以你只会看到最后一个字节,而不是其他字节。
Serial ports are generally not "fast devices" - and when you use 9600 baud, you are saying "this port transfers 9600 bits of information per second at most". That's roughly 960 bytes per second (slightly less than that due to start, stop, and parity bits in fact) - which in terms of your PC processing power is positively glacial. And the DataReceived event is signalled every time a byte is received by the hardware. So if your remote device sends five bytes, you will probably get five well-spaced events: one for each byte.
And each time your receive a byte, you overwrite what is in the textbox...so you will only ever see the final byte, none of the others.
如果你想读取超过1个字节(这个答案是附加的来自OG的解决方案然后您可以/应该等到SerialPort1.BytesToRead具有您想要的值 - 可能是循环或Do ... until...或者在方法serialPort1_DataReceived中首先检查BytesToRead具有正确的价值 - 在其他情况下你离开方法而不做任何事情...
例如:
If you want to read more than 1 Byte (this answer is additional to the solution from OG) then you could/should wait until "SerialPort1.BytesToRead" has that value you want to have - perhaps with a loop or "Do ... until" ... or in the method "serialPort1_DataReceived" you check first if BytesToRead has the right value - in other case you leave the method without doing anything ...
for example :
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
您可以使用缓冲区将接收的字节(一次一个)附加到。然后,当缓冲区中的累积字节数足够时,您可以处理它们以获取有意义的信息。
You might use a buffer to append received bytes (one at time) to. Then when the accumulated bytes in the buffer are enough, you process them in order to abtain the meaningful info.
这篇关于如何从串口读取超过1个字节的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!