Thanks both @jonathan and @h_classen . I'm happy to post the code, but because it's only usable with the device I'm using, (and because I'm a crappy coder so I'm hacking it together) it probably won't make very much sense.
It is a bluetooth device called MetaWear and I think the values I get from the linear acceleration is in Gs, but I may be wrong. The curve that I can monitor conforms to the explanation this video gives: IMU Data Analysis: Acceleration | Live Video Sync - YouTube
So if the device is moved in positiveX (right?) the curve dips down below zero, then comes up above zero and then settles back down at zero(ish) once device is still. When the device is moved negativeX (left?) then the curve goes up above zero, then goes below zero and then settles at zero when the device is static.
navigator.bluetooth.requestDevice(
{filters: [{name: 'MetaWear'}],
optionalServices: ['0000180a-0000-1000-8000-00805f9b34fb', '0000180f-0000-1000-8000-00805f9b34fb', '326a9000-85cb-9195-d9dd-464cfbbae75a'],
})
.then(device => {
return device.gatt.connect();
})
.then(server => {
return server.getPrimaryServices();
})
.then(services => {
services.forEach(service => {
service.getCharacteristics().then(characteristics => {
characteristics.forEach(characteristic => {
if (characteristic.uuid === '326a9006-85cb-9195-d9dd-464cfbbae75a') {
window.coordinates = characteristic;
window.coordinates.addEventListener('characteristicvaluechanged', coordinatesChanged);
}
if (characteristic.uuid === '326a9001-85cb-9195-d9dd-464cfbbae75a') {
window.led = characteristic;
}
if (characteristic.uuid === '00002a19-0000-1000-8000-00805f9b34fb') {
window.battery = characteristic;
window.battery.addEventListener('characteristicvaluechanged', batteryChanged);
}
})
})
})
})
}
function batteryChanged(event) {
let batteryLevel = event.target.value.getUint8(0);
document.querySelector('#batteryL').textContent = batteryLevel + '%';
document.querySelector('#batteryIndicator').textContent = batteryLevel + '%';
}
function coordinatesChanged(event) {
let value = event.target.value;
let a = [];
// Convert raw data bytes to hex values
for (let i = 0; i < value.byteLength; i++) {
a.push(('00' + value.getUint8(i).toString(16)).slice(-2));
}
if (a[0] === '13' && a[1] === '05') {
// document.querySelector('#valueHEX').textContent = 'x: ' + ' ' + a.join(' ');
}
//QUATERNION
if (a[0] === '19' && a[1] === '07') {
document.querySelector('#valueHEX').textContent = 'Quartenion: ' + ' ' + a.join(' ');
let w = event.target.value.getFloat32(14, 4, true);
document.querySelector('#w').textContent = w.toFixed(2);
let qx = event.target.value.getFloat32(6, 4, true);
document.querySelector('#qx').textContent = qx.toFixed(2);
let qy = event.target.value.getFloat32(2, 4, true);
document.querySelector('#qy').textContent = qy.toFixed(2);
let qz = event.target.value.getFloat32(10, 4, true);
document.querySelector('#qz').textContent = qz.toFixed(2);
}
//LINEAR ACCELERATION
if (a[0] === '19' && a[1] === '0a') {
document.querySelector('#valueHEX').textContent = 'Linear Acceleration: ' + ' ' + a.join(' ');
let y = event.target.value.getFloat32(10, 4, true);
document.querySelector('#y').textContent = y.toFixed(2);
let z = event.target.value.getFloat32(2, 4, true);
document.querySelector('#z').textContent = z.toFixed(2);
let x = event.target.value.getFloat32(6, 4, true);
document.querySelector('#x').textContent = x.toFixed(2);
}
//EULER ANGLES
if (a[0] === '19' && a[1] === '08') {
document.querySelector('#valueHEX').textContent = 'Euler: ' + ' ' + a.join(' ');
let yaw = event.target.value.getFloat32(14, 2, true);
document.querySelector('#yaw').textContent = yaw;
let roll = event.target.value.getFloat32(12, 2, true);
document.querySelector('#roll').textContent = roll;
let pitch = event.target.value.getFloat32(10, 2, true);
document.querySelector('#pitch').textContent = pitch;
}
I'm able to control an object rotation in 3D on screen (embedding three.js in Hype) with Quaternions and it's pretty accurate. But I can't figure out position. I have been reading up how difficult it is. But I'm not striving for too much accuracy, I just want to be able to use the bluetooth device as a basic game controller, which would be an achievement for me. I thought that if I just focus on a 2d implementation first I can aways add another axis later?
I just think it would be cool to play pong with a controller like this. Or asteroids. Then gradually get more sophisticated as I learn more.
Stumbled onto this article while searching and I think it may be promising: https://codepen.io/OliverBalfour/post/implementing-velocity-acceleration-and-friction-on-a-canvas
Thanks