Android Question Bluetooth Connection - Reception Fail

Discussion in 'Android Questions' started by rodmcm, Jul 1, 2019.

  1. rodmcm

    rodmcm Member Licensed User

    I have just started to reuse a program that successfully ran a while ago on a Levono TB- X103F running 6.01

    If I send from an ESP32 a multiple array (100 sets with a delay of 5mS between each set) of integers with 4 fields I get a crash of the Bluetooth reception

    When the BT reception crashes I always get "Buffer Length 0".

    (Oddly enough I can still send for a while until a separate reception watchdog activates)

    Tried lots of options with no luck.. When I use WIFI as the connection, and the same send/receive method, no problems...

    Any ideas?

    The following is the standard B4A reception procedure using prefix mode each end and B4rSerialization


    Sub AStream_NewData (Buffer() As Byte)
    Log("Buffer Length "& Buffer.length)
    Dim Data() As Object = ser.ConvertBytesToArray(Buffer)
    If Data.Length = 0 Then Return
    Log("From ESP32 "& Data(0) & " "& Data(1) &" " & Data(2) & " " & Data(3)&" "& Data(4))

    Do Stuff here....


    End Sub
     
  2. emexes

    emexes Well-Known Member Licensed User

    Firstly, you mention 4 fields but in the Log line you are accessing 5 array elements... perhaps that is causing the problem. If not:

    I don't have an ESP32 to hand, but it looks like a capable and comprehensive module. Which Bluetooth mode are you using?
    • Classic Bluetooth for legacy connections, also supporting L2CAP, SDP, GAP, SMP, AVDTP, AVCTP, A2DP (SNK) and AVRCP (CT)
    • Support for Bluetooth Low Energy (BLE) profiles including L2CAP, GAP, GATT, SMP, and GATT-based profiles like BluFi, SPP-like, etc
    If you are using BLE (eg SPP-like per HM10/HC08 BLE UART module) then it's only reliable for sending up to 20 bytes each BLE connection interval. The smallest connection interval is 7.5 ms, so the highest reliable throughput you could get (if you like living on the edge) is (1000 / 7.5) = 133 packets per second * 20 bytes = 2660 bytes per second.

    But the connection interval is whatever period the master and slave agree on, and BLE specs go all the way up to 4 s (ie 4000 ms) although obviously that's intended for super-low-power usage scenarios. A more typical connection interval is between 20 and 50 per second. If you try sending more than 20 bytes per connection event, you'll often start to get missed data.

    So... perhaps try increasing your 5 ms interval to 55 ms (and watch out for the trick/trap of Sleep(55) forking to an instant return from a Sub) and see if that makes a difference. If it then works, then start backing it down until the connection falls over, and then personally I'd double that minimum period to allow for the occasional missed connection event.
     
    Last edited: Jul 1, 2019
  3. rodmcm

    rodmcm Member Licensed User

    Thanks for that... Classic Bluetooth used.. I am actually sending 6 data points, extracting the first four for this part of the program. In other parts of the program extracting 6, but at a much reduced rate.

    Are you saying that the connection interval is invoked each time a write happens? If so what is the range of the connection period and where would I find this information?

    Can you explain 'trick/trap of Sleep(55)" please
     
  4. emexes

    emexes Well-Known Member Licensed User

    Bar one brief foray with Classic Bluetooth when I accidentally ordered a non-BLE wireless relay board, I have only dealt with BLE. I haven't studied Classic Bluetooth much. With BLE, once a connection is established, the two devices schedule regular communications, so that they don't need to keep their radios operating continuously (which helps with the low energy aspect), and that schedule is at intervals of 7.5 to 4000 ms. Low speed stuff like tyre pressure sensors would tend towards long periods, high speed stuff like accelerometers would tend towards shorter periods.

    For BLE, Google: ble connection interval

    For Bluetooth Classic, this limit shouldn't apply, but nonetheless I tried Googling: bluetooth connection interval -ble -"low energy" spp
    and got https://scholarworks.iupui.edu/bitstream/handle/1805/12496/LIBBY_ECET491_POSTER.pdf which mentions:

    and also a paragraph about SPP.
    The trick (in the good sense of the word) is that Sleep is an efficient way to do a delay.

    The trap is that, in B4X, Sleep(x) doesn't work the way you might be used to. Instead, it forks into two program flows: one returns immediately from the current Sub, before the delay takes effect, and thus the calling Sub does not see/experience the delay, and the other continues in the current Sub after delaying for the specified period.

    Thus, if you had something like:
    Code:
    Sub Main

        
    Log("Open warehouse")
        
    For I = 1 To 4
            SendRoses(I)
        
    Next I
        
    Log("Close warehouse")

    End Sub

    Sub SendRoses(N As Int)

        
    Log("Packing " & N & " roses")
        Sleep(
    300)
        
    Log("Sending " & N & " roses")
        Sleep(
    700)
        
    Log("Sent " & N & " roses")

    End Sub
    you would probably be surprised to find that your warehouse closed much sooner than you'd expected, per the log:
    Code:
    Waiting for debugger to connect...
    Program started.
    Open warehouse
    Packing 
    1 roses
    Packing 
    2 roses
    Packing 
    3 roses
    Packing 
    4 roses
    Packing 
    5 roses
    Close warehouse
    Sending 
    1 roses
    Sending 
    2 roses
    Sending 
    3 roses
    Sending 
    4 roses
    Sending 
    5 roses
    1 roses sent
    2 roses sent
    3 roses sent
    4 roses sent
    5 roses sent
    The fix for this is to declare the Sub "As ResumableSub":
    Code:
    Sub SendRoses(N As Int) As ResumableSub
    and then call the Sub using Wait For() Complete:
    Code:
    For I = 1 To 5
        
    Wait For (SendRoses(I)) Complete
    Next
    This example is for a Sub that nominally does not return a value (well, it does, but it's an unspecified Object and will default to Null, and B4X will be warning you about not returning a value). If your sub needs to return a value, read:
    https://www.b4x.com/android/forum/threads/b4x-resumable-subs-that-return-values-resumablesub.82670/
     
    Last edited: Jul 1, 2019
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice