VB.NET中的串口打包消息问题 [英] Serial Port Packed Message Problem in VB.NET
问题描述
我有编程手册协议,但是当我编写代码时,vb.net返回错误信息。
以下是字节数组的表结构/>
I have the Manual of Programming protocol, but when I write code vb.net returns error message.
The following is the table structure of bytes array
position 1 2 3 4 5 6 7 8
Name SOH LEN SEQ CMD DATA Post-amble BCC ETX
Lenth/bytes 1 1 1 1 0-200 1 4 1
Value (01h) (20h-FFh) (20h-FFh) (20h-FFh) (20h-FFh) (05h) (30h-3Fh) (03h)
缩写:
SOH - (起始标题)开始打包消息
LEN - 从位置2到位置6的总字节数加上固定偏移量20h。
SEQ - 数据包的序列号。 SLAVE在回复消息中放置相同的SEQ。如果SLAVE收到的消息与上次正确接收的消息具有相同的SEQ和CMD,则设备会忽略该消息并重复发送给主机的最后一个数据包。
CMD - 命令代码
DATA - 数据,根据命令。如果没有数据,则长度字段为零。
BCC - 控制和(0000h-FFFFh)。从位置2到位置6的数据字节总和。控制和以ASCІІ类型传输(12А被传输为31h32h3Аh3Вh)。
ETX - (TeXt结束)打包结束消息。
代码示例:
Abbreviations:
"SOH"- (Start Of Heading) start of packed message
"LEN"- total number of bytes from position 2 to position 6, plus fixed offset of 20h.
"SEQ"- serial number of packet. SLAVE puts the same "SEQ" in the reply message. In case when SLAVE receives a message with the same "SEQ"and "CMD" like the last correctly received message, the device ignores the message and repeats the last packet sent to the HOST.
"CMD" – code of command
"DATA"- data, according to the command. If there is no data, the length field is zero.
"BCC" – control sum(0000h-FFFFh). Sum of data bytes from position 2 to position 6. The control sum is transferred in ASCІІ type (12АВ is transferred as 31h 32h 3Аh 3Вh).
"ETX" – (End of TeXt) end of packed message.
Codes sample:
Public Class Form1
Private WithEvents sp As System.IO.Ports.SerialPort
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
For Each y As String In System.IO.Ports.SerialPort.GetPortNames
Me.ComboBox1.Items.Add(y)
Next
sp = New IO.Ports.SerialPort("COM4")
sp.StopBits = IO.Ports.StopBits.One
sp.BaudRate = 9600
sp.DataBits = 8
sp.Parity = IO.Ports.Parity.None
sp.Handshake = IO.Ports.Handshake.None
sp.Open()
Dim by As Byte = &H20
' MsgBox(&H20)
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Try
Dim By(9) As Byte
By(0) = 1
By(1) = &H2 + &H20
By(2) = &H58
By(3) = &H45
By(4) = &H5
Dim S As String = Hex(&H58 Xor &H45)
' MsgBox(S)
By(5) = &H30
By(6) = &H30
By(7) = &H31
By(8) = &H3D
By(9) = &H3
sp.Write(By, 0, By.Length - 1)
' MsgBox(sp.ReadByte)
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub
Private Sub sp_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles sp.DataReceived
Dim rec As System.IO.Ports.SerialPort = sender
MsgBox(Hex(rec.ReadByte))
End Sub
End Class
[edit]已添加代码块 - OriginalGriff [/ edit]
[edit]Code block added - OriginalGriff[/edit]
推荐答案
返回十进制21意味着消极承认。请真的需要解决这个问题。可能是BCC的计算!!
如果没有示例,有太多的可能性可以告诉我,但我首先要考虑到正确的长度...
"Return Decimal 21 which mean negative acknowledge. Please I real need to solve this problem. May be the calculation of BCC!!"
There are far too many possibilities to tell without examples, but I'd start by getting the length right...
"LEN"- total number of bytes from position 2 to position 6, plus fixed offset of 20h.
so2 可能会出错。
然后有命令,应该在0x20到0xFF范围内,但你提供的是0x05。
获取一个工作样本,并将其恢复到你需要做的事情。
然后写一个方法,它接受一个命令字节和一个字节数组,然后计算出休息 - 使用样本如果它正在工作,那就好了。
请注意每次序列号必须不同!
(提示:你可以使用BitConverter.GetBytes [ ^ ] to conver t一个整数到一个字节数组 - 这是你的校验和排序!)
so "2" is probably going to be wrong.
Then there is the command, which should be in the range 0x20 to 0xFF, but you are supplying 0x05.
Get a working sample, and work it back to what you need to do.
Then write a method that takes a command byte and a byte array and works out teh rest - use the sample to work out if it's working.
And do note that the sequence number must be different each time!
(Hint: you can use BitConverter.GetBytes[^] to convert an integer to an array of bytes - that's your checksum sorted!)
以下是工作方式
The followin is the way worked
Public Class PrinterControl
Private Const SOH As Byte = &H1
Private Const SEQ As Byte = 96
Private Const POST_AMBLE As Byte = &H5
Private Const ETX As Byte = &H3
Private _SerialPort As System.IO.Ports.SerialPort
Public Property SerialPort As System.IO.Ports.SerialPort
Get
Return _SerialPort
End Get
Set(ByVal value As System.IO.Ports.SerialPort)
_SerialPort = value
End Set
End Property
Public Function SendCommand(ByVal CMD As Byte, ByVal Data As String) As String
If Not SerialPort.IsOpen Then
SerialPort.Open()
End If
If Data = "" Then
Dim by() As Byte = Write(CMD)
SerialPort.Write(by, 0, by.Length)
Else
Dim FormASCII As Byte() = System.Text.ASCIIEncoding.ASCII.GetBytes(Data)
Dim by() As Byte = Write(CMD, FormASCII)
SerialPort.Write(by, 0, by.Length)
End If
If SerialPort.ReadByte = 21 Then
Return "Error"
End If
Dim Baf(SerialPort.ReadBufferSize) As Byte
SerialPort.Read(Baf, 0, Baf.Length)
Dim lstB As New List(Of Byte)
For px As Integer = 4 To 200 + 4
If Baf(px) = &H4 Then Exit For
lstB.Add(Baf(px))
Next
SerialPort.Close()
Dim st As String = ""
For Each bbb In lstB
st = st & Chr(bbb)
Next
Return st
Return "Error"
End Function
Public Function AddItem(ByVal ID As Integer, ByVal Description As String, ByVal Price As Double, ByVal VATGroup As String) As String
Return Me.SendCommand(&H6B, "P" & VATGroup & ID & "," & Price & "," & Description)
End Function
Public Function Write(ByVal CMD As Byte, Optional ByVal DATA As Byte() = Nothing) As Byte()
Dim LEN As Byte
If DATA Is Nothing Then
Len = (&H4 + &H20)
Dim By(9) As Byte
By(0) = SOH
By(1) = LEN
By(2) = SEQ
By(3) = CMD
By(4) = POST_AMBLE
Dim V_Int As Integer = LEN + SEQ + POST_AMBLE
V_Int = V_Int + CMD
Dim strHex As String = Hex(V_Int)
Dim reString As String = strHex
If strHex.Length = 1 Then
reString = "000" & strHex
End If
If strHex.Length = 2 Then
reString = "00" & strHex
End If
If strHex.Length = 3 Then
reString = "0" & strHex
End If
By(5) = "&H3" & reString(0)
By(6) = "&H3" & reString(1)
By(7) = "&H3" & reString(2)
By(8) = "&H3" & reString(3)
By(9) = ETX
Return By
Else
LEN = (&H4 + &H20) + DATA.Length
Dim By(9 + DATA.Length) As Byte
By(0) = SOH
By(1) = LEN
By(2) = SEQ
By(3) = CMD
Dim II As Integer = 4
Dim bCal As Integer = 0
For Each bb As Byte In DATA
By(II) = bb
bCal += bb
II += 1
Next
By(II) = POST_AMBLE
II += 1
Dim V_Int As Integer = LEN + SEQ + POST_AMBLE
V_Int = V_Int + CMD
V_Int = V_Int + bCal
Dim strHex As String = Hex(V_Int)
Dim reString As String = strHex
If strHex.Length = 1 Then
reString = "000" & strHex
End If
If strHex.Length = 2 Then
reString = "00" & strHex
End If
If strHex.Length = 3 Then
reString = "0" & strHex
End If
By(II) = "&H3" & reString(0)
II += 1
By(II) = "&H3" & reString(1)
II += 1
By(II) = "&H3" & reString(2)
II += 1
By(II) = "&H3" & reString(3)
II += 1
By(II) = ETX
Return By
End If
Return Nothing
End Function
End Class
这篇关于VB.NET中的串口打包消息问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!