Android Question Help with code snippet

Beja

Expert
Licensed User
Hi All,
I am trying to send a few bytes to a Bluetooth device to control a machine. But these bytes must change according to the intended function be executed.
I put the code in timer1_Tick but I know this is not the right place. I understand that the array variable (see code below) should be outside the timer1_tick
but didn't know how to do that.

B4X:
 lang="b4x" title="Byte array variable"]
'arry1:        75, 28, 82, 158, 127, 0, 1, 29
'array2:       83, 68, 82, 95, 127, 0, 0, 222
'arry3:         11, 22, 87, 127, 158, 0, 1, 29
'arry4:          59, 32, 82, 23, 95, 0, 65, 222
'array5:        57, 68, 54, 127, 127, 0, 0, 254

Sub Timer1_Tick
    If connected Then
        Dim a() As Byte = Array As Byte(75, 28, 82, 158, 127, 0, 1, 29)
        Dim out As OutputStream
        out = Serial1.OutputStream
        out.WriteBytes( a, 0, a.Length)
        out.Flush
    End If
End Sub
 

DonManfred

Expert
Licensed User
What are you trying to archieve?
Instead you can use a global variable.

But maybe a TIMER is wrong: what about a sub you can call to send anything?
B4X:
Sub Send_Text(mystring as String)
    If connected Then
        Dim a() As Byte = mystring.getBytes("UTF8")
        Dim out As OutputStream
        out = Serial1.OutputStream
        out.WriteBytes( a, 0, a.Length)
        out.Flush
    End If
End Sub

or similar
 
Upvote 0

klaus

Expert
Licensed User
Maybe use:
Dim a() As Byte = Array As Byte(0xAC, 0x05, 0xFE, 0x06, 0x03, 0x00, 0xCC, 0xD3)
instead of
Dim a() As Byte = Array As Byte(75, 28, 82, 158, 127, 0, 1, 29)
replace the numeric values by hex values, the hex values in the example above are not the same as your integer values.
 
Upvote 0

Beja

Expert
Licensed User
What are you trying to archieve?
Instead you can use a global variable.

But maybe a TIMER is wrong: what about a sub you can call to send anything?
B4X:
Sub Send_Text(mystring as String)
    If connected Then
        Dim a() As Byte = mystring.getBytes("UTF8")
        Dim out As OutputStream
        out = Serial1.OutputStream
        out.WriteBytes( a, 0, a.Length)
        out.Flush
    End If
End Sub

or similar

Ok Don, here's what it is:

Trying to control a robot by Bluetooth through Android app.
I must (continuously) send a packet of 8 bytes to control direction and speed .. For safety reasons the packet should be sent continuously and if stopped then the robot will stop automatically. So either I put the packet in the .tic sub or I put it outside and then call it from the tic procedure. I didn't try your code yet.
 
Upvote 0

Beja

Expert
Licensed User
Maybe use:
Dim a() As Byte = Array As Byte(0xAC, 0x05, 0xFE, 0x06, 0x03, 0x00, 0xCC, 0xD3)
instead of
Dim a() As Byte = Array As Byte(75, 28, 82, 158, 127, 0, 1, 29)
replace the numeric values by hex values, the hex values in the example above are not the same as your integer values.
Thank you Klaus for the time and advice..
The code as on my first post is working fine for one function, because it's hardcoded in the .tic sub. But the problem is when I want to change, say the robot direction, I must send a different byte array (one from the commented packets) then I must take the array outside the .tic sub and replace it with a variable, and change that variable in another sub or public variable.. this is the logic but I didn't know the actual code.
 
Upvote 0

alwaysbusy

Expert
Licensed User
Can't you just use a map and a global variable? Maybe you are overthinking this (or I misread what you want to do) ;)

Something like (untested):
B4X:
Sub Process_Globals
    Dim Timer1 as Timer
    Dim m as Map
    Dim CurrentState as String = "arry1"
End Sub

Sub AppStart (Args() As String)
    m.Initialize
    m.put("arry1", Array as Byte(75, 28, 82, 158, 127, 0, 1, 29))
    m.put("array2", Array as Byte(83, 68, 82, 95, 127, 0, 0, 222))
    m.put("arry3", Array as Byte(11, 22, 87, 127, 158, 0, 1, 29))
    m.put("arry4", Array as Byte(59, 32, 82, 23, 95, 0, 65, 222))
    m.put("array5", Array as Byte(57, 68, 54, 127, 127, 0, 0, 254))

    Timer1.Initialize("Timer1", 50)
    Timer1.Enabled = true
End Sub

Sub Timer1_Tick
    If connected Then
        Dim a() As Byte = m.Get(CurrentState) ' grabs the byte array with the current state
        Dim out As OutputStream
        out = Serial1.OutputStream
        out.WriteBytes( a, 0, a.Length)
        out.Flush
    End If
End Sub

' change direction
Sub Button1_Click
    CurrentState = "array2"
End Sub

' change direction again
Sub Button2_Click
    CurrentState = "arry3"
End Sub
...

Alwaysbusy
 
Upvote 0

Beja

Expert
Licensed User
Can't you just use a map and a global variable? Maybe you are overthinking this (or I misread what you want to do) ;)

Something like (untested):
B4X:
Sub Process_Globals
    Dim Timer1 as Timer
    Dim m as Map
    Dim CurrentState as String = "arry1"
End Sub

Sub AppStart (Args() As String)
    m.Initialize
    m.put("arry1", Array as Byte(75, 28, 82, 158, 127, 0, 1, 29))
    m.put("array2", Array as Byte(83, 68, 82, 95, 127, 0, 0, 222))
    m.put("arry3", Array as Byte(11, 22, 87, 127, 158, 0, 1, 29))
    m.put("arry4", Array as Byte(59, 32, 82, 23, 95, 0, 65, 222))
    m.put("array5", Array as Byte(57, 68, 54, 127, 127, 0, 0, 254))

    Timer1.Initialize("Timer1", 50)
    Timer1.Enabled = true
End Sub

Sub Timer1_Tick
    If connected Then
        Dim a() As Byte = m.Get(CurrentState) ' grabs the byte array with the current state
        Dim out As OutputStream
        out = Serial1.OutputStream
        out.WriteBytes( a, 0, a.Length)
        out.Flush
    End If
End Sub

' change direction
Sub Button1_Click
    CurrentState = "array2"
End Sub

' change direction again
Sub Button2_Click
    CurrentState = "arry3"
End Sub
...

Alwaysbusy

Hi Alwaysbusy,
Thanks for the time and effort.. the example you put here is throwing array exception.. please see the message and the full project.
Any meaning appreciated
Best regards.
 

Attachments

  • RobotContrl.zip
    9.1 KB · Views: 47
  • RobotControl.png
    RobotControl.png
    113.9 KB · Views: 65
Upvote 0

Beja

Expert
Licensed User
This time no errors, but no action either

B4X:
#Region Module Attributes
    #FullScreen: False
    #IncludeTitle: True
    #ApplicationLabel: Serial Example
    #VersionCode: 1
    #VersionName:
    #SupportedOrientations: unspecified
#End Region

'Activity module
Sub Process_Globals
    Dim Timer1 As Timer
    Dim m As Map
    Dim CurrentState As String = "arry1"
    Dim serial1 As Serial
    Dim connected As Boolean
End Sub

Sub Globals
    Dim btnSend As Button
    Dim txtLog As EditText
    Dim txtSend As EditText
End Sub

Sub Activity_Create(FirstTime As Boolean)
    If FirstTime Then
        serial1.Initialize("Serial1")
        Timer1.Initialize("Timer1", 200)
        m.Initialize
        m.put("arry1", Array As Byte(83, 68, 82, 158, 127, 0, 1, 29))
        m.put("aray2", Array As Byte(83, 68, 82, 95, 127, 0, 0, 222))
        m.put("arry3", Array As Byte(83, 68, 82, 127, 158, 0, 1, 29))
        m.put("arry4", Array As Byte(83, 68, 82, 127, 95, 0, 0, 229))
        m.put("arry5", Array As Byte(83, 68, 82, 127, 127, 0, 0,254))

        Timer1.Initialize("Timer1", 50)
        Timer1.Enabled = True
       
    End If
    Activity.LoadLayout("1")
    Activity.AddMenuItem("Connect", "mnuConnect")
    Activity.AddMenuItem("Disconnect", "mnuDisconnect")
End Sub
Sub Activity_Resume
    If serial1.IsEnabled = False Then
        Msgbox("Please enable Bluetooth.", "")
    Else
        serial1.Listen 'listen for incoming connections
    End If
End Sub
Sub mnuConnect_Click
    Dim PairedDevices As Map
    PairedDevices = serial1.GetPairedDevices
    Dim l As List
    l.Initialize
    For i = 0 To PairedDevices.Size - 1
        l.Add(PairedDevices.GetKeyAt(i))
    Next
    Dim res As Int
    res = InputList(l, "Choose device", -1) 'show list with paired devices
    If res <> DialogResponse.CANCEL Then
        serial1.Connect(PairedDevices.Get(l.Get(res))) 'convert the name to mac address
    End If
End Sub

Sub Serial1_Connected (Success As Boolean)
    If Success Then
        ToastMessageShow("Connected successfully", False)

        Timer1.Enabled = True
        connected = True
    Else
        connected = False
        Timer1.Enabled = False
        Msgbox(LastException.Message, "Error connecting.")
    End If
End Sub
Sub mnuDisconnect_Click
    serial1.Disconnect
    connected = False
End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

Sub btnSend_Click
    If connected Then
        Dim a() As Byte = Array As Byte(83, 68, 82, 127, 95, 0, 0, 222)
        Dim out As OutputStream
        out = serial1.OutputStream
        out.WriteBytes( a, 0, a.Length)
        out.Flush
    End If
End Sub


Sub Timer1_Tick
    If connected Then
        Dim a() As Byte = m.Get(CurrentState) ' grabs the byte array with the current state
        Dim out As OutputStream
        out = serial1.OutputStream
        out.WriteBytes( a, 0, a.Length)
        out.Flush
    End If
End Sub
 
Last edited:
Upvote 0

Beja

Expert
Licensed User
What exactly does not work?
Put some Logs in the code to see what happens.

Hi Klaus,
Here's the logs:
Main - 46: Msgbox and other modal dialogs are deprecated. Use the async methods instead. (warning #34)
Main - 60: Msgbox and other modal dialogs are deprecated. Use the async methods instead. (warning #34)
Main - 75: Msgbox and other modal dialogs are deprecated. Use the async methods instead. (warning #34)
The recommended value for android:targetSdkVersion is 29 (manifest editor). (warning #31)
---------------------------------------------------------------------------------------------------------------------
Logger connected to: 431dc6bd
WARNING: linker: libpla.so: unused DT entry: type 0x6ffffffe arg 0x44d8
WARNING: linker: libpla.so: unused DT entry: type 0x6fffffff arg 0x3
WARNING: linker: libpla.so: unused DT entry: type 0x6ffffffe arg 0x44d8
WARNING: linker: libpla.so: unused DT entry: type 0x6fffffff arg 0x3
--------- beginning of system
--------- beginning of main
 
Upvote 0

klaus

Expert
Licensed User
It seems that you are trying to use a very old example.

Main - 46: Msgbox and other modal dialogs are deprecated. Use the async methods instead. (warning #34)
This means that you are using he 'old' way for MsgBox, you should use MsgboxAsync.
You must have a look HERE.
The recommended value for android:targetSdkVersion is 29 (manifest editor). (warning #31)
The Manifest is not up to date.
To update it, the simplest way is to open the Manifest Editor, delete delete everything, close it, confirm that you will keep the changes, reopen it you will get the most recent general Manifest settings.
Logger connected to: 431dc6bd
WARNING: linker: libpla.so: unused DT entry: type 0x6ffffffe arg 0x44d8
Here, I am lost, I do not know what this does mean.

Set a breakpoint in the Timer1_Tick routine and check the value of the 'connected' value.
Are you sure that the devices are connected.

I have never used the Serial library in conjunction with Bluetooth, therefore no experience.
I had used the BLE2 library some time ago.
Several tests with a HC-05 Bluetooth module with an Arduino Uno, these examples are in the B4R Example projects booklet.
And another project for a friend reading weight values from a scale.
 
Last edited:
Upvote 0

Beja

Expert
Licensed User
It seems that you are trying to use a very old example.


This means that you are using he 'old' way for MsgBox, you should use MsgboxAsync.
You must have a look HERE.

The Manifest is not up to date.
To update it, the simplest way is to open the Manifest Editor, delete delete everything, close it, confirm that you will keep the changes, reopen it you will get the most recent general Manifest settings.

Here, I am lost, I do not know what this does mean.

Set a breakpoint in the Timer1_Tick routine and check the value of the 'connected' value.
Are you sure that the devices are connected.

I have never used the Serial library in conjunction with Bluetooth, therefore no experience.
I had used the BLE2 library some time ago.
Several tests with a HC-05 Bluetooth module with an Arduino Uno, these examples are in the B4R Example projects booklet.
And another project for a friend reading weight values from a scale.

Perfect! Thanks Klaus, it's working like a charm..
 
Upvote 0

klaus

Expert
Licensed User
Those 8-byte packets look like they're from a game controller.
I made program for a friend to communicate with between a B4X program and kitchen scale with BLE2 library.
The communication was always with 8 byte packets.
The first two bytes were always the same and the last byte was the checksum.
 
Upvote 0

Beja

Expert
Licensed User
I made program for a friend to communicate with between a B4X program and kitchen scale with BLE2 library.
The communication was always with 8 byte packets.
The first two bytes were always the same and the last byte was the checksum.

Almost exactly Klaus.
First 3 bytes fixed values.
Middle bytes for left, right, forward and backwards..(-125 to +125) each. Last byte for checksum.
As mentioned I cancelled the remote controller and modified the serial example from b4x. I bought the robot platform (Chassis) ready but the factory modified it for me and added an Arduino Uno board to it.
 
Upvote 0
Top