Send Battery Level notifications to nRF Connect app when battery level reaches certain level - bluetooth-lowenergy

I am new to BLE and I need help with Battery Service notifications. I am using nrf52840dk, nrf sdk 17.1.0 and I am using ble_app_proximity example which already uses Battery Service.
I need to send a pop up notification from device to nRF Connect mobile app when battery level reaches 40%. Whenever battery level reaches 40%, a notification should pop up in nRF Connect app telling us that battery level has reached 40% and please charge.
Can anyone please help me with this?
I have tested the ble_app_proximity code and it is showing battery level only when I Read it, but I need it to display a pop up notification on nRF Connect app when battery level reaches 40%.
Thanks,
Kanthi Deep.

There are two steps required in order to achieve what you want:-
Enable the notifications from the nRF Connect app (GATT client).
Send the notification from the nRF52840dk (GATT server).
Let's go through each one in details:-
Enable notifications from the nRF Connect app
Given that your phone is the GATT client, it needs to subscribe to the battery characteristic notifications. This way, when the nRF52840dk sends out a new battery notification, the nRF Connect app will receive it. In order to do this, connect to the devkit using the nRF Connect app, browse through the services and click on the Battery Service to reveal the characteristics. When you do that, you will see the battery level characteristic with a downward (read), upward (I'm not sure if this exists but maybe it doesn't) and multiple downward (enable notification) arrows. The downward arrow is for reading the battery value, the upward arrow (if it exists) is for writing to the battery value, and the multiple downward arrows are for subscribing to notifications. In your case, you want to click on the multiple downward arrows. I have attached a picture below of what the arrows should look like:-
Please note that in your case, this should be the battery value characteristic and not an unknown characteristic.
Send the notification from the nRF52840dk (GATT server)
In your code, you should be continuously monitoring the value of your battery to check if it has reached 40%. If you're using the SDK's libraries, you can have a look at this function that specifically does what you need in that it sends the battery value as a notification when you call it. There are a few posts on Nordic DevZone on how to read the battery voltage, and these are a few examples (link1 and link2).

Related

BLE Pairing with Android things acting as Peripheral

I'm using Android Things 1.0.4 in a prototype where it acts as BLE peripheral device: advertising services and running a GATT server.
I encounter an issue in the BLE pairing process when trying to bond the Android Things board (Raspberry Pi 3) and a smartphone.
Since the device has no display, I set using BluetoothConfigManager:
IoCapability = BluetoothConfigManager.IO_CAPABILITY_NONE
which results in the error AUTH_FAILED every time.
Instead,
IoCapability = BluetoothConfigManager.IO_CAPABILITY_OUT
logs the pairing key and prompts the smartphone to enter it during pairing, but it results in the REMOVED error.
Questions:
Is Android Things in peripheral role capable of handling BLE pairing or not yet?
Are there more things that need to be implemented in the app's code to replicate the full-fledged Android logic?
Here's the source code of the Android Things app to test BLE pairing and bonding
The same code stripped from Android Things specific elements completes BLE pairing and bonding successfully when running on an Android phone as Peripheral (server), and an Android device or iPhone as Central (client).
Generally speaking, if you attempt to read an encrypted GATT characteristic before pairing (which triggers the pairing logic automatically), this results in GATT error 137 returned from the read request (AUTH_FAIL). This is because the device doesn't have enough time to finish setting up the bond before a response is sent by the Bluetooth stack. Retying the read request again generally succeeds.
I have not tested this with an iOS client device, but it certainly holds true with an Android client connecting to an Android (Things) peripheral. As such, I would recommend a few things:
Have the client (mobile) device explicitly initiate pairing, and Android Things should simply react to these incoming requests in the BluetoothPairingCallback. This lets the mobile device decide the pairing type based on the reported capabilities of the IoT device.
Separate the pairing flow from the GATT flow. Pair to the discovered device separately from making any attempts to read the characteristics. This tends to be the best way to avoid timing problems.
Regarding capability choices, this depends on your device. In my experience, if you choose IO_CAPABILITY_NONE this results in PAIRING_VARIANT_CONSENT inside of onPairingInitiated() and the pairing operation succeeds once finishPairing() is called. If you adjust your capabilities, you should be prepared for any number of the variants requiring you to display a PIN for the mobile device to enter. I have not not personally tested these paths.

IBeacons with proximity and clickable button

I am trying to find informations about IBeacons, plus bluetooth Dash Buttons and google delivers contradictory results.
Is there a IBeacon's with an button to click. And an interface on the connected device to react on the click event?
I need if possible to have the proximity and click event.
Is this even possible with IBeacons/BLE specifications?
All kind of informations are welcome.
Thanks
IoT buttons like Amazon Dash and Bluetooth LE beacons like iBeacon have fundamental differences:
Amazon Dash connects to the internet over WiFi to make a web service call on button press, and requires configuration with your WiFi network. Other IoT buttons work similarly, although some connect to the internet via a nearby mobile device using Bluetooth. You must write some code and deploy it to a cloud server to do something whenever somebody taps the button.
Bluetooth LE beacons like iBeacon are transmit only Bluetooth LE devices that do not connect to the internet, but simply sent out a bluetooth packet with a unique identifier. These devices are much simpler, and rely on another bluetooth-enabled computer within 40 meters to be listening (typically a mobile phone). You must write an app on the mobile phone then does something when it detects the beacon transmission is detected.
Most Bluetooth LE beacons are always transmitting, although it is possible to buy ones that are click-on click-off like the RadBeacon Dot. This could provide similar functionality to a Amazon Dash if a mobile app is running nearby that can forward the detection to a similar cloud sever as used for an Amazon Dash solution.

Android BLE as Peripheral Multiple Advertising Issue

I am working on Android BLE as a peripheral connected to a custom device that runs Nordic NRF51 as a central. The project requires Android peripheral to connect to two NRF51 central devices.
Android is advertising two different Advertisement UUIDs one for left and other for right Nordic NRF51 devices. Ideally, I would like to have both Nordic Centrals to connect to the Android at the same time.
I have two main issues.
First issue. Android can get both connections fine. The problem occurs when Android sending notification or Android sending reply back as result of Write Request from the central. When both Centrals are connected, often notification nor the send reply works. I confirmed that the Nordic central does not receive the notification nor the reply. Does anyone have experiences in Android as a Peripheral supporting multiple connections at the same time? I have tried two BluetoothGattServer instances (one for each device) as well as one instance of BluetoothGattServer and based on the connected device, I can tell which Central the event if for and handle it correctly. It is sending notification or send reply to Write Request that at times it does not get sent from Android. I am using synchronized methods on the GattServerCallback event handlers.
Second Issue. Due to the first issue, I am now only advertising one UUID at a time. The idea is to switch between two advertising UUIDs, thus have only one connection at time. The problem now is switch advertising. About 1 out 3 times, when I start advertising with first UUID with its name (LFDroid), it appears that it is actually advertising second UUID with its name (RTDroid) briefly (1 or 2 seonds) and then advertises what was requested. Note that second UUID advertising was stopped on previous switching. It almost looks like when I ask to advertise, it starts to advertise with the last advertised UUID and name and then quickly advertises what is requested. This now causes problem because both Nordic Centrals sees the advertisement and connects.
Any suggestions would be appreciated.

Implement notification in BLE

How do I implement notification in BLE?
I have a smartphone, and every hour it will send notification to all nearby BLE devices (smartwatch, RFduino, etc) for time synchronization purpose.
Other devices are server now (since it provides data), and smartphone is the client that collect the data.
Could I piggyback into the advertisement packages? For example, the smartphone always broadcast an advertisement packet to annoucement its presence (that's how other devices can find it). Can I modify that packet to be a time sync?
In order to send notifications or advertisements, your smartphone has to act as a server, which also means that in order to be able to receive notifications or scan for advertisements, your peripheral devices must act as clients.
This can be a bit tricky, because if two devices act as client and server, they may not simultaneously fulfil the other role. You need to switch roles whenever needed, which is an open field for all kinds of problems.
Also, I am not convinced that it is really the optimal choice to let the smartphone regularly notify all devices in the vicinity. Each of the devices that wants to receive the notification has to be connected with the device in order to receive the notification, and this connection has to be already active when the notification is sent in order to really get the correct time. So all these devices need to connect in advance to the expected notification time, and hold up the connection until the notification has come.
It might be better to just advertise the current time, but remember that you can't connect to the smartphone as a server while it is advertising, because the link layer may not be in scanning and advertising mode at the same time, and you may also not be connected when advertising for a similar reason.
If you want to do it that way, you can include the time information in the advertising data. See the Supplement to the Bluetooth Core Specification v6, Part A for further information on the structure of the advertising data. You could put it in the manufacturer specific data.
However, another option would be to write the time directly to the device using a write request. You can define your own service and characteristics. You can include a "time synch necessary" information in the advertisement data of the servers, and when the smartphone evaluates the advertisement, it can connect to the corresponding device and send the time directly.
The advantage of this procedure is that time is only updated if you really need it on the device, and that you do not have to switch client/server roles, because the device in server role may advertise as normal, and the smartphone can always stay in client role.

Push Notification Over Wifi

I've got a problem that we are hoping there is a simple solution for.
We have a need to allow a push notification to appear on a device when it enters into a certain space. The space is only going to be about 1500 sq ft. So my thought is to set up a wifi network in this area... I'm curious if anyone is aware if it is possible to notify anyone with our app installed on their device when they enter into this wifi space if they want to take a certain action... for instance to open the app?
Create an Android service that is launched when the intent WIFI connected is triggered.
The service will check if the bssid of the wifi connection is the same of the wifi area you want to monitor and then it could either launch the app/show popup/show notification.

Resources