Software Development for BLE Devices: Best Practices
Developing mobile software for BLE devices has its own pitfalls and secrets. Below are a few top insights we have gather from our three-year experience of creating mobile applications operating with Bluetooth Low Energy devices.
Two states of BLE devices
Since BLE devices are compact and usually battery-powered, it is important to interact with them in an energy-efficient way. Thus, two types of connection are possible when working with them: a sessional and a permanent connection.
A sessional connection is used when certain requests are need to be performed on special occasions. Each session consists of three stages: connection, request execution, and disconnection.
Such approach is more battery-efficient and also fits when the device is used by multiple users (for instance, a smart bulb or a smart lock). But most devices can maintain only one active connection. So if one user has connected to a particular device, others cannot interact with it at the same time.
A permanent connection allows performing an unlimited number of requests during one session. It is used in personal devices, such as smartwatches or fitness trackers because they are expected to track data constantly.
Since there’s no need to reconnect to the device on every request, this approach is more time-efficient. Usually, connecting to a BLE device takes up to 3 seconds. On the other side, keeping a permanent connection is obviously more energy-consuming.
If talking about software development, it also adds complexity to debugging procedures. For instance, if a developer left a BLE device connected after working with it, another developer may spend some time figuring out why they can’t connect to it. Over time, though, we get used to it and double check if we disconnected the device after working with it.
When developing software for BLE devices that should connect and talk to Android smartphones, it’s also important to keep in mind that Android devices allow a limited number of simultaneously connected devices.
The timeout problems
CoreBluetooth, a standard iOS framework for letting apps communicate with BLE devices, doesn’t have a connection timer. So if a device sends a connection requests, and you need to get a feedback ASAP, resending a connection request quickly or reporting an error to the user will require manual timer implementation.
We also find it useful to add a timer to track the duration of the operation performed, as errors and bugs can happen here as well, and they don’t have a time-out.
In general, timers are a useful way to get a quick feedback for developers and users.
Working With Firmware
One of the frequent features of the mobile apps for BLE devices is the ability to update their firmware. The app downloads the firmware from a server and then sends it to the device via Bluetooth for further unpacking and installation.
During this process, a lot of things can go wrong so it’s important to implement this functionality right. Let’s talk in greater detail about that.
Possible Firmware Update Pitfalls
What can go wrong during the firmware installation process:
- The firmware upload process can stop suddenly.
Solution: Implement error processing, then switch the device to the DFU (Device Firmware Update) mode again and re-upload the firmware.
- Successful firmware upload does not guarantee successful installation.
Solution: To be on the safe side, implement sending a version request and comparing it to the one uploaded last time.
- Successful firmware installation may still end up with the device stuck in the DFU mode.
We faced it when one of our clients implemented a secure firmware update option (there are only two firmware update options: a secure and a non-secure).
To fix it, we wait for the devices to exit the DFU mode for a particular amount of time. If it didn’t exit, we considered it an error and re-uploaded the firmware.
Note: a secure firmware update is performed for a much much longer period of time than a non-secure. For instance, if a secure firmware installation takes 1-2 minutes, a non-secure will require only 20-40 seconds.
- On installation, a user may turn off their device or the app, disable Bluetooth, enable the airplane mode, etc.
In such cases the process will be interrupted, which in turn may lead to a bricked device.
Handling these scenarios require implementing a recovery mode for the app.
Usually, it is represented as a separate app screen where all devices left in the DFU mode are shown. On tapping a device the app will offer the user to select and install one of the available firmware updates.
Note: There’s a slight chance that a user will pick a wrong firmware update and make things even worse; or they can install firmware update on a wrong device that was occasionally in the DFU mode as well. Still, this approach allows users to save their devices from being bricked.
Tools we use for firmware updates
To debug the firmware (and we have dozens of them in each project), we use a development board by Nordic. It’s a chip with a radio module that we connect to via USB to upload necessary firmware. One of its advantages is an ability to debug the interaction process with the device and save the logs for further troubleshooting, no matter if the trouble was on the app’s or the BLE device’s side.
To install that firmware then we use the command line utility called nrfjprog.
A small side note: if a device has a debug console open, you’ll be unable to install firmware on it, so it saves a lot of time when figuring out what went wrong through logs.
Working with Advertisement Data
Advertisement data is a data package the BLE devices send many times per sec if there’s no active connection to it. Usually, it stores data that is updated often and there’s a need to be aware of those updates.
You need to be very careful with customizing the advertisement data. In one of our projects, the firmware developers customized it so much the iOS8-driven devices were getting zeros instead of the initial data (devices with a newer version of the OS received the data correctly).
We still have some troubles requiring research and addressing. One of the most notable lately is a mess with device IDs.
As told above, before the firmware gets updated, the app switches the device to the DFU mode. To make sure this operation went successful, the app scans the Bluetooth frequency to find the device with the required name. If it was found, the firmware installation process starts.
The problem is that when in a normal mode, a device has one unique ID, and once it switches to the DFU mode, it gets another unique identifier. If a user decides to update the firmware of two or more devices simultaneously and thus two devices will be switched to the DFU mode, the app may identify them wrong due to the ID change. This may end up in the app sending a firmware update to the device it was not intended for.
A possible solution that we see is adding another constant unique ID that won’t be changed when the device switches to another mode. For example, a MAC address can be added to the advertisement data and used as a constant identifier of the device.
Overall, implementing firmware update functionality is a troublesome task. While we find solutions to old troubles, new ones arise due to protocol updates, new versions of mobile OS’s for smartphones, etc., and that’s a normal thing.
If you’re interested in software development for BLE devices, follow our blog for more insights from our Brainbean Apps team. And feel free to drop us a line at firstname.lastname@example.org should you have any questions or development projects to get done.