diff --git a/src/colordistancesensor.ts b/src/colordistancesensor.ts index e1633be..2d2fc6d 100644 --- a/src/colordistancesensor.ts +++ b/src/colordistancesensor.ts @@ -12,19 +12,65 @@ export class ColorDistanceSensor extends Device { if (this.autoSubscribe) { switch (event) { case "color": - this.subscribe(0x00); + this.subscribe(0x08); break; case "distance": - this.subscribe(0x01); + this.subscribe(0x08); + break; + case "colorAndDistance": + this.subscribe(0x08); break; } } }); - } public receive (message: Buffer) { - // NK TODO + const mode = this._mode; + + switch (mode) { + case 0x08: + /** + * Emits when a color sensor is activated. + * @event ColorDistanceSensor#color + * @param {string} port + * @param {Color} color + */ + if (message[4] <= 10) { + const color = message[4]; + this.emit("color", color); + } + + let distance = message[5]; + const partial = message[7]; + + if (partial > 0) { + distance += 1.0 / partial; + } + + distance = Math.floor(distance * 25.4) - 20; + + /** + * Emits when a distance sensor is activated. + * @event ColorDistanceSensor#distance + * @param {string} port + * @param {number} distance Distance, in millimeters. + */ + this.emit("distance", distance); + + /** + * A combined color and distance event, emits when the sensor is activated. + * @event ColorDistanceSensor#colorAndDistance + * @param {string} port + * @param {Color} color + * @param {number} distance Distance, in millimeters. + */ + if (message[4] <= 10) { + const color = message[4]; + this.emit("colorAndDistance", color, distance); + } + break; + } } } diff --git a/src/controlpluslargemotor.ts b/src/controlpluslargemotor.ts index 8fcccec..66077b7 100644 --- a/src/controlpluslargemotor.ts +++ b/src/controlpluslargemotor.ts @@ -2,8 +2,9 @@ import { BasicMotor } from "./basicmotor"; import { Hub } from "./hub"; import * as Consts from "./consts"; +import { TachoMotor } from "./tachomotor"; -export class ControlPlusLargeMotor extends BasicMotor { +export class ControlPlusLargeMotor extends TachoMotor { constructor (hub: Hub, portId: number) { super(hub, portId, Consts.DeviceType.CONTROL_PLUS_LARGE_MOTOR); diff --git a/src/device.ts b/src/device.ts index 1579c74..bbf8760 100644 --- a/src/device.ts +++ b/src/device.ts @@ -7,6 +7,8 @@ export class Device extends EventEmitter { public autoSubscribe: boolean = true; + protected _mode: number = 0x00; + private _hub: Hub; private _portId: number; private _connected: boolean = true; @@ -57,7 +59,10 @@ export class Device extends EventEmitter { } public subscribe (mode: number) { - this.send(Buffer.from([0x41, this.portId, mode, 0x01, 0x00, 0x00, 0x00, 0x01])); + if (mode !== this._mode) { + this._mode = mode; + this.send(Buffer.from([0x41, this.portId, mode, 0x01, 0x00, 0x00, 0x00, 0x01])); + } } public receive (message: Buffer) { diff --git a/src/tachomotor.ts b/src/tachomotor.ts new file mode 100644 index 0000000..32240cd --- /dev/null +++ b/src/tachomotor.ts @@ -0,0 +1,55 @@ +import { BasicMotor } from "./basicmotor"; +import { Hub } from "./hub"; + +import * as Consts from "./consts"; +import { mapSpeed } from "./utils"; + +export class TachoMotor extends BasicMotor { + + constructor (hub: Hub, portId: number, type: number = Consts.DeviceType.UNKNOWN) { + super(hub, portId, type); + + this.on("newListener", (event) => { + if (this.autoSubscribe) { + switch (event) { + case "rotate": + this.subscribe(0x02); + break; + } + } + }); + } + + public receive (message: Buffer) { + const mode = this._mode; + + switch (mode) { + case 0x02: + const rotation = message.readInt32LE(4); + /** + * Emits when a rotation sensor is activated. + * @event TachoMotor#rotate + * @param {number} rotation + */ + this.emit("rotate", rotation); + break; + } + } + + /** + * Rotate a motor by a given angle. + * @method TachoMotor#setMotorAngle + * @param {number} angle How much the motor should be rotated (in degrees). + * @param {number} [speed=100] For forward, a value between 1 - 100 should be set. For reverse, a value between -1 to -100. + * @returns {Promise} Resolved upon successful completion of command (ie. once the motor is finished). + */ + public rotateByAngle (port: string, angle: number, speed: number = 100) { + return new Promise((resolve) => { + const message = Buffer.from([0x81, this.portId, 0x11, 0x0b, 0x00, 0x00, 0x00, 0x00, mapSpeed(speed), 0x64, 0x7f, 0x03]); + message.writeUInt32LE(angle, 4); + this.send(message); + return resolve(); + }); + } + +}