Android Question BLE2 WriteData to RN4871 BLE stops sending data after 8 transmissions

dxptech

Member
Licensed User
Longtime User
Most Apps and Examples using BLE demonstrate how to receive data but my App only Transmits.
I have an RN4871 Module connected to a micro that sets it all up for transparent uart mode.
I rename it as "Temp". Over the past few years, I have tried BLE2 and can scan, connect to the device, and can Transmit Commands (simple "g"CRLF) to it up to 8 times.
After that, the Manager_writecomplete event tells me it thinks a command has been sent but the micro never sees a command. (I have verified this by attaching an FTDI serial to usb cable to monitor the incoming (logic level) RxData from the RN4871.
After the BTLE gets stuck like this, I can shut down the App, restart, reconnect and can't get the RN4871 to receive anything. Only after power cycling the RN4871, can it receive any commands (although no more than 8).

I can run microchip smart data or Kai Morich's Serial Bluetooth Terminal and send commands and receive them all day.
Also, I can use BleExtEx and have no problem with Transmitting Data but, I want to use the recommended BLE2 if I can because I have run into problems connecting with various Android device versions recently.

Below is a modified BLEExample for B4A that can scan, connect but send only 8 transmissions to my RN4871 hardware.

I realize this is a unique problem with the RN4871 and that BleExtEx is not supported by Anywhere but it's the only way I can make this work.
Can BLE2 be used for scan and connect and BleExtEx be used just for WriteData? If so, how?

BLEExample (modified to connect to RN4871 with Temp in its name:
Sub Class_Globals
    Private Root As B4XView
    Private xui As XUI
    Private btnReadData As B4XView
    Private btnDisconnect As B4XView
    Private btnScan As B4XView
    Private lblDeviceStatus As B4XView
    Private lblState As B4XView
    Private pbReadData As B4XLoadingIndicator
    Private clv As CustomListView
    #if B4A
    Private manager As BleManager2
    Private rp As RuntimePermissions
    #else if B4i
    Private manager As BleManager
    #end if
    Private currentStateText As String = "UNKNOWN"
    Private currentState As Int
    Private connected As Boolean = False
    Private ConnectedName As String
    Private ConnectedServices As List
    Private pbScan As B4XLoadingIndicator
    Private flipflop As Boolean = False
    'dim serveuuid as string = 49535343-FE7D-4AE5-8FA9-9FAFD205E455    ' Transparent UART Service
    'dim txuuid as string = 49535343-1E4D-4BD9-BA61-23C647249616    ' Transparent UART TX
    '49535343-8841-43F4-A8D4-ECBE34729BB3    ' Transparent UART RX
    Private btnWriteData As Button
    'Private cwrite As BleCharacteristic
    'Private bs As BleService
    
End Sub

Public Sub Initialize
'    B4XPages.GetManager.LogEvents = True
End Sub

'This event will be called once, before the page becomes visible.
Private Sub B4XPage_Created (Root1 As B4XView)
    Root = Root1
    Root.LoadLayout("1")
    B4XPages.SetTitle(Me, "BLE Example")
    manager.Initialize("manager")
    
    StateChanged
End Sub

Public Sub StateChanged
    lblState.Text = currentStateText
    If connected Then
        lblDeviceStatus.Text = "Connected: " & ConnectedName
    Else
        lblDeviceStatus.Text = "Not connected"
    End If
    btnDisconnect.Enabled = connected
    btnScan.Enabled = Not(connected)
    pbReadData.Hide
    pbScan.Hide
    btnReadData.Enabled = connected
    btnWriteData.Enabled = connected
    
    
    btnScan.Enabled = (currentState = manager.STATE_POWERED_ON) And connected = False
End Sub

Sub btnScan_Click
    #if B4A
    'Don't forget to add permission to manifest
    rp.CheckAndRequest(rp.PERMISSION_ACCESS_FINE_LOCATION)
    Wait For B4XPage_PermissionResult (Permission As String, Result As Boolean)
    If Result = False Then
        ToastMessageShow("No permission", True)
        Return
    End If
    #end if
    pbScan.Show
    StartScan
End Sub

Sub btnDisconnect_Click
    manager.Disconnect
    Manager_Disconnected
End Sub

Sub btnReadData_Click
    pbReadData.Show
    clv.Clear
    For Each s As String In ConnectedServices
        manager.ReadData(s)
    Next
    
End Sub

Sub CreateServiceItem (service As String) As Panel
    Dim pnl As B4XView = xui.CreatePanel("")
    pnl.Color = 0xFF808080
    pnl.SetLayoutAnimated(0, 0, 0, clv.AsView.Width, 30dip)
    Dim lbl As B4XView = XUIViewsUtils.CreateLabel
    lbl.Text = service
    lbl.SetTextAlignment("CENTER", "CENTER")
    lbl.Font = xui.CreateDefaultBoldFont(14)
    pnl.AddView(lbl, 0, 0, clv.AsView.Width, 30dip)
    Return pnl
End Sub

Sub CreateCharacteristicItem(Id As String, Data() As Byte) As Panel
    Dim pnl As B4XView = xui.CreatePanel("")
    pnl.SetLayoutAnimated(0, 0, 0, clv.AsView.Width, 40dip)
    pnl.Color = Colors.White
    Dim lbl As B4XView = XUIViewsUtils.CreateLabel
    lbl.Text = Id
    pnl.AddView(lbl, 0, 0, clv.AsView.Width, 20dip)
    Dim lbl2 As B4XView = XUIViewsUtils.CreateLabel
    Try
        lbl2.Text = BytesToString(Data, 0, Data.Length, "UTF8")
    Catch
        Log(LastException)
        lbl2.Text = "Error reading data as string"
    End Try
    lbl2.TextColor = 0xFF909090
    lbl2.TextSize = 14
    pnl.AddView(lbl2, 0, 20dip, clv.AsView.Width, 20dip)
    Return pnl
End Sub

Sub Manager_StateChanged (State As Int)
    Select State
        Case manager.STATE_POWERED_OFF
            currentStateText = "POWERED OFF"
        Case manager.STATE_POWERED_ON
            currentStateText = "POWERED ON"
        Case manager.STATE_UNSUPPORTED
            currentStateText = "UNSUPPORTED"
    End Select
    currentState = State
    StateChanged
End Sub

Sub Manager_DeviceFound (Name As String, Id As String, AdvertisingData As Map, RSSI As Double)
    Log("Found: " & Name & ", " & Id & ", RSSI = " & RSSI & ", " & AdvertisingData) 'ignore
    
    'If Id = "04:91:62:AA:46:41" Then
    'ConnectedName = Name
    If (Name.Contains ("Temp") ) Then
        Log(Name)
        ConnectedName = Name
    
    
        manager.StopScan
        Log("connecting")
    #if B4A
        manager.Connect2(Id, False) 'disabling auto connect can make the connection quicker
    #else if B4I
        manager.Connect(Id)
    #end if
    
    End If    ' if name is Temp
    
End Sub

Public Sub StartScan
    If manager.State <> manager.STATE_POWERED_ON Then
        Log("Not powered on.")
    Else
        manager.Scan2(Null, False)
    End If
    
End Sub

Sub Manager_DataAvailable (ServiceId As String, Characteristics As Map)
    pbReadData.Hide
    clv.Add(CreateServiceItem(ServiceId), "")
    For Each id As String In Characteristics.Keys
        clv.Add(CreateCharacteristicItem(id, Characteristics.Get(id)), "")
    Next
End Sub

Sub Manager_Disconnected
    Log("Disconnected")
    connected = False
    StateChanged
End Sub

Sub Manager_Connected (services As List)
    Log("Connected")
    connected = True
    ConnectedServices = services
    StateChanged
End Sub

'utility to convert short UUIDs to long format on Android
Private Sub UUID(id As String) As String 'ignore
#if B4A
    Return "0000" & id.ToLowerCase & "-0000-1000-8000-00805f9b34fb"
#else if B4I
    Return id.ToUpperCase
#End If
End Sub


Private Sub btnWriteData_Click
    Dim myStr As String
    Dim serveuuid As String = "49535343-fe7d-4ae5-8fa9-9fafd205e455"     'UUID for RN4870 transparent service
    Dim txuuid As String = "49535343-1e4d-4bd9-ba61-23c647249616"    ' Transparent UART TX
    Dim rxuuid As String = "49535343-8841-43f4-a8d4-ecbe34729bb3"        'UUID for RN4870 transparent rx
    Dim sndArray(4) As Byte = Array As Byte(0,0,0,0)
    
    
    If flipflop=False Then
        'myStr = "g" & Chr(13)
        'send = bc.HexToBytes(myStr)
        'manager.WriteData(serveuuid,txuuid, myStr.GetBytes("utf8"))
        sndArray(0) = 103
        sndArray(1) = 0x13
        sndArray(2) = 0x0a
        
        manager.WriteData(serveuuid,txuuid, sndArray)
        flipflop=True
    Else
        myStr = "x" & Chr(13)
        'send = bc.HexToBytes(myStr)
        'manager.WriteData(serveuuid,txuuid, myStr.GetBytes("utf8"))
        'manager.WriteData(serveuuid,txuuid, send)
        sndArray(0) = 120
        sndArray(1) = 0x13
        sndArray(2) = 0x0a
        
        manager.WriteData(serveuuid,txuuid, sndArray)
        flipflop = False
    End If
    
End Sub

Sub Manager_writecomplete(Characteristic As String, status As Int)    'status = 0 GATT_SUCCESS
    Log("write " & Characteristic & " ,status = " & status)   'status = -1 error, status = 0 success
End Sub
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
Upvote 0

dxptech

Member
Licensed User
Longtime User
I found an old post where BleExtEx was updated to correct writes. I don't understand the java code that is zipped in the post. I don't see anything related to WriteData.

post #60

Kai Morich's ble terminal code has "device delegates" for the various ble modules (RN4870/71) vs BLE2

ble terminal github
I don't know what delegates do but could they have anything to do with why I can't use BLE2 to reliably transmit data to an RN4871?
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
Try this:
B4X:
Sub WriteData(Service As String, Characteristic As String, Value As String) As Boolean
Dim jo As JavaObject = manager
Dim gatt As JavaObject = jo.GetField("gatt")
Dim serv As JavaObject = jo.RunMethod("getService", Array(Service))
Dim char As Object = jo.RunMethod("getChar", Array(serv, Characteristic ))
char.RunMethod("setValue", Array(Value))
Return gatt.RunMethod("writeCharacteristic", Array(char))
End Sub
 
Upvote 0

dxptech

Member
Licensed User
Longtime User
changed char to charact and Object to JavaObject in WriteData sub :

Scans, finds, connects,
but, after 8 WriteData btn presses, it stopped sending anything.
 
Upvote 0
Top