mirror of
https://github.com/scratchfoundation/scratch-vm.git
synced 2024-12-24 06:52:40 -05:00
Fixing #1457: extension should parse incoming messages using port table.
This commit is contained in:
parent
d61f6e3d6f
commit
13edf16caa
1 changed files with 93 additions and 87 deletions
|
@ -59,6 +59,24 @@ const WeDo2Commands = {
|
||||||
SET_VOLUME: 255
|
SET_VOLUME: 255
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enum for modes for input sensors on the WeDo2.
|
||||||
|
* @enum {number}
|
||||||
|
*/
|
||||||
|
const WeDo2Modes = {
|
||||||
|
TILT: 0, // angle
|
||||||
|
DISTANCE: 0 // detect
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enum for units for input sensors on the WeDo2.
|
||||||
|
* @enum {number}
|
||||||
|
*/
|
||||||
|
const WeDo2Units = {
|
||||||
|
TILT: 0, // raw
|
||||||
|
DISTANCE: 1 // percent
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manage power, direction, and timers for one WeDo 2.0 motor.
|
* Manage power, direction, and timers for one WeDo 2.0 motor.
|
||||||
*/
|
*/
|
||||||
|
@ -503,90 +521,38 @@ class WeDo2 {
|
||||||
const data = Base64Util.base64ToUint8Array(base64);
|
const data = Base64Util.base64ToUint8Array(base64);
|
||||||
// log.info(data);
|
// log.info(data);
|
||||||
|
|
||||||
if (data.length === 2) { // disconnect sensor
|
/**
|
||||||
|
* If first byte of data is '1' or '2', then either clear the
|
||||||
|
* sensor present in ports 1 or 2 or set their format.
|
||||||
|
*
|
||||||
|
* If first byte of data is anything else, read incoming sensor value.
|
||||||
|
*/
|
||||||
|
switch (data[0]) {
|
||||||
|
case 1:
|
||||||
|
case 2: {
|
||||||
const connectID = data[0];
|
const connectID = data[0];
|
||||||
// zero out tilt
|
if (data[1] === 0) {
|
||||||
if (this._ports[connectID - 1] === WeDo2Types.TILT) {
|
// clear sensor or motor
|
||||||
this._sensors.tiltX = this._sensors.tiltY = 0;
|
this._clearPort(connectID);
|
||||||
}
|
} else {
|
||||||
// zero out distance
|
// register sensor or motor
|
||||||
if (this._ports[connectID - 1] === WeDo2Types.DISTANCE) {
|
this._registerSensorOrMotor(connectID, data[3]);
|
||||||
this._sensors.distance = 0;
|
|
||||||
}
|
|
||||||
// remove references to ports and motors
|
|
||||||
if (connectID === 1 || connectID === 2) {
|
|
||||||
this._ports[connectID - 1] = 'none';
|
|
||||||
this._motors[connectID - 1] = null;
|
|
||||||
// log.info(`this._ports = ${this._ports}`);
|
|
||||||
// log.info(`this._motors = ${this._mtors}`);
|
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
default: {
|
||||||
if (data.length === 3) { // distance sensor value?
|
// read incoming sensor value
|
||||||
this._sensors.distance = data[2];
|
const connectID = data[1];
|
||||||
}
|
const type = this._ports[connectID - 1];
|
||||||
|
|
||||||
if (data.length === 4) { // tilt sensor value?
|
|
||||||
this._sensors.tiltX = data[2];
|
|
||||||
this._sensors.tiltY = data[3];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data.length === 12) { // attached io?
|
|
||||||
|
|
||||||
const connectID = data[0];
|
|
||||||
const type = data[3];
|
|
||||||
|
|
||||||
// Record which port is connected to what type of device
|
|
||||||
if (connectID === 1 || connectID === 2) {
|
|
||||||
this._ports[connectID - 1] = type;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Motor
|
|
||||||
if (type === WeDo2Types.MOTOR) {
|
|
||||||
this._motors[connectID - 1] = new WeDo2Motor(this, connectID - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tilt Sensor
|
|
||||||
if (type === WeDo2Types.TILT) {
|
|
||||||
const cmd = new Uint8Array(11);
|
|
||||||
cmd[0] = 1; // sensor format
|
|
||||||
cmd[1] = 2; // command type: write
|
|
||||||
cmd[2] = connectID; // connect id
|
|
||||||
cmd[3] = WeDo2Types.TILT; // type
|
|
||||||
cmd[4] = 0; // mode: angle
|
|
||||||
cmd[5] = 1; // delta interval, 4 bytes
|
|
||||||
cmd[6] = 0;
|
|
||||||
cmd[7] = 0;
|
|
||||||
cmd[8] = 0;
|
|
||||||
cmd[9] = 0; // unit: raw
|
|
||||||
cmd[10] = 1; // notifications enabled: true
|
|
||||||
|
|
||||||
this._send(UUID.INPUT_COMMAND, Base64Util.uint8ArrayToBase64(cmd))
|
|
||||||
.then(() => {
|
|
||||||
this._ble.read(UUID.IO_SERVICE, UUID.INPUT_VALUES, true, this._onMessage.bind(this));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Distance Sensor
|
|
||||||
if (type === WeDo2Types.DISTANCE) {
|
if (type === WeDo2Types.DISTANCE) {
|
||||||
const cmd = new Uint8Array(11);
|
this._sensors.distance = data[2];
|
||||||
cmd[0] = 1; // sensor format
|
|
||||||
cmd[1] = 2; // command type: write
|
|
||||||
cmd[2] = connectID; // connect id
|
|
||||||
cmd[3] = WeDo2Types.DISTANCE; // type
|
|
||||||
cmd[4] = 0; // mode: detect
|
|
||||||
cmd[5] = 1; // delta interval, 4 bytes
|
|
||||||
cmd[6] = 0;
|
|
||||||
cmd[7] = 0;
|
|
||||||
cmd[8] = 0;
|
|
||||||
cmd[9] = 1; // unit: percent
|
|
||||||
cmd[10] = 1; // notifications enabled: true
|
|
||||||
|
|
||||||
this._send(UUID.INPUT_COMMAND, Base64Util.uint8ArrayToBase64(cmd))
|
|
||||||
.then(() => {
|
|
||||||
this._ble.read(UUID.IO_SERVICE, UUID.INPUT_VALUES, true, this._onMessage.bind(this));
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
if (type === WeDo2Types.TILT) {
|
||||||
|
this._sensors.tiltX = data[2];
|
||||||
|
this._sensors.tiltY = data[3];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -603,17 +569,57 @@ class WeDo2 {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the volume for the piezo.
|
* Clear the sensor or motor present at port 1 or 2.
|
||||||
|
* @param {number} connectID - the port to clear.
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
_setVolume () {
|
_clearPort (connectID) {
|
||||||
const cmd = new Uint8Array(4);
|
const type = this._ports[connectID - 1];
|
||||||
cmd[0] = WeDo2ConnectIDs.PIEZO; // connect id
|
if (type === WeDo2Types.TILT) {
|
||||||
cmd[1] = WeDo2Commands.SET_VOLUME; // command
|
this._sensors.tiltX = this._sensors.tiltY = 0;
|
||||||
cmd[2] = 1; // 1 byte to follow
|
}
|
||||||
cmd[3] = 100; // volume in range 0-100
|
if (type === WeDo2Types.DISTANCE) {
|
||||||
|
this._sensors.distance = 0;
|
||||||
|
}
|
||||||
|
this._ports[connectID - 1] = 'none';
|
||||||
|
this._motors[connectID - 1] = null;
|
||||||
|
}
|
||||||
|
|
||||||
this._send(UUID.OUTPUT_COMMAND, Base64Util.uint8ArrayToBase64(cmd));
|
/**
|
||||||
|
* Register a new sensor or motor connected at a port. Store the type of
|
||||||
|
* sensor or motor internally, and then register for notifications on input
|
||||||
|
* values if it is a sensor.
|
||||||
|
* @param {number} connectID - the port to register a sensor or motor on.
|
||||||
|
* @param {number} type - the type ID of the sensor or motor
|
||||||
|
*/
|
||||||
|
_registerSensorOrMotor (connectID, type) {
|
||||||
|
// Record which port is connected to what type of device
|
||||||
|
this._ports[connectID - 1] = type;
|
||||||
|
|
||||||
|
// Register motor
|
||||||
|
if (type === WeDo2Types.MOTOR) {
|
||||||
|
this._motors[connectID - 1] = new WeDo2Motor(this, connectID - 1);
|
||||||
|
} else {
|
||||||
|
// Register tilt or distance sensor
|
||||||
|
const typeString = type === WeDo2Types.DISTANCE ? 'DISTANCE' : 'TILT';
|
||||||
|
const cmd = new Uint8Array(11);
|
||||||
|
cmd[0] = 1; // sensor format
|
||||||
|
cmd[1] = 2; // command type: write
|
||||||
|
cmd[2] = connectID; // connect id
|
||||||
|
cmd[3] = type; // type
|
||||||
|
cmd[4] = WeDo2Modes[typeString]; // mode
|
||||||
|
cmd[5] = 1; // delta interval, 4 bytes, 1 = continuous updates
|
||||||
|
cmd[6] = 0;
|
||||||
|
cmd[7] = 0;
|
||||||
|
cmd[8] = 0;
|
||||||
|
cmd[9] = WeDo2Units[typeString]; // unit
|
||||||
|
cmd[10] = 1; // notifications enabled: true
|
||||||
|
|
||||||
|
this._send(UUID.INPUT_COMMAND, Base64Util.uint8ArrayToBase64(cmd))
|
||||||
|
.then(() => {
|
||||||
|
this._ble.read(UUID.IO_SERVICE, UUID.INPUT_VALUES, true, this._onMessage.bind(this));
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in a new issue