Serial Port Question

I am writing code to connect to an instrument. It uses the COM port communications protocol but does not send text (UTF8) instead it sends single byte data with values 0xA0 and higher, up to 0xF0. UTF8 uses 2 bytes for all characters above 0x1F (127).

The methods for SerialConnection.Read and SerialConnection.Write say that it is limited to ASCII text. Is this the case? If so, does any have a way to send single binary byte data to a SerialConnection?

I don’t know where you are seeing that but I send single bytes back and forth to serial devices without any encoding. Just don’t specify an encoding and read the number of bytes you want from the serial port.

You might also want to look at:

String.ChrByte()
String.AscByte()

XOJO documentation on the SerialPort class states:
Writeable.Write(data As [String]), it does not say (data As [byte])

Further instructions:

Both the Read and ReadAll methods can take an optional parameter that enables you to specify the encoding. Use the Encodings object to get the desired encoding and pass it as a parameter. For example, the code above has been modified to specify that the incoming text uses the ANSI encoding, a standard on Windows:

TextArea1.AddText([Me].ReadAll(Encodings.WindowsANSI))

You may need to specify the encoding when text is coming from another platform or is in another language.

Any String you create in Xojo has the UTF-8 encoding by default:

According to the UTF-8 standard collating table, characters above 0x7f have a second, high byte added.
|U+007D| } | 7d | RIGHT CURLY BRACKET |

|U+007E| ~ | 7e | TILDE |
|U+007F| | 7f | |
|U+0080| |c2 80| |
|U+00A2| ¢ | c2 a2| CENT SIGN |
|U+00F0| ð | c3 b0| LATIN SMALL LETTER ETH |

What you show in your post works absolutely fine for binary values below 0x7F but it does not work extended characters.

What does String.Chr(240) look like?

Sending data using serial port:

dim s as string
s = CHRB(158) + CHRB(162) + …
Serial.Write s

Strings in Xojo can contain any arbitrary binary data. It is perfectly valid to write

dim s as string = chrb(&hA0)
serial1.write(s)

or

dim s as string = serial1.read(1)
dim n as integer = ascb(s)

I routinely pass hex data. I change it to ASCII. I have an app that works as a remote control app to control AV devices. Some AV devices use Hex codes. If you would like, I am happy to share my code with you that will allow you to enter something like:

\x08\x22\x00\x00\x00\x02\xD4

Strip off the \x bit in front, convert the data to ASCII and then send it to the RS-232 port. I also have written code that allows you to mix ASCII and Hex in the same command string.

Jon,
This is exactly what I need to do. No CRLF, no escape sequences, just series of hex bytes out and a series of hex bytes returned.

Thank you for offering to share your codes, that would make this project move ahead so much faster.
danny.rich@sunchemical.com

Jon,
Here is the problem that I have encountered. ASCII only ranges from \x00 to \x7F, I need to range from \xA0 to \xF0 (your notations). According to the “documentation”, thin as it is, all strings in XOJO are default Encodings.UTF8 which add extra characters above the ASCII \x7F.

All I get are red crabs in my code as soon as I try to do what others have said is perfectly valid.

Your problem is not that a String can’t represent the chars. It’s in how you’re displaying them. Give us some more details so we can help you.

This is the issue - I am not displaying the data.
I have an instrument. I must pass it, via the COM port, a series of bytes. The bytes are all values greater 0x9F. ASCII only encodes text characters up to 0x7F. Above that you have to use an extended character set, like one of the Windows code pages that hold definitions of the bytes between 0x80 and 0xFF.
UTF8 is a universal translation format that uses the full 8 bits for its data. But, when you send a character stream, each byte is preceded by an identifier character - to identify what encoding table should be used. The default encoding for Xojo appears to be UTF8. What all of you have said to me is correct, if you want to display the characters. Then your codes will be between 0 and 127 and there is an ASCII character or at least a symbol for each code. You also have no issue sending characters above 127 because the encoding translates the 2-byte sequence in the proper extended symbol. But my instrument does not understand encodings - it only understand bytes, each byte has a specific meaning and if something comes between the first byte and the second byte the message is not just lost, the instrument shuts down the port and goes to sleep.

Oh - also it appears that Microsoft Visual Basic for Visual Studio has an overloaded function for its SerialPort methods that work as follows: Write(byte[ ], Offset, NumBytes) and ReadByte(). But I am hoping to not have to change horses in mid-stream.

I’m not sure where the problem is here, but a String variable can easily hold a single byte with values from 0x00 to 0xFF. Encoding is irrelevant because we’re not sending text, we’re sending raw byte values.

dim s as string = chrb(&hFF)
serial1.write(s)

will send a single byte with the value 0xFF to the serial port.

Or simply,

serial1.write(chrb(&hFF))

If code like this is not working for you, check the serial’s baud, parity, etc.