Fun with Bluetooth

A presentation at Domotica Grunn in November 2017 in Groningen, Netherlands by Niels Leenheer

Slide 1

Slide 1

fun with bluetooth

Slide 2

Slide 2

bluetooth s k c su

Slide 3

Slide 3

classic bluetooth vs. y d o b y r h e t v o e o t n e o u s l a b e s r e t e th ha control dr on es and oth bluetooth low energy er cool shi t

Slide 4

Slide 4

bluetooth low energy also known as B l Bluetooth Smar t uetooth LE B l u e t o o t h 4 BLE

Slide 5

Slide 5

u b y a pl s lb e r e h p b l u b y a l p

Slide 6

Slide 6

8 b b o i r e h p s

Slide 7

Slide 7

e n o r d i n parrot mi

Slide 8

Slide 8

activity tracker

Slide 9

Slide 9

the boring theoretical stuff

Slide 10

Slide 10

central peripheral

Slide 11

Slide 11

central

Slide 12

Slide 12

generic attribute profile a w p a g e s u a c e b , t t a g n e k a t y d a e r l a s

Slide 13

Slide 13

central peripheral client server

Slide 14

Slide 14

§ i device information light e c i v e d r e p s e c i v r e s e l p i t l mu

Slide 15

Slide 15

i device information battery flight control

Slide 16

Slide 16

i device information battery steering control

Slide 17

Slide 17

i device information battery heart rate

Slide 18

Slide 18

i device information battery heart rate

Slide 19

Slide 19

i device information battery heart rate

Slide 20

Slide 20

i device information manufacturer model number serial number hardware revision firmware revision software revision … s c i t s i r e t c a r a h c e l e p c i i t v l r e s mu r e p

Slide 21

Slide 21

server service characteristic value array of objects object property value

Slide 22

Slide 22

services and characteristics are identified by uuid’s 16 bit or 1 28 bit

Slide 23

Slide 23

i device information 16 bit 128 bit 0x180A 0000180A-0000-1000-8000-00805F9B34FB

Slide 24

Slide 24

battery 16 bit 128 bit 0x180F 0000180F-0000-1000-8000-00805F9B34FB

Slide 25

Slide 25

steering control light still, ever y body does 16 bit 128 bit flight c this not recommended any UUID outside of the range xxxxxxxx-0000-1000-8000-00805F9B34FB

Slide 26

Slide 26

i device information manufacturer model number serial number hardware revision firmware revision software revision …

Slide 27

Slide 27

i 0x180A 0x2A29 0x2A24 0x2A25 0x2A27 0x2A26 0x2A28 … b good fo ad for rea r saving dability bandwi , dth

Slide 28

Slide 28

s t r o p p u s c i t s i r e t e c s a e r h a t h f c o each one or more read write write without response notify

Slide 29

Slide 29

every value is an array of bytes s e t y b st no d y c n fa u j , s e p y t a t a

Slide 30

Slide 30

pfew…

Slide 31

Slide 31

Slide 32

Slide 32

s t c a f g n i r o b t u o ab fun with bluetooth

Slide 33

Slide 33

fun with bluetooth

Slide 34

Slide 34

web bluetooth still not t he fun pa rt :-( api

Slide 35

Slide 35

connecting to a device

Slide 36

Slide 36

1 navigator.bluetooth.requestDevice({ filters: [ { namePrefix: ‘PLAYBULB’ } ], optionalServices: [ 0xff0f ] }) .then(device => device.gatt.connect()) .then(server => server.getPrimaryService(0xff0f)) .then(service => service.getCharacteristic(0xfffc)) t a h w r e s w o r b e h t l l e we t t n a w e w e c i v e d f o d kin .then(characteristic => { return characteristic.writeValue( new Uint8Array([ 0x00, r, g, b ); }) ])

Slide 37

Slide 37

s t c e l e s r e s u e th al device u t c a the

Slide 38

Slide 38

2 navigator.bluetooth.requestDevice({ filters: [ { namePrefix: ‘PLAYBULB’ } ], optionalServices: [ 0xff0f ] }) .then(device => device.gatt.connect()) .then(server => server.getPrimaryService(0xff0f)) .then(service => service.getCharacteristic(0xfffc)) r e v r e s e h t o t t c e conn .then(characteristic => { return characteristic.writeValue( new Uint8Array([ 0x00, r, g, b ); }) ])

Slide 39

Slide 39

3 navigator.bluetooth.requestDevice({ filters: [ { namePrefix: ‘PLAYBULB’ } ], optionalServices: [ 0xff0f ] }) .then(device => device.gatt.connect()) .then(server => server.getPrimaryService(0xff0f)) .then(service => service.getCharacteristic(0xfffc)) .then(characteristic => { return characteristic.writeValue( new Uint8Array([ 0x00, r, g, b ); }) e c i v r e s get the ])

Slide 40

Slide 40

4 navigator.bluetooth.requestDevice({ filters: [ { namePrefix: ‘PLAYBULB’ } ], optionalServices: [ 0xff0f ] }) .then(device => device.gatt.connect()) .then(server => server.getPrimaryService(0xff0f)) .then(service => service.getCharacteristic(0xfffc)) .then(characteristic => { return characteristic.writeValue( new Uint8Array([ 0x00, r, g, b ); }) ]) c i t s i r e t c a r a h c e h get t

Slide 41

Slide 41

writing data

Slide 42

Slide 42

w s e t y b e m o s rite navigator.bluetooth.requestDevice({ … }) .then(device => device.gatt.connect()) .then(server => server.getPrimaryService(0xff0f)) .then(service => service.getCharacteristic(0xfffc)) .then(c => { return c.writeValue( new Uint8Array([ 0x00, r, g, b ); }) ])

Slide 43

Slide 43

reading data

Slide 44

Slide 44

e m o s d er a s e t y b navigator.bluetooth.requestDevice({ … }) .then(device => device.gatt.connect()) .then(server => server.getPrimaryService(0xff0f)) .then(service => service.getCharacteristic(0xfffc)) .then(c => c.readValue()) .then(value => { let r = value.getUint8(1); let g = value.getUint8(2); let b = value.getUint8(3); })

Slide 45

Slide 45

get notified of changes

Slide 46

Slide 46

add r e n e t s i l t n e ev navigator.bluetooth.requestDevice({ … }) .then(device => device.gatt.connect()) .then(server => server.getPrimaryService(0xff0f)) .then(service => service.getCharacteristic(0xfffc)) .then(c => { c.addEventListener(‘characteristicvaluechanged’, e => { let r = e.target.value.getUint8(1); let g = e.target.value.getUint8(2); let b = e.target.value.getUint8(3); }); c.startNotifications(); }) don’t forget to star t listen ing

Slide 47

Slide 47

things you need to know: • javascript • the webbluetooth api • promises • typed arrays d ! h u

Slide 48

Slide 48

browser support Chrome Opera Samsung Servo (behind flag) (soon)

Slide 49

Slide 49

browser support a d kin Chrome Opera s k r o w Samsung Servo WebBLE (behind flag) (soon) for iOS

Slide 50

Slide 50

and… npm install node-web-bluetooth

Slide 51

Slide 51

and… the puck.js

Slide 52

Slide 52

(linux) commandline tools Oh, com e on!

Slide 53

Slide 53

hcitool lescan r o f n a c s vices e d ble LE Scan … 82:4C:4B:17:AC:E6 11:75:58:1B:52:85 D9:97:A2:35:42:2C D5:72:4A:3F:C2:1F PLAYBULB sphere TimeBox-mini-light BB-422C Puck.js c21f

Slide 54

Slide 54

gatttool —device=82:4C:4B:17:AC:E6 —characteristics get a list o f character all istics handle char uuid handle char uuid handle char uuid = 0x0002, char properties = 0x20, value handle = 0x0003, = 00002a05-0000-1000-8000-00805f9b34fb = 0x0028, char properties = 0x06, value handle = 0x0029, = 0000fffc-0000-1000-8000-00805f9b34fb = 0x004a, char properties = 0x02, value handle = 0x004b, = 00002a50-0000-1000-8000-00805f9b34fb

Slide 55

Slide 55

gatttool —device=82:4C:4B:17:AC:E6 —char-read —handle=0x0029 Characteristic value/descriptor: 00 00 00 ff reading t h of a char e value acteristic

Slide 56

Slide 56

gatttool —device=82:4C:4B:17:AC:E6 —char-write —handle=0x0029 —value=0000ff00 e u l a v e h t g n c i i t t i s wr characteri of a

Slide 57

Slide 57

custom characteristics. wtf!

Slide 58

Slide 58

writing a value: function(r, g, b) { return new Uint8Array([ 0x00, r, g, b } ]); reading a value: function(buffer) { return { r: buffer.getUint8(1), g: buffer.getUint8(2), b: buffer.getUint8(3) } } fro g n i d a e r d n a o t g writin c i t s i r e t c a r a h c e m a s e h t m

Slide 59

Slide 59

writing a value: function(r, g, b) { return new Uint8Array([ 0x01, g, 0x01, 0x00, 0x01, b, 0x01, r, 0x01, 0x00 ]); } t n e r r u c e h t g n i read e l b i s s o p t o n s i r colo

Slide 60

Slide 60

writing a value: function(r, g, b) { var buffer = new Uint8Array([ 0xaa, 0x0a, 0xfc, 0x3a, 0x86, 0x01, 0x0d, 0x06, 0x01, r, g, b, 0x00, 0x00, (Math.random() * 1000) & 0xff, 0x55, 0x0d ]); for (var i = 1; i < buffer.length - 2; i++) { buffer[15] += buffer[i]; } return buffer; } t n e r r u c e h t g n i read e l b i s s o p t o n s i r colo

Slide 61

Slide 61

reading a value: 0 e f f x 0 e c servi 4 e f f x 0 c i t s i r e t c a char 1 write a specific value 2 get the event with the color 3 add event listener service 0xffe5 characteristic 0xffe 9

Slide 62

Slide 62

adafruit bluetooth sniffer

Slide 63

Slide 63

Slide 64

Slide 64

Slide 65

Slide 65

finally t he fun p ar t demo

Slide 66

Slide 66

warning experimental technology w o l g n i t set s n o i t a t c e p x e

Slide 67

Slide 67

warning wifi interference r e h t r u f n e v e m e h t g n loweri

Slide 68

Slide 68

Slide 69

Slide 69

change the colour of a lightbulb https://bluetooth.rocks/lightbulb https://github.com/NielsLeenheer/BluetoothBulb

Slide 70

Slide 70

control a lego racer using a gamepad use css animations to define a path https://bluetooth.rocks/racer https://github.com/NielsLeenheer/BluetoothRacer

Slide 71

Slide 71

control a drone from your browser https://bluetooth.rocks/drone https://github.com/poshaughnessy/web-bluetooth-parrot-drone

Slide 72

Slide 72

pixel matrix display https://bluetooth.rocks/pixel

Slide 73

Slide 73

find out your current heartbeat https://bluetooth.rocks/pulse https://github.com/NielsLeenheer/BluetoothPulse

Slide 74

Slide 74

fun with bluetooth !

Slide 75

Slide 75

questions? @htm l5test