Made Control+ tilt and accelerometer behave like normal devices

This commit is contained in:
Nathan Kellenicki 2019-11-11 11:01:10 -08:00
parent 6315f54a23
commit 8ff0664641
7 changed files with 138 additions and 35 deletions

View File

@ -0,0 +1,89 @@
<!DOCTYPE html>
<html>
<head>
<title>4x4 Crawler / PlayStation DualShock 4 Remote Control</title>
<!-- <script src="https://cdn.jsdelivr.net/npm/node-poweredup@latest/dist/browser/poweredup.js"></script> -->
<script src="../dist/browser/poweredup.js"></script>
<link rel="stylesheet" type="text/css" href="./web_bluetooth.css" />
<script>
const poweredUP = new PoweredUP.PoweredUP();
let car = null;
let controller = null;
poweredUP.on("discover", async (hub) => { // Wait to discover car
if (hub instanceof PoweredUP.ControlPlusHub) {
car = hub;
await car.connect();
car.setLEDColor(PoweredUP.Consts.Color.BLUE);
document.getElementById("color").style.backgroundColor = PoweredUP.Consts.ColorNames[PoweredUP.Consts.Color.BLUE];
console.log(`Connected to 4x4 Crawler (${car.name})!`);
}
if (car && controller) {
console.log("You're now ready to go!");
}
});
const scan = function () {
if (PoweredUP.isWebBluetooth) {
poweredUP.scan(); // Start scanning for hubs
} else {
alert("Your browser does not support the Web Bluetooth specification.");
}
}
window.addEventListener("gamepadconnected", (event) => {
controller = event.gamepad;
if (!(controller.id.indexOf("54c") >= 0 && controller.id.indexOf("5c4") >= 0)) {
return;
}
console.log("Connected to PlayStation DualShock 4!");
let start = null;
let previousLeft = 0;
let previousForward = 0;
const inputLoop = async () => {
controller = navigator.getGamepads()[0];
if (car) {
const left = Math.floor(100 * (controller.axes[0] * -1));
const forward = -(Math.floor(100 * (controller.axes[3] * -1)));
if (forward !== previousForward) {
car.setMotorSpeed("A", forward); // Move tracks based on analog stick input
car.setMotorSpeed("B", forward); // Move tracks based on analog stick input
previousLeft = left;
previousForward = forward;
}
}
start = requestAnimationFrame(inputLoop);
}
inputLoop();
if (car && controller) {
console.log("You're now ready to go!");
}
});
</script>
</head>
<body>
<div><h1>4x4 Crawler / PlayStation DualShock 4 Remote Control</h1></div>
<div>
<a class="button" href="#" onclick="scan();">Scan for car</a>
</div>
<div id="current_color">
<span>Current Color: </span><div id="color">&nbsp;</div>
</div>
</body>
</html>

View File

@ -23,8 +23,12 @@ poweredUP.on("discover", async (hub) => {
console.log(`Disconnected ${hub.name}`);
})
hub.on("tilt", (port, x, y) => {
console.log(`Tilt detected on port ${port} (X: ${x}, Y: ${y})`);
hub.on("tilt", (port, x, y, z) => {
console.log(`Tilt detected on port ${port} (X: ${x}, Y: ${y}${z !== "undefined" ? `, Z: ${z}`: ""})`);
});
hub.on("accel", (port, x, y, z) => {
console.log(`Accelerometer detected on port ${port} (X: ${x}, Y: ${y}, Z: ${z})`);
});
hub.on("distance", (port, distance) => {

View File

@ -19,10 +19,15 @@ poweredUP.on("discover", async (hub) => { // Wait to discover hubs
log(`Disconnected ${hub.name}`);
})
hub.on("tilt", (port, x, y) => {
log(`Tilt detected on port ${port} (X: ${x}, Y: ${y})`);
hub.on("tilt", (port, x, y, z) => {
log(`Tilt detected on port ${port} (X: ${x}, Y: ${y}${z !== "undefined" ? `, Z: ${z}`: ""})`);
});
hub.on("accel", (port, x, y, z) => {
log(`Accelerometer detected on port ${port} (X: ${x}, Y: ${y}, Z: ${z})`);
});
hub.on("distance", (port, distance) => {
log(`Motion detected on port ${port} (Distance: ${distance})`);
});

View File

@ -47,6 +47,8 @@ export let HubTypeNames = Object.keys(HubType).reduce((result: {[hubType: string
* @property {number} CONTROL_PLUS_LARGE_MOTOR 46
* @property {number} CONTROL_PLUS_XLARGE_MOTOR 47
* @property {number} POWERED_UP_REMOTE_BUTTON 55
* @property {number} CONTROL_PLUS_ACCELEROMETER 58
* @property {number} CONTROL_PLUS_TILT 59
*/
export enum DeviceType {
UNKNOWN = 0,
@ -66,7 +68,9 @@ export enum DeviceType {
DUPLO_TRAIN_BASE_SPEEDOMETER = 44,
CONTROL_PLUS_LARGE_MOTOR = 46,
CONTROL_PLUS_XLARGE_MOTOR = 47,
POWERED_UP_REMOTE_BUTTON = 55
POWERED_UP_REMOTE_BUTTON = 55,
CONTROL_PLUS_ACCELEROMETER = 58,
CONTROL_PLUS_TILT = 59
}

View File

@ -39,7 +39,8 @@ export class ControlPlusHub extends LPF2Hub {
"B": new Port("B", 1),
"C": new Port("C", 2),
"D": new Port("D", 3),
// "TILT": new Port("TILT", 60)
"ACCEL": new Port("ACCEL", 98),
"TILT": new Port("TILT", 99)
};
this.on("attach", (port, type) => {
this._combinePorts(port, type);
@ -52,8 +53,6 @@ export class ControlPlusHub extends LPF2Hub {
return new Promise(async (resolve, reject) => {
debug("Connecting to Control+ Hub");
await super.connect();
this._writeMessage(Consts.BLECharacteristic.LPF2_ALL, Buffer.from([0x41, 0x62, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x01])); // Accelerometer
this._writeMessage(Consts.BLECharacteristic.LPF2_ALL, Buffer.from([0x41, 0x63, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01])); // Gyro/Tilt
this._writeMessage(Consts.BLECharacteristic.LPF2_ALL, Buffer.from([0x41, 0x3d, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x01])); // Temperature
debug("Connect completed");
return resolve();

View File

@ -395,6 +395,10 @@ export class Hub extends EventEmitter {
return 0x02;
case Consts.DeviceType.CONTROL_PLUS_XLARGE_MOTOR:
return 0x02;
case Consts.DeviceType.CONTROL_PLUS_TILT:
return 0x00;
case Consts.DeviceType.CONTROL_PLUS_ACCELEROMETER:
return 0x00;
case Consts.DeviceType.BOOST_DISTANCE:
return (this.type === Consts.HubType.WEDO2_SMART_HUB ? 0x00 : 0x08);
case Consts.DeviceType.BOOST_TILT:

View File

@ -407,33 +407,6 @@ export class LPF2Hub extends Hub {
return;
}
if ((data[3] === 0x62 && this.type === Consts.HubType.CONTROL_PLUS_HUB)) { // Control+ Accelerometer
const accelX = Math.round((data.readInt16LE(4) / 28571) * 2000);
const accelY = Math.round((data.readInt16LE(6) / 28571) * 2000);
const accelZ = Math.round((data.readInt16LE(8) / 28571) * 2000);
/**
* Emits when accelerometer detects movement. Measured in DPS - degrees per second.
* @event LPF2Hub#accel
* @param {string} port
* @param {number} x
* @param {number} y
* @param {number} z
*/
this.emit("accel", "ACCEL", accelX, accelY, accelZ);
return;
}
if ((data[3] === 0x63 && this.type === Consts.HubType.CONTROL_PLUS_HUB)) { // Control+ Accelerometer
const tiltZ = data.readInt16LE(4);
const tiltY = data.readInt16LE(6);
const tiltX = data.readInt16LE(8);
this._lastTiltX = tiltX;
this._lastTiltY = tiltY;
this._lastTiltZ = tiltZ;
this.emit("tilt", "TILT", this._lastTiltX, this._lastTiltY, this._lastTiltZ);
return;
}
if ((data[3] === 0x3d && this.type === Consts.HubType.CONTROL_PLUS_HUB)) { // Control+ CPU Temperature
/**
* Emits when a change is detected on a temperature sensor. Measured in degrees centigrade.
@ -544,6 +517,31 @@ export class LPF2Hub extends Hub {
this.emit("rotate", port.id, rotation);
break;
}
case Consts.DeviceType.CONTROL_PLUS_TILT: {
const tiltZ = data.readInt16LE(4);
const tiltY = data.readInt16LE(6);
const tiltX = data.readInt16LE(8);
this._lastTiltX = tiltX;
this._lastTiltY = tiltY;
this._lastTiltZ = tiltZ;
this.emit("tilt", "TILT", this._lastTiltX, this._lastTiltY, this._lastTiltZ);
break;
}
case Consts.DeviceType.CONTROL_PLUS_ACCELEROMETER: {
const accelX = Math.round((data.readInt16LE(4) / 28571) * 2000);
const accelY = Math.round((data.readInt16LE(6) / 28571) * 2000);
const accelZ = Math.round((data.readInt16LE(8) / 28571) * 2000);
/**
* Emits when accelerometer detects movement. Measured in DPS - degrees per second.
* @event LPF2Hub#accel
* @param {string} port
* @param {number} x
* @param {number} y
* @param {number} z
*/
this.emit("accel", "ACCEL", accelX, accelY, accelZ);
break;
}
case Consts.DeviceType.BOOST_TILT: {
const tiltX = data.readInt8(4);
const tiltY = data.readInt8(5);