gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-01 21:32:49 29 4
gpt4 key购买 nike

我正在用 Visual Basic 编写一个程序,遇到了一个奇怪的问题。我正在通过串行端口将字符串发送到望远镜安装座。当我发送 check 字符串时,作用域可以返回 chr(0) 或 chr(255)。这在返回 chr(255) 的 python 和 c++ 中工作得很好。但是,当我在 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

最佳答案

.NET SerialPort 类有 an Encoding associated with it用于在端口上发送的文本和字节之间进行转换。该文档称它用于“文本传输前和传输后转换”。目前尚不清楚 Encoding 用于将接收到的字节转换为从 ReadTo() 返回的 string 的文本(但这可能就是意思是“传输后”)。

无论如何,我很确定这就是您的 255 角色所发生的情况。 ReadTo() 方法使用Encoding 将接收到的数据转换为文本以放入string 中。默认的 EncodingASCIIEncoding,它仅处理 0x00 - 0x7f 范围内的字符。超出该范围的字节将被编码为 '?' 字符,该字符的 ASCII 值恰好为 63

使用 ReadByte() 方法从端口读取数据,而不涉及任何文本编码。

更新:我发现 BCL 团队中某人发表的一篇博客文章证实了这一点,并指出了一个将传递未经修改的 8 位数据的编码对象。 Ryan Byington 在一篇名为 "SerialPort Encoding" on the Base Class Library (BCL) Blog 的文章中写道2006 年 5 月 26 日:

The SerialPort class uses the encoding specified by the SerialPort.Encoding property to convert strings and character arrays to bytes to send across the serial port. This encoding also gets used when reading from the serial port to convert bytes received by the serial port to strings and character arrays.

By default the SerialPort class uses ASCII encoding which converts all characters with the value of 0-127 to a single byte with the same value. So "Hello" gets converted to the byte array {72, 101, 108, 108, 111}. However every other character gets converted to a byte with the value of 63 or the '?' character. This applies for reading as well so if the serial port received the byte array {72, 101, 108, 108, 111} it will convert this to "Hello" and any byte with a value greater then 127 will get converted to the '?' character.

The ASCII encoding works perfectly fine for most serial devices but there are still quite a few device that either send bytes with values beyond 127 or you need to send bytes with values greater then 127. You have two options; one would be to use the API’s that deal with byte[] and bypass the Encoding, or to use the correct Encoding. However finding the correct encoding is a bit tricky as most encodings that deal with values above 127 will use multiple bytes which probably won’t work with the device attached to the serial port. The only encoding that converts all characters with a value 0-255 to a single byte with the corresponding value and vice versa when converting bytes to characters is the "Western European (ISO)" encoding. Use the following code to use this Encoding with the SerialPort class:

SerialPort mySerialPort = new SerialPort("COM1");
mySerialPort.Encoding = Encoding.GetEncoding(28591);

关于VB.net 将 chr(255) 返回为 chr(63),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30815256/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com