I am writing a program in visual basic and have run into an odd problem. I am sending strings via serial port to a telescope mount. When I send the check
string, the scope can return either chr(0) or chr(255). This works fine in python and c++ returning chr(255). However when I run the script in visual basic it returns chr(0) or chr(63).
below are two identical functions one in python and one in visual basic.
Can anyone give me an idea why visual basic returns 63 instead of 255?
function in python (returns correct values 0 and 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()
script in visual basic (returns incorrect values 0 and 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
The .NET
SerialPort
class has anEncoding
associated with it that is used for conversion between text and bytes sent on the port. The documentation says that it's used for "pre- and post-transmission conversion of text". It's not exactly clear that theEncoding
is used to convert bytes received into text for thestring
returned fromtReadTo()
(but that might be what is meant by "post-transmission").In any case, I'm pretty sure that that is what's happening to your
255
character. TheReadTo()
method uses theEncoding
to convert the data received to text to put in thestring
. The defaultEncoding
isASCIIEncoding
, which only deals with characters in the range0x00
-0x7f
. Bytes outside of that range will be encoded into'?'
characters, which happens to have an ASCII value of63
.Use the
ReadByte()
method instead to read the data from the port without any text encoding getting involved.Update: I have found a blog posting from someone on the BCL team that confirms this and also points out an encoding object that will pass 8-bit data unmodified. Ryan Byington wrote in an article called "SerialPort Encoding" on the Base Class Library (BCL) Blog on 26 May 2006: