Bluetooth low energy with android

Android Things — Communicating with Bluetooth Low Energy devices

Android Things supports both Bluetooth and Bluetooth Low Energy APIs.
In this blog post, we will use the Bluetooth LE API to communicate between a server (an Android Things board) and a client (an Android app on a phone / watch).

We will build a counter device for our awesomeness: every time you feel awesome (for any reason whatsoever), press a button on your mobile device. A lucky cat will move its paw and increment your awesomeness counter.

Understanding Bluetooth Low Energy (BLE)

BLE is based on a specification called “General ATTribute profile” (GATT), which defines how to transfer and receive short pieces of data known as “attributes” between a server and a client.

It mentions concepts, such as “profiles”, “services”, “characteristics” and “descriptors”.

A profile is a collection of (1 or multiple) services.
Each service (which can be thought of a behavior) can contain one or multiple characteristics that encapsulate data.

pic01_gatt

To ensure interoperability, the Bluetooth SIG (Special Interest Group) has predefined several profiles and services.
Imagine that we want to create our own keyboard device. To ensure compatibility, we will have to follow the HID (Human Interface Device) over GATT profile:

pic02_hid

A profile is mostly a specification telling us which services we will have to implement.
To create our custom keyboard, we will have to implement 3 mandatory services (HID, Battery, Device Info), and optionally a Scan Parameters service.

Читайте также:  Lenovo g510 драйвера bluetooth

If we take a look at the Battery Service, which exposes the state of a battery within a device, we can see that it embeds a single and mandatory read-only characteristic named Battery Level.
This characteristic encapsulates an int value between 0 and 100, which represents the device battery percentage. It also has an optional “Notify” property, which means that a client can subscribe to it, to be automatically notified when the value has changed.

pic03_battery-level

Getting started with BLE on Android

The official documentation is the best way to get started with Bluetooth Low Energy on Android.

Google also provides 2 sample projects:

  • android-BluetoothLeGatt: an Android client that scans devices exposing services and lists their characteristics.
  • sample-bluetooth-le-gattserver: an Android Things server that implements the Current Time service.

After deploying those two projects, you’ll be able to scan the Android Things GATT server:

pic04_sample-ble

Services and characteristics are uniquely identified by a UUID.
Here, the RPI3 exposes 3 services: Generic Attribute (0x1801), Generic Access (0x1800), and Current Time service (0x1805). This latter has two characteristics: Current Time (0x2A2B) and Local Time Information (0x2A0F)

A word on custom GATT services / characteristics

While implementing services as defined by the Bluetooth SIG is the recommended way, it is also possible to create your own proprietary services (and we will do that today). This can be a preferred solution in some cases, but you will not have the benefit of interoperability.

You should use 128-bit random UUIDs for your non-standard services and characteristics. Short 16-bit UUIDs are only for services / characteristics defined by the Bluetooth standard.

Читайте также:  Bluetooth hi res адаптер

Creating the server

Now that we are familiar with BLE key concepts, we can start implementing our GATT server.

Our Android Things project will expose a single service with two characteristics:

  • AwesomenessCounter : A read-only, notifyable, property that indicates the number of times you have been awesome so far
  • AwesomenessInteractor : When a client writes a value to this characteristic, the device should move the cat’s paw and increment the awesomeness counter.

The following code will be heavily inspired from the sample-bluetooth-le-gattserver. If you need to create a GATT server, you can use this project as a reference, or follow the official documentation.

Constants

We will define the following constants:

pic05_nrf1

Again, scanning is battery-intensive. We should create a handler that stops the scan after a few seconds (e.g. 10 seconds), and stop scanning as soon as we find the desired device.

The startScan method takes a ScanCallback implemented below:

pic07_8digits

A lucky cat

We will use a Lucky Cat.
To move the cat’s paw, we simply need to attach the paw to a servo motor (here, using a rubber band).

pic08_pwm

And then, we move the servo when the counter value changes:

Servo servo = new Servo(PWM_NAME); servo.setPulseDurationRange(1, 2); servo.setAngleRange(-90, 90); servo.setEnabled(true); servo.setAngle(servo.getMaximumAngle()); Thread.sleep(1000); servo.setAngle(servo.getMinimumAngle());

An Android Wear app

This was not planned initially, but since it uses exactly the same APIs, it took me only 10 minutes to port (I mean copy/paste) the Android (phone) client to an Android Wear app.

Conclusion

Communicating via Bluetooth LE may seem quite complicated at first. You will need to write a lot of code to communicate via Bluetooth LE, but once you understand how it works, you’ll find out that it’s actually very verbose, for sure, but still straightforward and completely coherent with the Bluetooth LE specs.

Читайте также:  Bluetooth адаптер наушники телевизор

To simplify the article, I did not handle edge cases (such as checking return values, enabling the Bluetooth if it is not enabled yet, etc.) here.
You can find a complete implementation on github.com/Nilhcem/blefun-androidthings.

pic09_final

Источник

Оцените статью
Adblock
detector