Skip to content

Instantly share code, notes, and snippets.


osnr/ Secret

Created Aug 8, 2021
What would you like to do?
Bluetooth Low Energy

I've been digging into Bluetooth Low Energy for a project (mostly out of frustration with the nature of Wi-Fi1, which I was using before).

I don't know how much you've read about BLE, but – it's actually really interesting. It's called "Bluetooth" Low Energy, but it has almost nothing to do with traditional "Bluetooth", other than using the same frequencies, I think. Sort of a Java-JavaScript situation.

It's not the stereotypical Bluetooth where you pair your laptop or phone with some device, then you have a kind of serial connection (that you desperately hope will stay alive) where you send things back and forth.

It's simpler – seemingly inspired by the underlying radio, using short asynchronous bursts on demand, rather than trying to model a continuous connection over a wire – but also somehow much richer, much more structured than most notions of communications (networking, serial) that I've seen. It doesn't pretend to be a link where bytes (or 'messages') get sent back and forth between two sides.

It has concepts of services and characteristics that live on a BLE "peripheral device" (a heart rate monitor or location beacon or earbuds or whatever). These seem sort of like 'objects' and 'properties' of those objects.

If you have, say, a heart rate monitor, maybe one characteristic would be 'heart rate'. The heart rate monitor (the "peripheral device") can write to the 'heart rate' characteristic based on what it senses. And any "central device" (your laptop or phone or whatever) can read that characteristic. (In other situations, you could have the opposite direction, where the central device is writing the characteristic, and the peripheral device is reading it. Different characteristics can have different read/write policies.)

I want to compare it to Unix flat text vs. JSON or Lisp. Unlike the plain files and streams of Unix, JSON and Lisp have objects that you can point to. They have a common language that programs can use to talk to each other that is more structured than just a sequence of bytes, and you (as the user) can inspect objects without needing to know about application-specific file formats or anything. BLE has this sort of structure as well.

let's say you're making a little gadget with an LED on it, and you're programming your gadget in C++. you can declare a BLE 'variable' (characteristic) ledState in your code, then get notified when someone else writes to that variable over the air!

isn't that cool? isn't that different from how you usually think about communication, especially with embedded devices? in that it's

  • reactive, sorta. you set up this 'fact', the variable, that people can already write and read, and you can make your program behavior downstream of that fact (rather than structuring your entire program around communications)
  • at the bare protocol level. it's not a friendly abstraction on top of some rickety stack of Wi-Fi or 3G and TCP and servers and stuff. the radio is made to think in these terms already, from the beginning!
  • exposes the object for interactive inspection and use, not just as an implementation detail within codebases that you control; you can flash this code to some gadget, open a Bluetooth scanner on your phone, and ledState will pop right up as characteristic 0x8601 on service 0x8600, and you can edit it directly by hand2

(doesn't it almost feel like something from Realtalk? put something up on a bulletin board, other people can change it or react to it, you never think about any 1-on-1 dance or lockstep or waiting or 'communication' or 'protocol', and you certainly never write any code for any of that. the model is the bulletin board model, right away, out of the box)

this is a weird comparison, but BLE almost has this energy that's like Dynamicland with the physical world, or like Plan 9 and TabFS with the filesystem. You map things into a space of objects (physical objects; files; BLE services and characteristics) where common, high-level operations already exist.

like, you could imagine mounting a BLE peripheral (a beacon or heart rate monitor or IoT thingy with a screen) as a FUSE filesystem, and having a folder for each service on the peripheral, and having files for each characteristic in that service. It wouldn't be a perfect mapping, but it wouldn't be ridiculous, either.3 There's this structure to it that I don't think exists in Bluetooth or in Wi-Fi (or in TCP or UDP or whatever).

I wonder if people have thought about it in these terms (BLE is a design by hardware people, I assume, not weird computing/HCI/operating systems people, and they aren't gonna think much about interaction or end users).

it's hard to see it – writing a program to talk BLE on your laptop or phone is way harder than talking TCP or UDP over Wi-Fi, it requires all these brutal low-level APIs. you have to step your way through this whole state machine of looking for things that are advertising, then connecting, then discovering what they can do, then reading or writing (and each one of these steps can fail, and each one breaks up the flow of your program and requires a delegate callback, at least in Apple's world). but there is this conceptual core that I like.

and there's no mass audience that is familiar with manipulating BLE services, not in the way that there's an audience that knows how to manipulate physical objects or how to manipulate computer files. (but it's possible – maybe that audience could be constructed someday)

And – this is vague, but I like how this BLE stuff cuts through layers. that you actually look at the radio and the communications protocol underneath your 'app', and you don't just take 'the Internet' for granted as the way you communicate. You don't have layer piled on layer of indirection that you don't understand that is working against you.

I like the idea that there'd be some payoff from caring about this whole system, end-to-end, from the end user's mental model all the way down to the radio chip.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment