Compare commits
42 Commits
Author | SHA1 | Date | |
---|---|---|---|
a054fdd3d3 | |||
a239589913 | |||
98a046237c | |||
eb385ec532 | |||
2fdce16685 | |||
74eb77a9ae | |||
4fba96588f | |||
03c07bdcf5 | |||
6da1bc3cb1 | |||
dfc9ca1db4 | |||
83b64c1e54 | |||
a0cf8655f2 | |||
e4cf2c99c0 | |||
076fb8487e | |||
c725561389 | |||
3dc781f4fd | |||
4456767f2d | |||
6dba240899 | |||
d7172a1f3a | |||
245ff9d5b2 | |||
bfb258ce61 | |||
63beb2cac7 | |||
73d3dce139 | |||
21be8a5021 | |||
03a82d6bcd | |||
60ea0f0cd5 | |||
f69a0d5289 | |||
e2e8536b37 | |||
4096875a88 | |||
9825a90df2 | |||
7ad5d123a3 | |||
3599483ed2 | |||
7a6818931f | |||
eda38ebbc4 | |||
026f7a3180 | |||
f58fcb60e2 | |||
dbda86abb5 | |||
3c13565e7c | |||
f8524cf1a7 | |||
bf4b1090fc | |||
ea4d8cf66a | |||
b32ae4e61a |
@ -82,12 +82,12 @@
|
|||||||
* [reset](/reference/sensors/gyro/reset)
|
* [reset](/reference/sensors/gyro/reset)
|
||||||
* [Ultrasonic](/reference/sensors/ultrasonic)
|
* [Ultrasonic](/reference/sensors/ultrasonic)
|
||||||
* [on event](/reference/sensors/ultrasonic/on-event)
|
* [on event](/reference/sensors/ultrasonic/on-event)
|
||||||
* [distance](reference/sensors/ultrasonic/distance)
|
* [distance](/reference/sensors/ultrasonic/distance)
|
||||||
* [pause until](reference/sensors/ultrasonic/pause-until)
|
* [pause until](/reference/sensors/ultrasonic/pause-until)
|
||||||
* [Infrared](/reference/sensors/infrared)
|
* [Infrared](/reference/sensors/infrared)
|
||||||
* [on event](/reference/sensors/infrared/on-event)
|
* [on event](/reference/sensors/infrared/on-event)
|
||||||
* [distance](reference/sensors/infrared/proximity)
|
* [distance](/reference/sensors/infrared/proximity)
|
||||||
* [pause until](reference/sensors/infrared/pause-until)
|
* [pause until](/reference/sensors/infrared/pause-until)
|
||||||
* [Infrared beacon](/reference/sensors/beacon)
|
* [Infrared beacon](/reference/sensors/beacon)
|
||||||
* [on event](/reference/sensors/beacon/on-event)
|
* [on event](/reference/sensors/beacon/on-event)
|
||||||
* [pause until](/reference/sensors/beacon/pause-until)
|
* [pause until](/reference/sensors/beacon/pause-until)
|
||||||
@ -123,3 +123,7 @@
|
|||||||
* [log](/reference/console/log)
|
* [log](/reference/console/log)
|
||||||
* [log value](/reference/console/log-value)
|
* [log value](/reference/console/log-value)
|
||||||
* [send to screen](/reference/console/send-to-screen)
|
* [send to screen](/reference/console/send-to-screen)
|
||||||
|
|
||||||
|
## #misc
|
||||||
|
|
||||||
|
## devs
|
||||||
|
@ -70,3 +70,12 @@
|
|||||||
|  |
|
|  |
|
||||||
| Download Button |
|
| Download Button |
|
||||||
|
|
||||||
|
#### #explorer-images
|
||||||
|
|
||||||
|
| |
|
||||||
|
|-|
|
||||||
|
|  |
|
||||||
|
| Explorer Button |
|
||||||
|
| |
|
||||||
|
|  |
|
||||||
|
| Explorer File View |
|
||||||
|
@ -20,6 +20,12 @@ Build a @boardname@ vehicle that can park itself safely without driver intervent
|
|||||||
|
|
||||||
[](https://le-www-live-s.legocdn.com/sc/media/lessons/mindstorms-ev3/building-instructions/ev3-rem-driving-base-79bebfc16bd491186ea9c9069842155e.pdf)
|
[](https://le-www-live-s.legocdn.com/sc/media/lessons/mindstorms-ev3/building-instructions/ev3-rem-driving-base-79bebfc16bd491186ea9c9069842155e.pdf)
|
||||||
|
|
||||||
|
### ~hint
|
||||||
|
|
||||||
|
If clicking the above image doesn't open the instructions, right-click on the image and choose "Save link as..." to download the PDF.
|
||||||
|
|
||||||
|
### ~
|
||||||
|
|
||||||
### Check
|
### Check
|
||||||
|
|
||||||
Before you program, check:
|
Before you program, check:
|
||||||
|
@ -24,6 +24,12 @@ Build red and green “lights” for your robot to detect. You can use LEGO bric
|
|||||||
|
|
||||||
[](https://le-www-live-s.legocdn.com/sc/media/files/support/mindstorms%20ev3/building-instructions/design%20engineering%20projects/color%20squares-0a88dfd98bb2e64b5b8151fc422bae36.pdf)
|
[](https://le-www-live-s.legocdn.com/sc/media/files/support/mindstorms%20ev3/building-instructions/design%20engineering%20projects/color%20squares-0a88dfd98bb2e64b5b8151fc422bae36.pdf)
|
||||||
|
|
||||||
|
### ~hint
|
||||||
|
|
||||||
|
If clicking the above images doesn't open the instructions, right-click on the image and choose "Save link as..." to download the PDF.
|
||||||
|
|
||||||
|
### ~
|
||||||
|
|
||||||
### Check
|
### Check
|
||||||
|
|
||||||
Before you program, check:
|
Before you program, check:
|
||||||
|
@ -24,6 +24,12 @@ Build an obstacle for your robot to detect. You can build the **cuboid model** o
|
|||||||
|
|
||||||
[](https://le-www-live-s.legocdn.com/sc/media/lessons/mindstorms-ev3/building-instructions/ev3-cuboid-dc93b2e60bed2981e76b3bac9ea04558.pdf)
|
[](https://le-www-live-s.legocdn.com/sc/media/lessons/mindstorms-ev3/building-instructions/ev3-cuboid-dc93b2e60bed2981e76b3bac9ea04558.pdf)
|
||||||
|
|
||||||
|
### ~hint
|
||||||
|
|
||||||
|
If clicking the above images doesn't open the instructions, right-click on the image and choose "Save link as..." to download the PDF.
|
||||||
|
|
||||||
|
### ~
|
||||||
|
|
||||||
### Check
|
### Check
|
||||||
|
|
||||||
Before you program, check:
|
Before you program, check:
|
||||||
|
@ -37,6 +37,12 @@ More building ideas:
|
|||||||
|
|
||||||
[](https://le-www-live-s.legocdn.com/sc/media/files/support/mindstorms%20ev3/building-instructions/design%20engineering%20projects/color%20sensor_v2-e7fd54b6fa3cdfe36f414c1d2510f9cb.pdf)
|
[](https://le-www-live-s.legocdn.com/sc/media/files/support/mindstorms%20ev3/building-instructions/design%20engineering%20projects/color%20sensor_v2-e7fd54b6fa3cdfe36f414c1d2510f9cb.pdf)
|
||||||
|
|
||||||
|
### ~hint
|
||||||
|
|
||||||
|
If clicking the above images doesn't open the instructions, right-click on the image and choose "Save link as..." to download the PDF.
|
||||||
|
|
||||||
|
### ~
|
||||||
|
|
||||||
|
|
||||||
Build a path for your robot to follow. You can use electrical tape on a floor, or marker on paper. You can use objects as milestones to indicate a path that can be detected by either the Touch Sensor, Color Sensor, or Ultrasonic Sensor.
|
Build a path for your robot to follow. You can use electrical tape on a floor, or marker on paper. You can use objects as milestones to indicate a path that can be detected by either the Touch Sensor, Color Sensor, or Ultrasonic Sensor.
|
||||||
|
|
||||||
@ -70,6 +76,12 @@ Two copies of the tracks are built: one for the right side and a mirror image fo
|
|||||||
|
|
||||||
[](https://le-www-live-s.legocdn.com/sc/media/lessons/mindstorms-ev3/ev3-dep/building%20instructions/track-rover-bi-6aadb1b053df0c58a0dea108b5ce0eea.pdf)
|
[](https://le-www-live-s.legocdn.com/sc/media/lessons/mindstorms-ev3/ev3-dep/building%20instructions/track-rover-bi-6aadb1b053df0c58a0dea108b5ce0eea.pdf)
|
||||||
|
|
||||||
|
### ~hint
|
||||||
|
|
||||||
|
If clicking the above image doesn't open the instructions, right-click on the image and choose "Save link as..." to download the PDF.
|
||||||
|
|
||||||
|
### ~
|
||||||
|
|
||||||
### Sample Program Solution
|
### Sample Program Solution
|
||||||
|
|
||||||
This program works with the Track Rover. If you create a different robot, adjust the program to fit your solution.
|
This program works with the Track Rover. If you create a different robot, adjust the program to fit your solution.
|
||||||
|
@ -30,6 +30,14 @@ If you want some building help you can follow these instructions.
|
|||||||
|
|
||||||
[](https://le-www-live-s.legocdn.com/sc/media/files/support/mindstorms%20ev3/building-instructions/design%20engineering%20projects/toddle%20bot-3dcad146d7f5deac4753f93e9dcc0739.pdf)
|
[](https://le-www-live-s.legocdn.com/sc/media/files/support/mindstorms%20ev3/building-instructions/design%20engineering%20projects/toddle%20bot-3dcad146d7f5deac4753f93e9dcc0739.pdf)
|
||||||
|
|
||||||
|
Click [here](https://le-www-live-s.legocdn.com/sc/media/files/support/mindstorms%20ev3/building-instructions/design%20engineering%20projects/toddle%20bot-3dcad146d7f5deac4753f93e9dcc0739.pdf)
|
||||||
|
|
||||||
|
### ~hint
|
||||||
|
|
||||||
|
If clicking the above image or link doesn't open the instructions, right-click on the link and choose "Save link as..." to download the PDF.
|
||||||
|
|
||||||
|
### ~
|
||||||
|
|
||||||
### Program
|
### Program
|
||||||
|
|
||||||
Before you program, think about:
|
Before you program, think about:
|
||||||
|
@ -36,22 +36,22 @@ Think about a creature’s movement for inspiration. Your mechanism can be attac
|
|||||||
|
|
||||||
More building ideas:
|
More building ideas:
|
||||||
|
|
||||||
| | | | | |
|
|
||||||
|-|-|-|-|-|
|
|
||||||
|[][EV3 Frames] | |[][Color Sensor 1] | |[][Gyro Sensor] |
|
|
||||||
| [EV3 Frames] | | [Color Sensor 1] | | [Gyro Sensor] |
|
|
||||||
<br/>
|
|
||||||
|
|
||||||
| | | | | |
|
* [EV3 Frames]
|
||||||
|-|-|-|-|-|
|
* [Color Sensor 1]
|
||||||
|[][Ultrasonic Sensor] | | [][Touch Sensor] | | [][Jaw] |
|
* [Gyro Sensor]
|
||||||
| [Ultrasonic Sensor] | | [Touch Sensor] | | [Jaw] |
|
* [Ultrasonic Sensor]
|
||||||
<br/>
|
* [Touch Sensor]
|
||||||
|
* [Jaw]
|
||||||
|
* [Leg 1]
|
||||||
|
* [Leg 2]
|
||||||
|
* [Leg 3]
|
||||||
|
|
||||||
| | | | | |
|
### ~hint
|
||||||
|-|-|-|-|-|
|
|
||||||
| [][Leg 1] | | [][Leg 2] | | [][Leg 3] |
|
If clicking the above links doesn't open the instructions, right-click on the image and choose "Save link as..." to download the PDF.
|
||||||
| [Leg 1] | | [Leg 2] | | [Leg 3] |
|
|
||||||
|
### ~
|
||||||
|
|
||||||
### Program
|
### Program
|
||||||
|
|
||||||
@ -86,6 +86,12 @@ Building Instructions:
|
|||||||
|
|
||||||
[](https://le-www-live-s.legocdn.com/sc/media/files/support/mindstorms%20ev3/building-instructions/design%20engineering%20projects/insect-94b8a46f0dc5082c9d78ddb734626dc9.pdf)
|
[](https://le-www-live-s.legocdn.com/sc/media/files/support/mindstorms%20ev3/building-instructions/design%20engineering%20projects/insect-94b8a46f0dc5082c9d78ddb734626dc9.pdf)
|
||||||
|
|
||||||
|
### ~hint
|
||||||
|
|
||||||
|
If clicking the above images or links doesn't open the instructions, right-click on the link and choose "Save link as..." to download the PDF.
|
||||||
|
|
||||||
|
### ~
|
||||||
|
|
||||||
### Sample Solution
|
### Sample Solution
|
||||||
|
|
||||||
This program checks if the Ultrasonic Sensor senses something near.
|
This program checks if the Ultrasonic Sensor senses something near.
|
||||||
|
@ -20,6 +20,12 @@ Build the robot driving base:
|
|||||||
|
|
||||||
[](https://le-www-live-s.legocdn.com/sc/media/lessons/mindstorms-ev3/building-instructions/ev3-rem-driving-base-79bebfc16bd491186ea9c9069842155e.pdf)
|
[](https://le-www-live-s.legocdn.com/sc/media/lessons/mindstorms-ev3/building-instructions/ev3-rem-driving-base-79bebfc16bd491186ea9c9069842155e.pdf)
|
||||||
|
|
||||||
|
### ~hint
|
||||||
|
|
||||||
|
If clicking the above image doesn't open the instructions, right-click on the image and choose "Save link as..." to download the PDF.
|
||||||
|
|
||||||
|
### ~
|
||||||
|
|
||||||
## Make It Move
|
## Make It Move
|
||||||
|
|
||||||
**Code it:** Create a program that makes the Driving Base move forward and stop at the finish line, which is ``1`` meter away.
|
**Code it:** Create a program that makes the Driving Base move forward and stop at the finish line, which is ``1`` meter away.
|
||||||
@ -68,6 +74,12 @@ Build and attach an Ultrasonic Sensor to your driving base:
|
|||||||
|
|
||||||
[](https://le-www-live-s.legocdn.com/sc/media/lessons/mindstorms-ev3/building-instructions/ev3-ultrasonic-sensor-driving-base-61ffdfa461aee2470b8ddbeab16e2070.pdf)
|
[](https://le-www-live-s.legocdn.com/sc/media/lessons/mindstorms-ev3/building-instructions/ev3-ultrasonic-sensor-driving-base-61ffdfa461aee2470b8ddbeab16e2070.pdf)
|
||||||
|
|
||||||
|
### ~hint
|
||||||
|
|
||||||
|
If clicking the above image doesn't open the instructions, right-click on the image and choose "Save link as..." to download the PDF.
|
||||||
|
|
||||||
|
### ~
|
||||||
|
|
||||||
## Detect an Object
|
## Detect an Object
|
||||||
|
|
||||||
**Code it:** Create a program that moves the Driving Base and makes it stop ``6`` cm from the Cuboid.
|
**Code it:** Create a program that moves the Driving Base and makes it stop ``6`` cm from the Cuboid.
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
{
|
{
|
||||||
"appref": "v0.3.6"
|
"appref": "v0.4.2"
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,12 @@ Think about what you have learned, then document it. Describe the problem in you
|
|||||||
|
|
||||||
Start by constructing this model. Read the building instructions [here](https://le-www-live-s.legocdn.com/sc/media/lessons/mindstorms-ev3/building-instructions/ev3-rem-color-sensor-down-driving-base-d30ed30610c3d6647d56e17bc64cf6e2.pdf) first.
|
Start by constructing this model. Read the building instructions [here](https://le-www-live-s.legocdn.com/sc/media/lessons/mindstorms-ev3/building-instructions/ev3-rem-color-sensor-down-driving-base-d30ed30610c3d6647d56e17bc64cf6e2.pdf) first.
|
||||||
|
|
||||||
|
### ~hint
|
||||||
|
|
||||||
|
If clicking the above image doesn't open the instructions, right-click on the image and choose "Save link as..." to download the PDF.
|
||||||
|
|
||||||
|
### ~
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
## Program
|
## Program
|
||||||
|
@ -25,6 +25,12 @@ The legs in the Walker Bot are designed to show how to change the rotary motion
|
|||||||
|
|
||||||
Start by reading [these](https://le-www-live-s.legocdn.com/sc/media/lessons/mindstorms-ev3/ev3-dep/building%20instructions/walker-bot-bi-180fc24f9298e1dd6201099627d43903.pdf) instructions first.
|
Start by reading [these](https://le-www-live-s.legocdn.com/sc/media/lessons/mindstorms-ev3/ev3-dep/building%20instructions/walker-bot-bi-180fc24f9298e1dd6201099627d43903.pdf) instructions first.
|
||||||
|
|
||||||
|
### ~hint
|
||||||
|
|
||||||
|
If clicking the above image doesn't open the instructions, right-click on the image and choose "Save link as..." to download the PDF.
|
||||||
|
|
||||||
|
### ~
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
|
||||||
|
@ -24,6 +24,12 @@ The legs in the Walker Bot are designed to show how to change the rotary motion
|
|||||||
|
|
||||||
Start by reading [these](https://le-www-live-s.legocdn.com/sc/media/lessons/mindstorms-ev3/ev3-dep/building%20instructions/walker-bot-bi-180fc24f9298e1dd6201099627d43903.pdf) instructions first.
|
Start by reading [these](https://le-www-live-s.legocdn.com/sc/media/lessons/mindstorms-ev3/ev3-dep/building%20instructions/walker-bot-bi-180fc24f9298e1dd6201099627d43903.pdf) instructions first.
|
||||||
|
|
||||||
|
### ~hint
|
||||||
|
|
||||||
|
If clicking the above image doesn't open the instructions, right-click on the image and choose "Save link as..." to download the PDF.
|
||||||
|
|
||||||
|
### ~
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
|
||||||
|
@ -42,14 +42,12 @@ This activity uses sensor inputs. You may want to try the [Use](/getting-started
|
|||||||
|
|
||||||
Follow the steps of the _Maker Design Process_ for this lesson:
|
Follow the steps of the _Maker Design Process_ for this lesson:
|
||||||
|
|
||||||
| | |
|
* Define the Problem
|
||||||
|-|-|
|
* Brainstorming
|
||||||
|  | **Define the Problem** |
|
* Define the Design Criteria
|
||||||
|  | **Brainstorming** |
|
* Go Make
|
||||||
|  | **Define the Design Criteria** |
|
* Review and Revise Your Solution
|
||||||
|  | **Go Make** |
|
* Communicate Your Solution
|
||||||
|  | **Review and Revise Your Solution** |
|
|
||||||
|  | **Communicate Your Solution** |
|
|
||||||
|
|
||||||
### Defining the Problem
|
### Defining the Problem
|
||||||
|
|
||||||
|
@ -41,14 +41,12 @@ This activity uses motor rotations and sensor inputs. You may want to try the [U
|
|||||||
|
|
||||||
Follow the steps of the _Maker Design Process_ for this lesson:
|
Follow the steps of the _Maker Design Process_ for this lesson:
|
||||||
|
|
||||||
| | |
|
* Define the Problem
|
||||||
|-|-|
|
* Brainstorming
|
||||||
|  | **Define the Problem** |
|
* Define the Design Criteria
|
||||||
|  | **Brainstorming** |
|
* Go Make
|
||||||
|  | **Define the Design Criteria** |
|
* Review and Revise Your Solution
|
||||||
|  | **Go Make** |
|
* Communicate Your Solution
|
||||||
|  | **Review and Revise Your Solution** |
|
|
||||||
|  | **Communicate Your Solution** |
|
|
||||||
|
|
||||||
### Defining the Problem
|
### Defining the Problem
|
||||||
|
|
||||||
|
@ -13,8 +13,8 @@
|
|||||||
color: rgba(0, 0, 0, 0.4);
|
color: rgba(0, 0, 0, 0.4);
|
||||||
}
|
}
|
||||||
|
|
||||||
.ui.grid {
|
.topbar {
|
||||||
background: rgb(170, 39, 143)!important;
|
background: rgb(170, 39, 143) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ui.inverted.content {
|
.ui.inverted.content {
|
||||||
@ -388,9 +388,14 @@
|
|||||||
}
|
}
|
||||||
function downloadWin64() {
|
function downloadWin64() {
|
||||||
// TODO: Keep this link up-to-date with the desired release version
|
// TODO: Keep this link up-to-date with the desired release version
|
||||||
window.open("https://makecode.com/api/release/ev3/v0.3.6/win64");
|
window.open("https://makecode.com/api/release/ev3/v0.4.2/win64");
|
||||||
tickEvent("offlineapp.download", { "target": "ev3", "platform": "win64" });
|
tickEvent("offlineapp.download", { "target": "ev3", "platform": "win64" });
|
||||||
}
|
}
|
||||||
|
function downloadMac64() {
|
||||||
|
// TODO: Keep this link up-to-date with the desired release version
|
||||||
|
window.open("https://makecode.com/api/release/ev3/v0.4.2/mac64");
|
||||||
|
tickEvent("offlineapp.download", { "target": "ev3", "platform": "mac64" });
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
@ -399,7 +404,7 @@
|
|||||||
|
|
||||||
<div class="ui inverted vertical center aligned segment content">
|
<div class="ui inverted vertical center aligned segment content">
|
||||||
|
|
||||||
<div class="ui grid">
|
<div class="ui grid topbar">
|
||||||
<div class="three wide column">
|
<div class="three wide column">
|
||||||
<img class="ui small image left" src="/static//lego_education_logo_white.png" />
|
<img class="ui small image left" src="/static//lego_education_logo_white.png" />
|
||||||
</div>
|
</div>
|
||||||
@ -421,7 +426,7 @@
|
|||||||
<span class="c4 c1">MICROSOFT PRE-RELEASE SOFTWARE LICENSE TERMS</span>
|
<span class="c4 c1">MICROSOFT PRE-RELEASE SOFTWARE LICENSE TERMS</span>
|
||||||
</p>
|
</p>
|
||||||
<p class="c11">
|
<p class="c11">
|
||||||
<span class="c4 c1">MICROSOFT MAKECODE SOFTWARE FOR LEGO MINDSTORMS EDUCATION EV3</span>
|
<span class="c4 c1">MICROSOFT MAKECODE FOR LEGO MINDSTORMS EDUCATION EV3</span>
|
||||||
</p>
|
</p>
|
||||||
<p class="c7">
|
<p class="c7">
|
||||||
<span class="c4 c1"></span>
|
<span class="c4 c1"></span>
|
||||||
@ -763,12 +768,23 @@
|
|||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div id="download-segment" class="ui center aligned segment hidden">
|
<div id="download-segment" class="ui center aligned segment hidden">
|
||||||
|
<div class="ui grid">
|
||||||
|
<div class="eight wide column">
|
||||||
<h3 class="ui">Windows</h3>
|
<h3 class="ui">Windows</h3>
|
||||||
<button class="ui icon button" onclick="downloadWin64()">
|
<button class="ui icon button" onclick="downloadWin64()">
|
||||||
<i class="download icon"></i>
|
<i class="download icon"></i>
|
||||||
makecode-ev3-setup-win64.exe
|
makecode-ev3-setup-win64.exe
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="eight wide column">
|
||||||
|
<h3 class="ui">Mac OS</h3>
|
||||||
|
<button class="ui icon button" onclick="downloadMac64()">
|
||||||
|
<i class="download icon"></i>
|
||||||
|
makecode-ev3-mac64.zip
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
BIN
docs/static/about/explorer-button.png
vendored
Normal file
After Width: | Height: | Size: 2.2 KiB |
BIN
docs/static/about/explorer-view.png
vendored
Normal file
After Width: | Height: | Size: 10 KiB |
1
docs/static/githubfilelogo.svg
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd" clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414"><path d="M16.097 2.686c-7.64 0-13.834 6.194-13.834 13.835 0 6.113 3.964 11.298 9.462 13.128.692.127.944-.301.944-.667 0-.328-.012-1.199-.019-2.353-3.848.836-4.66-1.855-4.66-1.855-.629-1.598-1.536-2.023-1.536-2.023-1.256-.859.095-.842.095-.842 1.388.099 2.119 1.426 2.119 1.426 1.234 2.114 3.238 1.504 4.027 1.15.125-.894.482-1.504.878-1.85-3.072-.349-6.302-1.536-6.302-6.838 0-1.51.539-2.745 1.424-3.712-.143-.35-.617-1.756.135-3.661 0 0 1.162-.372 3.805 1.418a13.228 13.228 0 0 1 3.464-.465c1.174.005 2.358.158 3.463.465 2.642-1.79 3.801-1.418 3.801-1.418.755 1.905.28 3.311.137 3.661.887.967 1.423 2.202 1.423 3.712 0 5.316-3.235 6.485-6.317 6.827.497.428.939 1.272.939 2.563 0 1.849-.017 3.341-.017 3.795 0 .37.249.8.951.665 5.494-1.833 9.454-7.015 9.454-13.126 0-7.641-6.195-13.835-13.836-13.835" fill="#696969"/></svg>
|
After Width: | Height: | Size: 973 B |
BIN
docs/static/setup/brickfw.jpg
vendored
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 102 KiB |
BIN
docs/static/setup/brickinfo.jpg
vendored
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 110 KiB |
@ -17,10 +17,10 @@ brick.showString("Hello world", 1)
|
|||||||
|
|
||||||
## Step 2
|
## Step 2
|
||||||
|
|
||||||
In the ``||brick:show string||`` block, type the text ``"Press my buttons to make music!"`` to replace ``"Hello world"``.
|
In the ``||brick:show string||`` block, type the text ``"Press my buttons!"`` to replace ``"Hello world"``.
|
||||||
|
|
||||||
```blocks
|
```blocks
|
||||||
brick.showString("Press my buttons to make music!", 1)
|
brick.showString("Press my buttons!", 1)
|
||||||
```
|
```
|
||||||
|
|
||||||
## Step 3
|
## Step 3
|
||||||
@ -31,7 +31,7 @@ Open the ``||brick:Brick||`` Toolbox drawer. From the **Buttons** section, drag
|
|||||||
brick.buttonEnter.onEvent(ButtonEvent.Pressed, function () {
|
brick.buttonEnter.onEvent(ButtonEvent.Pressed, function () {
|
||||||
|
|
||||||
})
|
})
|
||||||
brick.showString("Press my buttons to make music!", 1)
|
brick.showString("Press my buttons!", 1)
|
||||||
```
|
```
|
||||||
|
|
||||||
## Step 4
|
## Step 4
|
||||||
@ -40,13 +40,13 @@ Open the ``||music:Music||`` Toolbox drawer. Drag out **5** ``||music:play tone|
|
|||||||
|
|
||||||
```blocks
|
```blocks
|
||||||
brick.buttonEnter.onEvent(ButtonEvent.Pressed, function () {
|
brick.buttonEnter.onEvent(ButtonEvent.Pressed, function () {
|
||||||
music.playTone(0, music.beat(BeatFraction.Half))
|
music.playTone(262, music.beat(BeatFraction.Half))
|
||||||
music.playTone(0, music.beat(BeatFraction.Half))
|
music.playTone(262, music.beat(BeatFraction.Half))
|
||||||
music.playTone(0, music.beat(BeatFraction.Half))
|
music.playTone(262, music.beat(BeatFraction.Half))
|
||||||
music.playTone(0, music.beat(BeatFraction.Half))
|
music.playTone(262, music.beat(BeatFraction.Half))
|
||||||
music.playTone(0, music.beat(BeatFraction.Half))
|
music.playTone(262, music.beat(BeatFraction.Half))
|
||||||
})
|
})
|
||||||
brick.showString("Press my buttons to make music!", 1)
|
brick.showString("Press my buttons!", 1)
|
||||||
```
|
```
|
||||||
|
|
||||||
## Step 5
|
## Step 5
|
||||||
@ -63,7 +63,7 @@ brick.buttonEnter.onEvent(ButtonEvent.Pressed, function () {
|
|||||||
music.playTone(196, music.beat(BeatFraction.Half))
|
music.playTone(196, music.beat(BeatFraction.Half))
|
||||||
music.playTone(294, music.beat(BeatFraction.Whole))
|
music.playTone(294, music.beat(BeatFraction.Whole))
|
||||||
})
|
})
|
||||||
brick.showString("Press my buttons to make music!", 1)
|
brick.showString("Press my buttons!", 1)
|
||||||
```
|
```
|
||||||
|
|
||||||
## Step 6
|
## Step 6
|
||||||
|
@ -106,9 +106,9 @@ brick.buttonRight.onEvent(ButtonEvent.Pressed, function () {
|
|||||||
|
|
||||||
For the ``||motors:run||`` blocks that are in the ``||brick:on button left||`` and ``||brick:on button right||`` blocks, use the drop-down menu to select a ``medium motor`` on Port ``D``.
|
For the ``||motors:run||`` blocks that are in the ``||brick:on button left||`` and ``||brick:on button right||`` blocks, use the drop-down menu to select a ``medium motor`` on Port ``D``.
|
||||||
|
|
||||||
| | | |
|

|
||||||
|-|-|-|
|
<br/>
|
||||||
|  | | |  |
|

|
||||||
|
|
||||||
```blocks
|
```blocks
|
||||||
brick.buttonUp.onEvent(ButtonEvent.Pressed, function () {
|
brick.buttonUp.onEvent(ButtonEvent.Pressed, function () {
|
||||||
|
@ -30,7 +30,7 @@ pxt.editor.initExtensionsAsync = function (opts: pxt.editor.ExtensionOptions): P
|
|||||||
<div class="ui header">${lf("First time here?")}</div>
|
<div class="ui header">${lf("First time here?")}</div>
|
||||||
<strong style="font-size:small">${lf("You must have version 1.10E or above of the firmware")}</strong>
|
<strong style="font-size:small">${lf("You must have version 1.10E or above of the firmware")}</strong>
|
||||||
<div style="justify-content: center;display: flex;padding: 1rem;">
|
<div style="justify-content: center;display: flex;padding: 1rem;">
|
||||||
<img class="ui image" src="./static/download/firmware.png" style="height:100px;" />
|
<img class="ui image" src="/static/download/firmware.png" style="height:100px;" />
|
||||||
</div>
|
</div>
|
||||||
<a href="/troubleshoot" target="_blank">${lf("Check your firmware version here and update if needed")}</a>
|
<a href="/troubleshoot" target="_blank">${lf("Check your firmware version here and update if needed")}</a>
|
||||||
</div>
|
</div>
|
||||||
@ -42,7 +42,7 @@ pxt.editor.initExtensionsAsync = function (opts: pxt.editor.ExtensionOptions): P
|
|||||||
<div class="column">
|
<div class="column">
|
||||||
<div class="ui">
|
<div class="ui">
|
||||||
<div class="image">
|
<div class="image">
|
||||||
<img class="ui medium rounded image" src="./static/download/connect.svg" style="height:109px;width:261px;margin-bottom:1rem;" />
|
<img class="ui medium rounded image" src="/static/download/connect.svg" style="height:109px;width:261px;margin-bottom:1rem;" />
|
||||||
</div>
|
</div>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<div class="description">
|
<div class="description">
|
||||||
@ -57,7 +57,7 @@ pxt.editor.initExtensionsAsync = function (opts: pxt.editor.ExtensionOptions): P
|
|||||||
<div class="column">
|
<div class="column">
|
||||||
<div class="ui">
|
<div class="ui">
|
||||||
<div class="image">
|
<div class="image">
|
||||||
<img class="ui medium rounded image" src="./static/download/transfer.svg" style="height:109px;width:261px;margin-bottom:1rem;" />
|
<img class="ui medium rounded image" src="/static/download/transfer.svg" style="height:109px;width:261px;margin-bottom:1rem;" />
|
||||||
</div>
|
</div>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<div class="description">
|
<div class="description">
|
||||||
|
@ -133,14 +133,27 @@ export class FieldMotors extends Blockly.FieldDropdown implements Blockly.FieldC
|
|||||||
this.setText(text);
|
this.setText(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
getFirstValue(text: string) {
|
getFirstValue(value: string) {
|
||||||
// Get first set of words up until last space
|
const typeValue = value.indexOf('large') != -1 ? 'large' : 'medium';
|
||||||
return this.normalizeText_(text.substring(0, text.lastIndexOf(' ')));
|
const portValue = this.getSecondValue(value);
|
||||||
|
const isDual = portValue.length > 1;
|
||||||
|
return `${typeValue} motor${isDual ? 's' : ''}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
getSecondValue(text: string) {
|
getSecondValue(value: string) {
|
||||||
// Get last word
|
return (value.indexOf('large') != -1) ?
|
||||||
return this.normalizeText_(text.match(/\S*$/)[0]);
|
value.substring(value.indexOf('large') + 5) :
|
||||||
|
value.substring(value.indexOf('medium') + 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
getFirstValueI11n(value: string) {
|
||||||
|
const firstValue = this.getFirstValue(value);
|
||||||
|
const motorOptions = {
|
||||||
|
'medium motor': lf('medium motor'),
|
||||||
|
'large motor': lf('large motor'),
|
||||||
|
'large motors': lf('large motors')
|
||||||
|
}
|
||||||
|
return motorOptions[firstValue];
|
||||||
}
|
}
|
||||||
|
|
||||||
private normalizeText_(text: string) {
|
private normalizeText_(text: string) {
|
||||||
@ -198,8 +211,8 @@ export class FieldMotors extends Blockly.FieldDropdown implements Blockly.FieldC
|
|||||||
if (text === null) {
|
if (text === null) {
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
if (text.indexOf(' ') == -1) {
|
if (text.indexOf('|') == -1) {
|
||||||
text = `large motors ${text}`;
|
text = this.sourceBlock_.RTL ? `${text}|${lf("large motors")}` : `${lf("large motors")}|${text}`;
|
||||||
}
|
}
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
@ -296,16 +309,14 @@ export class FieldMotors extends Blockly.FieldDropdown implements Blockly.FieldC
|
|||||||
goog.dom.removeChildren(/** @type {!Element} */(this.textElement_));
|
goog.dom.removeChildren(/** @type {!Element} */(this.textElement_));
|
||||||
goog.dom.removeChildren(/** @type {!Element} */(this.textElement2_));
|
goog.dom.removeChildren(/** @type {!Element} */(this.textElement2_));
|
||||||
|
|
||||||
var text = this.text_;
|
|
||||||
text = this.patchDualMotorText(text);
|
|
||||||
|
|
||||||
// First dropdown
|
// First dropdown
|
||||||
const textNode1 = document.createTextNode(this.getFirstValue(text));
|
// Use one of the following options, medium motor, large motor or large motors (translated)
|
||||||
|
const textNode1 = document.createTextNode(this.getFirstValueI11n(this.value_));
|
||||||
this.textElement_.appendChild(textNode1);
|
this.textElement_.appendChild(textNode1);
|
||||||
|
|
||||||
// Second dropdown
|
// Second dropdown, no need to translate. Only port numbers
|
||||||
if (this.textElement2_) {
|
if (this.textElement2_) {
|
||||||
const textNode2 = document.createTextNode(this.getSecondValue(text));
|
const textNode2 = document.createTextNode(this.getSecondValue(this.value_));
|
||||||
this.textElement2_.appendChild(textNode2);
|
this.textElement2_.appendChild(textNode2);
|
||||||
}
|
}
|
||||||
this.updateWidth();
|
this.updateWidth();
|
||||||
@ -402,29 +413,28 @@ export class FieldMotors extends Blockly.FieldDropdown implements Blockly.FieldC
|
|||||||
contentDiv.setAttribute('aria-haspopup', 'true');
|
contentDiv.setAttribute('aria-haspopup', 'true');
|
||||||
let options = this.getOptions();
|
let options = this.getOptions();
|
||||||
|
|
||||||
// Hashmap of options
|
|
||||||
let opts = {};
|
let opts = {};
|
||||||
let conts = {};
|
let conts = {};
|
||||||
let vals = {};
|
let vals = {};
|
||||||
|
// Go through all option values and split them into groups
|
||||||
for (let opt = 0; opt < options.length; opt++) {
|
for (let opt = 0; opt < options.length; opt++) {
|
||||||
let text = options[opt][0].alt ? options[opt][0].alt : options[opt][0];
|
|
||||||
if (text.indexOf(' ') == -1) {
|
|
||||||
// Patch dual motors as they don't have prefixes.
|
|
||||||
text = this.patchDualMotorText(text);
|
|
||||||
if (options[opt][0].alt) options[opt][0].alt = text;
|
|
||||||
}
|
|
||||||
const value = options[opt][1];
|
const value = options[opt][1];
|
||||||
const firstValue = this.getFirstValue(text);
|
const motorValue = value.substring(value.indexOf('.') + 1);
|
||||||
const secondValue = this.getSecondValue(text);
|
const typeValue = motorValue.indexOf('large') == 0 ? 'large' : 'medium';
|
||||||
if (!opts[firstValue]) opts[firstValue] = [secondValue];
|
const portValue = motorValue.indexOf('large') == 0 ? motorValue.substring(5) : motorValue.substring(6);
|
||||||
else opts[firstValue].push(secondValue);
|
const isDual = portValue.length > 1;
|
||||||
// Store a hash of the original key value pairs for later
|
|
||||||
|
const text = `${typeValue} motor${isDual ? 's' : ''}|${portValue}`;
|
||||||
|
const key = `${typeValue} motor${isDual ? 's' : ''}`;
|
||||||
|
if (!opts[key]) opts[key] = [];
|
||||||
|
opts[key].push(portValue);
|
||||||
|
|
||||||
conts[text] = options[opt][0];
|
conts[text] = options[opt][0];
|
||||||
vals[text] = value;
|
vals[text] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
const currentFirst = this.getFirstValue(this.text_);
|
const currentFirst = this.getFirstValue(this.value_);
|
||||||
const currentSecond = this.getSecondValue(this.text_);
|
const currentSecond = this.getSecondValue(this.value_);
|
||||||
|
|
||||||
if (!this.isFirst_) {
|
if (!this.isFirst_) {
|
||||||
options = opts[currentFirst];
|
options = opts[currentFirst];
|
||||||
@ -432,9 +442,7 @@ export class FieldMotors extends Blockly.FieldDropdown implements Blockly.FieldC
|
|||||||
options = Object.keys(opts);
|
options = Object.keys(opts);
|
||||||
// Flip the first and second options to make it sorted the way we want it (medium, large, dual)
|
// Flip the first and second options to make it sorted the way we want it (medium, large, dual)
|
||||||
if (options.length == 3) {
|
if (options.length == 3) {
|
||||||
const temp = options[1];
|
options = [lf("medium motor"), lf("large motor"), lf("large motors")];
|
||||||
options[1] = options[0];
|
|
||||||
options[0] = temp;
|
|
||||||
} else {
|
} else {
|
||||||
options.reverse();
|
options.reverse();
|
||||||
}
|
}
|
||||||
@ -448,7 +456,7 @@ export class FieldMotors extends Blockly.FieldDropdown implements Blockly.FieldC
|
|||||||
const columns = options.length;
|
const columns = options.length;
|
||||||
|
|
||||||
for (let i = 0, option: any; option = options[i]; i++) {
|
for (let i = 0, option: any; option = options[i]; i++) {
|
||||||
let text = this.isFirst_ ? option + ' ' + opts[option][0] : currentFirst + ' ' + option;
|
let text = this.isFirst_ ? option + '|' + (option.indexOf('motors') != -1 ? 'BC' : 'A') : currentFirst + '|' + option;
|
||||||
text = text.replace(/\xA0/g, ' ');
|
text = text.replace(/\xA0/g, ' ');
|
||||||
const content: any = conts[text];
|
const content: any = conts[text];
|
||||||
const value = vals[text];
|
const value = vals[text];
|
||||||
@ -466,7 +474,7 @@ export class FieldMotors extends Blockly.FieldDropdown implements Blockly.FieldC
|
|||||||
button.setAttribute('id', ':' + i); // For aria-activedescendant
|
button.setAttribute('id', ':' + i); // For aria-activedescendant
|
||||||
button.setAttribute('role', 'menuitem');
|
button.setAttribute('role', 'menuitem');
|
||||||
button.setAttribute('class', 'blocklyDropDownButton');
|
button.setAttribute('class', 'blocklyDropDownButton');
|
||||||
button.title = this.isFirst_ ? this.getFirstValue(content.alt) : content.alt;
|
button.title = this.isFirst_ ? this.getFirstValueI11n(value) : this.getSecondValue(value);
|
||||||
button.style.width = ((this.itemWidth_) - 8) + 'px';
|
button.style.width = ((this.itemWidth_) - 8) + 'px';
|
||||||
button.style.height = ((this.itemWidth_) - 8) + 'px';
|
button.style.height = ((this.itemWidth_) - 8) + 'px';
|
||||||
let backgroundColor = this.backgroundColour_;
|
let backgroundColor = this.backgroundColour_;
|
||||||
@ -495,7 +503,15 @@ export class FieldMotors extends Blockly.FieldDropdown implements Blockly.FieldC
|
|||||||
contentDiv.removeAttribute('aria-activedescendant');
|
contentDiv.removeAttribute('aria-activedescendant');
|
||||||
});
|
});
|
||||||
let buttonImg = document.createElement('img');
|
let buttonImg = document.createElement('img');
|
||||||
buttonImg.src = this.isFirst_ ? isFirstUrl[option.replace(/\xA0/g, ' ')] : content.src;
|
let imgSrc = content.src;
|
||||||
|
if (this.isFirst_) {
|
||||||
|
const motorValue = value.substring(value.indexOf('.') + 1);
|
||||||
|
// Find out what kind of motor this is based on it's value, possible values: mediumX, largeX, and largeXY
|
||||||
|
if (motorValue.indexOf('medium') == 0) imgSrc = isFirstUrl['medium motor'];
|
||||||
|
else if (motorValue.length == 6) imgSrc = isFirstUrl['large motor'];
|
||||||
|
else imgSrc = isFirstUrl['large motors'];
|
||||||
|
}
|
||||||
|
buttonImg.src = imgSrc;
|
||||||
//buttonImg.alt = icon.alt;
|
//buttonImg.alt = icon.alt;
|
||||||
// Upon click/touch, we will be able to get the clicked element as e.target
|
// Upon click/touch, we will be able to get the clicked element as e.target
|
||||||
// Store a data attribute on all possible click targets so we can match it to the icon.
|
// Store a data attribute on all possible click targets so we can match it to the icon.
|
||||||
|
@ -20,7 +20,7 @@ export class FieldMusic extends pxtblockly.FieldImages implements Blockly.FieldC
|
|||||||
private categoriesCache_: string[];
|
private categoriesCache_: string[];
|
||||||
|
|
||||||
constructor(text: string, options: FieldMusicOptions, validator?: Function) {
|
constructor(text: string, options: FieldMusicOptions, validator?: Function) {
|
||||||
super(text, { sort: true, data: options.data }, validator);
|
super(text, { blocksInfo: options.blocksInfo, sort: true, data: options.data }, validator);
|
||||||
|
|
||||||
this.columns_ = parseInt(options.columns) || 4;
|
this.columns_ = parseInt(options.columns) || 4;
|
||||||
this.width_ = parseInt(options.width) || 380;
|
this.width_ = parseInt(options.width) || 380;
|
||||||
|
@ -11,7 +11,7 @@ export class FieldPorts extends pxtblockly.FieldImages implements Blockly.FieldC
|
|||||||
public isFieldCustom_ = true;
|
public isFieldCustom_ = true;
|
||||||
|
|
||||||
constructor(text: string, options: FieldPortsOptions, validator?: Function) {
|
constructor(text: string, options: FieldPortsOptions, validator?: Function) {
|
||||||
super(text, { sort: true, data: options.data }, validator);
|
super(text, { blocksInfo: options.blocksInfo, sort: true, data: options.data }, validator);
|
||||||
|
|
||||||
this.columns_ = parseInt(options.columns) || 4;
|
this.columns_ = parseInt(options.columns) || 4;
|
||||||
this.width_ = parseInt(options.width) || 300;
|
this.width_ = parseInt(options.width) || 300;
|
||||||
|
@ -1,285 +0,0 @@
|
|||||||
namespace pxt.editor {
|
|
||||||
import HF2 = pxt.HF2
|
|
||||||
import U = pxt.U
|
|
||||||
|
|
||||||
function log(msg: string) {
|
|
||||||
pxt.log("EWRAP: " + msg)
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface DirEntry {
|
|
||||||
name: string;
|
|
||||||
md5?: string;
|
|
||||||
size?: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
const runTemplate = "C00882010084XX0060640301606400"
|
|
||||||
const usbMagic = 0x3d3f
|
|
||||||
|
|
||||||
export class Ev3Wrapper {
|
|
||||||
msgs = new U.PromiseBuffer<Uint8Array>()
|
|
||||||
private cmdSeq = U.randomUint32() & 0xffff;
|
|
||||||
private lock = new U.PromiseQueue();
|
|
||||||
isStreaming = false;
|
|
||||||
dataDump = false;
|
|
||||||
|
|
||||||
constructor(public io: pxt.HF2.PacketIO) {
|
|
||||||
io.onData = buf => {
|
|
||||||
buf = buf.slice(0, HF2.read16(buf, 0) + 2)
|
|
||||||
if (HF2.read16(buf, 4) == usbMagic) {
|
|
||||||
let code = HF2.read16(buf, 6)
|
|
||||||
let payload = buf.slice(8)
|
|
||||||
if (code == 1) {
|
|
||||||
let str = U.uint8ArrayToString(payload)
|
|
||||||
if (Util.isNodeJS)
|
|
||||||
console.log("SERIAL: " + str.replace(/\n+$/, ""))
|
|
||||||
else
|
|
||||||
window.postMessage({
|
|
||||||
type: 'serial',
|
|
||||||
id: 'n/a', // TODO?
|
|
||||||
data: str
|
|
||||||
}, "*")
|
|
||||||
} else
|
|
||||||
console.log("Magic: " + code + ": " + U.toHex(payload))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (this.dataDump)
|
|
||||||
log("RECV: " + U.toHex(buf))
|
|
||||||
this.msgs.push(buf)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private allocCore(addSize: number, replyType: number) {
|
|
||||||
let len = 5 + addSize
|
|
||||||
let buf = new Uint8Array(len)
|
|
||||||
HF2.write16(buf, 0, len - 2) // pktLen
|
|
||||||
HF2.write16(buf, 2, this.cmdSeq++) // msgCount
|
|
||||||
buf[4] = replyType
|
|
||||||
return buf
|
|
||||||
}
|
|
||||||
|
|
||||||
private allocSystem(addSize: number, cmd: number, replyType = 1) {
|
|
||||||
let buf = this.allocCore(addSize + 1, replyType)
|
|
||||||
buf[5] = cmd
|
|
||||||
return buf
|
|
||||||
}
|
|
||||||
|
|
||||||
private allocCustom(code: number, addSize = 0) {
|
|
||||||
let buf = this.allocCore(1 + 2 + addSize, 0)
|
|
||||||
HF2.write16(buf, 4, usbMagic)
|
|
||||||
HF2.write16(buf, 6, code)
|
|
||||||
return buf
|
|
||||||
}
|
|
||||||
|
|
||||||
stopAsync() {
|
|
||||||
return this.isVmAsync()
|
|
||||||
.then(vm => {
|
|
||||||
if (vm) return Promise.resolve();
|
|
||||||
log(`stopping PXT app`)
|
|
||||||
let buf = this.allocCustom(2)
|
|
||||||
return this.justSendAsync(buf)
|
|
||||||
.then(() => Promise.delay(500))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
dmesgAsync() {
|
|
||||||
log(`asking for DMESG buffer over serial`)
|
|
||||||
let buf = this.allocCustom(3)
|
|
||||||
return this.justSendAsync(buf)
|
|
||||||
}
|
|
||||||
|
|
||||||
runAsync(path: string) {
|
|
||||||
let codeHex = runTemplate.replace("XX", U.toHex(U.stringToUint8Array(path)))
|
|
||||||
let code = U.fromHex(codeHex)
|
|
||||||
let pkt = this.allocCore(2 + code.length, 0)
|
|
||||||
HF2.write16(pkt, 5, 0x0800)
|
|
||||||
U.memcpy(pkt, 7, code)
|
|
||||||
log(`run ${path}`)
|
|
||||||
return this.justSendAsync(pkt)
|
|
||||||
}
|
|
||||||
|
|
||||||
justSendAsync(buf: Uint8Array) {
|
|
||||||
return this.lock.enqueue("talk", () => {
|
|
||||||
this.msgs.drain()
|
|
||||||
if (this.dataDump)
|
|
||||||
log("SEND: " + U.toHex(buf))
|
|
||||||
return this.io.sendPacketAsync(buf)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
talkAsync(buf: Uint8Array, altResponse = 0) {
|
|
||||||
return this.lock.enqueue("talk", () => {
|
|
||||||
this.msgs.drain()
|
|
||||||
if (this.dataDump)
|
|
||||||
log("TALK: " + U.toHex(buf))
|
|
||||||
return this.io.sendPacketAsync(buf)
|
|
||||||
.then(() => this.msgs.shiftAsync(1000))
|
|
||||||
.then(resp => {
|
|
||||||
if (resp[2] != buf[2] || resp[3] != buf[3])
|
|
||||||
U.userError("msg count de-sync")
|
|
||||||
if (buf[4] == 1) {
|
|
||||||
if (altResponse != -1 && resp[5] != buf[5])
|
|
||||||
U.userError("cmd de-sync")
|
|
||||||
if (altResponse != -1 && resp[6] != 0 && resp[6] != altResponse)
|
|
||||||
U.userError("cmd error: " + resp[6])
|
|
||||||
}
|
|
||||||
return resp
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
flashAsync(path: string, file: Uint8Array) {
|
|
||||||
log(`write ${file.length} bytes to ${path}`)
|
|
||||||
|
|
||||||
let handle = -1
|
|
||||||
|
|
||||||
let loopAsync = (pos: number): Promise<void> => {
|
|
||||||
if (pos >= file.length) return Promise.resolve()
|
|
||||||
let size = file.length - pos
|
|
||||||
if (size > 1000) size = 1000
|
|
||||||
let upl = this.allocSystem(1 + size, 0x93, 0x1)
|
|
||||||
upl[6] = handle
|
|
||||||
U.memcpy(upl, 6 + 1, file, pos, size)
|
|
||||||
return this.talkAsync(upl, 8) // 8=EOF
|
|
||||||
.then(() => loopAsync(pos + size))
|
|
||||||
}
|
|
||||||
|
|
||||||
let begin = this.allocSystem(4 + path.length + 1, 0x92)
|
|
||||||
HF2.write32(begin, 6, file.length) // fileSize
|
|
||||||
U.memcpy(begin, 10, U.stringToUint8Array(path))
|
|
||||||
return this.lock.enqueue("file", () =>
|
|
||||||
this.talkAsync(begin)
|
|
||||||
.then(resp => {
|
|
||||||
handle = resp[7]
|
|
||||||
return loopAsync(0)
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
|
|
||||||
lsAsync(path: string): Promise<DirEntry[]> {
|
|
||||||
let lsReq = this.allocSystem(2 + path.length + 1, 0x99)
|
|
||||||
HF2.write16(lsReq, 6, 1024) // maxRead
|
|
||||||
U.memcpy(lsReq, 8, U.stringToUint8Array(path))
|
|
||||||
|
|
||||||
return this.talkAsync(lsReq, 8)
|
|
||||||
.then(resp =>
|
|
||||||
U.uint8ArrayToString(resp.slice(12)).split(/\n/).map(s => {
|
|
||||||
if (!s) return null as DirEntry
|
|
||||||
let m = /^([A-F0-9]+) ([A-F0-9]+) ([^\/]*)$/.exec(s)
|
|
||||||
if (m)
|
|
||||||
return {
|
|
||||||
md5: m[1],
|
|
||||||
size: parseInt(m[2], 16),
|
|
||||||
name: m[3]
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return {
|
|
||||||
name: s.replace(/\/$/, "")
|
|
||||||
}
|
|
||||||
}).filter(v => !!v))
|
|
||||||
}
|
|
||||||
|
|
||||||
rmAsync(path: string): Promise<void> {
|
|
||||||
log(`rm ${path}`)
|
|
||||||
let rmReq = this.allocSystem(path.length + 1, 0x9c)
|
|
||||||
U.memcpy(rmReq, 6, U.stringToUint8Array(path))
|
|
||||||
|
|
||||||
return this.talkAsync(rmReq, 5)
|
|
||||||
.then(resp => { })
|
|
||||||
}
|
|
||||||
|
|
||||||
isVmAsync(): Promise<boolean> {
|
|
||||||
let path = "/no/such/dir"
|
|
||||||
let mkdirReq = this.allocSystem(path.length + 1, 0x9b)
|
|
||||||
U.memcpy(mkdirReq, 6, U.stringToUint8Array(path))
|
|
||||||
return this.talkAsync(mkdirReq, -1)
|
|
||||||
.then(resp => {
|
|
||||||
let isVM = resp[6] == 0x05
|
|
||||||
log(`${isVM ? "PXT app" : "VM"} running`)
|
|
||||||
return isVM
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
private streamFileOnceAsync(path: string, cb: (d: Uint8Array) => void) {
|
|
||||||
let fileSize = 0
|
|
||||||
let filePtr = 0
|
|
||||||
let handle = -1
|
|
||||||
let resp = (buf: Uint8Array): Promise<void> => {
|
|
||||||
if (buf[6] == 2) {
|
|
||||||
// handle not ready - file is missing
|
|
||||||
this.isStreaming = false
|
|
||||||
return Promise.resolve()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (buf[6] != 0 && buf[6] != 8)
|
|
||||||
U.userError("bad response when streaming file: " + buf[6] + " " + U.toHex(buf))
|
|
||||||
|
|
||||||
this.isStreaming = true
|
|
||||||
fileSize = HF2.read32(buf, 7)
|
|
||||||
if (handle == -1) {
|
|
||||||
handle = buf[11]
|
|
||||||
log(`stream on, handle=${handle}`)
|
|
||||||
}
|
|
||||||
let data = buf.slice(12)
|
|
||||||
filePtr += data.length
|
|
||||||
if (data.length > 0)
|
|
||||||
cb(data)
|
|
||||||
|
|
||||||
if (buf[6] == 8) {
|
|
||||||
// end of file
|
|
||||||
this.isStreaming = false
|
|
||||||
return this.rmAsync(path)
|
|
||||||
}
|
|
||||||
|
|
||||||
let contFileReq = this.allocSystem(1 + 2, 0x97)
|
|
||||||
HF2.write16(contFileReq, 7, 1000) // maxRead
|
|
||||||
contFileReq[6] = handle
|
|
||||||
return Promise.delay(data.length > 0 ? 0 : 500)
|
|
||||||
.then(() => this.talkAsync(contFileReq, -1))
|
|
||||||
.then(resp)
|
|
||||||
}
|
|
||||||
|
|
||||||
let getFileReq = this.allocSystem(2 + path.length + 1, 0x96)
|
|
||||||
HF2.write16(getFileReq, 6, 1000) // maxRead
|
|
||||||
U.memcpy(getFileReq, 8, U.stringToUint8Array(path))
|
|
||||||
return this.talkAsync(getFileReq, -1).then(resp)
|
|
||||||
}
|
|
||||||
|
|
||||||
streamFileAsync(path: string, cb: (d: Uint8Array) => void) {
|
|
||||||
let loop = (): Promise<void> =>
|
|
||||||
this.lock.enqueue("file", () =>
|
|
||||||
this.streamFileOnceAsync(path, cb))
|
|
||||||
.then(() => Promise.delay(500))
|
|
||||||
.then(loop)
|
|
||||||
return loop()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
downloadFileAsync(path: string, cb: (d: Uint8Array) => void) {
|
|
||||||
return this.lock.enqueue("file", () =>
|
|
||||||
this.streamFileOnceAsync(path, cb))
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private initAsync() {
|
|
||||||
return Promise.resolve()
|
|
||||||
}
|
|
||||||
|
|
||||||
private resetState() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
reconnectAsync(first = false): Promise<void> {
|
|
||||||
this.resetState()
|
|
||||||
if (first) return this.initAsync()
|
|
||||||
log(`reconnect`);
|
|
||||||
return this.io.reconnectAsync()
|
|
||||||
.then(() => this.initAsync())
|
|
||||||
}
|
|
||||||
|
|
||||||
disconnectAsync() {
|
|
||||||
log(`disconnect`);
|
|
||||||
return this.io.disconnectAsync()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
@ -1,28 +1,3 @@
|
|||||||
{
|
{
|
||||||
"name": "base",
|
"additionalFilePath": "../../node_modules/pxt-common-packages/libs/base"
|
||||||
"description": "The base library",
|
|
||||||
"files": [
|
|
||||||
"README.md",
|
|
||||||
"pxt-core.d.ts",
|
|
||||||
"pxt.cpp",
|
|
||||||
"pxtbase.h",
|
|
||||||
"core.cpp",
|
|
||||||
"pxt-helpers.ts",
|
|
||||||
"buffer.cpp",
|
|
||||||
"shims.d.ts",
|
|
||||||
"enums.d.ts",
|
|
||||||
"loops.cpp",
|
|
||||||
"math.ts",
|
|
||||||
"ns.ts",
|
|
||||||
"control.cpp",
|
|
||||||
"control.ts",
|
|
||||||
"console.ts",
|
|
||||||
"eventcontext.ts"
|
|
||||||
],
|
|
||||||
"testFiles": [
|
|
||||||
"test.ts"
|
|
||||||
],
|
|
||||||
"additionalFilePath": "../../node_modules/pxt-common-packages/libs/base",
|
|
||||||
"public": true,
|
|
||||||
"dependencies": {}
|
|
||||||
}
|
}
|
||||||
|
@ -368,7 +368,8 @@ namespace motors {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private __move(steps: boolean, stepsOrTime: number, speed: number) {
|
private __move(steps: boolean, stepsOrTime: number, speed: number) {
|
||||||
step(this._port, {
|
control.dmesg("motor.__move")
|
||||||
|
const p = {
|
||||||
useSteps: steps,
|
useSteps: steps,
|
||||||
step1: 0,
|
step1: 0,
|
||||||
step2: stepsOrTime,
|
step2: stepsOrTime,
|
||||||
@ -376,7 +377,10 @@ namespace motors {
|
|||||||
speed: this._regulated ? speed : undefined,
|
speed: this._regulated ? speed : undefined,
|
||||||
power: this._regulated ? undefined : speed,
|
power: this._regulated ? undefined : speed,
|
||||||
useBrake: this._brake
|
useBrake: this._brake
|
||||||
})
|
};
|
||||||
|
control.dmesg("motor.1")
|
||||||
|
step(this._port, p)
|
||||||
|
control.dmesg("motor.__move end")
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -706,24 +710,36 @@ namespace motors {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function step(out: Output, opts: StepOptions) {
|
function step(out: Output, opts: StepOptions) {
|
||||||
|
control.dmesg('step')
|
||||||
let op = opts.useSteps ? DAL.opOutputStepSpeed : DAL.opOutputTimeSpeed
|
let op = opts.useSteps ? DAL.opOutputStepSpeed : DAL.opOutputTimeSpeed
|
||||||
let speed = opts.speed
|
let speed = opts.speed
|
||||||
if (speed == null) {
|
if (undefined == speed) {
|
||||||
speed = opts.power
|
speed = opts.power
|
||||||
op = opts.useSteps ? DAL.opOutputStepPower : DAL.opOutputTimePower
|
op = opts.useSteps ? DAL.opOutputStepPower : DAL.opOutputTimePower
|
||||||
if (speed == null)
|
if (undefined == speed)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
speed = Math.clamp(-100, 100, speed)
|
speed = Math.clamp(-100, 100, speed)
|
||||||
|
control.dmesg('speed: ' + speed)
|
||||||
|
|
||||||
let b = mkCmd(out, op, 15)
|
let b = mkCmd(out, op, 15)
|
||||||
|
control.dmesg('STEP 5')
|
||||||
b.setNumber(NumberFormat.Int8LE, 2, speed)
|
b.setNumber(NumberFormat.Int8LE, 2, speed)
|
||||||
// note that b[3] is padding
|
// note that b[3] is padding
|
||||||
|
control.dmesg('STEP 1')
|
||||||
b.setNumber(NumberFormat.Int32LE, 4 + 4 * 0, opts.step1)
|
b.setNumber(NumberFormat.Int32LE, 4 + 4 * 0, opts.step1)
|
||||||
|
control.dmesg('STEP 2')
|
||||||
b.setNumber(NumberFormat.Int32LE, 4 + 4 * 1, opts.step2)
|
b.setNumber(NumberFormat.Int32LE, 4 + 4 * 1, opts.step2)
|
||||||
|
control.dmesg('STEP 3')
|
||||||
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.useBrake ? 1 : 0)
|
control.dmesg('STEP 4')
|
||||||
|
control.dmesg('br ' + opts.useBrake);
|
||||||
|
const br = !!opts.useBrake ? 1 : 0;
|
||||||
|
control.dmesg('Step 4.5 ' + br)
|
||||||
|
b.setNumber(NumberFormat.Int8LE, 4 + 4 * 3, br)
|
||||||
|
control.dmesg('STEP 5')
|
||||||
writePWM(b)
|
writePWM(b)
|
||||||
|
control.dmesg('end step')
|
||||||
}
|
}
|
||||||
|
|
||||||
const types = [0, 0, 0, 0]
|
const types = [0, 0, 0, 0]
|
||||||
|
@ -1,9 +1,16 @@
|
|||||||
#ifndef __PXTCORE_H
|
#ifndef __PXTCORE_H
|
||||||
#define __PXTCORE_H
|
#define __PXTCORE_H
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
namespace pxt {
|
namespace pxt {
|
||||||
void dmesg(const char *fmt, ...);
|
void dmesg(const char *fmt, ...);
|
||||||
#define DMESG pxt::dmesg
|
#define DMESG pxt::dmesg
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void itoa(int v, char *dst) {
|
||||||
|
|
||||||
|
snprintf(dst, 30, "%d", v);
|
||||||
|
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -9,5 +9,5 @@ sensors.ultrasonic1.pauseUntil(UltrasonicSensorEvent.ObjectDetected);
|
|||||||
## See Also
|
## See Also
|
||||||
|
|
||||||
[on event](/reference/sensors/ultrasonic/on-event),
|
[on event](/reference/sensors/ultrasonic/on-event),
|
||||||
[distance](reference/sensors/ultrasonic/distance),
|
[distance](/reference/sensors/ultrasonic/distance),
|
||||||
[pause until](reference/sensors/ultrasonic/pause-until)
|
[pause until](/reference/sensors/ultrasonic/pause-until)
|
2
package-lock.json
generated
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "pxt-ev3",
|
"name": "pxt-ev3",
|
||||||
"version": "0.4.1",
|
"version": "1.0.8",
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "pxt-ev3",
|
"name": "pxt-ev3",
|
||||||
"version": "0.4.1",
|
"version": "1.0.8",
|
||||||
"description": "LEGO MINDSTORMS EV3 for Microsoft MakeCode",
|
"description": "LEGO MINDSTORMS EV3 for Microsoft MakeCode",
|
||||||
"private": true,
|
"private": true,
|
||||||
"keywords": [
|
"keywords": [
|
||||||
@ -39,8 +39,8 @@
|
|||||||
"webfonts-generator": "^0.4.0"
|
"webfonts-generator": "^0.4.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"pxt-common-packages": "0.23.39",
|
"pxt-common-packages": "0.23.56",
|
||||||
"pxt-core": "3.20.11"
|
"pxt-core": "4.0.9"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "node node_modules/pxt-core/built/pxt.js travis"
|
"test": "node node_modules/pxt-core/built/pxt.js travis"
|
||||||
|
@ -79,11 +79,11 @@
|
|||||||
},
|
},
|
||||||
"appTheme": {
|
"appTheme": {
|
||||||
"accentColor": "#0089BF",
|
"accentColor": "#0089BF",
|
||||||
|
"logoWide": true,
|
||||||
"logoUrl": "https://education.lego.com/",
|
"logoUrl": "https://education.lego.com/",
|
||||||
"logo": "./static/lego_education_logo.png",
|
"logo": "./static/lego_education_logo.png",
|
||||||
"docsLogo": "./static/lego-logo.svg",
|
"docsLogo": "./static/lego_education_logo.png",
|
||||||
"portraitLogo": "./static/lego-logo.svg",
|
"portraitLogo": "./static/lego_education_logo.png",
|
||||||
"footerLogo": "./static/lego-logo.svg",
|
|
||||||
"cardLogo": "./static/icons/android-chrome-192x192.png",
|
"cardLogo": "./static/icons/android-chrome-192x192.png",
|
||||||
"appLogo": "./static/icons/android-chrome-192x192.png",
|
"appLogo": "./static/icons/android-chrome-192x192.png",
|
||||||
"organization": "Microsoft MakeCode",
|
"organization": "Microsoft MakeCode",
|
||||||
@ -95,14 +95,17 @@
|
|||||||
"privacyUrl": "https://go.microsoft.com/fwlink/?LinkId=521839",
|
"privacyUrl": "https://go.microsoft.com/fwlink/?LinkId=521839",
|
||||||
"termsOfUseUrl": "https://go.microsoft.com/fwlink/?LinkID=206977",
|
"termsOfUseUrl": "https://go.microsoft.com/fwlink/?LinkID=206977",
|
||||||
"githubUrl": "https://github.com/Microsoft/pxt-ev3",
|
"githubUrl": "https://github.com/Microsoft/pxt-ev3",
|
||||||
"betaUrl": "https://makecode.mindstorms.com/about",
|
|
||||||
"driveDisplayName": "EV3",
|
"driveDisplayName": "EV3",
|
||||||
"boardName": "LEGO® MINDSTORMS® Education EV3",
|
"boardName": "LEGO® MINDSTORMS® Education EV3",
|
||||||
"copyrightText": "LEGO, the LEGO logo, MINDSTORMS and the MINDSTORMS EV3 logo are trademarks and/ or copyrights of the LEGO Group. ©2018 The LEGO Group. All rights reserved.",
|
"copyrightText": "LEGO, the LEGO logo, MINDSTORMS and the MINDSTORMS EV3 logo are trademarks and/ or copyrights of the LEGO Group. ©2018 The LEGO Group. All rights reserved.",
|
||||||
"crowdinProject": "kindscript",
|
"crowdinProject": "kindscript",
|
||||||
"selectLanguage": true,
|
"selectLanguage": true,
|
||||||
"availableLocales": [
|
"availableLocales": [
|
||||||
"en"
|
"en",
|
||||||
|
"de",
|
||||||
|
"ja",
|
||||||
|
"ru",
|
||||||
|
"zh-CN"
|
||||||
],
|
],
|
||||||
"highContrast": true,
|
"highContrast": true,
|
||||||
"docMenu": [
|
"docMenu": [
|
||||||
@ -127,6 +130,7 @@
|
|||||||
"path": "/reference"
|
"path": "/reference"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"print": true,
|
||||||
"showHomeScreen": true,
|
"showHomeScreen": true,
|
||||||
"homeScreenHero": "./static/hero.png",
|
"homeScreenHero": "./static/hero.png",
|
||||||
"invertedMenu": false,
|
"invertedMenu": false,
|
||||||
@ -135,6 +139,7 @@
|
|||||||
"invertedToolbox": false,
|
"invertedToolbox": false,
|
||||||
"coloredToolbox": true,
|
"coloredToolbox": true,
|
||||||
"hasAudio": true,
|
"hasAudio": true,
|
||||||
|
"saveInMenu": true,
|
||||||
"usbHelp": [],
|
"usbHelp": [],
|
||||||
"extendEditor": true,
|
"extendEditor": true,
|
||||||
"extendFieldEditors": true,
|
"extendFieldEditors": true,
|
||||||
@ -172,7 +177,7 @@
|
|||||||
"monacoColors": {
|
"monacoColors": {
|
||||||
"editor.background": "#f9f9f9"
|
"editor.background": "#f9f9f9"
|
||||||
},
|
},
|
||||||
"fileNameExclusiveFilter": "[^a-zA-Z]"
|
"fileNameExclusiveFilter": "[^a-zA-Z0-9]"
|
||||||
},
|
},
|
||||||
"ignoreDocsErrors": true
|
"ignoreDocsErrors": true
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,6 @@
|
|||||||
"Maker": "maker"
|
"Maker": "maker"
|
||||||
},
|
},
|
||||||
"electronManifest": {
|
"electronManifest": {
|
||||||
"latest": "v0.3.6"
|
"latest": "v0.4.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|