btadv: encode & advertise accelerometer data

master
Rob Pilling 2023-07-26 07:15:31 +01:00
parent 63cbd45cc6
commit 31736cb447
2 changed files with 79 additions and 10 deletions

View File

@ -4,7 +4,12 @@
Bangle.loadWidgets();
Bangle.drawWidgets();
var HRM_MIN_CONFIDENCE_1 = 75;
var services_1 = ["0x180d", "0x181a", "0x1819"];
var services_1 = [
"0x180d",
"0x181a",
"0x1819",
"0xE95D0753251D470AA062FA1922DFA9A8",
];
var acc_1;
var bar_1;
var gps_1;
@ -215,13 +220,15 @@
];
};
encodeGpsHeadingOnly_1.maxLen = 17;
var encodeMag_1 = function (data) {
var encodeXYZ = function (data) {
var x = toByteArray_1(data.x, 2, true);
var y = toByteArray_1(data.y, 2, true);
var z = toByteArray_1(data.z, 2, true);
return [x[0], x[1], y[0], y[1], z[0], z[1]];
};
encodeMag_1.maxLen = 6;
encodeXYZ.maxLen = 6;
var encodeMag_1 = encodeXYZ;
var encodeAcc_1 = encodeXYZ;
var toByteArray_1 = function (value, numberOfBytes, isSigned) {
var byteArray = new Array(numberOfBytes);
if (isSigned && (value < 0)) {
@ -251,6 +258,7 @@
case "0x180d": return !!hrm_1;
case "0x181a": return !!(bar_1 || mag_1);
case "0x1819": return !!(gps_1 && gps_1.lat && gps_1.lon || mag_1);
case "0xE95D0753251D470AA062FA1922DFA9A8": return !!acc_1;
}
};
var serviceToAdvert_1 = function (serv, initial) {
@ -264,11 +272,20 @@
readable: true,
notify: true,
};
var os = {
maxLen: 1,
readable: true,
notify: true,
};
if (hrm_1) {
o.value = encodeHrm_1(hrm_1);
os.value = [2];
hrm_1 = undefined;
}
return _a = {}, _a["0x2a37"] = o, _a;
return _a = {},
_a["0x2a37"] = o,
_a["0x2a38"] = os,
_a;
}
return {};
case "0x1819":
@ -331,6 +348,21 @@
}
return o;
}
case "0xE95D0753251D470AA062FA1922DFA9A8": {
var o = {};
if (acc_1 || initial) {
o["0xE95DCA4B251D470AA062FA1922DFA9A8"] = {
maxLen: encodeAcc_1.maxLen,
readable: true,
notify: true,
};
if (acc_1) {
o["0xE95DCA4B251D470AA062FA1922DFA9A8"].value = encodeAcc_1(acc_1);
acc_1 = undefined;
}
}
return o;
}
}
};
var getBleAdvert_1 = function (map, all) {

View File

@ -33,10 +33,17 @@ const enum BleServ {
// contains: LocationAndSpeed
LocationAndNavigation = "0x1819",
// Acc // none known for this
// org.microbit.service.accelerometer
// contains: Acc
Acc = "0xE95D0753251D470AA062FA1922DFA9A8",
}
const services = [BleServ.HRM, BleServ.EnvSensing, BleServ.LocationAndNavigation];
const services = [
BleServ.HRM,
BleServ.EnvSensing,
BleServ.LocationAndNavigation,
BleServ.Acc,
];
const enum BleChar {
// org.bluetooth.characteristic.heart_rate_measurement
@ -69,6 +76,11 @@ const enum BleChar {
// org.bluetooth.characteristic.magnetic_flux_density_3d
// s16: x, y, z, tesla (10^-7)
MagneticFlux3D = "0x2aa1",
// org.microbit.characteristic.accelerometer_data
// s16 x3, -1024 .. 1024
// docs: https://lancaster-university.github.io/microbit-docs/ble/accelerometer-service/
Acc = "0xE95DCA4B251D470AA062FA1922DFA9A8",
}
type BleCharAdvert = {
@ -88,7 +100,7 @@ type LenFunc<T> = {
maxLen: number,
}
const enum SensorLocations = {
const enum SensorLocations {
Other = 0,
Chest = 1,
Wrist = 2,
@ -469,14 +481,19 @@ const encodeGpsHeadingOnly: LenFunc<CompassData> = (data: CompassData) => {
};
encodeGpsHeadingOnly.maxLen = 17;
const encodeMag: LenFunc<CompassData> = (data: CompassData) => {
type XYZ = { x: number, y: number, z: number };
const encodeXYZ: LenFunc<XYZ> = (data: XYZ) => {
const x = toByteArray(data.x, 2, true);
const y = toByteArray(data.y, 2, true);
const z = toByteArray(data.z, 2, true);
return [ x[0]!, x[1]!, y[0]!, y[1]!, z[0]!, z[1]! ];
};
encodeMag.maxLen = 6;
encodeXYZ.maxLen = 6;
const encodeMag: LenFunc<CompassData> = encodeXYZ;
const encodeAcc: LenFunc<AccelData> = encodeXYZ;
const toByteArray = (value: number, numberOfBytes: number, isSigned: boolean) => {
const byteArray: Array<number> = new Array(numberOfBytes);
@ -517,6 +534,7 @@ const haveServiceData = (serv: BleServ): boolean => {
case BleServ.HRM: return !!hrm;
case BleServ.EnvSensing: return !!(bar || mag);
case BleServ.LocationAndNavigation: return !!(gps && gps.lat && gps.lon || mag);
case BleServ.Acc: return !!acc;
}
};
@ -537,7 +555,7 @@ const serviceToAdvert = (serv: BleServ, initial = false): BleServAdvert => {
if (hrm) {
o.value = encodeHrm(hrm);
os.value = SensorLocations.Wrist;
os.value = [SensorLocations.Wrist];
hrm = undefined;
}
@ -615,6 +633,25 @@ const serviceToAdvert = (serv: BleServ, initial = false): BleServAdvert => {
return o;
}
case BleServ.Acc: {
const o: BleServAdvert = {};
if (acc || initial) {
o[BleChar.Acc] = {
maxLen: encodeAcc.maxLen,
readable: true,
notify: true,
};
if (acc) {
o[BleChar.Acc]!.value = encodeAcc(acc);
acc = undefined;
}
}
return o;
}
}
};