Ok, so what if we want to get data from a Bluetooth Peripheral?
Well, we could use characteristic.readValue()
which behaves exactly like
you’d expect - it returns a promise which resolves with the value.
However in many cases we’re not interested repeatedly making readings, but in getting notified when a reading changes.
Accelerometer
from the Badge’s menuThe Badge has now configured itself as the following:
So all we have to do is use getPrimaryService
and getCharacteristic
to find
the characteristic as before, but then characteristic.startNotifications()
to
start us receiving characteristicvaluechanged
events whenever the badge
sends a notification.
<html>
<body>
<button onclick="connect()">Connect to Web Bluetooth</button>
<div id="data"></div>
<script>
function connect() {
var options = {
filters: [
{namePrefix: 'Pixl.js'},
],
optionalServices: [ "7b340000-105b-2b38-3a74-2932f884e90e" ]
};
var busy = false;
var gatt, service;
navigator.bluetooth.requestDevice(options).then(function(device) {
console.log('Device: ' + JSON.stringify(device));
return device.gatt.connect();
}).then(function(g) {
gatt = g;
// Get our custom service
return gatt.getPrimaryService("7b340000-105b-2b38-3a74-2932f884e90e");
}).then(function(s) {
service = s;
// Get the Acceleorometer characteristic
return service.getCharacteristic("7b340003-105b-2b38-3a74-2932f884e90e");
}).then(function(characteristic) {
var dataDiv = document.querySelector("#data");
// When we get a notification, write the data to a div below the button
characteristic.addEventListener('characteristicvaluechanged', function(event) {
var value = event.target.value.buffer; // an arraybuffer
dataDiv.textContent = (new Int8Array(value)).toString();
});
// Now start getting notifications
return characteristic.startNotifications();
}).then(function() {
//gatt.disconnect();
console.log("Done!");
}).catch(function(error) {
console.log("Something went wrong. " + error);
});
}
</script>
</body>
</html>
The code needed to handle this on the peripheral (which is being called when you choose the menu item) is simply:
NRF.setServices({
"7b340000-105b-2b38-3a74-2932f884e90e" : {
"7b340003-105b-2b38-3a74-2932f884e90e" : {
readable : true,
notify : true,
value : [0,0,0]
}
}
},{uart:false});
// Only start sending notifications a few seconds
// after we're connected to.
var started = false;
NRF.on('connect',()=>{
if (started) return;
started = true;
setTimeout(()=>{
// Update the service with new accelerometer data
setInterval(()=>{
var accel = NC.accel();
NRF.updateServices({
"7b340000-105b-2b38-3a74-2932f884e90e" : {
"7b340003-105b-2b38-3a74-2932f884e90e" : {
value : [accel.x*63,accel.y*63,accel.z*63],
notify: true
}
}
});
},200);
}, 2000);
});