Android Question BLE Connection Problem

gatabi

New Member
Licensed User
Longtime User
I was not able to find any example for RN4871 module in the forum. I'm trying to modify the BLE chat example for RN4871 module in transparent UART mode. My B4A app finds the module, but never connects. When I use the "Microchip BluetoothData" app, It simply connects and sends/receives data. So, my N4871 configuration should be correct. Here are the logs when I run the BLE chat example:

Scanning
startLeScan(): null
STATE_ON
onClientRegistered() - status=0 clientIf=6
Found: BLE-0000, 00:00:00:00:00:00, RSSI = -89, (MyMap) {1=[B@75aff87, 9=[B@5041eb4, 0=[B@7541add}
stopLeScan()
STATE_ON
connect() - device: 00:00:00:00:00:00, auto: true
registerApp()
registerApp() - UUID=e744bc6a-9871-4bae-bcba-093dd4a017a3
onClientRegistered() - status=0 clientIf=6
onClientConnectionState() - status=133 clientIf=6 device=00:00:00:00:00:00
close()
unregisterApp() - mClientIf=6
Disconnected
Connect duration = 6719 miliseconds

I tried both "manager.Connect2(Id,False)" and "manager.Connect2(Id,True)", the same result. Am I missing something in my program? I'm posting both Main and BT_Service codes below. Any help is appreciated.
 
Last edited:

gatabi

New Member
Licensed User
Longtime User
B4X:
#Region  Project Attributes

    #ApplicationLabel: RN4020 Chat
    #VersionCode: 1
    #VersionName:
    'SupportedOrientations possible values: unspecified, landscape, sensorLandscape,
    'portrait and sensorPortrait.
    #SupportedOrientations: sensorPortrait
    #CanInstallToExternalStorage: False
#End Region
#Region  Activity Attributes
    #FullScreen: False
    #IncludeTitle: False
#End Region


Sub Process_Globals 

End Sub


Sub Globals
    ' following for Bluetooth operations
    Dim btnDisconnect As Button
    Dim btnScan As Button
    Dim lbl As Label
    Dim lblStatus As Label
    Dim edittext1 As EditText
    Dim edittext2 As EditText
    Dim btnSend As Button
    ' following for bluetooth operation
    Private RecDataFlag As Boolean
    Private MessagePntr As Byte
    Private MessageLength As Byte
    Private Message(256) As Byte
    Public MldpMsg As String
    Public MacAddr As String
    Public CR As String = Chr(13) & Chr(10)
End Sub

Sub Activity_Create(FirstTime As Boolean) 
    Activity.LoadLayout("Main")
    RecDataFlag = False
    Activity.Title="RN4020 Chat"
    BT_Service.ConnRetry = 0
    StartService(BT_Service)
    edittext1.Hint = "Enter msg to send"
    edittext1.Color=Colors.White
    edittext1.HintColor=Colors.LightGray
    edittext1.TextColor=Colors.Black
    edittext2.Color=Colors.White
    edittext2.TextColor=Colors.Black 
    btnDisconnect.Enabled=False
    btnSend.Enabled=False 
    lblStatus.Text = "Not connected" 
End Sub

Sub Activity_Resume
    StateChanged 
End Sub

Sub Activity_Pause (UserClosed As Boolean)
    If UserClosed Then
        CallSub(BT_Service, "Disconnect")
        StopService(BT_Service)
        CallSub2(BT_Service,"delay",250)
        ExitApplication    ' immediate close of app and processes prevents hangup when rapid app restart.
'        Activity.Finish
    End If 
End Sub

Public Sub StateChanged
    If BT_Service.connected Then
        Log("BT connected")
        btnDisconnect.Enabled = True
        btnScan.Enabled = False
        btnSend.Enabled = True
        lblStatus.Text = "Connected: " & BT_Service.ConnectedName
        RecDataFlag = False
        MessagePntr = 0
        MessageLength = 64  
        edittext2.Text = "sending: Chat test"
        CallSub2(BT_Service,"delay",250)  ' must delay 100 first string because of RN4020 weirdness.
        CallSub2(BT_Service, "SendStr", "Chat test" & CR) 'identify app to RN4020.
    End If
    If BT_Service.connected=False Then
        btnScan.Enabled=True
        btnDisconnect.Enabled=False
        btnSend.Enabled=False
        lblStatus.Text = "Not connected"
    End If
End Sub

Sub btnSend_Click
    Dim msgOut As String
    msgOut = edittext1.Text
    Log("sending: " & msgOut)
    CallSub2(BT_Service,"sendStr",msgOut & CR) 'adds cr/lf to end cuz PIC detects as end of string
End Sub

Sub btnClr_Click
    edittext1.Text="" 
End Sub

Sub btnScan_Click
        btnScan.Enabled=False
        lblStatus.Text = "Scanning"
        CallSub(BT_Service, "Scan")
End Sub

Sub btnDisconnect_Click
        CallSub(BT_Service, "Disconnect")
        edittext1.Text = ""
        edittext2.Text = ""
End Sub

Sub DataAvailable (Service As String, Characteristics As Map)
    For Each id As String In Characteristics.Keys
        Log ("ID=" & id)
        BuildMessage(Characteristics.Get(id))
    Next 
End Sub

Sub BuildMessage(Data() As Byte)
    If Not(RecDataFlag) Then
        RecDataFlag = True
        MessagePntr = 0
        MessageLength = 64
        MldpMsg=""
    End If

    If RecDataFlag Then
        For x = 0 To Data.Length-1
            Message(MessagePntr) = Data(x)
            MldpMsg = MldpMsg & Chr(Data(x))
            If(Message(MessagePntr)==10) Then        ' did we receive a LF? (end of string from PIC)
                MessageLength = MldpMsg.Length
                MessagePntr=MessageLength+1
            End If
        Next 
        If MessagePntr >= MessageLength Then
            RecDataFlag = False
            ServiceMessage
        End If 
    End If
End Sub

Sub ServiceMessage
    ' display the received message
    Log("Msg received: " & MldpMsg)
    edittext2.Text = MldpMsg
End Sub


B4X:
#Region  Service Attributes
    #StartAtBoot: False
    #ExcludeFromLibrary: True
#End Region

Sub Process_Globals  
    Public manager As BleManager2
    Public currentStateText As String = "UNKNOWN"
    Public currentState As Int
    Public connected As Boolean = False
    Public ConnectedName As String
    Public TimeConnected As Long
    Public TimeDiscon As Long
    Public ConnId As String
    Public ConnRetry As Int
    Public WriteStatus As Int
    Public msgLen As Int            ' for sendStr
    Public msgPtr As Int            ' for sendStr
    Public msgPkt As String         ' for sendStr
    Public msgAll As String
'''    'Private Service For Microchip MLDP
'''    Private MLDP_PRIVATE_SERVICE As String = "00035b03-58e6-07dd-021a-08123a000300"
'''    'Characteristic For MLDP Data, properties - notify, write
'''    Private MLDP_DATA_PRIVATE_CHAR As String = "00035b03-58e6-07dd-021a-08123a000301"
    Private MLDP_PRIVATE_SERVICE As String = "49535343-fE7D-4AE5-8FA9-9FAFD205E455"
    Private MLDP_DATA_PRIVATE_CHAR As String = "49535343-1E4D-4BD9-BA61-23C647249616"
End Sub

Sub Service_Create
    manager.Initialize("manager")
End Sub

Sub Service_Start (StartingIntent As Intent)

End Sub

'Return true to allow the OS default exceptions handler to handle the uncaught exception.
Sub Application_Error (Error As Exception, StackTrace As String) As Boolean 
    Return True 
End Sub

Sub Service_Destroy

End Sub

Public Sub Scan
    Log ("Scanning")
    ConnRetry = 0  
'''    manager.Scan(Null)
'''    'manager.Scan2(Null,True)
    manager.Scan2(Null,False)   'all devices, no duplicates  
End Sub

public Sub stopScan
    Log ("scan stopped")
    manager.StopScan
End Sub

Public Sub ReadData  
    ' Read message on the data channel
    manager.ReadData2(MLDP_PRIVATE_SERVICE, MLDP_DATA_PRIVATE_CHAR)  
End Sub

Public Sub SendStr(Data As String)
    '    Log("Sending: " & Data)
    msgAll = Data
    msgLen = msgAll.Length
    msgPtr=0
    writePkt
End Sub

Sub Manager_WriteComplete (Characteristic As String, Status As Int)
    If connected = False Then Return
    '    Log("Writecomplete: " & Characteristic)
    '    Log("Status=" & Status)
    writePkt
End Sub

Sub writePkt
' if the string to send is longer than 20 bytes (BLE limit) this breaks
' it down to multiple "packets" of 20 to complete the message.
    If msgLen = 0 Then Return
    If msgLen > 20 Then
        msgPkt = msgAll.SubString2(msgPtr,msgPtr+20)
        msgPtr = msgPtr+20
        msgLen = msgLen -20
    Else
        msgPkt = msgAll.SubString(msgPtr)
        msgLen = 0
    End If
    Dim D() As Byte = msgPkt.GetBytes("UTF8")
    delay(125)    ' sending multiple back to back packets fails without this delay.
    'Sleep(25)    ' using sleep as a delay does not work in service module.
    manager.WriteData(MLDP_PRIVATE_SERVICE, MLDP_DATA_PRIVATE_CHAR, D)
    delay(125)
    manager.SetNotify(MLDP_PRIVATE_SERVICE, MLDP_DATA_PRIVATE_CHAR, True)
End Sub

Sub Manager_DataAvailable (ServiceId As String, Characteristics As Map)  
    CallSub3(Main, "DataAvailable", ServiceId, Characteristics)      
End Sub

Public Sub Disconnect
    Log("Disconnecting")
    If connected Then
        manager.SetNotify(MLDP_PRIVATE_SERVICE, MLDP_DATA_PRIVATE_CHAR, False)
        manager.Disconnect
    End If  
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"
            '            Log("BT State = Powered On")
        Case manager.STATE_UNSUPPORTED
            currentStateText = "UNSUPPORTED"
    End Select  
    CallSub(Main, "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)
    '''If Name.Contains("ZWGDO-01") Then
    If Name="BLE-0000" Then      
        TimeConnected = DateTime.Now   
        ConnectedName = Name
        ConnId = Id
        manager.StopScan    
        '''manager.Connect(Id)
        manager.Connect2(Id,False)
        'manager.Connect2(Id,True)  
    End If
End Sub

Sub Manager_Disconnected  
    Log("Disconnected")
    connected = False
    TimeDiscon = DateTime.Now
    Log ("Connect duration = " & (TimeDiscon - TimeConnected) & " miliseconds")
    If (TimeDiscon - TimeConnected)< 400 Then    ' if < 400 msec do a connect retry
        ConnRetry = ConnRetry + 1
        If ConnRetry < 5 Then                    ' max of 5 retries
            Log ("Retry = " & ConnRetry)   
            '''manager.Connect(ConnId)
            manager.Connect2(ConnId,False)   
        End If
    End If  
    CallSub(Main, "StateChanged")  
End Sub

Sub Manager_Connected (services As List)  
    Log("Connected")
    TimeConnected = DateTime.Now
    connected = True
    CallSub(Main, "StateChanged")  
End Sub

public Sub delay(ms As Int)
    Dim temp As Int
    Dim futuretime As Long
    futuretime = DateTime.Now + ms
    Do While DateTime.Now < futuretime
        temp=1
    Loop
End Sub
 
Last edited:
Upvote 0

gatabi

New Member
Licensed User
Longtime User
Thanks for your response. Yes, it connects with other BLE apps such as "Microchip Bluetooth Data" app and transfers data over UART. I'm using an Android phone (Android 6.0) with Bluetooth 4.0/A2DP/LE/aptX. Does the version of phone Android and Bluetooth matter?
 
Upvote 0

gatabi

New Member
Licensed User
Longtime User
Thanks for your helpful response, The problem was RN4871 missing its address after power OFF/ON cycle. sending &R command after powering the module will set a random address and solve the issue.
 
Upvote 0
Top