Bluetooth LE, ESP32 and Pi/Linux

The ESP WROOM module is a low cost dual core module with Bluetooth LE and Wifi capabilities. It has i2c, SPI, 1wire, 2x 12bit ADCs with 8 channels each, although only 1 ADC can be used with Bluetooth LE. It has a deep sleep current of 25uA and costs arround 5 GBP on Ebay as a dev board. It can be programmed with the Ardion IDE and the libraries there appear to be upto date and functional maintained by the Aduino maintainers and Espressiv who make the modules.

Bluetooth on Linux uses the Bluez stack from Qualcom. Various tools are available for interacting with the kernel socket (AF_BLUETOOTH), although I have found it hard to get working reliably. The standard tools frequently fail to connect, and often drop out of connections. The Pi3 firmware needed flashing (rpi-update) to fix timeouts and the kernel seems to be tightly bound in some way to the firmware. Worst of all, if you are thinking of using Bluetooth LE on a Linux/Pi box is there is no device to talk to or user space interaction of any sort. Programs must be run privalaged as root or with raised kernel capabilities (net raw + net admin), which can be achieved by raising the cpapabilities on the executable, having the use inherit raised capabilities with pam_cap or running everything via sudo. Although there is a bluetooth group, this does nothing when it comes to running an app that needs to interact with Bluetooth LE. Setting capabilities on an executable might be a bad thing to do, especially if that executable is generic, like the node executable. pam_cap looks like a pain. So sigh, and use sudo.

On the Pi I like to use node over python or c, becuase its single threaded and efficient generally leading to much lower resource usage. However, the support for Bluetooth LE is not great in npm with many modules abandoned. @abandonware/noble does compile and work provided you always run via sudo. Some of the example code (peripheral-explorer.js) is specaulary broken, probably as a developer trying to be ‘super cool’ and making the core 10x more complex than it needs to be using async (refactoring with forEach reduces the complexity and works).

OSX does have Bluetooth, however as I eventually discovered older hardware has no Bluetooth LE support and they are not the same. Comilint anything on OSX is a complete and utter pain due to the Apple policy for forced obselecence. The XCode version will only build with a narrow range of hardware, getting narrower each year and once built the binaries will only work with that narrow range. The libraries appear to have poor backward compatibility. @adabdonware/noble uses an async module that has a build target of 10.7 in its bindings.gyp which generates errors on later than 10.8. Changing that to 10.8 makes the build suceed on later than 10.8, however, as I found out, no support for Bluetooth LE. Your hardware may vary, check the system report under he “bluetooth” heading there is a bluetooth LE yes/no flag.

Android just works, but I cant see myself writing a BLE->SignalK server bridge on Android.

Alternatives. I could use Wifi, but I would want to hibernate the Wifi and there is lots of talk of the ESP32 wifi not comming out of hibernation cleanly. Doing so would require that the device descovers the wifi network its operating in, rather than the Pi server discovering the BLE devices advertising characteristics. So BLE it is, for the moment.