diff --git a/libs/core/_locales/core-strings.json b/libs/core/_locales/core-strings.json index 4a5ed53a..a46e3c0f 100644 --- a/libs/core/_locales/core-strings.json +++ b/libs/core/_locales/core-strings.json @@ -30,13 +30,19 @@ "input.buttonLeft|block": "button left", "input.buttonRight|block": "button right", "input.buttonUp|block": "button up", - "input.color|block": "color sensor", + "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.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|block": "input", "output.getCurrentSpeed|block": "motor %out|speed", "output.pattern|block": "%pattern", diff --git a/libs/core/color.ts b/libs/core/color.ts index 1c5a5633..49ef569c 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() { @@ -81,6 +81,15 @@ namespace input { } } - //% whenUsed block="color sensor" weight=95 fixedInstance - export const color: ColorSensor = new ColorSensor() + //% 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 3" weight=95 fixedInstance + export const color3: ColorSensor = new ColorSensor(3) + + //% 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 25668737..9bcf4d50 100644 --- a/libs/core/gyro.ts +++ b/libs/core/gyro.ts @@ -7,8 +7,8 @@ const enum GyroSensorMode { namespace input { //% fixedInstances export class GyroSensor extends internal.UartSensor { - constructor() { - super() + constructor(port: number) { + super(port) } _deviceType() { @@ -51,5 +51,14 @@ namespace input { } //% whenUsed - export const gyro: GyroSensor = new GyroSensor() + export const gyro1: GyroSensor = new GyroSensor(1) + + //% whenUsed + export const gyro2: GyroSensor = new GyroSensor(2) + + //% whenUsed + export const gyro3: GyroSensor = new GyroSensor(3) + + //% whenUsed + 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 29c0ec0f..542a86f1 100644 --- a/libs/core/ir.ts +++ b/libs/core/ir.ts @@ -40,30 +40,46 @@ namespace input { } } + let buttons: Button[] + + 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) { + buttons.push(new Button()) + } + + // make sure sensors are up + create(ir1) + create(ir2) + create(ir3) + create(ir4) + } + + 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 - private buttons: Button[]; - constructor() { - super() + constructor(port: number) { + super(port) this.channel = IrRemoteChannel.Ch0 - this.buttons = [] - // otherwise button events won't work - this.mode = IrSensorMode.RemoteControl - for (let i = 0; i < 5; ++i) { - this.buttons.push(new Button()) - } - } + irButton(0) // make sure buttons array is initalized - button(id: IrRemoteButton) { - let num = -1 - while (id) { - id >>= 1; - num++; - } - num = Math.clamp(0, this.buttons.length - 1, num) - return this.buttons[num] + // and set the mode, as otherwise button events won't work + this.mode = IrSensorMode.RemoteControl } _query() { @@ -73,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) } } @@ -131,35 +147,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/test.ts b/libs/core/test.ts index 66e065da..d481fe74 100644 --- a/libs/core/test.ts +++ b/libs/core/test.ts @@ -31,7 +31,7 @@ input.buttonUp.onEvent(ButtonEvent.Click, () => { let num = 0 -input.touchSensor.onEvent(ButtonEvent.Click, () => { +input.touchSensor1.onEvent(ButtonEvent.Click, () => { screen.print("Click! " + num, 10, 60) num++ }) @@ -57,4 +57,4 @@ loops.forever(() => { 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..c75ac0b9 100644 --- a/libs/core/touch.ts +++ b/libs/core/touch.ts @@ -4,8 +4,8 @@ namespace input { export class TouchSensor extends internal.AnalogSensor { button: Button; - constructor() { - super() + constructor(port: number) { + super(port) this.button = new Button() } @@ -23,8 +23,23 @@ namespace input { } //% whenUsed - export const touchSensorImpl: TouchSensor = new TouchSensor() + export const touchSensorImpl1: TouchSensor = new TouchSensor(1) + //% whenUsed + export const touchSensorImpl2: TouchSensor = new TouchSensor(2) + //% whenUsed + export const touchSensorImpl3: TouchSensor = new TouchSensor(3) + //% whenUsed + export const touchSensorImpl4: TouchSensor = new TouchSensor(4) - //% whenUsed block="touch sensor" weight=95 fixedInstance - export const touchSensor: Button = touchSensorImpl.button + //% whenUsed block="touch sensor 1" weight=95 fixedInstance + export const touchSensor1: Button = touchSensorImpl1.button + + //% whenUsed block="touch sensor 2" weight=95 fixedInstance + export const touchSensor2: Button = touchSensorImpl2.button + + //% whenUsed block="touch sensor 3" weight=95 fixedInstance + export const touchSensor3: Button = touchSensorImpl3.button + + //% whenUsed block="touch sensor 4" weight=95 fixedInstance + export const touchSensor4: Button = touchSensorImpl4.button } diff --git a/libs/core/ultrasonic.ts b/libs/core/ultrasonic.ts index a08833aa..0a16cb20 100644 --- a/libs/core/ultrasonic.ts +++ b/libs/core/ultrasonic.ts @@ -1,8 +1,8 @@ namespace input { export class UltraSonicSensor extends internal.UartSensor { - constructor() { - super() + constructor(port: number) { + super(port) } _deviceType() { @@ -18,5 +18,14 @@ namespace input { } //% whenUsed - export const ultrasonic: UltraSonicSensor = new UltraSonicSensor() + export const ultrasonic1: UltraSonicSensor = new UltraSonicSensor(1) + + //% whenUsed + export const ultrasonic2: UltraSonicSensor = new UltraSonicSensor(2) + + //% whenUsed + export const ultrasonic3: UltraSonicSensor = new UltraSonicSensor(3) + + //% whenUsed + export const ultrasonic4: UltraSonicSensor = new UltraSonicSensor(4) }