B4A Library [B4X] BLE 2 - Bluetooth Low Energy

Status
Not open for further replies.
This library replaces the previous BLE library.
It is simpler to use and it is more powerful. Its API is based on B4i iBLE library which makes it easy to reuse B4i code.

See the iBLE tutorial: https://www.b4x.com/android/forum/threads/ble-bluetooth-low-energy-library.46099/#content

Tips & Notes

- You can call Manager.Scan2 with AllowDuplicates set to True if you want to monitor the state of an unconnected device.
- The AdvertisingData map in DeviceFound event holds pairs of integers as keys (data types) and bytes arrays as values.
- Call ReadData2 if you are only interested in a single characteristic.
- BLE is only supported on Android 4.3+.

See the attached example. Note that the important code in in the Starter service module.

Edit:

A new version of BLE_Example was uploaded. targetSdkVersion is now set to 29
Setting the targetSdkVersion to 29 requires some changes:

1. Add the fine location permission in the manifest editor.
2. Request this permission with RuntimePermissions.

Otherwise scanning will fail with a message visible in the unfiltered logs.

BLE2 is an internal library now. It is included in the IDE.

Example is based on B4XPages and will work with B4A and B4i.
 

Attachments

  • BLEExample.zip
    181.5 KB · Views: 516
Last edited:

mczubel

Member
Licensed User
Assuming that you are using Arduino: From B4A, using BLEEXT, you can send a string to Arduino HM-10 BT.
Sub Button1_Click
Dim HMString As String
HMString = "1" & CRLF ' 20 characters max
If ConnectState = cstateConnect Then
Log("Write -> " & HMString)
writeCharacteristic.SetStringValue(HMString)
Manager.WriteCharacteristic(writeCharacteristic)
End If
End Sub

Now, on the Arduino side, you can read this character and to send the command: bluetooth.write('AT+IBE094900001');

#include <SoftwareSerial.h>

SoftwareSerial bluetooth(5, 6); // RX, TX
int info;
void setup()
{
Serial.begin(9600);
bluetooth.begin(9600);
}

void loop()
{
if (bluetooth.available()>0)
{
info = bluetooth.read();
if (info=='1') //READ STRING FROM B4A
{
bluetooth.write('AT+IBE094900001');
}

} //bt available
} //loop

If you have trouble, I can send you a general code in both languages (Arduino C, B4A)


yes, is arduino, next week hardware will be ready and I'll test it.
I'll let you know how it works
sorry my eng and
1000 thanks again!!!
 

coslad

Well-Known Member
Licensed User
Hi,

is it possible to connect two smartphone with BLE ?
 

freedom2000

Well-Known Member
Licensed User
Assuming that you are using Arduino: From B4A, using BLEEXT, you can send a string to Arduino HM-10 BT.
Sub Button1_Click
Dim HMString As String
HMString = "1" & CRLF ' 20 characters max
If ConnectState = cstateConnect Then
Log("Write -> " & HMString)
writeCharacteristic.SetStringValue(HMString)
Manager.WriteCharacteristic(writeCharacteristic)
End If
End Sub

Hi,

I am as well using BLE ext to write to the HM-10 and it works.

HOwever I would like to use only BLE2 to do the same thing.

How could we do to replace these lines to write to the HM10 with BLE2 ?

B4X:
  writeCharacteristic.SetStringValue(HMString)
        Manager.WriteCharacteristic(writeCharacteristic)
 

ncabilis

Member
Licensed User
Hello Erel
Today I was update android to Marshmallow (Motorola Moto g 2nd gen). From that time BLE2 is not working. The same happens with the library BleExt, so all my programs based on Ble not working. What can i do with this problem?
 

freedom2000

Well-Known Member
Licensed User
Hi

I have tested on an old Samsung Galaxy S3 with cyanogen ROM Marshmallow and BLE2 works (surprisingly for me)
 

ncabilis

Member
Licensed User
Okay, I made it working. I used the class MPermission.bas (https://www.b4x.com/android/forum/threads/marshmallow-permissions.58379/) and in manifest editor i add these commands: AddPermission(android.permission.ACCESS_COARSE_LOCATION)
AddPermission(android.permission.ACCESS_FINE_LOCATION).
Then on Activity_Create:
Permission.Initialize
If Permission.CheckPermission ("android.permission.ACCESS_COARSE_LOCATION") = False Then
Permission.RequestPermission ("android.permission.ACCESS_COARSE_LOCATION")
End If

If Permission.CheckPermission ("android.permission.ACCESS_FINE_LOCATION") = False Then
Permission.RequestPermission ("android.permission.ACCESS_FINE_LOCATION")
End If
All apps (BLE based) now work fine.

I forgot to mention that i have to enable Location in Phone System Settings
 
Last edited:

freedom2000

Well-Known Member
Licensed User

ncabilis

Member
Licensed User
I used
<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="23"/>
so in Marshmallow with sdk 23 i need to activate Location, otherwise app stop responding.
 

freedom2000

Well-Known Member
Licensed User
I used
<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="23"/>
so in Marshmallow with sdk 23 i need to activate Location, otherwise app stop responding.
Thank you for the advice.

I still have my Galaxy S5 stuck on Lollipop (thank you Samsung :mad:)
 

Turbo3

Active Member
Licensed User
I need to send 22 bytes of data which is more data then will fit in one Writedata transfer which is limited to 20 bytes. To do this I send one transfer of 20 bytes followed by a second writedata of 2 bytes but the second writedata can not take place until the first write has completed. If the second writedata is executed before the first completes the app crashes with a write error. To avoid overrunning the first writedata I currently use a timer to wait 350 msecs before sending the second writedata. This does not seem like a good way to handle this.

Is there a way to detect when the Bluetooth controller has received the write response message signaling that the first writedata has completed? Keep in mind a notification is only sent back after the full 22 bytes have been received by the target device. So I can not use the DataAvailable event which I normally use to trigger when next the writedata can be sent.

I have been using WireShark to examine the btsnoop_hci.log files of the Bluetooth traffic to verify this behavior. On the trace I can see the Write Request going out followed by the the inbound "Number of Completed Packets" and "Write Response" sent from the controller to the host. I just need some way to see this in my app.
 

Turbo3

Active Member
Licensed User
V1.30 with retries causes my app to become unresponsive. I can still see all my debug messages from the Service code and the "retries: 4" down to "retries: 1" messages on the log screen. Eventually I get the "TM-Spy isn't responding. Do you want to close it?" message.

Looks like while you retry you are taking all the cycles not leaving any for the foreground process that handles user input and screen updates.

What was the version number of the latest code without retry? I need to put that one back.

Or provide a way to disable auto retry. I had my code working with my app handling the retry. Strange I don't have this problem on the iOS version that uses BLE 1.31. I only see these false write errors with B4A. I say false because I see the WriteComplete event shortly after the write error message with a status of 0.

Ok, I put back v1.21 and things are working again.
 
Last edited:
Status
Not open for further replies.
Top