Android Question [Solved]BLE notify question: how to make them work with RN4020

JordiCP

Expert
Licensed User
Longtime User
Hi all,

I am starting with BLE, using a RN4020 module. At this moment, the module is connected with USB to the PC serial port. The final purpose is to stablish a communication channel with a microcontroller that will be behind the module.

I have read documentation and tried many examples here
What I have done (from a post here in the forum) on the module side :

I define a private service in the module,
B4X:
SS,00000001 Set User Defined Private Profile
SR,20000000 Module is peripheral, Auto Advertise
R,1 Reboot, to let the changes become effective
PS,11223344556677889900AABBCCDDEEFF //Set the UUID of the Private Service. You can use any 128 bit number.
PC,AA02030405060708090A0B0C0D0E0F,06,14 //Add the first Characteristic to the Private Service. UUID,
Properties READ and WRITE WITHOUT ANSWER , maximum data size 20. Note, that all values have to be typed as hex numbers.
PC,BB02030405060708090A0B0C0D0E0F,06,14 // Add the second

Doing it, either using BleExtEx or BLE2 library, I can see the service and the Characteristics. Also, they can be read and written to. So it works ok.




The problem comes when I want to use notifications. Perhaps I have understood wrongly the purpose of these, but if I do, in any of the examples ( in this case using BLEExtEx)

I change the definition of the first Characteristic in the module
B4X:
PC,AA02030405060708090A0B0C0D0E0F,16,14 //Change characteristic to be notifiable
And tell the manager that I want to be notified
B4X:
Manager.SetCharacteristicNotification(CharRead,True) 'CharRead is the read characteristic
Then the code fails on the above line

java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.bluetooth.BluetoothGattDescriptor.setValue(byte[])' on a null object reference
at anywheresoftware.b4a.objects.BleManager.SetCharacteristicNotification(BleManager.java:266)
at b4a.terminal.main._ble_characteristicread(main.java:407)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:169)
at anywheresoftware.b4a.BA$2.run(BA.java:328)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:155)
at android.app.ActivityThread.main(ActivityThread.java:5696)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1028)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:823)
java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.bluetooth.BluetoothGattDescriptor.setValue(byte[])' on a null object reference

I get a similar error if I use the BLE2 library/example and "Starter.Manager.setNotify.."


What am I missing? Is the problem on the RN4020 side, on the android side (or in me :mad:)?
 

ac9ts

Active Member
Licensed User
Longtime User
I would suggest using MLDP mode on the RN4020 as it is acting in a pass-thru mode; data received over BT is sent out over serial, date received over serial is sent out over BT.

This is what I send to the RN4020 from the PIC to configure it.

"SF,1" = Reset to factory default configuration.
"SR,32000000" = Auto Advertise, Enable MLDP, UART flow control
"R,1" = Reboot RN4020 to make the changes effective.

Once the app connects, the PIC sends "I" to inter MLDP mode which allows 2 way communication

Attached is a simple app I put together for a board I developed. It should give you a start. You do need BLE2, as suggested. Download the latest version as there were missing pieces in the earlier releases.
 

Attachments

  • RN4020_B4A.zip
    31.3 KB · Views: 522
Last edited:
Upvote 0

JordiCP

Expert
Licensed User
Longtime User
Hi,

Now it works with both BLEExtEx and BLE2, thanks to both :)

The problem was that if I change the services and characteristics in the module (I started with 0x06 for read/write to make it work and then changed to 0x16 for notifications) , it seems (at least in my case) that they don't take effect on the android side unless you unpair that device and pair it again, it is not enough with rebooting. So (my mistake for not checking it in the logs), both examples were working, but as there wasn't any "notification" mask(0x10) in the "cached" characteristics flags, in both cases an error was thrown.

@ac9ts: Althought now it is working ok with private services, MLDP is what I was looking for from the very start, will take a look at it. Thanks a lot!!
 
Upvote 0

Toley

Active Member
Licensed User
Longtime User
@ac9ts I am also playing with the RN4020. I had a look at your code and I would like to know where did you get those numbers? Are they generic or device dependant?
B4X:
'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"
Thank you very much.
 
Upvote 0
Top