I'm wrinting some software to interface a datalogger to a sensor which talks through binary serial data.
Here's a typical message I'd receive:
0x5A 0x31 0x00 0x00 0x15 0x00 0x00 0x00 0x00 0x03
If I try,
Public String Message As String *11
... SerialInBlock(Com1,message,11)
And then if I try and read back the results:
data_ascii = "" For I = 1 To 10 data_ascii = data_ascii & FormatLong(ASCII(Message(1,1,I)),"%02x") & " " Next I
I get something like:
0x5a 0x31 0x15 0x03 0x00 0x5f 0xab 0xc8 0x00 0x00
Which doesn't match as above. It seems to be skipping all the 0x00 null bytes - because it's a string. I can confirm with another device the binary data is being sent out correctly.
So how can I store the binary data without this happening? If I were programming in C I could use an array of bytes or something but I'm stuck with longs in basic. The number of bytes I receive/send is variable and often odd numbered so it seems a bit complicated and would involve bit manipulation to get it to work?
Is there a way to do this?
On the sending messages side of things I've also tried sending this (decimal equivalent of above):
Public Message As String *11 = CHR(90) + CHR(49) + CHR(00) + CHR(00) + CHR(21) + CHR(00) + CHR(00) + CHR(00) + CHR(00) + CHR(00) + CHR(03)
Which also when I read back that string gets turned into:
0x5a 0x31 0x15 0x03 0x00 0x5f 0xab 0xc8 0x00 0x00
(same as above)
Any ideas? Just a way to send and receive single bytes(including NULLs/nonprintables) is all I need.
String functions stop at the first null character they encounter. So, you cannot concatenate strings with nulls in them. It cuts out the nulls.
The SerialInBlock and SerialOutBlock commands handle null characters without issue.
You can address the third dimension on a string to change position in a string. If you go in order, you can load null characters into a string. That is what I do in this example program.
'This program shows how FormatLong can be used to display the ' contents of a binary string in a formatted hexadecimal string. ' It displays the true contents of a string, being useful for troubleshooting. Public BinString As String Public HexString As String * 64 Dim LongVal As Long Dim i As Long 'Main Program BeginProg BinString(1,1,1) = CHR(13) BinString(1,1,2) = CHR(00) BinString(1,1,3) = CHR(14) Scan (1,Sec,0,0) 'Read each character of BinString and build formatted HexString HexString = "" For i = 1 To 16 LongVal = ASCII(BinString(1,1,i)) HexString = HexString & FormatLong (LongVal,"%02X") & " " Next NextScan EndProg
Thanks for the reply. I also did fnd a solution although it is a bit nasty.
I kind of ended up bitshifting longs into place to get what I wanted. The receive is a bit more complicated becuase of twos compliment. This way I can have arrays of longs which makes it easy to do some maths on the data eg. CRC etc.
'Send out Serial byte Function SendByte(dataByte As Long) dataByte = dataByte << 24 SerialOutBlock(TCP_Socket,dataByte,1) EndFunction 'Check and see if we have data in our Serial buffer. Returns 256 if empty. Function ReveiveByte() As Long Dim reveivedByte As Long If SerialInChk(TCP_Socket) > 0 SerialInBlock(TCP_Socket,reveivedByte,1) RX_val = reveivedByte >> 24 If (RX_val < 0) RX_val = 127 + (129 + RX_val) EndIf Return RX_val Else Return 256 EndIf EndFunction