diff --git a/libs/core/_locales/core-jsdoc-strings.json b/libs/core/_locales/core-jsdoc-strings.json index 37e6da8a..24fc79ec 100644 --- a/libs/core/_locales/core-jsdoc-strings.json +++ b/libs/core/_locales/core-jsdoc-strings.json @@ -9,6 +9,7 @@ "MMap.setNumber": "Write a number in specified format in the buffer.", "MMap.slice": "Read a range of bytes into a buffer.", "MMap.write": "Perform write(2) on the underlaying file", + "TouchSensorEvent": "Touch sensor interactions", "control": "Program controls and events.", "control.allocateNotifyEvent": "Allocates the next user notification event", "control.deviceFirmwareVersion": "Determine the version of system software currently running.", @@ -23,15 +24,22 @@ "input.Button.onEvent": "Do something when a button or sensor is clicked, double clicked, etc...", "input.Button.onEvent|param|body": "code to run when the event is raised", "input.Button.wasPressed": "See if the button was pressed again since the last time you checked.", - "input.ColorSensor.getAmbientLight": "Get current ambient light value from the color sensor.", - "input.ColorSensor.getColor": "Get the current color from the color sensor.", - "input.ColorSensor.getReflectedLight": "Get current reflected light value from the color sensor.", - "input.UltraSonicSensor.getDistance": "Get distance in mm", - "input.buttonDown": "Down button.", - "input.buttonEnter": "Enter button.", - "input.buttonLeft": "Left button.", - "input.buttonRight": "Right button.", - "input.buttonUp": "Up button.", + "input.ColorSensor.ambientLight": "Get current ambient light value from the color sensor.", + "input.ColorSensor.color": "Get the current color from the color sensor.", + "input.ColorSensor.reflectedLight": "Get current reflected light value from the color sensor.", + "input.GyroSensor.angle": "Get the current angle from the gyroscope.", + "input.GyroSensor.rate": "Get the current rotation rate from the gyroscope.", + "input.IrSensor.distance": "Get the distance measured by the infrared sensor.", + "input.IrSensor.remoteCommand": "Get the remote commandreceived the infrared sensor.", + "input.TouchSensor.isTouched": "Check if touch sensor is touched.", + "input.TouchSensor.onEvent": "Do something when a touch sensor is touched...", + "input.TouchSensor.onEvent|param|body": "code to run when the event is raised", + "input.UltraSonicSensor.distance": "Gets the distance from the sonar in millimeters", + "input.buttonDown": "Down button on the EV3 Brick.", + "input.buttonEnter": "Enter button on the EV3 Brick.", + "input.buttonLeft": "Left button on the EV3 Brick.", + "input.buttonRight": "Right button on the EV3 Brick.", + "input.buttonUp": "Up button on the EV3 Brick.", "input.remoteBottomLeft": "Remote bottom-left button.", "input.remoteBottomRight": "Remote bottom-right button.", "input.remoteCenter": "Remote beacon (center) button.", @@ -41,19 +49,19 @@ "output.createBuffer|param|size": "number of bytes in the buffer", "output.getCurrentSpeed": "Get motor speed.", "output.getCurrentSpeed|param|out": "the output connection that the motor is connected to", - "output.getPattern": "Pattern block.", - "output.getPattern|param|pattern": "the lights pattern to use. eg: LightsPattern.Green", - "output.setLights": "Set lights.", - "output.setLights|param|pattern": "the lights pattern to use.", + "output.pattern": "Pattern block.", + "output.pattern|param|pattern": "the lights pattern to use. eg: LightsPattern.Green", + "output.powerMotor": "Switch the motor on or off.", + "output.powerMotor|param|on": "1 to turn the motor on, 0 to turn it off", + "output.powerMotor|param|out": "the output connection that the motor is connected to", "output.setPower": "Set motor power.", "output.setPower|param|out": "the output connection that the motor is connected to", "output.setPower|param|power": "the desired power to use. eg: 100", "output.setSpeed": "Set motor speed.", "output.setSpeed|param|out": "the output connection that the motor is connected to", "output.setSpeed|param|speed": "the desired speed to use. eg: 100", - "output.switchMotor": "Switch the motor on or off.", - "output.switchMotor|param|on": "1 to turn the motor on, 0 to turn it off", - "output.switchMotor|param|out": "the output connection that the motor is connected to", + "output.setStatusLight": "Set lights.", + "output.setStatusLight|param|pattern": "the lights pattern to use.", "output.turn": "Turn a motor on for a specified number of milliseconds.", "output.turn|param|ms": "the number of milliseconds to turn the motor on, eg: 500", "output.turn|param|out": "the output connection that the motor is connected to", @@ -61,10 +69,10 @@ "screen.clear": "Clear screen and reset font to normal.", "screen.doubleIcon": "Double size of an icon.", "screen.drawIcon": "Draw an icon on the screen.", - "screen.drawText": "Show text on the screen.", - "screen.drawText|param|text": "the text to print on the screen, eg: \"Hello world\"", - "screen.drawText|param|x": "the starting position's x coordinate, eg: 0", - "screen.drawText|param|y": "the starting position's x coordinate, eg: 0", + "screen.print": "Show text on the screen.", + "screen.print|param|text": "the text to print on the screen, eg: \"Hello world\"", + "screen.print|param|x": "the starting position's x coordinate, eg: 0", + "screen.print|param|y": "the starting position's x coordinate, eg: 0", "serial": "Reading and writing data over a serial connection.", "serial.writeDmesg": "Send DMESG debug buffer over serial." } \ No newline at end of file diff --git a/libs/core/_locales/core-strings.json b/libs/core/_locales/core-strings.json index 14c4dc5f..7d3dea98 100644 --- a/libs/core/_locales/core-strings.json +++ b/libs/core/_locales/core-strings.json @@ -1,7 +1,6 @@ { "ButtonEvent.Click|block": "click", "ButtonEvent.Down|block": "down", - "ButtonEvent.LongClick|block": "long click", "ButtonEvent.Up|block": "up", "LightsPattern.GreenFlash|block": "Flashing Green", "LightsPattern.GreenPulse|block": "Pulsing Green", @@ -13,36 +12,60 @@ "LightsPattern.RedFlash|block": "Flashing Red", "LightsPattern.RedPulse|block": "Pulsing Red", "LightsPattern.Red|block": "Red", + "TouchSensorEvent.Bumped|block": "bumped", + "TouchSensorEvent.Released|block": "released", + "TouchSensorEvent.Touched|block": "touched", "control.raiseEvent|block": "raise event|from %src|with value %value", "control|block": "control", "input.Button.isPressed|block": "%button|is pressed", "input.Button.onEvent|block": "on %button|%event", "input.Button.wasPressed|block": "%button|was pressed", - "input.ColorSensor.getAmbientLight|block": "%color| ambient light", - "input.ColorSensor.getColor|block": "%color| color", - "input.ColorSensor.getReflectedLight|block": "%color| reflected light", - "input.buttonDown|block": "button down", - "input.buttonEnter|block": "button enter", - "input.buttonLeft|block": "button left", - "input.buttonRight|block": "button right", - "input.buttonUp|block": "button up", - "input.color|block": "color sensor", + "input.ColorSensor.ambientLight|block": "%color| ambient light", + "input.ColorSensor.color|block": "%color| color", + "input.ColorSensor.reflectedLight|block": "%color| reflected light", + "input.GyroSensor.angle|block": "%sensor|angle", + "input.GyroSensor.rate|block": "%sensor|rotation rate", + "input.IrSensor.distance|block": "%infrared|distance", + "input.IrSensor.remoteCommand|block": "%infrared|remote command", + "input.TouchSensor.isTouched|block": "%sensor|is touched", + "input.TouchSensor.onEvent|block": "on %sensor|%event", + "input.UltraSonicSensor.distance|block": "%sensor|distance", + "input.buttonDown|block": "brick button down", + "input.buttonEnter|block": "brick button enter", + "input.buttonLeft|block": "brick button left", + "input.buttonRight|block": "brick button right", + "input.buttonUp|block": "brick button up", + "input.color1|block": "color sensor 1", + "input.color2|block": "color sensor 2", + "input.color3|block": "color sensor 3", + "input.color4|block": "color sensor 4", + "input.gyro1|block": "gyro sensor 1", + "input.gyro2|block": "gyro sensor 2", + "input.gyro3|block": "gyro sensor 3", + "input.gyro4|block": "gyro sensor 4", "input.remoteBottomLeft|block": "remote bottom-left", "input.remoteBottomRight|block": "remote bottom-right", "input.remoteCenter|block": "remote center", "input.remoteTopLeft|block": "remote top-left", "input.remoteTopRight|block": "remote top-right", - "input.touchSensor|block": "touch sensor", + "input.touchSensor1|block": "touch sensor 1", + "input.touchSensor2|block": "touch sensor 2", + "input.touchSensor3|block": "touch sensor 3", + "input.touchSensor4|block": "touch sensor 4", + "input.ultrasonic1|block": "ultrasonic sensor 1", + "input.ultrasonic2|block": "ultrasonic sensor 2", + "input.ultrasonic3|block": "ultrasonic sensor 3", + "input.ultrasonic4|block": "ultrasonic sensor 4", "input|block": "input", "output.getCurrentSpeed|block": "motor %out|speed", - "output.getPattern|block": "%pattern", - "output.setLights|block": "set status light %pattern=led_pattern", + "output.pattern|block": "%pattern", + "output.powerMotor|block": "power motor %out|%on", "output.setPower|block": "set motor %out| power to %power", "output.setSpeed|block": "set motor %out| speed to %speed", - "output.switchMotor|block": "turn motor %out|%on", - "output.turn|block": "turn motor %out| on for %ms|milliseconds", + "output.setStatusLight|block": "set status light %pattern=led_pattern", + "output.turn|block": "turn motor %out| on for %ms=timePicker|milliseconds", "output|block": "output", - "screen.drawText|block": "print %text| at x: %x| y: %y", + "screen.print|block": "print %text| at x: %x| y: %y", "screen|block": "screen", "serial|block": "serial", "{id:category}Control": "Control", @@ -51,7 +74,11 @@ "{id:category}Output": "Output", "{id:category}Screen": "Screen", "{id:category}Serial": "Serial", - "{id:group}Lights": "Lights", + "{id:group}Brick": "Brick", + "{id:group}Color Sensor": "Color Sensor", + "{id:group}Gyro Sensor": "Gyro Sensor", + "{id:group}Infrared Sensor": "Infrared Sensor", "{id:group}Motors": "Motors", - "{id:group}Screen": "Screen" + "{id:group}Touch Sensor": "Touch Sensor", + "{id:group}Ultrasonic Sensor": "Ultrasonic Sensor" } \ No newline at end of file diff --git a/libs/core/buttons.ts b/libs/core/buttons.ts index 27fc5076..c2c84cbe 100644 --- a/libs/core/buttons.ts +++ b/libs/core/buttons.ts @@ -4,34 +4,34 @@ */ const enum LightsPattern { //% block=Off enumval=0 - //% blockIdentity=output.getPattern + //% blockIdentity=output.pattern Off = 0, //% block=Green enumval=1 - //% blockIdentity=output.getPattern + //% blockIdentity=output.pattern Green = 1, //% block=Red enumval=2 - //% blockIdentity=output.getPattern + //% blockIdentity=output.pattern Red = 2, //% block=Orange enumval=3 - //% blockIdentity=output.getPattern + //% blockIdentity=output.pattern Orange = 3, //% block="Flashing Green" enumval=4 - //% blockIdentity=output.getPattern + //% blockIdentity=output.pattern GreenFlash = 4, //% block="Flashing Red" enumval=5 - //% blockIdentity=output.getPattern + //% blockIdentity=output.pattern RedFlash = 5, //% block="Flashing Orange" enumval=6 - //% blockIdentity=output.getPattern + //% blockIdentity=output.pattern OrangeFlash = 6, //% block="Pulsing Green" enumval=7 - //% blockIdentity=output.getPattern + //% blockIdentity=output.pattern GreenPulse = 7, //% block="Pulsing Red" enumval=8 - //% blockIdentity=output.getPattern + //% blockIdentity=output.pattern RedPulse = 8, //% block="Pulsing Orange" enumval=9 - //% blockIdentity=output.getPattern + //% blockIdentity=output.pattern OrangePulse = 9, } @@ -41,8 +41,6 @@ const enum LightsPattern { const enum ButtonEvent { //% block="click" Click = 1, - //% block="long click" - LongClick = 2, //% block="up" Up = 3, //% block="down" @@ -76,7 +74,8 @@ namespace input { } else { control.raiseEvent(this._id, ButtonEvent.Up) let delta = control.millis() - this.downTime - control.raiseEvent(this._id, delta > 500 ? ButtonEvent.LongClick : ButtonEvent.Click) + control.raiseEvent(this._id, ButtonEvent.Click) + //control.raiseEvent(this._id, delta > 500 ? ButtonEvent.LongClick : ButtonEvent.Click) } } @@ -87,12 +86,10 @@ namespace input { //% help=input/button/is-pressed //% block="%button|is pressed" //% blockId=buttonIsPressed - //% parts="buttonpair" + //% parts="brick" //% blockNamespace=input - //% button.fieldEditor="gridpicker" - //% button.fieldOptions.width=220 - //% button.fieldOptions.columns=3 //% weight=81 blockGap=8 + //% group="Brick" isPressed() { return this._isPressed } @@ -104,12 +101,10 @@ namespace input { //% help=input/button/was-pressed //% block="%button|was pressed" //% blockId=buttonWasPressed - //% parts="buttonpair" + //% parts="brick" //% blockNamespace=input - //% button.fieldEditor="gridpicker" - //% button.fieldOptions.width=220 - //% button.fieldOptions.columns=3 //% weight=80 blockGap=8 + //% group="Brick" wasPressed() { const r = this._wasPressed this._wasPressed = false @@ -124,12 +119,10 @@ namespace input { */ //% help=input/button/on-event //% blockId=buttonEvent block="on %button|%event" - //% parts="buttonpair" + //% parts="brick" //% blockNamespace=input - //% button.fieldEditor="gridpicker" - //% button.fieldOptions.width=220 - //% button.fieldOptions.columns=3 - //% weight=99 + //% weight=99 blockGap=8 + //% group="Brick" onEvent(ev: ButtonEvent, body: () => void) { control.onEvent(this._id, ev, body) } @@ -183,35 +176,36 @@ namespace input { initBtns() // always ON as it handles ESCAPE button + /** - * Left button. + * Enter button on the EV3 Brick. */ - //% whenUsed block="button left" weight=95 fixedInstance + //% whenUsed block="brick button enter" weight=95 fixedInstance + export const buttonEnter: Button = new DevButton(DAL.BUTTON_ID_ENTER) + + /** + * Left button on the EV3 Brick. + */ + //% whenUsed block="brick button left" weight=95 fixedInstance export const buttonLeft: Button = new DevButton(DAL.BUTTON_ID_LEFT) /** - * Right button. + * Right button on the EV3 Brick. */ - //% whenUsed block="button right" weight=94 fixedInstance + //% whenUsed block="brick button right" weight=94 fixedInstance export const buttonRight: Button = new DevButton(DAL.BUTTON_ID_RIGHT) /** - * Up button. + * Up button on the EV3 Brick. */ - //% whenUsed block="button up" weight=95 fixedInstance + //% whenUsed block="brick button up" weight=95 fixedInstance export const buttonUp: Button = new DevButton(DAL.BUTTON_ID_UP) /** - * Down button. + * Down button on the EV3 Brick. */ - //% whenUsed block="button down" weight=95 fixedInstance + //% whenUsed block="brick button down" weight=95 fixedInstance export const buttonDown: Button = new DevButton(DAL.BUTTON_ID_DOWN) - - /** - * Enter button. - */ - //% whenUsed block="button enter" weight=95 fixedInstance - export const buttonEnter: Button = new DevButton(DAL.BUTTON_ID_ENTER) } @@ -240,8 +234,8 @@ namespace output { * @param pattern the lights pattern to use. */ //% blockId=setLights block="set status light %pattern=led_pattern" - //% weight=100 group="Lights" - export function setLights(pattern: number): void { + //% weight=100 group="Brick" + export function setStatusLight(pattern: number): void { if (currPattern === pattern) return currPattern = pattern @@ -258,7 +252,7 @@ namespace output { //% blockId=led_pattern block="%pattern" //% shim=TD_ID colorSecondary="#6e9a36" //% blockHidden=true useEnumVal=1 pattern.fieldOptions.decompileLiterals=1 - export function getPattern(pattern: LightsPattern): number { + export function pattern(pattern: LightsPattern): number { return pattern; } } diff --git a/libs/core/color.ts b/libs/core/color.ts index 1c5a5633..a7051e11 100644 --- a/libs/core/color.ts +++ b/libs/core/color.ts @@ -23,8 +23,8 @@ namespace input { //% fixedInstances export class ColorSensor extends internal.UartSensor { - constructor() { - super() + constructor(port: number) { + super(port) } _deviceType() { @@ -45,7 +45,8 @@ namespace input { //% parts="colorsensor" //% blockNamespace=input //% weight=65 blockGap=8 - getAmbientLight() { + //% group="Color Sensor" + ambientLight() { this.setMode(ColorSensorMode.Ambient) return this.getNumber(NumberFormat.UInt8LE, 0) } @@ -60,7 +61,8 @@ namespace input { //% parts="colorsensor" //% blockNamespace=input //% weight=64 blockGap=8 - getReflectedLight(): number { + //% group="Color Sensor" + reflectedLight(): number { this.setMode(ColorSensorMode.Reflect) return this.getNumber(NumberFormat.UInt8LE, 0) } @@ -75,12 +77,22 @@ namespace input { //% parts="colorsensor" //% blockNamespace=input //% weight=66 blockGap=8 - getColor(): ColorSensorColor { + //% group="Color Sensor" + color(): ColorSensorColor { this.setMode(ColorSensorMode.Color) return this.getNumber(NumberFormat.UInt8LE, 0) } } - //% whenUsed block="color sensor" weight=95 fixedInstance - export const color: ColorSensor = new ColorSensor() + //% whenUsed block="color sensor 3" weight=95 fixedInstance + export const color3: ColorSensor = new ColorSensor(3) + + //% whenUsed block="color sensor 1" weight=95 fixedInstance + export const color1: ColorSensor = new ColorSensor(1) + + //% whenUsed block="color sensor 2" weight=95 fixedInstance + export const color2: ColorSensor = new ColorSensor(2) + + //% whenUsed block="color sensor 4" weight=95 fixedInstance + export const color4: ColorSensor = new ColorSensor(4) } diff --git a/libs/core/gyro.ts b/libs/core/gyro.ts index c58c94d0..3f0b5ed8 100644 --- a/libs/core/gyro.ts +++ b/libs/core/gyro.ts @@ -5,9 +5,10 @@ const enum GyroSensorMode { } namespace input { + //% fixedInstances export class GyroSensor extends internal.UartSensor { - constructor() { - super() + constructor(port: number) { + super(port) } _deviceType() { @@ -18,17 +19,48 @@ namespace input { this._setMode(m) } - getAngle() { + /** + * Get the current angle from the gyroscope. + * @param sensor the gyroscope to query the request + */ + //% help=input/gyro/angle + //% block="%sensor|angle" + //% blockId=gyroGetAngle + //% parts="gyroscope" + //% blockNamespace=input + //% weight=65 blockGap=8 + //% group="Gyro Sensor" + angle() { this.setMode(GyroSensorMode.Angle) return this.getNumber(NumberFormat.Int16LE, 0) } - getRate() { + /** + * Get the current rotation rate from the gyroscope. + * @param sensor the gyroscope to query the request + */ + //% help=input/gyro/rate + //% block="%sensor|rotation rate" + //% blockId=gyroGetRate + //% parts="gyroscope" + //% blockNamespace=input + //% weight=65 blockGap=8 + //% group="Gyro Sensor" + rate() { this.setMode(GyroSensorMode.Rate) return this.getNumber(NumberFormat.Int16LE, 0) } } - //% whenUsed - export const gyro: GyroSensor = new GyroSensor() + //% fixedInstance whenUsed block="gyro sensor 2" + export const gyro2: GyroSensor = new GyroSensor(2) + + //% fixedInstance whenUsed block="gyro sensor 1" + export const gyro1: GyroSensor = new GyroSensor(1) + + //% fixedInstance whenUsed block="gyro sensor 3" + export const gyro3: GyroSensor = new GyroSensor(3) + + //% fixedInstance whenUsed block="gyro sensor 4" + export const gyro4: GyroSensor = new GyroSensor(4) } diff --git a/libs/core/input.ts b/libs/core/input.ts index 53446d89..386b0238 100644 --- a/libs/core/input.ts +++ b/libs/core/input.ts @@ -27,30 +27,27 @@ namespace input.internal { let analogMM: MMap let uartMM: MMap let devcon: Buffer - let sensors: SensorInfo[] - let autoSensors: Sensor[] + let sensorInfos: SensorInfo[] class SensorInfo { port: number sensor: Sensor + sensors: Sensor[] connType: number devType: number - manual: boolean constructor(p: number) { this.port = p this.connType = DAL.CONN_NONE this.devType = DAL.DEVICE_TYPE_NONE - this.sensor = null - this.manual = false + this.sensors = [] } } function init() { - if (sensors) return - sensors = [] - for (let i = 0; i < DAL.NUM_INPUTS; ++i) sensors.push(new SensorInfo(i)) - autoSensors = [] + if (sensorInfos) return + sensorInfos = [] + for (let i = 0; i < DAL.NUM_INPUTS; ++i) sensorInfos.push(new SensorInfo(i)) devcon = output.createBuffer(DevConOff.Size) analogMM = control.mmap("/dev/lms_analog", AnalogOff.Size, 0) @@ -64,7 +61,7 @@ namespace input.internal { loops.pause(500) }) - for (let info_ of sensors) { + for (let info_ of sensorInfos) { let info = info_ unsafePollForChanges(50, () => { if (info.sensor) return info.sensor._query() @@ -90,7 +87,7 @@ namespace input.internal { let conns = analogMM.slice(AnalogOff.InConn, DAL.NUM_INPUTS) let numChanged = 0 - for (let info of sensors) { + for (let info of sensorInfos) { let newConn = conns[info.port] if (newConn == info.connType) continue @@ -117,77 +114,42 @@ namespace input.internal { if (numChanged == 0) return - let autos = sensors.filter(s => !s.manual) - - // first free up disconnected sensors - for (let info of autos) { - if (info.sensor && info.devType == DAL.DEVICE_TYPE_NONE) - info.sensor._setPort(0) - } - - for (let info of autos) { - if (!info.sensor && info.devType != DAL.DEVICE_TYPE_NONE) { - let found = false - for (let s of autoSensors) { - if (s.getPort() == 0 && s._deviceType() == info.devType) { - s._setPort(info.port + 1) - found = true - break - } + for (let si of sensorInfos) { + if (si.sensor && si.sensor._deviceType() != si.devType) { + si.sensor = null + } + if (si.devType != DAL.DEVICE_TYPE_NONE) { + si.sensor = si.sensors.filter(s => s._deviceType() == si.devType)[0] || null + if (si.sensor == null) { + control.dmesg(`sensor not found for type=${si.devType} at ${si.port}`) + } else { + control.dmesg(`sensor connected type=${si.devType} at ${si.port}`) + si.sensor._activated() } - if (!found) - control.dmesg(`sensor not found for type=${info.devType} at ${info.port}`) } } } export class Sensor extends control.Component { - protected port: number + protected port: number // this is 0-based - constructor() { + constructor(port_: number) { super() + if (!(1 <= port_ && port_ <= DAL.NUM_INPUTS)) + control.panic(120) + this.port = port_ - 1 init() - this.port = -1 - let tp = this._deviceType() - if (autoSensors.filter(s => s._deviceType() == tp).length == 0) { - autoSensors.push(this) - } } - // 0 - disable, 1-4 port number - _setPort(port: number, manual = false) { - port = Math.clamp(0, 4, port | 0) - 1; - if (port == this.port) return - this.port = port - control.dmesg(`sensor set port ${port} on devtype=${this._deviceType()}`) - for (let i = 0; i < sensors.length; ++i) { - if (i != this.port && sensors[i].sensor == this) { - sensors[i].sensor = null - sensors[i].manual = false - } - } - if (this.port >= 0) { - let prev = sensors[this.port].sensor - if (prev && prev != this) - prev._setPort(0) - sensors[this.port].sensor = this - sensors[this.port].manual = manual - } - this._portUpdated() - } - - protected _portUpdated() { } - - setPort(port: number) { - this._setPort(port, true) - } + _activated() { } + // 1-based getPort() { return this.port + 1 } - isManual() { - return this.port >= 0 && sensors[this.port].manual + isActive() { + return sensorInfos[this.port].sensor == this } _query() { @@ -203,12 +165,12 @@ namespace input.internal { } export class AnalogSensor extends Sensor { - constructor() { - super() + constructor(port: number) { + super(port) } _readPin6() { - if (this.port < 0) return 0 + if (!this.isActive()) return 0 return analogMM.getNumber(NumberFormat.Int16LE, AnalogOff.InPin6 + 2 * this.port) } } @@ -216,32 +178,26 @@ namespace input.internal { export class UartSensor extends Sensor { - protected mode: number - protected realmode: number + protected mode: number // the mode user asked for + protected realmode: number // the mode the hardware is in - constructor() { - super() + constructor(port: number) { + super(port) this.mode = 0 this.realmode = -1 } - protected _portUpdated() { - this.realmode = -1 - if (this.port >= 0) { - if (this.isManual()) { - uartReset(this.port) - } else { - this.realmode = 0 - } - this._setMode(this.mode) - } + _activated() { + this.realmode = 0 + // uartReset(this.port) // TODO is it ever needed? + this._setMode(this.mode) } protected _setMode(m: number) { //control.dmesg(`_setMode p=${this.port} m: ${this.realmode} -> ${m}`) let v = m | 0 this.mode = v - if (this.port < 0) return + if (!this.isActive()) return if (this.realmode != this.mode) { this.realmode = v setUartMode(this.port, v) @@ -249,10 +205,12 @@ namespace input.internal { } getBytes(): Buffer { - return getUartBytes(this.port) + return getUartBytes(this.isActive() ? this.port : -1) } getNumber(fmt: NumberFormat, off: number) { + if (!this.isActive()) + return 0 return getUartNumber(fmt, off, this.port) } } diff --git a/libs/core/ir.ts b/libs/core/ir.ts index dd5bf626..2ceaed5a 100644 --- a/libs/core/ir.ts +++ b/libs/core/ir.ts @@ -40,29 +40,46 @@ namespace input { } } - export class IrSensor extends internal.UartSensor { - private channel: IrRemoteChannel - private buttons: Button[]; + let buttons: Button[] - constructor() { - super() - this.channel = IrRemoteChannel.Ch0 - this.buttons = [] - // otherwise button events won't work - this.mode = IrSensorMode.RemoteControl + function create(ir: IrSensor) { + // it's created by referencing it + } + + export function irButton(id: IrRemoteButton) { + if (buttons == null) { + buttons = [] for (let i = 0; i < 5; ++i) { - this.buttons.push(new Button()) + buttons.push(new Button()) } + + // make sure sensors are up + create(ir1) + create(ir2) + create(ir3) + create(ir4) } - button(id: IrRemoteButton) { - let num = -1 - while (id) { - id >>= 1; - num++; - } - num = Math.clamp(0, this.buttons.length - 1, num) - return this.buttons[num] + let num = -1 + while (id) { + id >>= 1; + num++; + } + num = Math.clamp(0, buttons.length - 1, num) + return buttons[num] + } + + //% fixedInstance + export class IrSensor extends internal.UartSensor { + private channel: IrRemoteChannel + + constructor(port: number) { + super(port) + this.channel = IrRemoteChannel.Ch0 + irButton(0) // make sure buttons array is initalized + + // and set the mode, as otherwise button events won't work + this.mode = IrSensorMode.RemoteControl } _query() { @@ -72,9 +89,9 @@ namespace input { } _update(prev: number, curr: number) { - for (let i = 0; i < this.buttons.length; ++i) { + for (let i = 0; i < buttons.length; ++i) { let v = !!(curr & (1 << i)) - this.buttons[i].update(v) + buttons[i].update(v) } } @@ -92,16 +109,39 @@ namespace input { this._setMode(m) } - getDistance() { + /** + * Get the distance measured by the infrared sensor. + * @param ir the infrared sensor + */ + //% help=input/infrared/distance + //% block="%infrared|distance" + //% blockId=infraredGetDistance + //% parts="infrared" + //% blockNamespace=input + //% weight=65 blockGap=8 + //% group="Infrared Sensor" + distance() { this.setMode(IrSensorMode.Proximity) return this.getNumber(NumberFormat.UInt8LE, 0) } - getRemoteCommand() { + /** + * Get the remote commandreceived the infrared sensor. + * @param ir the infrared sensor + */ + //% help=input/infrared/remote-command + //% block="%infrared|remote command" + //% blockId=infraredGetRemoteCommand + //% parts="infrared" + //% blockNamespace=input + //% weight=65 blockGap=8 + //% group="Infrared Sensor" + remoteCommand() { this.setMode(IrSensorMode.RemoteControl) return this.getNumber(NumberFormat.UInt8LE, this.channel) } + // TODO getDirectionAndDistance() { this.setMode(IrSensorMode.Seek) return this.getNumber(NumberFormat.UInt16LE, this.channel * 2) @@ -109,35 +149,44 @@ namespace input { } //% whenUsed - export const ir: IrSensor = new IrSensor() + export const ir1: IrSensor = new IrSensor(1) + + //% whenUsed + export const ir2: IrSensor = new IrSensor(2) + + //% whenUsed + export const ir3: IrSensor = new IrSensor(3) + + //% whenUsed + export const ir4: IrSensor = new IrSensor(4) /** * Remote top-left button. */ //% whenUsed block="remote top-left" weight=95 fixedInstance - export const remoteTopLeft = ir.button(IrRemoteButton.TopLeft) + export const remoteTopLeft = irButton(IrRemoteButton.TopLeft) /** * Remote top-right button. */ //% whenUsed block="remote top-right" weight=95 fixedInstance - export const remoteTopRight = ir.button(IrRemoteButton.TopRight) + export const remoteTopRight = irButton(IrRemoteButton.TopRight) /** * Remote bottom-left button. */ //% whenUsed block="remote bottom-left" weight=95 fixedInstance - export const remoteBottomLeft = ir.button(IrRemoteButton.BottomLeft) + export const remoteBottomLeft = irButton(IrRemoteButton.BottomLeft) /** * Remote bottom-right button. */ //% whenUsed block="remote bottom-right" weight=95 fixedInstance - export const remoteBottomRight = ir.button(IrRemoteButton.BottomRight) + export const remoteBottomRight = irButton(IrRemoteButton.BottomRight) /** * Remote beacon (center) button. */ //% whenUsed block="remote center" weight=95 fixedInstance - export const remoteCenter = ir.button(IrRemoteButton.CenterBeacon) + export const remoteCenter = irButton(IrRemoteButton.CenterBeacon) } diff --git a/libs/core/ns.ts b/libs/core/ns.ts index e1cfb040..4902e556 100644 --- a/libs/core/ns.ts +++ b/libs/core/ns.ts @@ -1,4 +1,5 @@ //% color="#B4009E" weight=98 icon="\uf192" +//% groups='["Touch Sensor", "Gyro Sensor", "Color Sensor", "Ultrasonic Sensor", "Infrared Sensor", "Remote", "Brick"]' namespace input { } diff --git a/libs/core/output.ts b/libs/core/output.ts index 10b31af7..d84de427 100644 --- a/libs/core/output.ts +++ b/libs/core/output.ts @@ -67,7 +67,7 @@ namespace output { * @param ms the number of milliseconds to turn the motor on, eg: 500 * @param useBrake whether or not to use the brake, defaults to false */ - //% blockId=output_turn block="turn motor %out| on for %ms|milliseconds" + //% blockId=output_turn block="turn motor %out| on for %ms=timePicker|milliseconds" //% weight=100 group="Motors" export function turn(out: Output, ms: number, useBrake = false) { // TODO: use current power / speed configuration @@ -87,14 +87,14 @@ namespace output { * @param out the output connection that the motor is connected to * @param on 1 to turn the motor on, 0 to turn it off */ - //% blockId=output_switch block="turn motor %out|%on" + //% blockId=outputMotorPowerOnOff block="power motor %out|%on" //% weight=90 group="Motors" - //% on.fieldEditor="toggle" - export function switchMotor(out: Output, on: number, useBrake = false) { - if (on == 0) { - output.stop(out, useBrake); - } else { + //% on.fieldEditor="toggleonoff" + export function powerMotor(out: Output, on: boolean, useBrake = false) { + if (on) { output.start(out); + } else { + output.stop(out, useBrake); } } diff --git a/libs/core/screen.ts b/libs/core/screen.ts index f32fb730..30b6b411 100644 --- a/libs/core/screen.ts +++ b/libs/core/screen.ts @@ -92,10 +92,10 @@ namespace screen { * @param x the starting position's x coordinate, eg: 0 * @param y the starting position's x coordinate, eg: 0 */ - //% blockId=screen_drawText block="print %text| at x: %x| y: %y" - //% weight=99 group="Screen" blockNamespace=output inlineInputMode="inline" + //% blockId=screen_print block="print %text| at x: %x| y: %y" + //% weight=99 group="Brick" blockNamespace=output inlineInputMode="inline" //% x.min=0 x.max=178 y.min=0 y.max=128 - export function drawText(text: string, x: number, y: number, mode = Draw.Normal) { + export function print(text: string, x: number, y: number, mode = Draw.Normal) { x |= 0 y |= 0 if (!currFont) currFont = defaultFont() diff --git a/libs/core/test.ts b/libs/core/test.ts index 7d1281d8..d481fe74 100644 --- a/libs/core/test.ts +++ b/libs/core/test.ts @@ -1,8 +1,8 @@ screen.clear() -screen.drawText("PXT!", 10, 30, Draw.Quad) +screen.print("PXT!", 10, 30, Draw.Quad) screen.drawRect(40, 40, 20, 10, Draw.Fill) -output.setLights(LightsPattern.Orange) +output.setStatusLight(LightsPattern.Orange) screen.drawIcon(100, 50, screen.doubleIcon(screen.heart), Draw.Double | Draw.Transparent) @@ -12,37 +12,37 @@ input.buttonEnter.onEvent(ButtonEvent.Click, () => { input.buttonLeft.onEvent(ButtonEvent.Click, () => { screen.drawRect(10, 70, 20, 10, Draw.Fill) - output.setLights(LightsPattern.Red) + output.setStatusLight(LightsPattern.Red) screen.setFont(screen.microbitFont()) }) input.buttonRight.onEvent(ButtonEvent.Click, () => { - screen.drawText("Right!", 10, 60) + screen.print("Right!", 10, 60) }) input.buttonDown.onEvent(ButtonEvent.Click, () => { - screen.drawText("Down! ", 10, 60) + screen.print("Down! ", 10, 60) }) input.buttonUp.onEvent(ButtonEvent.Click, () => { - screen.drawText("Up! ", 10, 60) + screen.print("Up! ", 10, 60) }) let num = 0 -input.touchSensor.onEvent(ButtonEvent.Click, () => { - screen.drawText("Click! " + num, 10, 60) +input.touchSensor1.onEvent(ButtonEvent.Click, () => { + screen.print("Click! " + num, 10, 60) num++ }) input.remoteTopLeft.onEvent(ButtonEvent.Click, () => { - screen.drawText("TOPLEFT " + num, 10, 60) + screen.print("TOPLEFT " + num, 10, 60) num++ }) input.remoteTopRight.onEvent(ButtonEvent.Down, () => { - screen.drawText("TOPRIGH " + num, 10, 60) + screen.print("TOPRIGH " + num, 10, 60) num++ }) @@ -54,7 +54,7 @@ loops.forever(() => { /* loops.forever(() => { let v = input.color.getColor() - screen.drawText(10, 60, v + " ") + screen.print(10, 60, v + " ") loops.pause(200) }) -*/ \ No newline at end of file +*/ diff --git a/libs/core/touch.ts b/libs/core/touch.ts index da99c178..4f93e55a 100644 --- a/libs/core/touch.ts +++ b/libs/core/touch.ts @@ -1,12 +1,26 @@ +// keep TouchSensorEvent in sync with ButtonEvent + +/** + * Touch sensor interactions + */ +const enum TouchSensorEvent { + //% block="touched" + Touched = 4, + //% block="bumped" + Bumped = 1, + //% block="released" + Released = 3, +} + namespace input { //% fixedInstances export class TouchSensor extends internal.AnalogSensor { - button: Button; + private button: Button; - constructor() { - super() - this.button = new Button() + constructor(port: number) { + super(port) + this.button = new Button(); } _query() { @@ -20,11 +34,45 @@ namespace input { _deviceType() { return DAL.DEVICE_TYPE_TOUCH } + + /** + * Check if touch sensor is touched. + * @param sensor the port to query the request + */ + //% help=input/touch/is-touched + //% block="%sensor|is touched" + //% blockId=touchIsTouched + //% parts="touch" + //% blockNamespace=input + //% weight=81 blockGap=8 + //% group="Touch Sensor" + isTouched() { + return this.button.isPressed(); + } + + /** + * Do something when a touch sensor is touched... + * @param sensor the touch sensor that needs to be clicked or used + * @param event the kind of button gesture that needs to be detected + * @param body code to run when the event is raised + */ + //% help=input/touch/on-event + //% blockId=touchEvent block="on %sensor|%event" + //% parts="touch" + //% blockNamespace=input + //% weight=99 blockGap=8 + //% group="Touch Sensor" + onEvent(ev: TouchSensorEvent, body: () => void) { + this.button.onEvent(ev, body) + } } - //% whenUsed - export const touchSensorImpl: TouchSensor = new TouchSensor() - - //% whenUsed block="touch sensor" weight=95 fixedInstance - export const touchSensor: Button = touchSensorImpl.button + //% whenUsed block="touch sensor 1" weight=95 fixedInstance + export const touchSensor1: TouchSensor = new TouchSensor(1) + //% whenUsed block="touch sensor 2" weight=95 fixedInstance + export const touchSensor2: TouchSensor = new TouchSensor(2) + //% whenUsed block="touch sensor 3" weight=95 fixedInstance + export const touchSensor3: TouchSensor = new TouchSensor(3) + //% whenUsed block="touch sensor 4" weight=95 fixedInstance + export const touchSensor4: TouchSensor = new TouchSensor(4) } diff --git a/libs/core/ultrasonic.ts b/libs/core/ultrasonic.ts index a08833aa..79b63a0f 100644 --- a/libs/core/ultrasonic.ts +++ b/libs/core/ultrasonic.ts @@ -1,22 +1,42 @@ namespace input { + //% fixedInstances export class UltraSonicSensor extends internal.UartSensor { - constructor() { - super() + constructor(port: number) { + super(port) } _deviceType() { return DAL.DEVICE_TYPE_ULTRASONIC } - /** Get distance in mm */ - getDistance() { + /** + * Gets the distance from the sonar in millimeters + * @param sensor the ultrasonic sensor port + */ + //% help=input/ultrasonic/distance + //% block="%sensor|distance" + //% blockId=sonarGetDistance + //% parts="ultrasonic" + //% blockNamespace=input + //% weight=65 blockGap=8 + //% group="Ultrasonic Sensor" + distance() { // it supposedly also has an inch mode, but we stick to mm this._setMode(0) return this.getNumber(NumberFormat.UInt16LE, 0) & 0x0fff } } - //% whenUsed - export const ultrasonic: UltraSonicSensor = new UltraSonicSensor() + //% fixedInstance whenUsed block="ultrasonic sensor 4" + export const ultrasonic4: UltraSonicSensor = new UltraSonicSensor(4) + + //% fixedInstance whenUsed block="ultrasonic sensor 1" + export const ultrasonic1: UltraSonicSensor = new UltraSonicSensor(1) + + //% fixedInstance whenUsed block="ultrasonic sensor 2" + export const ultrasonic2: UltraSonicSensor = new UltraSonicSensor(2) + + //% fixedInstance whenUsed block="ultrasonic sensor 3" + export const ultrasonic3: UltraSonicSensor = new UltraSonicSensor(3) } diff --git a/libs/ev3/ns.ts b/libs/ev3/ns.ts index d9ca84c7..a1065794 100644 --- a/libs/ev3/ns.ts +++ b/libs/ev3/ns.ts @@ -4,7 +4,7 @@ namespace input { } //% color="#8AC044" weight=90 icon="\uf185" -//% groups='["Lights", "Screen", "Motors"]' +//% groups='["Motors", "Brick"]' namespace output { }