Help with Serial requested

Can someone help me out here with a Serial Port question?
I am interfacing to a piece of equipment that has very strange and strict serial protocol requirements but I’m failing to interface to it because the code that I am outputting at the serial port is not the same as the code that I am sending to the port. To get the devices attention I need to send the hex character 8F, which should be followed by a string of standard ascii characters

Here is the code snippet that I am using

Dim tx as String
tx = Encodings.ASCII.Chr( 143 ) + “?x050000000000050019999”
Serial1.Flush
Serial1.Write( tx )

Serial1 has been configured to the correct baud, bits, parity, handshaking etc. and opened OK. When I connected a serial decode to the output I found that it was actually sending the following

00000 | 8f ef bb bf c2 8f 78 30 35 30 30 30 30 30 30 30 | …x050000000
00010 | 30 30 30 30 35 30 30 31 39 39 39 39 | 000050019999

As you can see there is a rather strange set of characters before the ‘x’ which is causing the hardware to hang up.

I normally program in C/C++/C# and am fairly new to Xojo so I’m sure that it’s something that I’m doing but I can’t for the life of me figure what it is. I would normally use an array of byte to hold the data and send that when using C/C++ but there doesn’t seem to be any way to do that.

Can anyone help?

Thanks
Chris

I have made some progress in that it seems as if the string initialisation has a bearing on the problem but it is still most odd. I know there is nothing wrong with the serial port itself as I can communicate with it using CoolTerm.
I have posted a video on YouTube which explains the problems that I am seeing so if anyone has any ideas I would be most grateful

https://youtu.be/xiB8uGyfHF8

Try Serial1.Write(Chr(143) + DecodeHex(“050000000000050019999”))

You are sending the “hex values” but you should send the binary part (string)

sorry if it isn’t clear from the example but the data in the string is actually a string of decimal numbers which is what the analyser is expecting. That part is being transferred correctly. The problem lies with the initial non-printing character which seems to get garbled.
If I was using C/C++ I would do this -

byte tx[] = {0x8F, 0x78, 0x30, 0x35, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30… }etc

and then pass the byte array into the serial object write method.

Try ChrB rather than Chr

[quote=444784:@Chris Mower]sorry if it isn’t clear from the example but the data in the string is actually a string of decimal numbers which is what the analyser is expecting. That part is being transferred correctly. The problem lies with the initial non-printing character which seems to get garbled.
If I was using C/C++ I would do this -

byte tx[] = {0x8F, 0x78, 0x30, 0x35, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30… }etc

and then pass the byte array into the serial object write method.[/quote]

Did you even tried it ?

String is a “bucket of bytes”

But you are sending HUMAN READABLE ASCII “0xx050000000000050019999”

Since XOJO strings are UTF8 by default you can just use Chr(143) + the exact string to be send (as it will be send over the line).

You are saying it sends BYTES in C/C++ then send them as bytes in Xojo as well.

Serial1.Write(Chr(143) + DecodeHex("050000000000050019999"))

To send “8f ef bb bf c2 8f 78 30 35 30 30 30 30 30 30 30”
The code example above does the same and just says “Send my hex values as binary” or DIY ChrB(143) + ChrB(&h8f) + ChrB(&hef) + etc…

ChrB should be used yes as well

OR create a New MemoryBlock and assign the values to it.

To get a hexadecimal value ChrB(&hFF) the “&h” is the xojo equivalent of “0x” in C/C++

Hi Derk
sorry but there is still some misunderstanding here. It is not the actual data in the string that is the problem but what is happening to the Hex 8F at the front when it gets to the Serial.write.

If I examine the string tx before it is sent it shows 8f 78 30 35 30 30 30 30 30 30 30 30 30 35 30 30 31 39 39 39 39 which is absolutely correct. This is what I am intending to send. However when I put a trace on the code that is actually coming out of the serial port I see 8F EF BB BF C2 8F 78 30 35 30 30 30 30 30 30 30 30 30 30 30 35 30 30 31 39 39 39 39 . Somehow the initial 8F has been transformed into 8F EF BB BF C2 8F. Actually, it is transformed into what appears to be a random set of bytes with 8F at the front and back. I have seen 8F E7 8F as well as 8F C5 E2 66 54 8F

It appears that somehow the data is getting corrupted as it is being passed in, or there is something odd with the buffer initialisation perhaps? As you can see the code around the serial write is pretty simple so I am at a loss to understand what is causing the data to be changed and I’m hoping someone can tell me.
Thanks

you are flushing before writing, one thing IF you should even flush then do it AFTER .Write()

in your video you say i have to send in… "0x… "
Can you post some protocol information (datasheet or so) or orginal code c/c++ ?

If you have pasted the string into Xojo it might contain some gremlins that you cannot see but are being transmitted. Try selecting the code in the IDE, context clicking the selection and choosing the clean invisible ascii characters option.
If there are some there you might also be able to see them by trying to cursor through the string as the cursor sometimes appears to stick on a character when there are invisibles.

@Chris Mower — This is likely a problem of internal encoding conversion. For example, the code point 8F is represented as “C2 8F” in UTF8 which corresponds to a part of the unwanted characters you reported.

I think you should set the string encoding to nil before using it:

tx = DefineEncoding( tx, nil )

It should prevent conversion errors, since nil-encoded strings are left intact with ConvertEncoding.

I agree that this is all about the encoding, though I find CharB, rather than Char is necessary for setting the 143 byte.

I’ve done a few tests, using an arduino to show me the hex string received by the target

The following seems to work…

    self.objComTTY.Write(DefineEncoding(ChrB( 143 ), Encodings.ASCII))
    self.objComTTY.Write(DefineEncoding("x050000000000050019999", Encodings.ASCII))

as does

    dim tx as string
    tx = DefineEncoding(ChrB( 143 ), Encodings.ASCII)
    tx = tx + DefineEncoding("x050000000000050019999", Encodings.ASCII)
   self.objComTTY.Write(tx)

Note: Combining the 2 by:-

    self.objComTTY.Write( DefineEncoding(ChrB( 143 ) + "x050000000000050019999", Encodings.ASCII))

does NOT work

[quote=444869:@StphaneMons]…
I think you should set the string encoding to nil before using it
…[/quote]

Note: I also tried the above with nil encoding - and that worked too.

Well I have sort-of tracked the problem down and it would appear that the problem is caused by me calling the Flush method after the Write. Not sure why but when I disable the flush the serial data is correct, but when the flush is enabled it has the garbage at the front. Very odd.

Chris Mower — That really sounds like a bug. Flush should not change anything.

I had been having problems with the port holding on to short length packets as the documentation implied The device I’m trying to talk to is a swine for requiring a strict protocol and unless the packets arrive all together it ignores the data. I had been experiencing data sent to the serial being aggregated hence my using the Flush method to force the data out.
I think I’m going to have to write my own serial port driver. It shouldn’t be too difficult as it is fixed at 57600,n,8,1 with no handshaking so I might be able to write directly to the /dev/ttyUSB driver.

@Chris Mower — Maybe I am wrong but it seems to me that bytes are padded to either 4 or 8 bytes ; that would explain why you obtain different results sometimes.

You may want to add enough NUL characters to achieve that padding manually.

I did try padding but the protocol requirements of the spectrum analyser are awful and any spurious bytes in the command string cause havoc. To be honest I really don’t like the fact that they use a string rather than an a byte array to send data to a serial port. It is much easier to format non-ascii data into a byte array. Also the data that comes back is effectively made up of two byte 16 bit words representing signal strength so i need to figure out how to extract them from a string and put them into an array of Int16.

BTW: My tests were on Windows 7… but I still think encoding is the main issue. Flush after Write seems logical to me.

@Chris Mower — Well if you prefer a byte array, you can use it in Xojo as well with:

dim myArray() as UInt8

Populate it and then you can build a MemoryBlock object of the right size, use Byte to set every byte

dim mb as new MemoryBlock( ubound( myArray ) + 1 ) for i as integer=0 to ubound( myArray ) dim myByte as UInt8 = myArray( i ) mb.Byte( i ) = myByte next

then send the data:

sendData  DefineEncoding( mb.StringValue( 0, ubound( myArray ) + 1 ), nil )( 

Stphane

you may be able to help me with my struggle to extract the return data. What comes back is a number of 16 bit words representing signal strength, a typical example is -
70EF BFBD 70EF 70DD 71BE 69AA 71AE

I need to convert that to, in this case, 7 words -
28911, 49085, 28911, 28893, 29118, …etc

but i can’t seem to find anything in the language which will extract the data from the string and put it into an array of UInt16.
If you can provide a clue as to how this can be done I would be most grateful