我正在用Visual Basic编写程序,遇到了一个奇怪的问题。我通过串口将字符串发送到望远镜支架。当我发送check
字符串时,范围可以返回chr(0)或chr(255)。这在python和c ++返回chr(255)时工作正常。但是,当我在visual basic中运行脚本时,它返回chr(0)或chr(63)。
下面是两个相同的函数,一个在python中,一个在visual basic中。
有谁能让我知道为什么visual basic会返回63而不是255?
python中的函数(返回正确的值0和255):
global d, check
d=chr(80)+chr(4)+chr(16)+chr(2)+chr(1)+chr(112)+chr(252)+chr(0)
check=chr(80) + chr(1) + chr(16) + chr(19) + chr(0) + chr(0) + chr(0)+chr(1)
def test():
ser.write(d)
time.sleep(.1)
print ser.readline()
ser.write(check)
time.sleep(.1)
out=ser.readline()[0]
print "out=",ord(out)
while out == chr(0):
print "out = ", ord(out)
ser.write(check)
time.sleep(.1)
out=ser.readline()[0]
print "out=",ord(out)
print "out is now", ord(out)
ser.readline()
Visual Basic中的脚本(返回错误的值0和63)
Public Sub test()
Dim out As Char
Dim d As String = Chr(80) + Chr(4) + Chr(16) + Chr(2) + Chr(1) + Chr(112) + Chr(252) + Chr(0)
Dim check As String = Chr(80) + Chr(1) + Chr(16) + Chr(19) + Chr(0) + Chr(0) + Chr(0) + Chr(1)
port.Write(d)
Threading.Thread.Sleep(100)
Console.Write(port.ReadTo("#"))
port.Write(check)
Threading.Thread.Sleep(100)
out = port.ReadTo("#")
Console.Write(vbNewLine & "out=" & out)
While out = Chr(0)
Console.Write("out = " & Convert.ToInt16(out))
port.Write(check)
Threading.Thread.Sleep(0.1)
out = port.ReadTo("#")
Console.Write("out=" & Convert.ToInt16(out))
End While
Console.Write("out is now" & Convert.ToInt16(out))
port.ReadLine()
End Sub
答案 0 :(得分:8)
.NET SerialPort
类具有an Encoding
associated with it,用于在端口上发送的文本和字节之间进行转换。文档说它用于"文本传输前后的转换"。我并不完全清楚Encoding
用于将收到的字节转换为从string
返回的ReadTo()
的文本(但这可能是"传输后"。)
无论如何,我很确定这就是255
字符发生的事情。 ReadTo()
方法使用Encoding
将收到的数据转换为文本以放入string
。默认Encoding
为ASCIIEncoding
,仅处理0x00
- 0x7f
范围内的字符。该范围之外的字节将被编码为'?'
个字符,其ASCII值恰好为63
。
使用ReadByte()
方法来读取端口中的数据,而不涉及任何文本编码。
更新:我发现BCL团队中有人发布了一篇博文,证实了这一点,并指出了一个未经修改的8位数据传输的编码对象。 Ryan Byington在2006年5月26日的一篇名为"SerialPort Encoding" on the Base Class Library (BCL) Blog的文章中写道:
SerialPort
类使用由...指定的编码SerialPort.Encoding
属性转换字符串和字符数组 到串口发送的字节数。此编码也会被使用 从串口读取时转换后接收的字节数 串口到字符串和字符数组。默认情况下,
SerialPort
类使用ASCII编码转换所有 值为0-127的字符与单个字节相同 值。那么"你好"转换为字节数组{72,101,108,108, 111}。但是,每个其他字符都会被转换为一个字节 值为63或'?'
个字符。这也适用于阅读 如果串口接收到字节数组{72,101,108,108,111} 将此转换为"你好"以及任何大于的字节 127将转换为'?'
字符。对于大多数串行设备,ASCII编码非常适用 还有不少设备要么发送带有值的字节 超过127或你需要发送值大于127的字节。你 有两种选择;一个是使用处理
byte[]
的API 并绕过Encoding
,或使用正确的编码。然而 找到正确的编码就像大多数编码那样有点棘手 处理127以上的值将使用多个字节 不适用于连接到串行端口的设备。唯一的 将值为0-255的所有字符转换为单个字符的编码 转换字节时,字节具有相应的值,反之亦然 字符是"西欧(ISO)"编码。使用 以下代码将此编码与SerialPort类一起使用:SerialPort mySerialPort = new SerialPort("COM1"); mySerialPort.Encoding = Encoding.GetEncoding(28591);