VB.net返回chr(255)为chr(63)

时间:2015-06-13 04:57:30

标签: vb.net chr

我正在用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

1 个答案:

答案 0 :(得分:8)

.NET SerialPort类具有an Encoding associated with it,用于在端口上发送的文本和字节之间进行转换。文档说它用于"文本传输前后的转换"。我并不完全清楚Encoding用于将收到的字节转换为从string返回的ReadTo()的文本(但这可能是"传输后"。)

无论如何,我很确定这就是255字符发生的事情。 ReadTo()方法使用Encoding将收到的数据转换为文本以放入string。默认EncodingASCIIEncoding,仅处理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);