B4J Question Regex (Hex string)

atiaust

Active Member
Licensed User
Longtime User
Hi All,

I have a B4J app with a Bluetooth/RS232 connection.

The data being received by the B4J app is in HEX and is among other things the X & Y position of a laser head in mm from home.

The hex string "1B 00 58 1B 14 59 1B 02" is the header for the XY location information and is followed by "1B 02 20 20 33 35 2E 31 30 "which is X position of 35.30 mm and "1B 22 20 20 35 2E 32 32 " which is 5.22 mm Y position etc...

Does anyone have an idea how to capture the data and convert it to text to display on X & Y labels on a form.

Thanks
 

atiaust

Active Member
Licensed User
Longtime User
Erel,

Thanks for the reply.

I am using Asyncstreams to capture the data with a timer to get the full string as the serial link only runs @ 9600 baud, so encoding is "UTF8"

B4X:
Sub AStream_NewData (Buffer() As Byte)
    mybuffer=mybuffer & BytesToString(Buffer, 0, Buffer.Length, "UTF8")
 
Upvote 0

atiaust

Active Member
Licensed User
Longtime User
Yes, spaces added for readability. There is quite a bit of data received.
I need to read the data stream looking for the hex header and then display the following position data.

I am using the timer_tick to write the received data out to a text file (attached)

B4X:
Sub timerStreams_tick
    Log("BT Message = "& mybuffer)
    lg(mybuffer)    'log data in to taDataIn.text
    Dim Writer As TextWriter
    Writer.Initialize(File.OpenOutput("D:\Log","MyData.txt",True))
    Writer.WriteLine(mybuffer)
    Writer.Flush
    Writer.Close
    mybuffer=""                            'clear my buffer
    timerStreams.enabled = False
'
End Sub
 

Attachments

  • MacData130718.txt
    1.5 KB · Views: 238
Upvote 0

Daestrum

Expert
Licensed User
Longtime User
It looks like the data is just plain ascii bytes.

With your example data
The header for xy starts with 1B00
The X position start 1B02 followed by 2 spaces followed by 2 digits decimal point then 2 digits ( I assume max distance can only be 99.99mm )
The Y position is the same layout as X except the header starts 1B22.

If the header is 1B02 to get the X position
convert the buffer to string, then get the string from byte 4 to the end, that will give you the X value.
If the header is 1B22 to get the Y position
convert the buffer to string, then get the string from byte 4 to the end, that will give you the Y value.

Hope this helps.
 
Upvote 0

atiaust

Active Member
Licensed User
Longtime User
Thanks Daestrum,

I think you are correct. The data is ascii HEX values. The header 1B02 signafies that the following is the X position with some spaces and the acual position represented by a HEX value. This machine can have a maximum travel of 18000 mm's in the X plus direction.

As each block of data is received I need to work thru it looking for the various headers.
 
Upvote 0

Daestrum

Expert
Licensed User
Longtime User
Looking at your header block it appears to have 3 headers in it

it appears the control blocks begin with 'Esc' (0x1b) followed by a single byte.

Your header 1B 00 58 1B 14 59 1B 02

1, 1B 00 - data 58 (Character X)
2, 1B 14 - data 59 (Character Y)
3, 1B 02 - This is the header for the X position.

Pure guess at the following decipher of the data block.

1B 00 58 denotes the X position is available
1B 14 59 denotes the Y position is available
1B ?? 60 (possible if able to work in 3D to denote Z position)
1B 02 ?? ?? ?? X position.
1B 22 ?? ?? ?? Y position.

If you had a larger data sample it would make it easier to check the logic and probably make it possible to use regex.split on Esc to get the individual data blocks, then the first byte will determine the contents of the block, and a switch statement used to extract the data.
 
Last edited:
Upvote 0

atiaust

Active Member
Licensed User
Longtime User
The machine is 2d only. X & Y.

I think the larger header says the data following is X & Y data. Followed by X & Y positions as the machine moves.

There is other headers that request some user feedback by way of keyboard key presses.

This is a very old motion controller and the user terminal has died. I have built both B4A & B4J apps that connect thru a Bluetooth / RS232 converter.
I have limited info on the original system. I have motion control working. Now working on the user display.
 
Upvote 0

Daestrum

Expert
Licensed User
Longtime User
This seems to work - small example
B4X:
Sub Process_Globals
 Private fx As JFX
 Private MainForm As Form
 Dim data() As Byte
 Dim sData As String
 Dim bc As ByteConverter
End Sub
Sub AppStart (Form1 As Form, Args() As String)
 MainForm = Form1
 'MainForm.RootPane.LoadLayout("Layout1") 'Load the layout file.
 MainForm.Show
 'data is just an arry for test - you would use live data
 data = Array As Byte(0x1B,0x00,0x58,0x1B,0x14,0x59,0x1B,0x02,0x20,0x20,0x33,0x35,0x2E,0x31,0x30,0x1B,0x22,0x20,0x20,0x35,0x2E,0x32,0x32)
 sData = bc.StringFromBytes(data,"ascii")
 decode(sData)
End Sub
Sub decode(s As String)
 Dim cnt As Int = 0
 Do While cnt < s.Length
  If s.CharAt(cnt) = Chr(0x1b) Then  ' look for the esc char
   Select s.CharAt(cnt+1)   ' get the code for header
    Case Chr(0x00)
     Log("X available")
     cnt = cnt + 3
    Case Chr(0x14)
     Log("Y available")
     cnt = cnt + 3
    Case Chr(0x02) ' X value
     Log("X value = "&s.SubString2(cnt+2,s.IndexOf2(Chr(0x1b),cnt+2)).Trim)
     cnt = cnt + 9
    Case Chr(0x22) ' Y value
     Log("Y value = "&s.SubString(cnt+2).Trim)
     cnt = cnt + 8
   End Select
  End If
 Loop
End Sub
 
Upvote 0
Top