Reliable Bluetooth LE Comms Between Arduino and MIT App Inventor (AI2)

MIT_AI2_IconIn a previous post, I looked at creating reliable communications using Classic Bluetooth. While that approach works well, and is a reliable way to connect devices, there may be circumstances when a Bluetooth Low Energy (BLE) connection is preferable.

As it turns out, Bluetooth and BLE are about as similar as apples and oranges. The change in transmission protocol technology is more than a trivial change in the code and its structure.

In this article I explore the difference between BT and BLE and how the previous BT AI2 app needs to be adapted.

This article does not repeat information contained in its predecessor, so it is advisable to read that first for a complete picture.

Bluetooth and Bluetooth Low Energy

It is important to understand that BLE is not at all backwards compatible with older versions of Bluetooth. For the purposes of this article, I will highlight the differences that are important in this application.

Bluetooth Low Energy (aka BLE, Bluetooth 4.0, Bluetooth Smart) is the most recent Bluetooth technology standard. Its main use is for applications that transfer small data packets at relatively low speed using low power consumption.

With BT Classic, a device must be paired in order to establish communications. With BLE there are a number of differences to the connection process:

  • the target device must be advertising that it is connectable when a connection is required.
  • a connection can be made without pairing. Pairing is an optional security mode only.
  • a connection does not have to be made in order to get data from a remote device.

The BLE specification allows a device to take one of two roles, depending on the device’s capabilities. The two types are central or peripheral, and client or server.

BLE_Topology

  • Central vs Peripheral. The role of the central device is similar the ‘master’ in BT Classic. The central device is responsible for searching for and establishing a connection with one or more peripheral devices.
    The role of the peripheral device is similar to ‘slave’ in BT Classic. The peripheral device advertises whether it is connectable, and the services it might provide, so that the central device can decide if it should connect to the peripheral device.
  • Client vs Server. The client and server roles relate to data ownership and transmission relationship in a BLE network. Typically, the central device will take the client role – requesting and sending data from and to one or more server devices. Peripheral devices typically take on the role of server, keeping a database of attributes a connected client can write to, read or subscribe to receive changes.

This specificity of roles means that the BLE interface is not as transparent to the application as a BT Classic one might be, as each device’s available data must be accessed in a specific way.

BLE_ProfilesGeneric Attribute Profiles (GATT Profiles) define the hierarchical structure of the server’s database. A profile is made up of a list of Services, each of which may contain one or more Characteristics. This web site has a list of the officially adopted GATT profiles, although manufacturers may create their own.

A service is used to group a category of characteristics and all characteristics must belong to a service. A characteristic represents one client accessible data attribute. Each characteristic stores a single value and has associated permissions such as read, write, and notify.

Services and characteristics are all assigned and referenced using a Universally Unique IDentifier (UUID).

BLE_HM10_ModuleIn this application, the commonly available HM-10 BLE module is used at the Arduino end of the link. The standard module firmware exposes a BLE peripheral with a proprietary connectivity service (UUID: 0000ffe0-0000-1000-8000-00805f9b34fb) that enables bidirectional communication between the module and any central device connected to it. The service defines a single characteristic (UUID: 0000ffe1-0000-1000-8000-00805f9b34fb) that stores 20 bytes of unformatted data. When the central device wants to send data to the module, it writes the characteristic with the desired content. When the module wants to send data, it sends a notification to the central device.

We now have enough information to modify the original BT Android App for BLE applications.

AI2 Support for BLE

The Connectivity modules in AI2 include a BT Classic Server and Client object. The BLE object is an extension to the standard modules that must be loaded into the AI2 interface. The BluetoothLE extension and instructions for installation are found here.

AI2_BLE_Code
Click to enlarge

There is a bug in the permissions of the BLE object that requires the BT Client to also be loaded in each Application, even if it is not used. This bug and the solution are described here.

The BLE module works differently from the BT module – most of the BLE functionality is implemented as event callbacks – requiring structural as well as syntax changes to the previously implemented BT code.

The Android AI2 BLE interface code (shown at right) is split into a number of functional blocks triggered from application events.

Screen Initialization

AI2_BLE_uuid

AI2_BLE_Initialize

The initialization process is similar to the previous code, with the important addition of the UUID’s as global variables. As mentioned, the BT client needs to be loaded, so we may as well continue using this to detect if the BT hardware is not started.

Discovering and Connecting to a BLE Device

The first significant difference in code is in how the devices are selected. As the BT devices are not paired to the BT server, they will be discovered over a period of time once Scanning is started.

AI2_BLE_Connect

This discovery process means that devices will become progressively available, changing how the user interface is implemented. The ListPicker object does not seem to handle changes once it is displayed, so it is replaced by a ListView object. As each new device is discovered, the ListView is cleared and refreshed from the DeviceFound callback event.

There may also not be any devices to discover, so ‘Cancel’ functionality must be added to allow the user to abort the discovery process.

AI2_BLE_Connect2

Once a selection is made, the App stops device Scanning, separates the IP address and connection name from the ListView selection, and starts connecting to the device using the IP address.

When a connection is confirmed through the Connected event, the App requests to be notified when there are any changes to the string data associated with the Service/Characteristic, setting up future data change events to be captured.

Sending Request Messages

AI2_BLE_SendCommand

Sending message to the Arduino application is essentially similar to the previous code.

However, the Timeout timer is set for the full timeout rather than increments. The previous BT module was invoked in a ‘polling’ mode, using the timer event to check for available characters. The BLE module data receive is handled via callback events. The timer is therefore is used to detect the full timeout time.

Handling Response Messages

AI2_BLE_Receive

The message receive portion of the BLE app is also different from the previous code.

The timeout is handled directly by a timer (as explained above).

The receive Finite State Machine does not run off the timer but is now part of the StringValueChange event. The code is essentially equivalent to the BT code in the polling timer event with requisite changes for the changed data source.

Advertisements

7 thoughts on “Reliable Bluetooth LE Comms Between Arduino and MIT App Inventor (AI2)

  1. jaldomir

    When I found this article by title search, I assume “Reliable Bluetooth LE Comms Between Arduino and MIT App Inventor (AI2)” is about the two code parts, MIT App Inventor AND Arduino sketch.
    So, where is the Arduino sketch?

    Like

    1. Good question. The article is meant to show how to implement the AI2 end of the protocol defined in the previous article at https://arduinoplusplus.wordpress.com/2017/05/10/reliable-bluetooth-data-transfer-between-arduino-and-mit-app-inventor-ai2/#more-6619. The Arduino end is really up to the reader to implement, as this would generally be the easier end for an Arduino programmer.
      An example of one in my own code can be found in the Parola_Bluetooth_Control example of the Parola library at https://github.com/MajicDesigns/MD_Parola.
      Hope this helps.

      Like

      1. No UUIDs required at the Arduino end. The firmware in the interface module makes it work very similarly to the non-BLE modules for simple serial communications, which really simplifies the Arduino code for that application.

        Liked by 1 person

  2. Thank you again Marco. Now, only one more thing: the link for large and complete blocks picture is broken, or don’t exists, so the procedures you have created isn’t available. Could you recheck the link? Thanks again, and congratulations for this simple but outstanding tutorial.

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s