Does a project ever go according to plan? Have you ever decided to take down a wall in your house and as soon as you take down the drywall, you discover some unexpected plumbing in the walls you now have to cap?
Often, technical research papers or blog posts will tell you the problem, the approach, and the solution. They often omit the things that went wrong, or the things that did not go to plan. When analyzing the solution it may seem obvious after the fact, but as they say, “hindsight is always 20/20”.
Embedded systems design is no different. The end solution may seem obvious, but how did that design come to be? How many iterations did it take to get the design “right?”
This post is a follow-up post to “Can you have multiple phones connected simultaneously via Bluetooth” (if you have not read it, I suggest you read it now at Can Multiple Phones Be Connected Simultaneously via Bluetooth.
In the previous article, we described the solution to having multiple concurrent connections between a device and six mobile phones. We managed to take down the wall in our house successfully, but we did find some plumbing and electrical issues. This article shows you how we handled those issues.
To recap briefly, the customer wanted to be able to simultaneously control a device from six mobile phones. There was no explicit requirement for Bluetooth, but after exploring the alternatives, it seemed like Bluetooth was the correct solution. So what did this system need to do?
For Bluetooth 4.0, a central device is allowed to have multiple peripherals, but a peripheral is only allowed to have a single central. In the Bluetooth 4.1+ specification, a peripheral can support multiple masters, but at the time of this project the Bluetooth chip manufacturer did not have any firmware support for Bluetooth 4.2, at least not with regards to a peripheral having multiple masters.
The Bluetooth chip used was a Nordic Semiconductors nRF52 series module. At the time, their latest firmware release supported eight simultaneous connections as a Central, but only one connection as a peripheral.
One solution we explored was to have the hardware act as a peripheral and simply ‘fake’ the simultaneous connections. Essentially, the phones would connect with the hardware one at a time, and the hardware would cycle through the connections to see if there was any new data the phone wanted to send. If the hardware device could switch a connection fast enough, the phones would think they are all simultaneously connected, but in fact, they would only have a connection for a short period of time.
In practice, this approach did not work. The pairing process takes a few seconds on average, although sometimes it takes longer. When a central connects to a peripheral, some negotiation occurs. After a connection is successful, the security and pairing information is exchanged before data is allowed to be sent.
In order for this approach to work, the hardware would need a way to allow only one phone to pair with it at a time. Since the peripheral cannot initiate a connection (only the central device can) the phones would have to constantly be ‘scanning’ for a peripheral, and the peripheral would have to reject pairing requests from a phone if it wasn’t their turn. One approach would be to cycle through a whitelist of MAC addresses and simply let the phones constantly try to connect. In practice, this approach would be noticeably slow to the user, since the time between pressing a button to send a command and that command actually being sent to the hardware could be 20+ seconds if they were the 6th phone in line.
Phone manufacturers have been quick at implementing the “central” role on mobile phones since 2011. A phone can easily maintain multiple connections without much trouble. This is a well-tested and well-established use case in the mobile phone market. What about the phone’s ability to be a peripheral? Oh, the Woes of Peripheral Mode on Mobile Phones
DornerWorks found that the mobile phone manufacturers were not consistent with their implementation of the Bluetooth Peripheral mode. Prior to Android 5.0 there was no support for peripheral mode. Older versions of the iPhone (iPhone 4, for example) did not support the peripheral mode either. This means that multiple phones connected via Bluetooth would not work on older phones. Therefore, our solution must be targeted to a specific version of Android. It is common that 5-year-old phones are not supported by new technology, so this constraint was not a show stopper.
However, DornerWorks found that several phone manufacturers simply did not implement peripheral mode on their Bluetooth chipset even though the version of Android said it supported peripheral mode.
The Moto X, for example, running Android 5.1 said peripheral mode was not supported. As testing continued, more incompatible devices were discovered. The Moto G4 running Android 6.0 and an HTC One M8, also running Android 6.0.1, did not support peripheral mode. However, a Samsung Galaxy Note 5 running Android 6.0.1 supported peripheral mode and functioned flawlessly. This meant that the peripheral mode issue was not simply OS version specific, but device manufacturer specific!
Aside from a lack of support for peripheral mode, DornerWorks found that the implementation of peripheral mode varied from device to device. The Google Pixel running Android 7.0 would not maintain a Bluetooth connection as a peripheral device. The device would establish a connection, but the phone would immediately disconnect.
After upgrading the Pixel to Android 7.1.1, the connection worked perfectly. A similar experiment with the Nexus 6P and Nexus 5X yielded the same results. Android 7.0 phones prevented the central device from establishing and maintaining a connection. However, upgrading the Nexus 6P and 5X to Android 7.1.1 fixed the issue.
To further complicate things, Samsung’s Android 7 release was Android 7.0 instead of Android 7.1.1. This meant that the Samsung Galaxy S6, Galaxy S7, and Note 5 would not work with this solution while running Android 7.0. At the time, we had a Galaxy Note 5 and S6 device running Android 6.0.1 and they both worked perfectly. We had a Galaxy S6 and Galaxy S7 that were running Android 7.0 and they were unable to establish and maintain a connection.
The inconsistency between implementations of peripheral mode on the mobile devices made this solution very difficult. The design of the system was solid, but the integration with thousands of combinations of mobile devices turned into a bigger ordeal than anyone expected.
One issue with this design was using a chipset that had Bluetooth 4.2 compliant hardware but did not have full Bluetooth 4.2 compliant firmware. As of this writing, the chip manufacturer Nordic Semiconductors has released an updated version of the Bluetooth Protocol Stack (known as a SoftDevice) that supports Bluetooth 4.2’s “slave with multiple masters” feature. If our project had started 6 months later, we would not have needed to deal with the peripheral mode issues.
However, the primary issue was the inconsistency in implementation of peripheral mode on the mobile devices. A more consistent implementation to the specification needs to be followed in order to easily get to the kind of solution we were looking for. There either needs to be better standardization of peripheral mode or better compliance with the existing standards. Until then, solutions utilizing peripheral mode for mobile devices will be frustrating both for the developers and the end users who simply want a product that works.