Wait, my browser can do Bluetooth?!

Introduction and Personal Background

Introduction to the speaker, Simon Hildebrandt, who describes his hobbies and interests, particularly in making various electronic devices and circuit boards.

Motivation for Exploring Bluetooth Technology

Discussion about the motivation behind exploring Bluetooth technology, including the idea of creating low-cost, wireless communication between devices.

Overview of Bluetooth Technology

An overview of Bluetooth technology, including its different versions and functionalities like Bluetooth high speed and Bluetooth low energy.

Bluetooth vs. Wi-Fi

Comparison between Bluetooth and Wi-Fi technologies, focusing on their specific uses and functionalities.

Understanding Bluetooth Profiles

Explanation of Bluetooth profiles, particularly GAP (General Access Profile) and GATT (Generic Attribute Profile), and their roles in device communication.

Focus on Generic Attribute Profile (GATT)

Detailed discussion on the Generic Attribute Profile (GATT), its use in custom and experimental Bluetooth applications, and its significance in Bluetooth low energy.

Service and Characteristics in GATT

Explanation of services and characteristics within GATT, including their unique IDs and functional representation in Bluetooth communication.

Demonstration of a Bluetooth-enabled Device

A demonstration of a self-made Bluetooth-enabled device, explaining its components and functionality.

Technical Specifications of the Bluetooth Device

Technical details of the Bluetooth and Wi-Fi capabilities of the device, including information about the microcontroller used.

Web Bluetooth API and Browser Compatibility

Exploration of the Web Bluetooth API, its browser compatibility, and steps to enable it in browsers.

Implementing Bluetooth in the Browser

Insights into implementing Bluetooth functionality in the browser, covering security aspects and device connection requirements.

Connecting and Interacting with Bluetooth Devices

Practical demonstration of connecting to and interacting with Bluetooth devices using web technologies.

Challenges in Bluetooth Connectivity

Discussion of challenges encountered in Bluetooth connectivity, including device caching and security restrictions in browsers.

Real-time Demonstration of Bluetooth Device Features

Live demonstration showcasing the accelerometer and LED functionalities of the Bluetooth device.

Embedded Development with Arduino

Introduction to embedded development using Arduino, highlighting its use in Bluetooth and sensor integration.

Front-end Development for Bluetooth Devices

Insight into the front-end development process for controlling Bluetooth devices, including code demonstrations.

Thank you.

Am I sufficiently amplified?

Seems like I am.

Cool.

All right.

This is me, maker of weird junk, that's mostly self serving stuff, like weird little authentication services and shopping list junk and all sorts of other stuff.

My desk has crap all over it, laser cut bits and custom made circuit boards and all sorts of nonsense, because that's the sort of stuff that I do for fun.

That's what keeps me alive.

so yeah, that's some of the context, and this is the sort of thing that happens to me is I see these things and I think, oh, that's ridiculously expensive.

I reckon I could make that for a couple of bucks, a couple of LEDs and a few microcontrollers.

The only thing I'm a bit iffy is how would I get them to like, talk to each other?

I'm not sophisticated enough to make a wired connection between a couple of these and actually make that work properly.

So maybe it could be a wireless connection enter, a whole batch of modern microcontrollers and stuff that talk Bluetooth.

So what is Bluetooth?

that's the Wikipedia page.

Answers the question, right?

yeah, it's, because you all know what Bluetooth is, right?

You've seen it, you've got devices, somehow it does the magic, it does the wireless.

And, and yeah, it just works, right?

it's been around for a while.

You can see we've got a whole bunch of versions of it that have come past.

4 gave us a new version of the previous stuff packaged up and called Classic.

and it gave us Bluetooth high speed and it gave us Bluetooth low energy, which, keep an eye on, we'll be talking about that in a minute.

we're actually up to version 5 now, so we've just been, iterating really fast and getting a lot of, different behavior and stuff from this standard.

So it's a wireless connection, right?

Wi Fi, yeah?

But not, right?

Because we know intuitively that Wi Fi does this one thing where it gives you internet, right?

Bluetooth isn't like that.

Bluetooth is very specific utility, right?

It does very specific things for you.

It's not like a general purpose thing.

When you've used Bluetooth, you've used it to pair like a phone headset or something, or connected maybe to a printer, or like different sorts of stuff.

And it's never just it's never just Bluetooth.

It's always like these specific behaviors.

Okay, what are those behaviors?

those are called profiles.

Those are specific, carefully described standards for how this kind of thing can talk to this kind of thing.

If you go and have a look at this list of, Bluetooth profiles, you can see there are tons and tons.

the two that we particularly pay attention to for what we're talking about now is, the GAP, which is actually the GAP, that's the generic, it's the "general, attribute profile", I think.

anyway, it's the one that's the minimal set of Bluetooth behavior that every other Bluetooth profile depends on basic connectivity and stuff.

And then the GATT is the one that we're gonna be particularly talking about today, which is, the, the "generic attribute profile".

because.

What we're talking about today, the weird stuff that we might be experimenting with, having some fun with, is not, connecting a commodity headset to a commodity phone or whatever, right?

there's a profile for that.

there's a, there's many companies doing that themselves.

What we want to do is, some experimentation.

We want to build something.

different novel that's not that general, that those specific things, we want to do something that's a bit more general.

that's what the generic attribute profile is for.

It's for all of the, it's the catch all, it's the use case for when you're not a big company, when you don't have a profile, an existing profile that you're going to be complying with, or like a clever new one that you're going to set up.

this is the experimental one.

the GATT is actually technically part of the Bluetooth Low Energy profile.

the devices that you see out there, the new microcontrollers and stuff, they say, oh, I do Bluetooth Low Energy, cool, I can GATT with you.

and that came, as I said, in Bluetooth 4.

the way the GATT works is, it's, each, GATT setup that you do is a group of services.

and that's how you can divide the behavior of your device into, Different clusters, and so each service has a unique ID.

This is how we can, find them and address them.

you'll see examples of this, soon.

each service that you, create is made up of characteristics.

A characteristic also has a unique ID and it's basically, it tends to represent like a number.

A value that's coming out of some thing.

Whether it's like a blood pressure cuff telling you the current pressure or, that kind of thing.

I thought it would be most appropriate to actually show you something, that actually can talk Bluetooth.

This is my ridiculous cardboard engineering nonsense.

this I refer to as the attention getting device with, this is supposed to get your attention so you can be impressed and, think that this can actually work to some extent.

It's like a buck fifty of, commodity.

hobbyist electronics, and my emergency phone battery, in there to provide power just so I'm not tethered to the laptop.

so yeah, that's this.

clearly we're talking about doing all this stuff on the web, but clearly there's a physical component to this, so I can give you a quick rundown of what this is.

this company Seed, they do a series, they do all sorts of like micro controllery kind of things.

this one particularly is this Xiao ESP32.

and, it has Bluetooth and Wi Fi, so it's got a little, programmable radio in there, and it's really simple to, to get up and use.

And just because I really didn't want to faff around, I just bought one of their expansion boards and just plugged it in, and it comes, that kit comes with the LEDs and the sensors that you'll see.

super easy, barely an inconvenience.

to get up and running, in most, so let's, have a quick look.

I wonder if this is still loaded.

It is.

Yeah.

so what are we seeing here?

This is Can I Use, Web Bluetooth, we're looking at Chrome, we're looking at Edge, we're distinctly not looking at Safari, we're distinctly not looking at Firefox yet for these sorts of things.

this is not universal by any stretch of the imagination.

The other thing to be aware of is it's not turned on by default.

if we pop over here, you can see I've actually got it switched on now.

But what you'll need to do is come in here, set this flag.

And then you'll need to restart your browser.

Okay, cool.

but, like, how do we actually do this stuff in the browser?

all of the Bluetooth stuff is namespaced under this Bluetooth key.

And absolute bare bones thing that you need to do is called, getAvailability.

Does this device do Bluetooth?

And you can get an answer for that.

It's a promise, returns a value.

and then And what we want to say, what we want to do next is just call get devices, like what devices am I currently connected to?

This might not necessarily do exactly what you think, but we'll get to that.

as we heard in the keynote yesterday, security is an important part of this process.

And we have, the whole sort of web security model to lean on, the way we tie things to domain names and stuff.

So it's actually, quite reliable.

the next layer of security that we have is, we require you, the, browser requires you to be quite specific about the device that you're trying to connect to.

So you need to know, say a vendor ID and a product ID under normal circumstances to make a connection.

if you are Fitbit and you say, come to the Fitbit website and I will connect to your Fitbit and I'll tell you about what's going on in your Fitbit, then you would say, I'm a Fitbit vendor and I'm gonna provide you a couple of different product IDs of the, Fitbits that I'd be interested to talk to.

All well and good if you are, like, Fitbit, and your device does GAP and stuff.

I don't know what the vendor ID is or the product ID of my Bluetooth gizmo.

It's just commodity stuff off the shelf.

It's not what I'm interested in.

I do know the service and stuff because I wrote the code.

That runs on the Bluetooth device, but so that the thing that's useful to me is this second mode where I can put it in this like slightly more promiscuous, mode and say accept all devices, but the important thing is like what we're talking, what I'm hoping to talk about with you, Bluetooth stack, is this service.

So I'm going to give you a service ID.

so that's cool.

this is it.

I have a dinky little app.

And, so let's, try and this is the get device call.

And it's giving me this list of devices, as you can see.

The attention getter 2000 is there.

let's try and connect to it.

Okay, it's not even on.

So actually, that's weird.

Why, is it in the list?

the Bluetooth stack aggressively caches.

Information about devices that it's connected to previously and stuff and it's yeah, no, like I totally know about this device and it's okay, but can I connect to it?

Is it, even on?

and it's okay, let's try turning it on.

Let's see if that helps.

Eh, got your attention now, haven't I?

okay, so let's give it another go.

Still no connection.

Okay.

And this is the security stuff that I was talking about.

it aggressively caches the devices it's talked to it, it knows about where, where they are, but I haven't, in this session, I haven't given permission to talk to this device.

And so it trying to reach out and connect to this thing not gonna happen.

So what we need to do is actually jump in here and try and find a device to pair.

Now a friend of mine, when I told him I was gonna do this said " you are mad".

There is going to be 15 zillion Bluetooth devices in that room, and you're not going to be able to find yours.

I came in here a few minutes ago, tried it out, and I was like, oh, thank God, it appears right there in the list.

So that's easy.

So we can pick this one.

Now it knows that it has paired with it previously, but it's saying, we, we demand a click in this dialogue saying pair right now before you can have access to this device, which is, okay, fair enough.

ignore the crappy state in my app, but I can now connect to this, and there we go.

this thing has, strip of LEDs, it also has, tucked in the top, a little 3 axis accelerometer.

So the most noticeable thing you can see there is the accelerometer.

So if I switch the orientation, you can see, particularly the blue one there is switching, and it's basically saying, I'm getting zero acceleration there, and I'm getting a gravity's worth of acceleration there.

that's the sort of thing, and so you can spin it around and get different things.

And then, so we can switch this over to, a nice rainbowy thing.

Looks quite pretty and then back to the lines.

Yeah.

Awesome.

Cool.

so what's actually happening with this code?

so first I should actually just show you some of the actual embedded stuff.

So to do this kind of stuff, you'll probably be using something like this, which is Arduino.

it's a really convenient ecosystem for this kind of embedded stuff.

And under these circumstances, you basically write something that's like C++ So you just got a bunch of headers of different libraries that you need to use for, the Bluetooth behavior, for the accelerometer, and then for controlling the pixels.

Now, I told you about service IDs, so you'll find, you'll see, here's some, UUIDs that I generated, one for the service and then two for the characteristics.

Now I said that the characteristics represent numbers.

So I've got one value, which is which version of the, what type of LED pattern we're doing.

And one value, which is a, an encoded description of the three accelerometer states, which I package up on the device and then I split it open, in the browser.

So there's two characteristics.

Cool.

It runs this little server that's able to do things with callbacks and stuff to keep track of the changing state of the characteristics.

You see some of that stuff.

The setup is just, standard initialization stuff.

I've got two characteristics here that we're defining.

The LED one is fairly simple, and that's down here.

And it's just read write behavior, that's simple, but the, accelerometer, does notify behavior, so that we don't have to poll, which is, slightly more sophisticated, and you can see in there that I'm specifying notify on the, top, on the upper one, and we'll get into how that works later on, and then, it wouldn't be a home, microcontroller project, if there wasn't a bunch of like weird hacky, make, the LEDs, just blinking lights, no.

yeah, there's a compile window down here and stuff.

Arduino is very easy to get into.

I can strongly recommend it.

and the code, of course.

This, whole presentation is all in GitHub.

I'll show you the link later.

and it includes all of the, Arduino stuff, so you can, see what I'm doing there as well.

This is the front end.

And this is the code for that.

I don't know if that's big enough, might go a bit bigger.

Here we go.

ignore my extremely unprofessional React code.

here we have those services.

so it's able to, specify the service that it wants to talk to and then connect to it.

Here's that get availability check.

and then Now, getAvailability, it may or may not tell you whether or not this device can do Bluetooth, but whether or not you have the flag checked, and a few other things, basically, the real test of whether or not you can actually do Bluetooth is to some extent if you try and do it, and you can.

So that's what this check is all about.

yeah, cool.

Let's, have a find devices button, as you saw in the interface.

which is going to call this find matches.

which is, there's the, request device.

That's where the dialogue comes up.

And, forces the user to get involved in the process.

and then, bunch of polling, just getting, devices periodically.

because, devices can get turned off, they can drift in and out of range, other things can happen, and yeah, I'm just polling to, to get those, those different devices.

once we've got a device, I list it out, and then I give you the option to try and actually connect to it and start, build that relationship where we can actually talk back and forth with it, which is cool.

And then As I said, Bluetooth devices have, one or more services.

the absolute easiest way is literally just say, gatt.getPrimaryService and then, it'll just find the first one or the one marked primary.

Now, all of the stuff when you're talking to a device, as I said, is GATT because that's the protocol that's supported in browsers.

and so every time you talk to a device, you're talking through this GATT key because, at least for the moment that's the only thing your browser can do.

It can only GATT.

It can't do anything else.

so that's the only one, the one and only profile that we're going to be using.

yeah, I have a service class.

I have characteristics class.

I've got a couple of, classes, for, for the lights and for the, circles, the, for the, accelerometer sensors, that I used to just render those little components in the front end, but they are all, they basically just build off this, which is, that we get information about characteristics.

It's a lot of callbacks, a lot of promises, a lot of waiting for the device to answer you and stuff.

So the code looks a lot like that.

and then we, you'll see a lot of references to like text decoder and text encoder and stuff because it's an embedded device we're pushing bytes back and forth and so from the JavaScript layer we need to be building array buffers as like actual binary data and then we can push that down into the Bluetooth stack and pull stuff up and decode it and then start treating it like grown ups data so Yeah, for just sending a value, it's pretty simple, we have this, the characteristic has this right value and with a response if you want to find out whether it definitely was successful in writing.

And that's, you build up your buffer, stuff it into that function, and it gets pushed down to the device, which is pretty simple.

you can also read values up with something very simple, very similar.

but the interesting stuff happens, I think particularly when the characteristic announces that it can do notifications.

Because that means you can, actually just hang a callback like I do here and literally just wait for the characteristic value to change.

And so that's how the, the accelerometer works in this setup is that I'm not polling.

every tenth of a second, it has a timeout.

it says, I'm going to notify you again.

And that comes up here and hits this callout.

And so as you saw from the, from the actual Interface, that's super responsive.

it's very quick.

So we've got a nice high bandwidth there of information going back and forth, which is really cool.

so yeah, that's the bulk of, what I had to say.

As I said, the presentation's here.

I think we can do some questions now.

Who am I?

I'm Simon Hildebrandt.

I'm a web developer, working as a team lead at Equinox Ventures.

I'm interested in hardware hacking, 3D printing, laser cutting.

  • Login-With.Link (authentication)
  • RunTo.Store (shopping list app)
  • Scrawl (pixel-art editor)
  • SimonHildebrandt.com (my blog)
The image contains a photograph of Simon Hildebrandt along with a child.

So... why?

Nanoleaf tiles - these are cool, but expensive...

Could I build my own?

The image includes a visual representation of triangular and square shaped colorful tiles interlocked with each other, resembling a modular electronic lighting system.

What Is Bluetooth?

Bluetooth is a short-range technology standard that is used for exchanging data between fixed and mobile devices over short distances and building personal area networks. In the most widely used mode, transmission power is limited to 2.5 milliwatts, giving it a very short range of up to 10 metres.

It employs Ultra high frequency radio waves in the ISM bands, from 2.402 GHz to 2.48 GHz. It is mainly used as an alternative to wire connections, to exchange files between nearby portable devices and connect cell phones and music players with wireless headphones."

Source: https://en.wikipedia.org/wiki/Bluetooth

Bluetooth 4.0 included Classic Bluetooth, Bluetooth high speed and Bluetooth Low Energy - we're now at Bluetooth 5.0.

Bluetooth in the Browser

Huh?

You mean like wifi?

Bluetooth is different

Think about how you've used Bluetooth:

  • Phone headset
  • Wireless earphones
  • Wireless speaker
  • Wireless keyboard
  • Wireless printer

Profiles

Each of those examples is a different kind of behaviour, and in Bluetooth these behaviours are called profiles.

https://en.wikipedia.org/wiki/List_of_Bluetooth_profiles

Working with profiles

If industry uses standardised profiles for interoperability, what's the easiest way to create our own weird behaviour? Use the Generic Attribute Profile (GATT).

(The GATT is actually a foundational part of the Bluetooth Low Energy standard, which was introduced as part of Bluetooth 4.0).

GATT Services

The GATT uses services to group behaviour.

Each service has a unique id.

GATT Characteristics

GATT services are, in turn, a group of characteristics.

Each characteristic also has a unique id.

A characteristic represents a value - something like a number.

A brief diversion - embedded development

Seeed Studio XIAO ESP32C3

Seeed Studio Expansion Board Base for XIAO with Grove OLED

Bluetooth in the Browser

Browser setup

chrome://flags/#enable-web-bluetooth-new-permissions-backend

Enable, then restart browser.

Shows Can I use table for Web Bluetooth. Shows suport in recent Chrome, Edge and Opera browsers.

Browser setup

chrome://flags/#enable-web-bluetooth-new-permissions-backend

Enable, then restart browser.

Basics – Bluetooth essentials

navigator.bluetooth.getAvailability();

// Promise with availability of Bluetooth stack

navigator.bluetooth.getDevices();

// Promise with list of paired, attached devices

Basics - Bluetooth security

navigator.bluetooth.requestDevice({
    filters: [
      { vendorId: 0x1209, productId: 0xa800 },
      { vendorId: 0x1209, productId: 0xa850 },
    ]
  });

  // or...

  navigator.bluetooth.requestDevice({
    acceptAllDevices: true,
    optionalServices: [SERVICE_UUID]
  });

  // Triggers browser Bluetooth device selection dialog
  

Bluetooth in the Browser

The image displays a simple UI titled "Example app". The interface includes a section labeled "Devices" with a listed device named "AttentionGetter2000" alongside a "connect" link. There is also a "Find Devices" button depicted to the side of the device section.
A web interface is depicted that includes a "Devices" section with a listed device named "AttentionGetter2000" and a UUID "beb5483e-36e1-4688-b7b5-ea07361b26a8". There is a "disconnect" link next to the device name. Below this, a "Find Devices" button is visible, and there are representations of a red bar graph, a green bar graph, and a blue bar graph without any labels or values indicated. Inset is a still from the talk featuring Simon holding the device with lights. He changes its orientation, and the bars in the UI change in response.
shows the IDE for programming Arduino
Simon scrolls through the JSX code for the web app, describing different features of the code.
Again we see the example app in action

Thanks!

Questions?

This presentation: https://github.com/simonhildebrandt/bluetooth