bt-sensors-plugin-sk
Version:
Bluetooth Sensors for Signalk - see https://www.npmjs.com/package/bt-sensors-plugin-sk#supported-sensors for a list of supported sensors
136 lines (114 loc) • 5.09 kB
JavaScript
const BTSensor = require("../../BTSensor");
class WT901Sensor extends BTSensor {
static Domain = this.SensorDomains.environmental
static ManufacturerUUID = '0000ffe5-0000-1000-8000-00805f9a34fb'
static async identify(device){
const name = await this.getDeviceProp(device,"Name")
const uuids = await this.getDeviceProp(device,'UUIDs')
if (name && name.match(this.getIDRegex()) &&
uuids && uuids.length > 0 &&
uuids[0] == this.ManufacturerUUID)
return this
else
return null
}
getManufacturer(){
return "WitMotion"
}
wt901ReadReg(regAddr) {
return [0xff, 0xaa, 0x27, regAddr, 0x00];
}
/**
* Send read register command (used to get quaturnions)
*/
async sendCommand(regAddr) {
this.debug(`Sending command 0x${regAddr}`);
return await this.txChar.writeValue(
Buffer.from(this.wt901ReadReg(regAddr))
);
}
getSignInt16(num) {
if (num >= Math.pow(2, 15)) {
num -= Math.pow(2, 16);
}
return num;
}
processData(Bytes) {
if (Bytes[1] === 0x61) {
let Ax = this.getSignInt16((Bytes[3] << 8) | Bytes[2]) / 32768 * 16;
let Ay = this.getSignInt16((Bytes[5] << 8) | Bytes[4]) / 32768 * 16;
let Az = this.getSignInt16((Bytes[7] << 8) | Bytes[6]) / 32768 * 16;
let Gx = this.getSignInt16((Bytes[9] << 8) | Bytes[8]) / 32768 * 2000;
let Gy = this.getSignInt16((Bytes[11] << 8) | Bytes[10]) / 32768 * 2000;
let Gz = this.getSignInt16((Bytes[13] << 8) | Bytes[12]) / 32768 * 2000;
let AngX = this.getSignInt16((Bytes[15] << 8) | Bytes[14]) / 32768 * 180;
let AngY = this.getSignInt16((Bytes[17] << 8) | Bytes[16]) / 32768 * 180;
let AngZ = this.getSignInt16((Bytes[19] << 8) | Bytes[18]) / 32768 * 180;
this.set("AccX", Math.round(Ax * 1000) / 1000);
this.set("AccY", Math.round(Ay * 1000) / 1000);
this.set("AccZ", Math.round(Az * 1000) / 1000);
this.set("AsX", Math.round(Gx * 1000) / 1000);
this.set("AsY", Math.round(Gy * 1000) / 1000);
this.set("AsZ", Math.round(Gz * 1000) / 1000);
this.set("AngX", Math.round(AngX * 1000) / 1000);
this.set("AngY", Math.round(AngY * 1000) / 1000);
this.set("AngZ", Math.round(AngZ * 1000) / 1000);
//this.debugLog(this.data)
this.emitAttitude()
} else {
// magnetic field
if (Bytes[2] === 0x3A) {
let Hx = this.getSignInt16((Bytes[5] << 8) | Bytes[4]) / 120;
let Hy = this.getSignInt16((Bytes[7] << 8) | Bytes[6]) / 120;
let Hz = this.getSignInt16((Bytes[9] << 8) | Bytes[8]) / 120;
this.set("HX", Math.round(Hx * 1000) / 1000);
this.set("HY", Math.round(Hy * 1000) / 1000);
this.set("HZ", Math.round(Hz * 1000) / 1000);
}
// Quaternion
else if (Bytes[2] === 0x51) {
let Q0 = this.getSignInt16((Bytes[5] << 8) | Bytes[4]) / 32768;
let Q1 = this.getSignInt16((Bytes[7] << 8) | Bytes[6]) / 32768;
let Q2 = this.getSignInt16((Bytes[9] << 8) | Bytes[8]) / 32768;
let Q3 = this.getSignInt16((Bytes[11] << 8) | Bytes[10]) / 32768;
this.set("Q0", Math.round(Q0 * 100000) / 100000);
this.set("Q1", Math.round(Q1 * 100000) / 100000);
this.set("Q2", Math.round(Q2 * 100000) / 100000);
this.set("Q3", Math.round(Q3 * 100000) / 100000);
} else {
// pass
}
}
}
set(key, value) {
// Implement your set method here
this.data[key] = value;
}
quaternionToEuler(q_w, q_x, q_y, q_z) {
// Roll (x-axis rotation)
const roll = Math.atan2(2 * (q_w * q_x + q_y * q_z), 1 - 2 * (q_x ** 2 + q_y ** 2));
// Pitch (y-axis rotation)
const pitch = Math.asin(2 * (q_w * q_y - q_z * q_x));
// Yaw (z-axis rotation)
const yaw = Math.atan2(2 * (q_w * q_z + q_x * q_y), 1 - 2 * (q_y ** 2 + q_z ** 2));
return [roll, pitch, yaw];
}
degreesToRadians(deg) {
return deg * (Math.PI / 180);
}
emitAttitude(packedValue, tempIsNegative ){
//const att = this.quaternionToEuler(this.data.Q0,this.data.Q1,this.data.Q2,this.data.Q3)
this.emit("roll", this.degreesToRadians(this.data.AngX))
this.emit("pitch", this.degreesToRadians(this.data.AngY))
this.emit("yaw", this.degreesToRadians(this.data.AngZ))
}
async propertiesChanged(props){
super.propertiesChanged(props)
if (!props.hasOwnProperty("ManufacturerData")) return
const buffer = this.getManufacturerData(this.constructor.DATA_ID)
if (buffer) {
this.emitValuesFrom(buffer)
}
}
}
module.exports=WT901Sensor