Compare commits

...

21 Commits

Author SHA1 Message Date
8b3064f4e0 0.0.13 2017-08-08 13:05:00 -07:00
138709285a bump pxt-core to 2.0.9, 2017-08-08 13:04:55 -07:00
65dd4617f1 Add get speed block 2017-08-08 13:02:11 -07:00
bdc8c1c62c bump pxt-core to 2.0.8, 2017-08-08 12:04:54 -07:00
ebcde71950 Fix hid deployment from command line 2017-08-08 11:47:10 +02:00
d42117a2a5 Add reading motor speed data (untested) 2017-08-08 11:41:47 +02:00
b0145cf378 Fix test.ts so it compiles 2017-08-08 11:41:31 +02:00
868ee826ab 0.0.12 2017-08-07 23:40:14 -07:00
ce489bba56 Update core-strings 2017-08-07 23:39:54 -07:00
b0944ba431 Change say to print. 2017-08-07 21:50:45 -07:00
8736d32f09 Add screen blocks 2017-08-07 21:50:04 -07:00
f8c481555c 0.0.11 2017-08-07 17:39:55 -07:00
15f50966aa Update motor APIs 2017-08-07 17:39:37 -07:00
88e21db35e fixing raiseEvent 2017-08-07 12:07:43 -07:00
4e9d3aa413 0.0.10 2017-08-07 11:33:51 -07:00
1efad776e6 bump pxt-core to 2.0.6, 2017-08-07 11:33:46 -07:00
5e7af872b5 Add setLights shadow block 2017-08-07 10:19:38 -07:00
17683033b1 Add branch info 2017-08-07 12:15:56 +02:00
31f3d108c5 Update build instructions 2017-08-07 12:15:06 +02:00
b45bf7512c 0.0.9 2017-08-07 11:13:05 +02:00
2dec405a9b Catch errors from initAsync 2017-08-07 11:12:52 +02:00
12 changed files with 204 additions and 35 deletions

View File

@ -9,12 +9,12 @@ This repo contains the editor target hosted at https://lego.makecode.com
These instructions assume familiarity with dev tools and languages. These instructions assume familiarity with dev tools and languages.
* install Node.js 6+ * install Node.js 6+
* install [yotta](http://docs.yottabuild.org/#installing) * install Docker; make sure `docker` command is in your `PATH`
* (optional) install [Visual Studio Code](https://code.visualstudio.com/) * (optional) install [Visual Studio Code](https://code.visualstudio.com/)
In a common folder, In a common folder,
* clone https://github.com/Microsoft/pxt to ``pxt`` folder * clone https://github.com/Microsoft/pxt to ``pxt`` folder (currently, build against `freshcoat` branch)
* clone https://github.com/Microsoft/pxt-common-packages to ``pxt-common-packages`` folder * clone https://github.com/Microsoft/pxt-common-packages to ``pxt-common-packages`` folder
* clone https://github.com/Microsoft/pxt-ev3 to ``pxt-ev3`` folder * clone https://github.com/Microsoft/pxt-ev3 to ``pxt-ev3`` folder
* go to ``pxt`` and run * go to ``pxt`` and run

View File

@ -28,18 +28,33 @@ namespace pxt.editor {
let initPromise: Promise<Ev3Wrapper> let initPromise: Promise<Ev3Wrapper>
function initAsync() { function initAsync() {
const forceHexDownload = /forceHexDownload/i.test(window.location.href); if (initPromise)
if (!initPromise && Cloud.isLocalHost() && Cloud.localToken && !forceHexDownload) return initPromise
let canHID = false
if (U.isNodeJS) {
canHID = true
} else {
const forceHexDownload = /forceHexDownload/i.test(window.location.href);
if (Cloud.isLocalHost() && Cloud.localToken && !forceHexDownload)
canHID = true
}
if (noHID)
canHID = false
if (canHID) {
initPromise = hf2Async() initPromise = hf2Async()
.catch(err => { .catch(err => {
initPromise = null initPromise = null
noHID = true noHID = true
return Promise.reject(err) return Promise.reject(err)
}) })
else { } else {
noHID = true noHID = true
initPromise = Promise.reject(new Error("no HID")) initPromise = Promise.reject(new Error("no HID"))
} }
return initPromise return initPromise
} }
@ -121,13 +136,9 @@ namespace pxt.editor {
const res: pxt.editor.ExtensionResult = { const res: pxt.editor.ExtensionResult = {
deployCoreAsync, deployCoreAsync,
}; };
initAsync() initAsync().catch(e => {
/* // probably no HID - we'll try this again upon deployment
.then(w => w.streamFileAsync("/tmp/serial.txt", buf => { })
let str = Util.fromUTF8(Util.uint8ArrayToString(buf))
}))
*/
return Promise.resolve<pxt.editor.ExtensionResult>(res); return Promise.resolve<pxt.editor.ExtensionResult>(res);
} }
} }

View File

@ -20,10 +20,33 @@
"input.remoteTopRight": "Remote top-right button.", "input.remoteTopRight": "Remote top-right button.",
"output.createBuffer": "Create a new zero-initialized buffer.", "output.createBuffer": "Create a new zero-initialized buffer.",
"output.createBuffer|param|size": "number of bytes in the buffer", "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": "Set lights.",
"output.setLights|param|pattern": "the lights pattern to use.",
"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.start": "Turn motor on.",
"output.start|param|out": "the output connection that the motor is connected to",
"output.stop": "Turn motor off.",
"output.stop|param|out": "the output connection that the motor is connected to",
"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",
"output.turn|param|useBrake": "whether or not to use the brake, defaults to false",
"screen.clear": "Clear screen and reset font to normal.", "screen.clear": "Clear screen and reset font to normal.",
"screen.doubleIcon": "Double size of an icon.", "screen.doubleIcon": "Double size of an icon.",
"screen.drawIcon": "Draw an icon on the screen.", "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",
"serial": "Reading and writing data over a serial connection.", "serial": "Reading and writing data over a serial connection.",
"serial.writeDmesg": "Send DMESG debug buffer over serial." "serial.writeDmesg": "Send DMESG debug buffer over serial."
} }

View File

@ -3,7 +3,7 @@
"ButtonEvent.Down|block": "down", "ButtonEvent.Down|block": "down",
"ButtonEvent.LongClick|block": "long click", "ButtonEvent.LongClick|block": "long click",
"ButtonEvent.Up|block": "up", "ButtonEvent.Up|block": "up",
"control.raiseEvent|block": "raise event|from %src|with value value", "control.raiseEvent|block": "raise event|from %src|with value %value",
"control|block": "control", "control|block": "control",
"input.buttonDown|block": "button down", "input.buttonDown|block": "button down",
"input.buttonEnter|block": "button enter", "input.buttonEnter|block": "button enter",
@ -16,13 +16,24 @@
"input.remoteTopLeft|block": "remote top-left", "input.remoteTopLeft|block": "remote top-left",
"input.remoteTopRight|block": "remote top-right", "input.remoteTopRight|block": "remote top-right",
"input|block": "input", "input|block": "input",
"output.setLights|block": "set lights %pattern", "output.getCurrentSpeed|block": "motor %out|speed",
"output.getPattern|block": "%pattern",
"output.setLights|block": "set status light %pattern=led_pattern",
"output.setPower|block": "set motor %out| power to %power",
"output.setSpeed|block": "set motor %out| speed to %speed",
"output.start|block": "turn motor %out|on",
"output.stop|block": "turn motor %out|off",
"output.turn|block": "turn motor %out| on for %ms|milliseconds",
"output|block": "output", "output|block": "output",
"screen.drawText|block": "print %text| at x: %x| y: %y",
"screen|block": "screen", "screen|block": "screen",
"serial|block": "serial", "serial|block": "serial",
"{id:category}Control": "Control", "{id:category}Control": "Control",
"{id:category}Input": "Input", "{id:category}Input": "Input",
"{id:category}Output": "Output", "{id:category}Output": "Output",
"{id:category}Screen": "Screen", "{id:category}Screen": "Screen",
"{id:category}Serial": "Serial" "{id:category}Serial": "Serial",
"{id:group}Lights": "Lights",
"{id:group}Motors": "Motors",
"{id:group}Screen": "Screen"
} }

View File

@ -70,6 +70,7 @@ namespace input {
//% blockGap=8 //% blockGap=8
//% parts="buttonpair" //% parts="buttonpair"
//% blockNamespace=input //% blockNamespace=input
//% group="Brick buttons"
//% button.fieldEditor="gridpicker" //% button.fieldEditor="gridpicker"
//% button.fieldOptions.width=220 //% button.fieldOptions.width=220
//% button.fieldOptions.columns=3 //% button.fieldOptions.columns=3
@ -86,6 +87,7 @@ namespace input {
//% blockId=buttonWasPressed //% blockId=buttonWasPressed
//% parts="buttonpair" blockGap=8 //% parts="buttonpair" blockGap=8
//% blockNamespace=input advanced=true //% blockNamespace=input advanced=true
//% group="Brick buttons"
//% button.fieldEditor="gridpicker" //% button.fieldEditor="gridpicker"
//% button.fieldOptions.width=220 //% button.fieldOptions.width=220
//% button.fieldOptions.columns=3 //% button.fieldOptions.columns=3
@ -105,6 +107,7 @@ namespace input {
//% blockId=buttonEvent block="on %button|%event" //% blockId=buttonEvent block="on %button|%event"
//% parts="buttonpair" //% parts="buttonpair"
//% blockNamespace=input //% blockNamespace=input
//% group="Brick buttons"
//% button.fieldEditor="gridpicker" //% button.fieldEditor="gridpicker"
//% button.fieldOptions.width=220 //% button.fieldOptions.width=220
//% button.fieldOptions.columns=3 //% button.fieldOptions.columns=3
@ -215,9 +218,11 @@ namespace output {
/** /**
* Set lights. * Set lights.
* @param pattern the lights pattern to use.
*/ */
//% blockId=setLights block="set lights %pattern" //% blockId=setLights block="set status light %pattern=led_pattern"
export function setLights(pattern: LightsPattern): void { //% weight=100 group="Lights"
export function setLights(pattern: number): void {
if (currPattern === pattern) if (currPattern === pattern)
return return
currPattern = pattern currPattern = pattern
@ -225,4 +230,16 @@ namespace output {
cmd[0] = pattern + 48 cmd[0] = pattern + 48
input.internal.getBtnsMM().write(cmd) input.internal.getBtnsMM().write(cmd)
} }
/**
* Pattern block.
* @param pattern the lights pattern to use. eg: LightsPattern.Green
*/
//% blockId=led_pattern block="%pattern"
//% shim=TD_ID colorSecondary="#6e9a36"
//% blockHidden=true
export function getPattern(pattern: LightsPattern): number {
return pattern;
}
} }

View File

@ -9,7 +9,7 @@ namespace control {
* @param mode optional definition of how the event should be processed after construction. * @param mode optional definition of how the event should be processed after construction.
*/ */
//% weight=21 blockGap=12 blockId="control_raise_event" //% weight=21 blockGap=12 blockId="control_raise_event"
//% block="raise event|from %src|with value value" blockExternalInputs=1 //% block="raise event|from %src|with value %value" blockExternalInputs=1
void raiseEvent(int src, int value) { void raiseEvent(int src, int value) {
pxt::raiseEvent(src, value); pxt::raiseEvent(src, value);
} }

View File

@ -42,6 +42,11 @@ namespace output {
pwmMM.write(buf) pwmMM.write(buf)
} }
function readPWM(buf: Buffer): void {
init()
pwmMM.read(buf);
}
function mkCmd(out: Output, cmd: number, addSize: number) { function mkCmd(out: Output, cmd: number, addSize: number) {
let b = createBuffer(2 + addSize) let b = createBuffer(2 + addSize)
b.setNumber(NumberFormat.UInt8LE, 0, cmd) b.setNumber(NumberFormat.UInt8LE, 0, cmd)
@ -49,12 +54,43 @@ namespace output {
return b return b
} }
export function stop(out: Output, useBreak = false) { /**
* Turn a motor on for a specified number of milliseconds.
* @param out the output connection that the motor is connected to
* @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"
//% weight=100 group="Motors"
export function turn(out: Output, ms: number, useBrake = false) {
// TODO: use current power / speed configuration
output.step(out, {
power: 100,
step1: 0,
step2: ms,
step3: 0,
useBrake: useBrake
})
}
/**
* Turn motor off.
* @param out the output connection that the motor is connected to
*/
//% blockId=output_stop block="turn motor %out|off"
//% weight=90 group="Motors"
export function stop(out: Output, useBrake = false) {
let b = mkCmd(out, DAL.opOutputStop, 1) let b = mkCmd(out, DAL.opOutputStop, 1)
b.setNumber(NumberFormat.UInt8LE, 2, useBreak ? 1 : 0) b.setNumber(NumberFormat.UInt8LE, 2, useBrake ? 1 : 0)
writePWM(b) writePWM(b)
} }
/**
* Turn motor on.
* @param out the output connection that the motor is connected to
*/
//% blockId=output_start block="turn motor %out|on"
//% weight=95 group="Motors"
export function start(out: Output) { export function start(out: Output) {
let b = mkCmd(out, DAL.opOutputStart, 0) let b = mkCmd(out, DAL.opOutputStart, 0)
writePWM(b) writePWM(b)
@ -65,12 +101,72 @@ namespace output {
writePWM(b) writePWM(b)
} }
export function clearCount(out: Output) {
let b = mkCmd(out, DAL.opOutputClearCount, 0)
writePWM(b)
for (let i = 0; i < DAL.NUM_OUTPUTS; ++i) {
if (out & (1 << i)) {
motorMM.setNumber(NumberFormat.Int32LE, i * MotorDataOff.Size + MotorDataOff.TachoSensor, 0)
}
}
}
function outOffset(out: Output) {
for (let i = 0; i < DAL.NUM_OUTPUTS; ++i) {
if (out & (1 << i))
return i * MotorDataOff.Size
}
return 0
}
export interface MotorData {
actualSpeed: number; // -100..+100
tachoCount: number;
count: number;
}
// only a single output at a time
export function getMotorData(out: Output): MotorData {
let buf = motorMM.slice(outOffset(out), MotorDataOff.Size)
return {
actualSpeed: buf.getNumber(NumberFormat.Int8LE, MotorDataOff.Speed),
tachoCount: buf.getNumber(NumberFormat.Int32LE, MotorDataOff.TachoCounts),
count: buf.getNumber(NumberFormat.Int32LE, MotorDataOff.TachoSensor),
}
}
/**
* Get motor speed.
* @param out the output connection that the motor is connected to
*/
//% blockId=output_getCurrentSpeed block="motor %out|speed"
//% weight=70 group="Motors"
export function getCurrentSpeed(out: Output) {
return getMotorData(out).actualSpeed;
}
/**
* Set motor speed.
* @param out the output connection that the motor is connected to
* @param speed the desired speed to use. eg: 100
*/
//% blockId=output_setSpeed block="set motor %out| speed to %speed"
//% weight=81 group="Motors"
//% speed.min=-100 speed.max=100
export function setSpeed(out: Output, speed: number) { export function setSpeed(out: Output, speed: number) {
let b = mkCmd(out, DAL.opOutputSpeed, 1) let b = mkCmd(out, DAL.opOutputSpeed, 1)
b.setNumber(NumberFormat.Int8LE, 2, Math.clamp(-100, 100, speed)) b.setNumber(NumberFormat.Int8LE, 2, Math.clamp(-100, 100, speed))
writePWM(b) writePWM(b)
} }
/**
* Set motor power.
* @param out the output connection that the motor is connected to
* @param power the desired power to use. eg: 100
*/
//% blockId=output_setPower block="set motor %out| power to %power"
//% weight=80 group="Motors"
//% power.min=-100 power.max=100
export function setPower(out: Output, power: number) { export function setPower(out: Output, power: number) {
let b = mkCmd(out, DAL.opOutputPower, 1) let b = mkCmd(out, DAL.opOutputPower, 1)
b.setNumber(NumberFormat.Int8LE, 2, Math.clamp(-100, 100, power)) b.setNumber(NumberFormat.Int8LE, 2, Math.clamp(-100, 100, power))
@ -90,7 +186,7 @@ namespace output {
step2: number; step2: number;
step3: number; step3: number;
useSteps?: boolean; // otherwise use milliseconds useSteps?: boolean; // otherwise use milliseconds
useBreak?: boolean; useBrake?: boolean;
} }
export function step(out: Output, opts: StepOptions) { export function step(out: Output, opts: StepOptions) {
@ -110,7 +206,7 @@ namespace output {
b.setNumber(NumberFormat.Int32LE, 4 + 4 * 0, opts.step1) b.setNumber(NumberFormat.Int32LE, 4 + 4 * 0, opts.step1)
b.setNumber(NumberFormat.Int32LE, 4 + 4 * 1, opts.step2) b.setNumber(NumberFormat.Int32LE, 4 + 4 * 1, opts.step2)
b.setNumber(NumberFormat.Int32LE, 4 + 4 * 2, opts.step3) b.setNumber(NumberFormat.Int32LE, 4 + 4 * 2, opts.step3)
b.setNumber(NumberFormat.Int8LE, 4 + 4 * 3, opts.useBreak ? 1 : 0) b.setNumber(NumberFormat.Int8LE, 4 + 4 * 3, opts.useBrake ? 1 : 0)
writePWM(b) writePWM(b)
} }

View File

@ -85,7 +85,16 @@ namespace screen {
_setPixel(x, y, mode) _setPixel(x, y, mode)
} }
export function drawText(x: number, y: number, text: string, mode = Draw.Normal) {
/**
* Show text on the screen.
* @param text the text to print on the screen, eg: "Hello world"
* @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"
export function drawText(text: string, x: number, y: number, mode = Draw.Normal) {
x |= 0 x |= 0
y |= 0 y |= 0
if (!currFont) currFont = defaultFont() if (!currFont) currFont = defaultFont()

View File

@ -51,7 +51,7 @@ declare namespace control {
* @param mode optional definition of how the event should be processed after construction. * @param mode optional definition of how the event should be processed after construction.
*/ */
//% weight=21 blockGap=12 blockId="control_raise_event" //% weight=21 blockGap=12 blockId="control_raise_event"
//% block="raise event|from %src|with value value" blockExternalInputs=1 shim=control::raiseEvent //% block="raise event|from %src|with value %value" blockExternalInputs=1 shim=control::raiseEvent
function raiseEvent(src: int32, value: int32): void; function raiseEvent(src: int32, value: int32): void;
/** /**

View File

@ -1,10 +1,10 @@
screen.clear() screen.clear()
screen.drawText(10, 30, "PXT!", Draw.Quad) screen.drawText("PXT!", 10, 30, Draw.Quad)
screen.drawRect(40, 40, 20, 10, Draw.Fill) screen.drawRect(40, 40, 20, 10, Draw.Fill)
output.setLights(LightsPattern.Orange) output.setLights(LightsPattern.Orange)
screen.drawIcon(100, 50, screen.doubleIcon(screen.heart), Draw.Double|Draw.Transparent) screen.drawIcon(100, 50, screen.doubleIcon(screen.heart), Draw.Double | Draw.Transparent)
input.buttonEnter.onEvent(ButtonEvent.Click, () => { input.buttonEnter.onEvent(ButtonEvent.Click, () => {
screen.clear() screen.clear()
@ -17,32 +17,32 @@ input.buttonLeft.onEvent(ButtonEvent.Click, () => {
}) })
input.buttonRight.onEvent(ButtonEvent.Click, () => { input.buttonRight.onEvent(ButtonEvent.Click, () => {
screen.drawText(10, 60, "Right!") screen.drawText("Right!", 10, 60)
}) })
input.buttonDown.onEvent(ButtonEvent.Click, () => { input.buttonDown.onEvent(ButtonEvent.Click, () => {
screen.drawText(10, 60, "Down! ") screen.drawText("Down! ", 10, 60)
}) })
input.buttonUp.onEvent(ButtonEvent.Click, () => { input.buttonUp.onEvent(ButtonEvent.Click, () => {
screen.drawText(10, 60, "Up! ") screen.drawText("Up! ", 10, 60)
}) })
let num = 0 let num = 0
input.touchSensor.onEvent(ButtonEvent.Click, () => { input.touchSensor.onEvent(ButtonEvent.Click, () => {
screen.drawText(10, 60, "Click! " + num) screen.drawText("Click! " + num, 10, 60)
num++ num++
}) })
input.remoteTopLeft.onEvent(ButtonEvent.Click, () => { input.remoteTopLeft.onEvent(ButtonEvent.Click, () => {
screen.drawText(10, 60, "TOPLEFT " + num) screen.drawText("TOPLEFT " + num, 10, 60)
num++ num++
}) })
input.remoteTopRight.onEvent(ButtonEvent.Down, () => { input.remoteTopRight.onEvent(ButtonEvent.Down, () => {
screen.drawText(10, 60, "TOPRIGH " + num) screen.drawText("TOPRIGH " + num, 10, 60)
num++ num++
}) })

View File

@ -1,9 +1,11 @@
//% color="#D42878" //% color="#D42878"
//% groups="['Brick buttons']"
namespace input { namespace input {
} }
//% color="#8AC044" weight=90 icon="\uf185" //% color="#8AC044" weight=90 icon="\uf185"
//% groups="['Lights', 'Screen', Motors']"
namespace output { namespace output {
} }

View File

@ -1,6 +1,6 @@
{ {
"name": "pxt-ev3", "name": "pxt-ev3",
"version": "0.0.8", "version": "0.0.13",
"description": "LEGO Mindstorms EV3 for Microsoft MakeCode", "description": "LEGO Mindstorms EV3 for Microsoft MakeCode",
"private": true, "private": true,
"keywords": [ "keywords": [
@ -40,7 +40,7 @@
}, },
"dependencies": { "dependencies": {
"pxt-common-packages": "0.9.2", "pxt-common-packages": "0.9.2",
"pxt-core": "2.0.2" "pxt-core": "2.0.9"
}, },
"scripts": { "scripts": {
"test": "node node_modules/pxt-core/built/pxt.js travis" "test": "node node_modules/pxt-core/built/pxt.js travis"