B4R Library rESP32SimpleBLE - ESP32 BLE

This library makes it very simple to advertise data through BLE. You just need to call ble.Advertise with the string that you want to advertise as the device name.

Note that it doesn't support making connections.


Usage example:

B4X:
#StackBufferSize: 600
Sub Process_Globals
   Public Serial1 As Serial
   Private ble As ESP32SimpleBLE
   Private timer1 As Timer
End Sub

Private Sub AppStart
   Serial1.Initialize(115200)
   Log("AppStart")
   timer1.Initialize("timer1_Tick", 500)
   timer1.Enabled = True
End Sub

Private Sub Timer1_Tick
   Dim data As String = JoinStrings(Array As String("B4RTime: ", NumberFormat(Millis, 0, 0)))
   If ble.Advertise(data) = False Then
       Log("failed to set name.")
   End If
End Sub

iOS app:


The clients need to scan for near by devices and check the device name.
B4i and B4A clients examples are attached.

On Android the name is cached so we need to get it from the advertising data map.
On iOS it stops scanning after a while so we restart the scanning process every 10 seconds.
 

Attachments

  • rESP32SimpleBLE.zip
    1.9 KB · Views: 1,107
  • B4A_BLE_Client.zip
    8.3 KB · Views: 1,056
  • B4i_BLE_Client.zip
    1 KB · Views: 844

MathiasM

Active Member
Licensed User
I'm a bit confused by the 'name' vs 'data' in this library and your explanation.

On Android the name is cached so we need to get it from the advertising data map.

But is the data the same as the name here? This seems to imply this:

If ble.Advertise(data) = False Then
Log("failed to set name.")
End If

Altough in the B4A code I see this:


So the name is never actually used here? It's just checking if the data starts with a B4R?

Does a 'name' actually exist in this advertise context? Isn't everything data?
Sorry for my questions, I'm just trying to understand.

My ESP32 is not yet in my possesion, so I cannot check out. I see you can send a string, but would it be possible to set bytes and convert them to a string. I'm willing to implement the Eddystone protocol with this code: https://github.com/google/eddystone/tree/master/eddystone-uid

Thanks for your clarification.
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
The B4R code sets the advertised device name.

The B4A event is:
B4X:
DeviceFound (Name As String, DeviceId As String, AdvertisingData As Map, RSSI As Double)

In most cases you will use the Name parameter to get the advertised device name. However as Android caches the value we cannot use it in this case and instead we read it from the advertising map directly. If you try it you will see that the Name parameter is not being updated. It will keep the first value that was sent.
 

peacemaker

Expert
Licensed User
Longtime User
Works, thanks.
Max 31 bytes are allowed to transmit.
Minimal working timer interval = 15 msec.
B4X:
timer1.Initialize("timer1_Tick", 15)
If smaller the board is restarted or does not work at all.

Max payload incoming transfer speed is about 0.2 KBps only.

I think, if BLE works so at any possibility - it's not suitable for fast sensors data collection.
It's just for battery economy work of low-speed sensors.


update: checked BT-chat https://www.b4x.com/android/forum/threads/resp32bluetooth-esp32-classic-bluetooth.93257/#content
incoming speed is 5 times higher, 1 KBps with the same timer 15 msec, sending 1000 bytes each time
B4X:
Public Sub NewMessage (msg As String)
    Counter = Counter + msg.Length
    Log(Counter)
    Dim now As Long = DateTime.Now
    Dim speed As Float = Counter / 1000 / ((now - StartTime) / 1000)    'kbps
    Log("speed = " & speed)
    Activity.Title = "speed = " & NumberFormat2(speed, 1, 3, 3, False) & "kbps"
    Dim n As String = (now - PrevTime).As(Int) & ": " & msg
    Log(n)
    PrevTime = now
  
  
  
    LogMessage("You", msg)
End Sub
 
Last edited: