From ac41b8adb1d538ad3e64b8e8b4bf77cda57e1fc1 Mon Sep 17 00:00:00 2001 From: Dmitriy Antipov Date: Fri, 3 Nov 2023 01:13:55 +0300 Subject: [PATCH 1/5] Screen clear lines block (#1039) * add-clear-lines-block * Update targetoverrides.ts * Update targetoverrides.ts * Update targetoverrides.ts --- libs/screen/targetoverrides.ts | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/libs/screen/targetoverrides.ts b/libs/screen/targetoverrides.ts index 0d0005a9..92d8dacc 100644 --- a/libs/screen/targetoverrides.ts +++ b/libs/screen/targetoverrides.ts @@ -311,12 +311,29 @@ namespace brick { return image; } + /** + * Clear on the screen at a specific lines (1..12). + * @param lines list of lines to clear (starting at 1 and ends with 12) + */ + //% blockId=clearLines block="clear lines $lines" + //% weight=94 group="Screen" inlineInputMode="inline" blockGap=8 + export function clearLines(lines: number[]) { + if (screenMode != ScreenMode.ShowLines) { + screenMode = ScreenMode.ShowLines; + screen.fill(0); + } + + for (let i = 0; i < lines.length; i++) { + clearLine(lines[i]); + } + } + /** * Clear on the screen at a specific line. * @param line the line number to clear at (starting at 1), eg: 1 */ //% blockId=clearLine block="clear line $line" - //% weight=94 group="Screen" inlineInputMode="inline" blockGap=8 + //% weight=93 group="Screen" inlineInputMode="inline" blockGap=8 //% line.min=1 line.max=12 export function clearLine(line: number) { if (screenMode != ScreenMode.ShowLines) { @@ -337,7 +354,7 @@ namespace brick { * Clear the screen */ //% blockId=screen_clear_screen block="clear screen" - //% weight=93 group="Screen" + //% weight=92 group="Screen" //% help=brick/clear-screen weight=1 export function clearScreen() { screen.fill(0) From 62e41f628cf893660d888049638242a5093ff252 Mon Sep 17 00:00:00 2001 From: Dmitriy Antipov Date: Fri, 3 Nov 2023 01:14:37 +0300 Subject: [PATCH 2/5] add turtle tutorial image (#1037) --- docs/static/tutorials/turtle.png | Bin 0 -> 19465 bytes docs/tutorials/motors.md | 3 ++- 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 docs/static/tutorials/turtle.png diff --git a/docs/static/tutorials/turtle.png b/docs/static/tutorials/turtle.png new file mode 100644 index 0000000000000000000000000000000000000000..e37a92e5b6de6081c49805198f23e250ca83b761 GIT binary patch literal 19465 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 LS3j3^P6 Date: Fri, 3 Nov 2023 01:15:36 +0300 Subject: [PATCH 3/5] Editor display changes (#1036) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update style.less The first change returns the background pattern as in the stable version. The second change is to fix #downloadArea overlapping on the simulator. I don’t really understand why this bug is visible only in pxt-ev3. This bug is not detected in microbit, but the #downloadArea field is also larger than the height of #editortools itself. I compared the properties, but they seem to be all the same. * revet-editortools-overflow-hidden * Update style.less Filling the background color is not required, because The #editortools parent element already has a background fill. --- theme/style.less | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/theme/style.less b/theme/style.less index cd1bcf93..c7fefa6b 100644 --- a/theme/style.less +++ b/theme/style.less @@ -115,14 +115,10 @@ text-transform: lowercase; } -#filelist { +#simulator .editor-sidebar { background: @simulatorBackground data-uri("../docs/static/backgrounds/simulator.png") 0 0 repeat !important; } -#downloadArea { - background: @legoGreyLight; -} - /* Editor download dialog */ .ui.downloaddialog.modal>.content { padding: 1rem; From 92ff13169e041eed36459f8267355c6e5e4d9a8d Mon Sep 17 00:00:00 2001 From: Dmitriy Antipov Date: Fri, 3 Nov 2023 19:44:00 +0300 Subject: [PATCH 4/5] Pxt core bump 9.1.1x and more (#1038) * bump-pxt-core Timely update of the pxt-core version to support the project. * active-item-fill-height-change * pxt-core-bump-9.1.14 * pxt-bump-9-1-15 * add-subcategories-planned-sens * ht-color-sen-add-lib * Remove-queryArr-and-infoArr Got rid of queryArr and infoArr, which I created to support the color sensor in the RawRgb mode in the simulator. * revert-ms-automation-ext Revert automation extension. * pxt-bump-9.1.16 * move-status-indicator-to-new-group Move the status indicator to a separate group. It was in a button group, but according to the ev3 manual it is not a button, so I created a separate group for it and output the code to a separate file. It's logical. * exitProgram-moved-from-buttons-to-program exitProgram has been moved from buttons to the program group. * bump-pxt-9.1.17 * pxt-bump-9.1.18 * pxt-bump-9.1.19 * i2c-sens-work-when-start-program The i2c sensors will work when the program starts. Before this, the i2c sensor started working only when other sensors were reconnected, calling detectDevices() again. * Update input.ts * Update input.ts * pxt-bump-9.1.21 * pxt-bump-9.1.23 * color-for-separator-lego-ana-microsoft-logos * Update style.less * Update style.less * revert-approvedRepos * Update targetconfig.json --- libs/color-sensor/color.ts | 36 ++-- libs/core/buttons.ts | 59 +------ libs/core/indicator.ts | 55 ++++++ libs/core/input.ts | 248 +++++++++++---------------- libs/core/pxt.json | 1 + libs/ev3/brick.ts | 2 +- libs/ev3/ns.ts | 3 +- libs/gyro-sensor/gyro.ts | 16 +- libs/infrared-sensor/ir.ts | 14 +- libs/screen/targetoverrides.ts | 8 +- libs/touch-sensor/touch.ts | 6 +- libs/ultrasonic-sensor/ultrasonic.ts | 10 +- package.json | 2 +- theme/style.less | 7 +- 14 files changed, 206 insertions(+), 261 deletions(-) create mode 100644 libs/core/indicator.ts diff --git a/libs/color-sensor/color.ts b/libs/color-sensor/color.ts index 007c7064..34fd3f82 100644 --- a/libs/color-sensor/color.ts +++ b/libs/color-sensor/color.ts @@ -81,7 +81,7 @@ namespace sensors { else maxModeRange = 100; // ReflectedLightIntensity or AmbientLightIntensity this._setMode(m); // Change mode pause(MODE_SWITCH_DELAY); - pauseUntil(() => (this.getStatus() == 8 && (this.mode == ColorSensorMode.RgbRaw ? this._queryArr()[0] : this._query()) <= maxModeRange)); // Pause until mode change + pauseUntil(() => (this.getStatus() == 8 && this._query()[0] <= maxModeRange)); // Pause until mode change } else { this._setMode(m); } @@ -98,47 +98,33 @@ namespace sensors { if (this.mode == ColorSensorMode.Color || this.mode == ColorSensorMode.AmbientLightIntensity || this.mode == ColorSensorMode.ReflectedLightIntensity) - return this.getNumber(NumberFormat.UInt8LE, 0) + return [this.getNumber(NumberFormat.UInt8LE, 0)]; else if (this.mode == ColorSensorMode.RefRaw) - return this.getNumber(NumberFormat.UInt16LE, 0) - return 0 - } - - _queryArr(): number[] { - if (this.mode == ColorSensorMode.RgbRaw) { + return [this.getNumber(NumberFormat.UInt16LE, 0)]; + else if (this.mode == ColorSensorMode.RgbRaw) { return [this.getNumber(NumberFormat.UInt16LE, 0), this.getNumber(NumberFormat.UInt16LE, 2), this.getNumber(NumberFormat.UInt16LE, 4)]; } - return [0, 0, 0]; + return [0]; } - _info(): string { + _info() { switch (this.mode) { case ColorSensorMode.Color: - return ["none", + return [["none", "black", "blue", "green", "yellow", "red", "white", - "brown"][this._query()]; + "brown"][this._query()[0]]]; case ColorSensorMode.AmbientLightIntensity: case ColorSensorMode.ReflectedLightIntensity: - return `${this._query()}%`; - case ColorSensorMode.RgbRaw: - return "array"; - default: - return this._query().toString(); - } - } - - _infoArr(): string[] { - switch (this.mode) { + return [`${this._query()}%`]; case ColorSensorMode.RgbRaw: - const queryArr = this._queryArr().map(number => number.toString()); - return queryArr; + return this._query().map(number => number.toString()); default: - return ["0", "0", "0"]; + return [this._query()[0].toString()]; } } diff --git a/libs/core/buttons.ts b/libs/core/buttons.ts index 3033d3c0..34c6bca2 100644 --- a/libs/core/buttons.ts +++ b/libs/core/buttons.ts @@ -1,30 +1,3 @@ - -/** - * Patterns for lights under the buttons. - */ -const enum StatusLight { - //% block=off enumval=0 - Off = 0, - //% block=green enumval=1 - Green = 1, - //% block=red enumval=2 - Red = 2, - //% block=orange enumval=3 - Orange = 3, - //% block="green flash" enumval=4 - GreenFlash = 4, - //% block="red flash" enumval=5 - RedFlash = 5, - //% block="orange flash" enumval=6 - OrangeFlash = 6, - //% block="green pulse" enumval=7 - GreenPulse = 7, - //% block="red pulse" enumval=8 - RedPulse = 8, - //% block="orange pulse" enumval=9 - OrangePulse = 9, -} - /** * User interaction on buttons */ @@ -246,34 +219,4 @@ namespace control { } return r } -} - -namespace brick { - // the brick starts with the red color - let currPattern: StatusLight = StatusLight.Off; - - /** - * Gets the current light pattern. - */ - //% weight=99 group="Buttons" - //% help=brick/status-light - export function statusLight() { - return currPattern; - } - - /** - * Set lights. - * @param pattern the lights pattern to use. eg: StatusLight.Orange - */ - //% blockId=setLights block="set status light to %pattern" - //% weight=100 group="Buttons" - //% help=brick/set-status-light - export function setStatusLight(pattern: StatusLight): void { - if (currPattern === pattern) - return - currPattern = pattern; - const cmd = output.createBuffer(2) - cmd[0] = pattern + 48 - brick.internal.getBtnsMM().write(cmd) - } -} +} \ No newline at end of file diff --git a/libs/core/indicator.ts b/libs/core/indicator.ts new file mode 100644 index 00000000..c327a70b --- /dev/null +++ b/libs/core/indicator.ts @@ -0,0 +1,55 @@ +/** + * Patterns for lights under the buttons. + */ +const enum StatusLight { + //% block=off enumval=0 + Off = 0, + //% block=green enumval=1 + Green = 1, + //% block=red enumval=2 + Red = 2, + //% block=orange enumval=3 + Orange = 3, + //% block="green flash" enumval=4 + GreenFlash = 4, + //% block="red flash" enumval=5 + RedFlash = 5, + //% block="orange flash" enumval=6 + OrangeFlash = 6, + //% block="green pulse" enumval=7 + GreenPulse = 7, + //% block="red pulse" enumval=8 + RedPulse = 8, + //% block="orange pulse" enumval=9 + OrangePulse = 9, +} + +namespace brick { + // the brick starts with the red color + let currPattern: StatusLight = StatusLight.Off; + + /** + * Gets the current light pattern. + */ + //% weight=99 group="Indicator" + //% help=brick/status-light + export function statusLight() { + return currPattern; + } + + /** + * Set lights. + * @param pattern the lights pattern to use. eg: StatusLight.Orange + */ + //% blockId=setLights block="set status light to %pattern" + //% weight=100 group="Indicator" + //% help=brick/set-status-light + export function setStatusLight(pattern: StatusLight): void { + if (currPattern === pattern) + return + currPattern = pattern; + const cmd = output.createBuffer(2) + cmd[0] = pattern + 48 + brick.internal.getBtnsMM().write(cmd) + } +} diff --git a/libs/core/input.ts b/libs/core/input.ts index 9e1c5fff..a56cfde7 100644 --- a/libs/core/input.ts +++ b/libs/core/input.ts @@ -1,4 +1,8 @@ namespace sensors.internal { + + const UART_PORT_CHANGED = 1; + const UART_DATA_READY = 8; + export class Poller { private query: () => number; private update: (previous: number, current: number) => void; @@ -7,7 +11,7 @@ namespace sensors.internal { private previousValue: number; private currentValue: number; private lastQuery: number; // track down the last time we did a query/update cycle - private lastPause: number; // track down the last time we pause in the sensor polling loop + private lastPause: number; // track down the last time we pause in the sensor polling loop constructor(interval: number, query: () => number, update: (previous: number, current: number) => void) { this.interval = interval | 0; @@ -35,6 +39,7 @@ namespace sensors.internal { private poll() { control.runInBackground(() => { + pause(this.interval); this.lastQuery = this.lastPause = control.millis(); this.previousValue = this.currentValue = this.query(); this.update(this.previousValue, this.currentValue); @@ -55,12 +60,12 @@ namespace sensors.internal { return s } - let analogMM: MMap - let uartMM: MMap - let IICMM: MMap - let powerMM: MMap - let devcon: Buffer - let devPoller: Poller + let analogMM: MMap; + let uartMM: MMap; + let IICMM: MMap; + let powerMM: MMap; + let devcon: Buffer; + let devPoller: Poller; let sensorInfos: SensorInfo[]; let batteryInfo: { @@ -94,7 +99,7 @@ namespace sensors.internal { } private query() { - if (this.sensor) return this.sensor._query(); + if (this.sensor) return this.sensor._query()[0]; return 0; } @@ -120,10 +125,11 @@ namespace sensors.internal { powerMM = control.mmap("/dev/lms_power", 2, 0) - devPoller = new Poller(250, () => { return hashDevices(); }, + devPoller = new Poller(900, () => { return hashDevices(); }, (prev, curr) => { detectDevices(); - }); + } + ); } export function getActiveSensors(): Sensor[] { @@ -131,25 +137,6 @@ namespace sensors.internal { return sensorInfos.filter(si => si.sensor && si.sensor.isActive()).map(si => si.sensor); } - function readUartInfo(port: number, mode: number) { - let buf = output.createBuffer(UartCtlOff.Size) - buf[UartCtlOff.Port] = port - buf[UartCtlOff.Mode] = mode - uartMM.ioctl(IO.UART_READ_MODE_INFO, buf) - return buf - //let info = `t:${buf[TypesOff.Type]} c:${buf[TypesOff.Connection]} m:${buf[TypesOff.Mode]} n:${buf.slice(0, 12).toHex()}` - //serial.writeLine("UART " + port + " / " + mode + " - " + info) - } - - export function readIICID(port: number) { - const buf = output.createBuffer(IICStr.Size) - buf[IICStr.Port] = port - IICMM.ioctl(IO.IIC_READ_TYPE_INFO, buf) - const manufacturer = bufferToString(buf.slice(IICStr.Manufacturer, 8)) - const sensorType = bufferToString(buf.slice(IICStr.SensorType, 8)) - return manufacturer + sensorType; - } - const ADC_REF = 5000 //!< [mV] maximal value on ADC const ADC_RES = 4095 //!< [CNT] maximal count on ADC // see c_ui.c @@ -220,42 +207,7 @@ namespace sensors.internal { const CinCnt = batteryInfo.CinCnt; const CoutCnt = batteryInfo.CoutCnt; const VinCnt = batteryInfo.VinCnt; - /* -void cUiUpdatePower(void) -{ -#ifndef Linux_X86 - DATAF CinV; - DATAF CoutV; - - if ((UiInstance.Hw == FINAL) || (UiInstance.Hw == FINALB)) - { - CinV = CNT_V(UiInstance.CinCnt) / AMP_CIN; - UiInstance.Vbatt = (CNT_V(UiInstance.VinCnt) / AMP_VIN) + CinV + VCE; - - UiInstance.Ibatt = CinV / SHUNT_IN; - CoutV = CNT_V(UiInstance.CoutCnt) / AMP_COUT; - UiInstance.Imotor = CoutV / SHUNT_OUT; - - } - else - { - CinV = CNT_V(UiInstance.CinCnt) / EP2_AMP_CIN; - UiInstance.Vbatt = (CNT_V(UiInstance.VinCnt) / AMP_VIN) + CinV + VCE; - - UiInstance.Ibatt = CinV / EP2_SHUNT_IN; - UiInstance.Imotor = 0; - - } - -#endif -#ifdef DEBUG_TEMP_SHUTDOWN - - UiInstance.Vbatt = 7.0; - UiInstance.Ibatt = 5.0; - -#endif -} - */ + const CinV = CNT_V(CinCnt) / AMP_CIN; const Vbatt = CNT_V(VinCnt) / AMP_VIN + CinV + VCE; const Ibatt = CinV / SHUNT_IN; @@ -281,82 +233,68 @@ void cUiUpdatePower(void) return r; } - let nonActivated = 0; function detectDevices() { - control.dmesg(`detect devices (hash ${hashDevices()})`) - const conns = analogMM.slice(AnalogOff.InConn, DAL.NUM_INPUTS) - let numChanged = 0; - const uartSensors: SensorInfo[] = []; + control.dmesg(`DETECT DEVICES (hash ${hashDevices()})`); + const conns = analogMM.slice(AnalogOff.InConn, DAL.NUM_INPUTS); for (const sensorInfo of sensorInfos) { - const newConn = conns[sensorInfo.port] - if (newConn == sensorInfo.connType - && sensorInfo.sensor - && sensorInfo.sensor.isActive()) { - if (newConn == DAL.CONN_INPUT_UART) - uartSensors.push(sensorInfo); + const newConn = conns[sensorInfo.port]; + if (newConn == sensorInfo.connType && sensorInfo.sensor && sensorInfo.sensor.isActive()) { continue; } - numChanged++ - sensorInfo.connType = newConn - sensorInfo.devType = DAL.DEVICE_TYPE_NONE + sensorInfo.connType = newConn; + sensorInfo.devType = DAL.DEVICE_TYPE_NONE; if (newConn == DAL.CONN_INPUT_UART) { - control.dmesg(`new UART connection at ${sensorInfo.port}`) + const status = getUartStatus(sensorInfo.port); + control.dmesg(`new UART connection at port ${sensorInfo.port} with status ${status}`); updateUartMode(sensorInfo.port, 0); - uartSensors.push(sensorInfo); } else if (newConn == DAL.CONN_NXT_IIC) { - control.dmesg(`new IIC connection at ${sensorInfo.port}`) - sensorInfo.devType = DAL.DEVICE_TYPE_IIC_UNKNOWN - sensorInfo.iicid = readIICID(sensorInfo.port) - control.dmesg(`IIC ID ${sensorInfo.iicid.length}`) + sensorInfo.devType = DAL.DEVICE_TYPE_IIC_UNKNOWN; + sensorInfo.iicid = readIICID(sensorInfo.port); + control.dmesg(`new IIC connection at port ${sensorInfo.port} with ID ${sensorInfo.iicid.length}`); } else if (newConn == DAL.CONN_INPUT_DUMB) { - control.dmesg(`new DUMB connection at ${sensorInfo.port}`) - // TODO? for now assume touch - sensorInfo.devType = DAL.DEVICE_TYPE_TOUCH + control.dmesg(`new DUMB connection at port ${sensorInfo.port}`); + sensorInfo.devType = DAL.DEVICE_TYPE_TOUCH; // TODO? for now assume touch sensor } else if (newConn == DAL.CONN_NONE || newConn == 0) { - //control.dmesg(`disconnect at port ${sensorInfo.port}`) + control.dmesg(`disconnect at port ${sensorInfo.port}`); } else { - control.dmesg(`unknown connection type: ${newConn} at ${sensorInfo.port}`) + control.dmesg(`unknown connection type ${newConn} at port ${sensorInfo.port}`); } } - if (uartSensors.length > 0) { + const uartSens = sensorInfos.filter(si => si.connType == DAL.CONN_INPUT_UART).length; + if (uartSens > 0) { setUartModes(); - for (const sensorInfo of uartSensors) { - let uinfo = readUartInfo(sensorInfo.port, 0) - sensorInfo.devType = uinfo[TypesOff.Type] + for (const sensorInfo of sensorInfos.filter(si => si.connType == DAL.CONN_INPUT_UART && si.devType == DAL.CONN_NONE)) { + const uinfo = readUartInfo(sensorInfo.port, 0); + sensorInfo.devType = uinfo[TypesOff.Type]; const mode = uinfo[TypesOff.Mode]; - control.dmesg(`UART type ${sensorInfo.devType} mode ${mode}`) + control.dmesg(`UART type ${sensorInfo.devType} mode ${mode} at port ${sensorInfo.port}`); } } - if (numChanged == 0 && nonActivated == 0) - return - - //control.dmesg(`updating sensor status`) - nonActivated = 0; - for (const sensorInfo of sensorInfos) { + control.dmesg(`UPDATE SENSOR STATUS`); + for (const sensorInfo of sensorInfos.filter(si => !si.sensor)) { if (sensorInfo.devType == DAL.DEVICE_TYPE_IIC_UNKNOWN) { - sensorInfo.sensor = sensorInfo.sensors.filter(s => s._IICId() == sensorInfo.iicid)[0] + sensorInfo.sensor = sensorInfo.sensors.filter(s => s._IICId() == sensorInfo.iicid)[0]; if (!sensorInfo.sensor) { - control.dmesg(`sensor not found for iicid=${sensorInfo.iicid} at ${sensorInfo.port}`) - nonActivated++; + control.dmesg(`sensor not found for iicid=${sensorInfo.iicid} at port ${sensorInfo.port}`); } else { - control.dmesg(`sensor connected iicid=${sensorInfo.iicid} at ${sensorInfo.port}`) - sensorInfo.sensor._activated() + control.dmesg(`sensor connected iicid=${sensorInfo.iicid} at port ${sensorInfo.port}`); + sensorInfo.sensor._activated(); } } else if (sensorInfo.devType != DAL.DEVICE_TYPE_NONE) { - sensorInfo.sensor = sensorInfo.sensors.filter(s => s._deviceType() == sensorInfo.devType)[0] + sensorInfo.sensor = sensorInfo.sensors.filter(s => s._deviceType() == sensorInfo.devType)[0]; if (!sensorInfo.sensor) { - control.dmesg(`sensor not found for type=${sensorInfo.devType} at ${sensorInfo.port}`) - nonActivated++; + control.dmesg(`sensor not found for type=${sensorInfo.devType} at port ${sensorInfo.port}`); } else { - control.dmesg(`sensor connected type=${sensorInfo.devType} at ${sensorInfo.port}`) - sensorInfo.sensor._activated() + control.dmesg(`sensor connected type=${sensorInfo.devType} at port ${sensorInfo.port}`); + sensorInfo.sensor._activated(); } } } - //control.dmesg(`detect devices done`) + + control.dmesg(`DETECT DEVICES DONE`); } export class Sensor extends control.Component { @@ -392,16 +330,12 @@ void cUiUpdatePower(void) return sensorInfos[this._port].sensor == this } - _query() { - return 0 - } - - _info(): string { - return this._query().toString(); + _query(): number[] { + return [0]; } - _infoArr(): string[] { - return [this._query().toString()]; + _info(): string[] { + return [this._query()[0].toString()]; } _update(prev: number, curr: number) { @@ -520,7 +454,28 @@ void cUiUpdatePower(void) } } - export const iicsensor = new IICSensor(3) + export const i2csensor1 = new IICSensor(1); + export const i2csensor2 = new IICSensor(2); + export const i2csensor3 = new IICSensor(3); + export const i2csensor4 = new IICSensor(4); + + function readUartInfo(port: number, mode: number) { + let buf = output.createBuffer(UartCtlOff.Size); + buf[UartCtlOff.Port] = port; + buf[UartCtlOff.Mode] = mode; + uartMM.ioctl(IO.UART_READ_MODE_INFO, buf); + //control.dmesg(`UART_READ_MODE p:${port} t:${buf[TypesOff.Type]} c:${buf[TypesOff.Connection]} m:${buf[TypesOff.Mode]} n:${buf.slice(0, 12).toHex()}`); + return buf; + } + + export function readIICID(port: number) { + const buf = output.createBuffer(IICStr.Size); + buf[IICStr.Port] = port; + IICMM.ioctl(IO.IIC_READ_TYPE_INFO, buf); + const manufacturer = bufferToString(buf.slice(IICStr.Manufacturer, 8)); + const sensorType = bufferToString(buf.slice(IICStr.SensorType, 8)); + return manufacturer + sensorType; + } function uartReset(port: number) { if (port < 0) return @@ -537,16 +492,18 @@ void cUiUpdatePower(void) } function waitNonZeroUartStatus(port: number) { - while (true) { - if (port < 0) return 0 - let s = getUartStatus(port) - if (s) return s - pause(25) + let retry = 20; + while (retry-- > 0) { + const s = getUartStatus(port); + if (s) return s; + control.dmesg(`UART status 0 at port ${port}, waiting...`); + pause(25); } + return 0; } function uartClearChange(port: number) { - control.dmesg(`UART clear change`); + control.dmesg(`UART clear change at port ${port}`); while (true) { let status = getUartStatus(port) if (port < 0) break @@ -557,18 +514,17 @@ void cUiUpdatePower(void) devcon.setNumber(NumberFormat.Int8LE, DevConOff.Connection + port, DAL.CONN_INPUT_UART) devcon.setNumber(NumberFormat.Int8LE, DevConOff.Type + port, 0) devcon.setNumber(NumberFormat.Int8LE, DevConOff.Mode + port, 0) - + control.dmesg(`UART_CLEAR_CHANGED status ${status} ${devcon.toHex()}`) uartMM.ioctl(IO.UART_CLEAR_CHANGED, devcon) - uartMM.setNumber(NumberFormat.Int8LE, UartOff.Status + port, - getUartStatus(port) & 0xfffe) + uartMM.setNumber(NumberFormat.Int8LE, UartOff.Status + port, getUartStatus(port) & 0xfffe) pause(10) } } function setUartModes() { - control.dmesg(`UART set modes 0x${devcon.toHex()}`) - uartMM.ioctl(IO.UART_SET_CONN, devcon) + control.dmesg(`UART_SET_CONN ${devcon.toHex()}`); + uartMM.ioctl(IO.UART_SET_CONN, devcon); const ports: number[] = []; for (let port = 0; port < DAL.NUM_INPUTS; ++port) { if (devcon.getNumber(NumberFormat.Int8LE, DevConOff.Connection + port) == DAL.CONN_INPUT_UART) { @@ -578,38 +534,36 @@ void cUiUpdatePower(void) while (ports.length) { const port = ports.pop(); - const status = waitNonZeroUartStatus(port) - control.dmesg(`UART status ${status} at ${port}`); + const status = waitNonZeroUartStatus(port); + control.dmesg(`UART status ${status} at port ${port}`); if (!(status & UART_DATA_READY)) setUartMode(port, devcon[DevConOff.Mode + port]); } } function updateUartMode(port: number, mode: number) { - control.dmesg(`UART update mode to ${mode} at ${port}`) + control.dmesg(`UART update mode to ${mode} at port ${port}`); devcon.setNumber(NumberFormat.Int8LE, DevConOff.Connection + port, DAL.CONN_INPUT_UART) devcon.setNumber(NumberFormat.Int8LE, DevConOff.Type + port, 33) devcon.setNumber(NumberFormat.Int8LE, DevConOff.Mode + port, mode) } - - const UART_PORT_CHANGED = 1 - const UART_DATA_READY = 8 + function setUartMode(port: number, mode: number) { while (true) { - if (port < 0) return + if (port < 0) return; updateUartMode(port, mode); - control.dmesg(`UART set mode 0x${devcon.toHex()}`) - uartMM.ioctl(IO.UART_SET_CONN, devcon) - let status = waitNonZeroUartStatus(port) + control.dmesg(`UART_SET_CONN ${devcon.toHex()}`); + uartMM.ioctl(IO.UART_SET_CONN, devcon); + let status = waitNonZeroUartStatus(port); if (status & UART_PORT_CHANGED) { - control.dmesg(`UART clear changed at ${port}`) - uartClearChange(port) + control.dmesg(`UART clear changed at port ${port}`); + uartClearChange(port); } else { - control.dmesg(`UART status ${status}`); + control.dmesg(`UART status ${status} at port ${port}`); if (status & UART_DATA_READY) break; } - pause(10) + pause(10); } } @@ -638,7 +592,7 @@ void cUiUpdatePower(void) export function transactionIIC(port: number, deviceAddress: number, writeBuf: number[], readLen: number) { if (port < 0) return; - let iicdata = output.createBuffer(IICDat.Size) + const iicdata = output.createBuffer(IICDat.Size) iicdata.setNumber(NumberFormat.Int8LE, IICDat.Port, port) iicdata.setNumber(NumberFormat.Int8LE, IICDat.Repeat, 0) iicdata.setNumber(NumberFormat.Int16LE, IICDat.Time, 0) diff --git a/libs/core/pxt.json b/libs/core/pxt.json index d2b1a923..b72d6d61 100644 --- a/libs/core/pxt.json +++ b/libs/core/pxt.json @@ -13,6 +13,7 @@ "timer.ts", "serialnumber.cpp", "buttons.ts", + "indicator.ts", "screen.cpp", "battery.ts", "output.cpp", diff --git a/libs/ev3/brick.ts b/libs/ev3/brick.ts index 16c073ef..d8c5f10c 100644 --- a/libs/ev3/brick.ts +++ b/libs/ev3/brick.ts @@ -6,7 +6,7 @@ namespace brick { //% help=reference/brick/exit-program //% weight=10 //% blockGap=8 - //% group="Buttons" + //% group="Program" export function exitProgram() { control.reset(); } diff --git a/libs/ev3/ns.ts b/libs/ev3/ns.ts index 6a0f436d..812781b8 100644 --- a/libs/ev3/ns.ts +++ b/libs/ev3/ns.ts @@ -1,5 +1,5 @@ //% color="#68C3E2" weight=100 icon="\uf106" -//% groups='["Buttons", "Screen", "Power"]' +//% groups='["Buttons", "Indicator", "Screen", "Power", "Program"]' //% labelLineWidth=60 namespace brick { } @@ -7,6 +7,7 @@ namespace brick { //% color="#C8509B" weight=95 icon="\uf10f" //% labelLineWidth=100 //% groups='["Touch Sensor", "Color Sensor", "Ultrasonic Sensor", "Gyro Sensor", "Infrared Sensor", "Remote Infrared Beacon", "Calibration"]' +//% subcategories='["NXT", "HiTechnic"]' namespace sensors { } diff --git a/libs/gyro-sensor/gyro.ts b/libs/gyro-sensor/gyro.ts index 208a748f..7e73153e 100644 --- a/libs/gyro-sensor/gyro.ts +++ b/libs/gyro-sensor/gyro.ts @@ -23,10 +23,10 @@ namespace sensors { return DAL.DEVICE_TYPE_GYRO } - _query(): number { + _query() { const v = this.getNumber(NumberFormat.Int16LE, 0); this._angle.integrate(v - this._drift); - return v; + return [v]; } setMode(m: GyroSensorMode) { @@ -73,7 +73,7 @@ namespace sensors { this.poke(); if (this._calibrating) pauseUntil(() => !this._calibrating, 2000); - return this._query() - this._drift; + return this._query()[0] - this._drift; } /** @@ -253,21 +253,21 @@ namespace sensors { const n = 10; let d = 0; for (let i = 0; i < n; ++i) { - d += this._query(); + d += this._query()[0]; pause(20); } this._drift = d / n; this._angle.reset(); } - _info(): string { + _info() { if (this._calibrating) - return "cal..."; + return ["cal..."]; - let r = `${this._query()}r`; + let r = `${this._query()[0]}r`; if (this._drift != 0) r += `-${this._drift | 0}`; - return r; + return [r]; } } diff --git a/libs/infrared-sensor/ir.ts b/libs/infrared-sensor/ir.ts index cadecac7..99763386 100644 --- a/libs/infrared-sensor/ir.ts +++ b/libs/infrared-sensor/ir.ts @@ -155,19 +155,19 @@ namespace sensors { _query() { if (this.mode == InfraredSensorMode.RemoteControl) - return mapButton(this.getNumber(NumberFormat.UInt8LE, this._channel)); + return [mapButton(this.getNumber(NumberFormat.UInt8LE, this._channel))]; else if (this.mode == InfraredSensorMode.Proximity) { - return this.getNumber(NumberFormat.UInt16LE, 0) & 0x0fff; + return [this.getNumber(NumberFormat.UInt16LE, 0) & 0x0fff]; } - return 0 + return [0]; } - _info(): string { + _info() { if (this.mode == InfraredSensorMode.RemoteControl) - return "remote"; + return ["remote"]; else if (this.mode == InfraredSensorMode.Proximity) - return `${this._query()}%`; - return ""; + return [`${this._query()}%`]; + return [""]; } _update(prev: number, curr: number) { diff --git a/libs/screen/targetoverrides.ts b/libs/screen/targetoverrides.ts index 92d8dacc..aef10628 100644 --- a/libs/screen/targetoverrides.ts +++ b/libs/screen/targetoverrides.ts @@ -272,13 +272,13 @@ namespace brick { const x = (si.port() - 1) * col + 2; const inf = si._info(); if (screenMode != ScreenMode.Ports) return; - if (inf == "array") { - let infArr = si._infoArr(); + if (inf.length > 1) { + let infArr = si._info(); for (let data = 0, str = Math.min(infArr.length + 1, 4); data < Math.min(infArr.length, 3); data++, str--) { screen.print(infArr[data], x, h - str * lineHeight8, 1, infArr[data].length > 4 ? image.font5 : image.font8); } - } else if (inf) { - screen.print(inf, x, h - 2 * lineHeight8, 1, inf.length > 4 ? image.font5 : image.font8); + } else if (inf[0]) { + screen.print(inf[0], x, h - 2 * lineHeight8, 1, inf[0].length > 4 ? image.font5 : image.font8); } } } diff --git a/libs/touch-sensor/touch.ts b/libs/touch-sensor/touch.ts index 854220b4..8c3fb979 100644 --- a/libs/touch-sensor/touch.ts +++ b/libs/touch-sensor/touch.ts @@ -12,11 +12,11 @@ namespace sensors { } _query() { - return this._readPin6() > 2500 ? 1 : 0 + return this._readPin6() > 2500 ? [1] : [0]; } - _info(): string { - return this._query() ? "pres" : "rel"; + _info() { + return this._query() ? ["pres"] : ["rel"]; } _update(prev: number, curr: number) { diff --git a/libs/ultrasonic-sensor/ultrasonic.ts b/libs/ultrasonic-sensor/ultrasonic.ts index 8ed8bc22..a9fe0690 100644 --- a/libs/ultrasonic-sensor/ultrasonic.ts +++ b/libs/ultrasonic-sensor/ultrasonic.ts @@ -23,12 +23,12 @@ namespace sensors { return DAL.DEVICE_TYPE_ULTRASONIC } - _query(): number { - return ((this.getNumber(NumberFormat.UInt16LE, 0) & 0x0fff) / 10) >> 0; // range is 0..2550, in 0.1 cm increments. + _query() { + return [((this.getNumber(NumberFormat.UInt16LE, 0) & 0x0fff) / 10) >> 0]; // range is 0..2550, in 0.1 cm increments. } - _info(): string { - return `${this.distance()}cm` + _info() { + return [`${this.distance()}cm`]; } _update(prev: number, curr: number) { @@ -87,7 +87,7 @@ namespace sensors { this.poke(); // it supposedly also has an inch mode, but we stick to cm this._setMode(0) - return this._query(); + return this._query()[0]; } diff --git a/package.json b/package.json index b000b91e..8846277c 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,7 @@ }, "dependencies": { "pxt-common-packages": "11.1.2", - "pxt-core": "9.1.10" + "pxt-core": "9.1.23" }, "scripts": { "test": "node node_modules/pxt-core/built/pxt.js travis" diff --git a/theme/style.less b/theme/style.less index c7fefa6b..47092260 100644 --- a/theme/style.less +++ b/theme/style.less @@ -76,6 +76,11 @@ min-width: 2.0rem; } +/* lego and microsoft logos separator */ +.menubar .ui.menu .brand:before { + border-left: 2px solid #888888; +} + /* Editor menu toggle */ #root:not(.hc) #editordropdown { padding: 0 1em; @@ -102,7 +107,7 @@ } .menubar .ui.item.editor-menuitem .item.toggle { - height: 45px; + height: 100%; } .sandboxfooter a:not(.thin) { From c1d3a5ce5b4229c8f0876d47a1f21915e632bee5 Mon Sep 17 00:00:00 2001 From: Joey Wunderlich Date: Fri, 3 Nov 2023 09:49:35 -0700 Subject: [PATCH 5/5] 1.4.37 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8846277c..daa1c029 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "pxt-ev3", - "version": "1.4.36", + "version": "1.4.37", "description": "LEGO MINDSTORMS EV3 for Microsoft MakeCode", "private": false, "keywords": [