Android Question [SOLVED] BLE2 Change Write Type

rwblinn

Well-Known Member
Licensed User
Longtime User
Hi,

[SOLVED] See post #3.

seeking for a solution to change the BLE2 write type from WRITE_TYPE_NO_RESPONSE to WRITE_TYPE_DEFAULT (write with response).

The device BuWizz2 Brick specifically requires the ACK, otherwise it ignores the command.

Have tried with JavaObject, but did not work. The Brick does not take any command. The BLE connection is working OK.

B4X:
Public Sub BuWizzWriteRaw(Data() As Byte)
    ' --- get the gatt object from your BLE manager ---
    Dim jo As JavaObject = mBLEMgr
    Sleep(200)
    Dim gatt As JavaObject = jo.GetFieldJO("gatt")
    If gatt.IsInitialized = False Then
        Log("[BuWizzWriteRaw] ERROR: gatt not initialized")
        Return
    End If

    ' --- convert UUID strings to Java UUID objects ---
    Dim UUID As JavaObject
    UUID.InitializeStatic("java.util.UUID")
    Dim svcUUID As JavaObject = UUID.RunMethod("fromString", Array(BLEConstants.SERVICE_UUID))
    Dim chrUUID As JavaObject = UUID.RunMethod("fromString", Array(BLEConstants.CHAR_UUID_TX))

    ' --- get the service ---
    Dim serviceObj As JavaObject = gatt.RunMethod("getService", Array(svcUUID))
    If serviceObj.IsInitialized = False Then
        Log("[BuWizzWriteRaw] ERROR: service not found")
        Return
    End If

    ' --- get the characteristic ---
    Dim charObj As JavaObject = serviceObj.RunMethod("getCharacteristic", Array(chrUUID))
    If charObj.IsInitialized = False Then
        Log("[BuWizzWriteRaw] ERROR: characteristic not found")
        Return
    End If

    ' --- set WRITE_TYPE_DEFAULT ---
    Dim BGattChar As JavaObject
    BGattChar.InitializeStatic("android.bluetooth.BluetoothGattCharacteristic")
    charObj.RunMethod("setWriteType", Array(BGattChar.GetField("WRITE_TYPE_DEFAULT")))

    ' --- set the value ---
    charObj.RunMethod("setValue", Array(Data))

    ' --- write characteristic ---
    gatt.RunMethod("writeCharacteristic", Array(charObj))

    Log($"[BuWizzWriteRaw] sent data=${Convert.HexFromBytes(Data)}"$)
End Sub
 
Last edited:

drgottjr

Expert
Licensed User
Longtime User
i'm having trouble with your posted snippet. the default write type IS write with response.
and writecharacteristic() - regardless of whether you're using the deprecated version or not - returns an int (success
or failure). i don't understand what your last statement is doing. what data ("${Convert.HexFromBytes(Data)}")?
 
Upvote 0

rwblinn

Well-Known Member
Licensed User
Longtime User
SOLVED
Developed a B4A library BleGattManager which allows to set the Write Type:
  • BuWizz = WRITE_WITH_RESPONSE
  • ESP32 UART = WRITE_NO_RESPONSE
Tested with the BuWizz2 Brick as that was my requirement.

Next
  • More work on this library documentation, test with other devices and then publish in the B4A library forum.
  • Share example controlling a BuWizz2 brick using my HMITiles library.
Answer Post #2: The data is the array of bytes sent to the BuWizz2 brick to set the output/power level.

Example snippet usage but rather BuWizz2 Brick specific:

B4X:
' BuWizz2
Public BLE_MAC As String             = "50:FA:AB:38:A6:1A"                        ' BuWizz2 MAC address
Public BLE_DEVICE_NAME As String     = "BuWizz2"                                    ' Case sensitive

' BLE Service & Characteristics BuWizz V2
Public SERVICE_UUID As String         = "4e050000-74fb-4481-88b3-9919b1676e93"    ' BuWizz2 service UUID
Public CHAR_UUID_RX  As String        = "000092d1-0000-1000-8000-00805f9b34fb"     ' Control characteristic UUID Flags read,notify,write
Public CHAR_UUID_TX  As String        = "000092d1-0000-1000-8000-00805f9b34fb"     ' Control characteristic UUID Flags read,notify,write


    ' Ports
    Public PORT_0 As Byte = 0
    Public PORT_1 As Byte = 1
    Public PORT_2 As Byte = 2
    Public PORT_3 As Byte = 3

    ' RailBuzz
    ' Private CMD_DELAY As Long = 100
    Private OUTPUT_LEVEL_DEFAULT As Byte = 1

    ' Commands
    Public CMD_OUTPUT_LEVEL As Byte = 0x11
    Public CMD_POWER_LEVEL As Byte = 0x10

    ' Power Level
    Public POWER_LEVEL_FULL_BACKWARDS As Int = -127
    Public POWER_LEVEL_STOP As Int = 0
    Public POWER_LEVEL_FULL_FORWARDS As Int = 127

    ' Speed
    Public SPEED_OFFSET As Int = 51
    Public SPEED_MIN As Int = 0    '51
    Public SPEED_MAX As Int = 127    '100
    Public DIRECTION_STP As Int = 0
    Public DIRECTION_FWD As Int = 1
    Public DIRECTION_BCK As Int = 2

Private BuWizz As BleGattManager

Private Sub B4XPage_Created (Root1 As B4XView)
    ...
    BuWizz.Initialize(Me, "BuWizz")
    BuWizz.setWriteMode(BuWizz.WRITE_WITH_RESPONSE)
End Sub

Public Sub Connect
    ' Ensure to add permission to manifest ACCESS_FINE_LOCATION, BLUETOOTH_SCAN, BLUETOOTH_CONNECT)
    Dim rp As RuntimePermissions
    Dim Permissions As List
    Dim phone As Phone

    If phone.SdkVersion >= 31 Then
        Permissions = Array("android.permission.BLUETOOTH_SCAN", "android.permission.BLUETOOTH_CONNECT", rp.PERMISSION_ACCESS_FINE_LOCATION)
    Else
        Permissions = Array(rp.PERMISSION_ACCESS_FINE_LOCATION)
    End If
    For Each per As String In Permissions
        rp.CheckAndRequest(per)
        Wait For B4XPage_PermissionResult (Permission As String, Result As Boolean)
        If Result = False Then
            ToastMessageShow("No permission: " & Permission, True)
            Return
        End If
    Next

    ' Check if BLE is powered on
    If BuWizz.IsBluetoothOn = False Then
        Log("[Connect] BLE not powered on.")
        Return
    End If

    BuWizz.Connect( _
        BLE_MAC, _
        SERVICE_UUID, _
        CHAR_UUID_TX)
End Sub

' Events
Sub BuWizz_Connected
    Log("[Connect] Connected")
End Sub

Sub BuWizz_ConnectionFailed
    Log("[Connect] Connection failed")
End Sub

Sub BuWizz_Disconnected
    Log("[Connect] Disconnected")
    SetTilesInitialState
End Sub

Sub BuWizz_DeviceNotFound
    Log("[Connect] BuWizz device not found")
End Sub

Sub BuWizz_DataReceived (Data() As Byte)
    Log($"[DataReceived] ${bc.HexFromBytes(Data)}"$)
End Sub

' Write to the BuWizz2 Brick

' Set output level = mandatory befor driving motors
' Write 2 bytes:
'    Byte 1 = 0x11
'    Byte 2 = output level with low: 1, medium: 2, high: 3, ludicrous: 4
' level - default 1
Public Sub SetOutputLevel
    Dim cmd() As Byte = Array As Byte(CMD_OUTPUT_LEVEL, OUTPUT_LEVEL_DEFAULT)
    Log($"[SetOutputLevel] cmd=${Convert.HexFromBytes(cmd)}, level=${CMD_OUTPUT_LEVEL}, leveldefault=${OUTPUT_LEVEL_DEFAULT}"$)
    BuWizz.Write(cmd)
End Sub

' Set power level for a port.
' Write 6 bytes:
'    Byte 1 = 0x10
'    Byte 2 = 7 bit signed channel 1 output value
'    Byte 3 = 7 bit signed channel 2 output value
'    Byte 4 = 7 bit signed channel 3 output value
'    Byte 5 = 7 bit signed channel 4 output value
'    Byte 6 = 0x00
' port - 0-3
' level -127 - 127
Public Sub SetPowerLevel(p As Byte, level As Int)
    ' Set mandatory output level
    SetOutputLevel

    ' Define the command as byte array
    Dim cmd() As Byte = Array As Byte(CMD_POWER_LEVEL, 0, 0, 0, 0, 0x00)
    Log($"[SetPowerLevel] cmd=${Convert.HexFromBytes(cmd)}, port=${p}, level=${level}"$)

    ' Set the port level for bytes 1 (=port 1 with index 0) to 4 (=port 4 with index 3)
    cmd(1 + p) = level
    ' Write the command
    BuWizz.Write(cmd)
End Sub
 

Attachments

  • BleGattManager.b4xlib
    2.2 KB · Views: 11
Upvote 0
Top