Compare commits
105 Commits
Author | SHA1 | Date | |
---|---|---|---|
dad1bd0cd4 | |||
b71bfef418 | |||
2e0a34c99b | |||
4133828a10 | |||
f0c19bc976 | |||
a09b4a083f | |||
15dff9af08 | |||
6fa5c1b688 | |||
d76cea1477 | |||
ca09a0a833 | |||
fcc864823e | |||
166dc27b93 | |||
66e50473c4 | |||
58452e1ca3 | |||
2b7498ea2d | |||
5ab2b97663 | |||
ffe0f0fb32 | |||
f27d13f88e | |||
31067dcef8 | |||
123f6c84b2 | |||
c5f07ca67c | |||
22fc7dee18 | |||
1f58b649c5 | |||
fc75fe8e16 | |||
b399c37527 | |||
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 | |||
1df90a6ea3 | |||
09ac2a7a47 | |||
06565995d3 | |||
1a73aec74d | |||
5516d041d6 | |||
7aac8ab5f3 | |||
73da17a395 | |||
16197f2987 | |||
5ec7eb6f04 | |||
f05ad887b8 | |||
c8a7b73101 | |||
0b9d029ecc | |||
d6f0fee300 | |||
d78b4c5ee3 | |||
13f5ebd6a7 | |||
ccbebabc55 | |||
5c61677ab9 | |||
21025b5f83 | |||
f9a0729b63 | |||
8e456f5c3c | |||
e05e147d6a | |||
fc83cc5d5b | |||
7974f36c31 | |||
6513dbc901 | |||
97215e894a | |||
1368ee824b | |||
f2344ac52e | |||
299acea61f | |||
a99f0212ac | |||
d128dad3dc | |||
3d7ebeb7b7 | |||
304cbb5ee3 | |||
0f7ec45db4 | |||
2bc2bda502 | |||
51cb7a5299 | |||
068eb7017f | |||
bb4966dca7 | |||
e981d1b95d |
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
[](https://ci2.dot.net/job/Private/job/pxt_project_rainbow/job/master/job/pxt-ev3_Push/)
|
[](https://ci2.dot.net/job/Private/job/pxt_project_rainbow/job/master/job/pxt-ev3_Push/)
|
||||||
|
|
||||||
This repo contains the editor target hosted at https://makecode.legoeducation.com
|
This repo contains the editor target hosted at https://makecode.mindstorms.com
|
||||||
|
|
||||||
LEGO Auth: https://src.education.lego.com/groups/ev3-makecode (use Google Authenticator)
|
LEGO Auth: https://src.education.lego.com/groups/ev3-makecode (use Google Authenticator)
|
||||||
LEGO Chat: https://chat.internal.education.lego.com/make-code/channels/town-square
|
LEGO Chat: https://chat.internal.education.lego.com/make-code/channels/town-square
|
||||||
|
@ -11,5 +11,8 @@
|
|||||||
<div class="ui container horizontal small divided link list">
|
<div class="ui container horizontal small divided link list">
|
||||||
<a class="ui centered item" href="https://makecode.com/" title="Microsoft MakeCode" target="_blank" rel="noopener">Powered by Microsoft MakeCode</a>
|
<a class="ui centered item" href="https://makecode.com/" title="Microsoft MakeCode" target="_blank" rel="noopener">Powered by Microsoft MakeCode</a>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="ui centered container small list">
|
||||||
|
<p class="item">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.</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
* [Troubleshoot](/troubleshoot)
|
* [Troubleshoot](/troubleshoot)
|
||||||
* [EV3 Manager](https://ev3manager.education.lego.com/)
|
* [EV3 Manager](https://ev3manager.education.lego.com/)
|
||||||
* [LEGO Support](https://www.lego.com/service/)
|
* [LEGO Support](https://www.lego.com/service/)
|
||||||
|
* [FIRST LEGO League](/fll)
|
||||||
|
|
||||||
## Projects #projects
|
## Projects #projects
|
||||||
|
|
||||||
@ -82,12 +83,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 +124,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.
|
||||||
|
112
docs/fll.md
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
# MakeCode for _FIRST_ LEGO League
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
For teams participating in the Open Software Platform Pilot utilizing MakeCode, we’ve compiled a list of resources and information that we hope will be helpful for you.
|
||||||
|
|
||||||
|
## FAQ
|
||||||
|
|
||||||
|
### How do I use MakeCode with my EV3?
|
||||||
|
|
||||||
|
* You will need to install the latest EV3 firmware on your brick. Instructions on how to do that are located here: https://makecode.mindstorms.com/troubleshoot.
|
||||||
|
* You will need a computer with a USB port to connect to the EV3 in order to download your programs.
|
||||||
|
* You will need internet access and a browser on your computer to get to https://makecode.mindstorms.com.
|
||||||
|
|
||||||
|
### What’s the best way to get started with MakeCode?
|
||||||
|
|
||||||
|
Watch some of the videos at https://makecode.mindstorms.com (at the bottom of the page).
|
||||||
|
Try some of the provided tutorials:
|
||||||
|
|
||||||
|
* [Wake Up!](@homeurl@#tutorial:tutorials/wake-up) – show your EV3 brick waking up
|
||||||
|
* [Animation](@homeurl@#tutorial:tutorials/make-an-animation) – create a custom animation to show
|
||||||
|
* [Music Brick](@homeurl@#tutorial:tutorials/music-brick) – transform your EV3 into a musical instrument
|
||||||
|
* [Run Motors](@homeurl@#tutorial:tutorials/run-motors) – control the motors of your robot
|
||||||
|
* [Red Light, Green Light](@homeurl@#tutorial:tutorials/redlight-greenlight) – play red light, green light with the color sensor
|
||||||
|
* [Line Following](@homeurl@#tutorial:tutorials/line-following) – have your robot follow a line
|
||||||
|
|
||||||
|
### Can I load both LEGO MINDSTORMS EV3 Software and MakeCode programs onto my EV3?
|
||||||
|
|
||||||
|
Yes.
|
||||||
|
|
||||||
|
### How do I figure out what a block does?
|
||||||
|
|
||||||
|
You can right-click on any block and select “Help” in the context menu to open the documentation page describing what that block does.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
### How do I program in JavaScript?
|
||||||
|
|
||||||
|
Click the **JavaScript** button at the top of the page to get to the JavaScript editor. Students can drag and drop code snippets from the Toolbox on the left, or type directly in the editor. You can switch back and forth between **Blocks** and **JavaScript** as you program.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Also, watch the [Text-based Coding](https://legoeducation.videomarketingplatform.co/v.ihtml/player.html?token=3513a83b87fe536b2dc512237465fd1b&source=embed&photo%5fid=35719471) video for more about coding using the JavaScript editor.
|
||||||
|
|
||||||
|
### How do I use the Simulator?
|
||||||
|
|
||||||
|
The Simulator will show the physical representation of your code blocks. For example, based on this code snippet, the Simulator will show the touch sensor on Port 1, and a large motor on Port D.
|
||||||
|
|
||||||
|
```blocks
|
||||||
|
sensors.touch1.onEvent(ButtonEvent.Pressed, function () {
|
||||||
|
motors.largeD.run(50)
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Note that the Simulator is also interactive, so you can simulate inputs with any of the sensors.
|
||||||
|
|
||||||
|
See the video [Block-based Coding and Simulation](https://legoeducation.videomarketingplatform.co/v.ihtml/player.html?token=629730c938e452f0fd7653fbc4708166&source=embed&photo%5fid=35719470) for more about using the simulator.
|
||||||
|
|
||||||
|
### How do I save my programs?
|
||||||
|
|
||||||
|
MakeCode will automatically save your recent projects in the browser. However, you can also save a copy of your project as a file on your computer:
|
||||||
|
|
||||||
|
* From the **Settings** menu, select **Save Project**
|
||||||
|
* This will download your program from the browser as a _lego-myproject.uf2_ file
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
* You can import your saved projects by clicking the Import button on the Home Page
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
### How do I share my programs?
|
||||||
|
|
||||||
|
You can share your projects by clicking on the **share** button in the top left of the screen. This will create a URL which you can send others to open and view your project.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Sharing programs is also shown in the [Tips and Tricks](https://legoeducation.videomarketingplatform.co/v.ihtml/player.html?token=5c594c2373367f7870196f519f3bfc7a&source=embed&photo%5fid=35719472) video.
|
||||||
|
|
||||||
|
### Why can't I delete my program (*.uf2) files from the Brick?
|
||||||
|
|
||||||
|
There's a bug in the firmware which prevents you from deleting the programs (``*.uf2`` files) from your EV3 Brick. There isn't a firmware update to fix this yet. As a workaround, you can temporarily downgrade your firmware version, delete the files, and then upgrade back to the version that works with MakeCode.
|
||||||
|
|
||||||
|
Follow these steps to downgrade your firmware version, delete the files, and uprgade back again:
|
||||||
|
|
||||||
|
1. Go into **EV3 LabVIEW** - if it's not installed get it [here](https://education.lego.com/en-us/downloads/mindstorms-ev3/software)
|
||||||
|
2. Plug in your EV3 Brick and start a new project
|
||||||
|
3. Go to the **Tools** menu in the upper right corner, select **Firmware Update**
|
||||||
|
4. In the **Firmware Update** dialog box, click on the **Show Details** button
|
||||||
|
5. From the **Available Firmware Files** list, select **EV3 Firmware V1.09E**
|
||||||
|
6. Click the **Update Firmware** button and wait for the update to complete
|
||||||
|
|
||||||
|
Now the firmware version on the EV3 Brick will be **V1.09E**. Also, in the process, the downgrade deleted all of the saved programs from the EV3 Brick. To continue to use MakeCode, the firmware version must be at **V1.10E** or above. So, the Brick firmware needs to be upgraded again. If you don't know or do remember how to do this, see the **Upgrade your @drivename@** section in the [troubleshooting](/troubleshoot) page.
|
||||||
|
|
||||||
|
For other common questions, try the FAQ page https://makecode.mindstorms.com/faq.
|
||||||
|
|
||||||
|
## Workarounds
|
||||||
|
|
||||||
|
1. Deleting Programs from the EV3 brick
|
||||||
|
|
||||||
|
>* Description: Unable to delete program files from the EV3 brick after downloading them
|
||||||
|
>* Status: LEGO Education team is working on a fix, no estimated date yet
|
||||||
|
|
||||||
|
## Community connection
|
||||||
|
|
||||||
|
For questions, issues, feedback and community for the Open Software Platform Pilot:
|
||||||
|
|
||||||
|
We are using a messaging service called **Slack**. Slack can be accessed via an app you download to your computer or mobile device, and via a web interface. For more information about Slack, click [here](https://slack.com/). Anyone in the pilot can participate by signing up with Slack first, and then clicking this [FIRST LEGO League Robot SW](https://fllrobotsw.slack.com/join/shared_invite/enQtNDgxOTQ5MDc2OTkyLTg2ZTRkYzQ4OGMyZTg1OTZmMDFhMWNlOTQ1OWRlNDdmNzNmMjlhMmZiM2M3OWUxYjU1ODEwY2FmODJkNjZkOTA) link to join the Slack workspace.
|
@ -7,7 +7,7 @@
|
|||||||
{
|
{
|
||||||
"name": "Prepare",
|
"name": "Prepare",
|
||||||
"imageUrl": "/static/lessons/firmware.png",
|
"imageUrl": "/static/lessons/firmware.png",
|
||||||
"description": "To use Microsoft MakeCode with your EV3 Brick, you will need to install the latest LEGO® MINDSTORMS® Education EV3 firmware. Follow these steps to make sure you're up to date and install the latest firmware if you need to.",
|
"description": "To use Microsoft MakeCode with your EV3 Brick, you will need to install the latest LEGO® MINDSTORMS® Education EV3 firmware.",
|
||||||
"label": "New? Start Here!",
|
"label": "New? Start Here!",
|
||||||
"labelClass": "red ribbon large",
|
"labelClass": "red ribbon large",
|
||||||
"url": "https://makecode.mindstorms.com/troubleshoot"
|
"url": "https://makecode.mindstorms.com/troubleshoot"
|
||||||
|
@ -135,15 +135,15 @@ Keeping the Large Motor connected to **Port D**, connect the Color Sensor to **P
|
|||||||
|
|
||||||
```blocks
|
```blocks
|
||||||
brick.buttonEnter.onEvent(ButtonEvent.Pressed, function () {
|
brick.buttonEnter.onEvent(ButtonEvent.Pressed, function () {
|
||||||
sensors.color3.pauseUntilColorDetected(ColorSensorColor.Green)
|
sensors.color4.pauseUntilColorDetected(ColorSensorColor.Green)
|
||||||
motors.largeD.run(50, 1, MoveUnit.Rotations)
|
motors.largeD.run(50, 1, MoveUnit.Rotations)
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
* Using the same program, replace the ``||sensors:pause until touch 1||`` block with a ``||sensors:pause color sensor 3||`` for color block.
|
* Using the same program, replace the ``||sensors:pause until touch 1||`` block with a ``||sensors:pause color sensor 4||`` for color block.
|
||||||
|
|
||||||
```block
|
```block
|
||||||
sensors.color3.pauseUntilColorDetected(ColorSensorColor.Green)
|
sensors.color4.pauseUntilColorDetected(ColorSensorColor.Green)
|
||||||
```
|
```
|
||||||
|
|
||||||
* Select the color you want to detect (e.g., green).
|
* Select the color you want to detect (e.g., green).
|
||||||
|
@ -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.1.57"
|
"appref": "v1.0.8"
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
791
docs/offline-app.html
Normal file
@ -0,0 +1,791 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:og="http://ogp.me/ns#" xmlns:fb="http://www.facebook.com/2008/fbml">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>LEGO® MINDSTORMS® Education EV3 Offline App</title>
|
||||||
|
<meta name="Description" content="A MakeCode for LEGO® MINDSTORMS® Education EV3 offline app" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<!-- @include indexhead.html -->
|
||||||
|
|
||||||
|
<style>
|
||||||
|
p.item {
|
||||||
|
color: rgba(0, 0, 0, 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.topbar {
|
||||||
|
background: rgb(170, 39, 143) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ui.inverted.content {
|
||||||
|
/* background: #00a5c8; */
|
||||||
|
background: #2a7af3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content.segment {
|
||||||
|
min-height: 80%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content .welcomeheader {
|
||||||
|
font-weight: 300;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer.segment {
|
||||||
|
padding: 5em 0em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image.left {
|
||||||
|
padding-left: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image.right {
|
||||||
|
padding-right: 2em;
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.segments {
|
||||||
|
max-width: 60%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.segments.terms-container {
|
||||||
|
margin-top: 5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.terms-container .segment {
|
||||||
|
background-color: rgb(250, 250, 250);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 800px) {
|
||||||
|
.grid .column .image {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.segments {
|
||||||
|
max-width: 95%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<!-- Auto-generated styles for the license terms -->
|
||||||
|
<style type="text/css">
|
||||||
|
.terms ol {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
.terms table td,
|
||||||
|
.terms table th {
|
||||||
|
padding: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
.c2 {
|
||||||
|
margin-left: 22.5pt;
|
||||||
|
padding-top: 6pt;
|
||||||
|
text-indent: -18pt;
|
||||||
|
padding-bottom: 6pt;
|
||||||
|
line-height: 1.15;
|
||||||
|
orphans: 2;
|
||||||
|
widows: 2;
|
||||||
|
text-align: left
|
||||||
|
}
|
||||||
|
|
||||||
|
.c8 {
|
||||||
|
margin-left: 40.5pt;
|
||||||
|
padding-top: 6pt;
|
||||||
|
text-indent: -18pt;
|
||||||
|
padding-bottom: 6pt;
|
||||||
|
line-height: 1.15;
|
||||||
|
orphans: 2;
|
||||||
|
widows: 2;
|
||||||
|
text-align: left
|
||||||
|
}
|
||||||
|
|
||||||
|
.c15 {
|
||||||
|
padding-top: 0pt;
|
||||||
|
padding-bottom: 12pt;
|
||||||
|
line-height: 1.15;
|
||||||
|
orphans: 2;
|
||||||
|
widows: 2;
|
||||||
|
text-align: left;
|
||||||
|
height: 11pt
|
||||||
|
}
|
||||||
|
|
||||||
|
.c7 {
|
||||||
|
padding-top: 0pt;
|
||||||
|
padding-bottom: 0pt;
|
||||||
|
line-height: 1.15;
|
||||||
|
orphans: 2;
|
||||||
|
widows: 2;
|
||||||
|
text-align: left;
|
||||||
|
height: 11pt
|
||||||
|
}
|
||||||
|
|
||||||
|
.c0 {
|
||||||
|
margin-left: 23pt;
|
||||||
|
padding-top: 6pt;
|
||||||
|
padding-bottom: 6pt;
|
||||||
|
line-height: 1.15;
|
||||||
|
orphans: 2;
|
||||||
|
widows: 2;
|
||||||
|
text-align: left
|
||||||
|
}
|
||||||
|
|
||||||
|
.c10 {
|
||||||
|
margin-left: 40.5pt;
|
||||||
|
padding-top: 6pt;
|
||||||
|
padding-bottom: 6pt;
|
||||||
|
line-height: 1.15;
|
||||||
|
orphans: 2;
|
||||||
|
widows: 2;
|
||||||
|
text-align: left
|
||||||
|
}
|
||||||
|
|
||||||
|
.c6 {
|
||||||
|
margin-left: 40.5pt;
|
||||||
|
padding-top: 0pt;
|
||||||
|
padding-bottom: 0pt;
|
||||||
|
line-height: 1.15;
|
||||||
|
orphans: 2;
|
||||||
|
widows: 2;
|
||||||
|
text-align: left
|
||||||
|
}
|
||||||
|
|
||||||
|
.c20 {
|
||||||
|
padding-top: 0pt;
|
||||||
|
padding-bottom: 0pt;
|
||||||
|
line-height: 1.15;
|
||||||
|
orphans: 2;
|
||||||
|
widows: 2;
|
||||||
|
text-align: center
|
||||||
|
}
|
||||||
|
|
||||||
|
.c4 {
|
||||||
|
color: #000000;
|
||||||
|
font-weight: 700;
|
||||||
|
text-decoration: none;
|
||||||
|
vertical-align: baseline;
|
||||||
|
font-family: "Arial";
|
||||||
|
font-style: normal
|
||||||
|
}
|
||||||
|
|
||||||
|
.c11 {
|
||||||
|
padding-top: 0pt;
|
||||||
|
padding-bottom: 0pt;
|
||||||
|
line-height: 1.15;
|
||||||
|
orphans: 2;
|
||||||
|
widows: 2;
|
||||||
|
text-align: left
|
||||||
|
}
|
||||||
|
|
||||||
|
.c12 {
|
||||||
|
padding-top: 6pt;
|
||||||
|
padding-bottom: 6pt;
|
||||||
|
line-height: 1.15;
|
||||||
|
orphans: 2;
|
||||||
|
widows: 2;
|
||||||
|
text-align: left
|
||||||
|
}
|
||||||
|
|
||||||
|
.c3 {
|
||||||
|
color: #000000;
|
||||||
|
font-weight: 400;
|
||||||
|
text-decoration: none;
|
||||||
|
vertical-align: baseline;
|
||||||
|
font-family: "Arial";
|
||||||
|
font-style: normal
|
||||||
|
}
|
||||||
|
|
||||||
|
.c16 {
|
||||||
|
padding-top: 0pt;
|
||||||
|
padding-bottom: 12pt;
|
||||||
|
line-height: 1.15;
|
||||||
|
orphans: 2;
|
||||||
|
widows: 2;
|
||||||
|
text-align: left
|
||||||
|
}
|
||||||
|
|
||||||
|
.c13 {
|
||||||
|
color: #000000;
|
||||||
|
text-decoration: none;
|
||||||
|
vertical-align: baseline;
|
||||||
|
font-family: "Arial";
|
||||||
|
font-style: italic
|
||||||
|
}
|
||||||
|
|
||||||
|
.c14 {
|
||||||
|
text-decoration-skip-ink: none;
|
||||||
|
-webkit-text-decoration-skip: none;
|
||||||
|
color: #1155cc;
|
||||||
|
text-decoration: underline
|
||||||
|
}
|
||||||
|
|
||||||
|
.c17 {
|
||||||
|
background-color: #ffffff;
|
||||||
|
max-width: 540pt;
|
||||||
|
padding: 36pt 36pt 36pt 36pt
|
||||||
|
}
|
||||||
|
|
||||||
|
.c18 {
|
||||||
|
text-decoration-skip-ink: none;
|
||||||
|
-webkit-text-decoration-skip: none;
|
||||||
|
text-decoration: underline
|
||||||
|
}
|
||||||
|
|
||||||
|
.c9 {
|
||||||
|
color: inherit;
|
||||||
|
text-decoration: inherit
|
||||||
|
}
|
||||||
|
|
||||||
|
.c5 {
|
||||||
|
font-weight: 700
|
||||||
|
}
|
||||||
|
|
||||||
|
.c1 {
|
||||||
|
font-size: 10pt
|
||||||
|
}
|
||||||
|
|
||||||
|
.c19 {
|
||||||
|
font-size: 11pt
|
||||||
|
}
|
||||||
|
|
||||||
|
.terms .title {
|
||||||
|
padding-top: 0pt;
|
||||||
|
color: #000000;
|
||||||
|
font-size: 26pt;
|
||||||
|
padding-bottom: 3pt;
|
||||||
|
font-family: "Arial";
|
||||||
|
line-height: 1.15;
|
||||||
|
page-break-after: avoid;
|
||||||
|
orphans: 2;
|
||||||
|
widows: 2;
|
||||||
|
text-align: left
|
||||||
|
}
|
||||||
|
|
||||||
|
.terms .subtitle {
|
||||||
|
padding-top: 0pt;
|
||||||
|
color: #666666;
|
||||||
|
font-size: 15pt;
|
||||||
|
padding-bottom: 16pt;
|
||||||
|
font-family: "Arial";
|
||||||
|
line-height: 1.15;
|
||||||
|
page-break-after: avoid;
|
||||||
|
orphans: 2;
|
||||||
|
widows: 2;
|
||||||
|
text-align: left
|
||||||
|
}
|
||||||
|
|
||||||
|
.terms li {
|
||||||
|
color: #000000;
|
||||||
|
font-size: 11pt;
|
||||||
|
font-family: "Arial"
|
||||||
|
}
|
||||||
|
|
||||||
|
.terms p {
|
||||||
|
margin: 0;
|
||||||
|
color: #000000;
|
||||||
|
font-size: 11pt;
|
||||||
|
font-family: "Arial"
|
||||||
|
}
|
||||||
|
|
||||||
|
.terms h1 {
|
||||||
|
padding-top: 20pt;
|
||||||
|
color: #000000;
|
||||||
|
font-size: 20pt;
|
||||||
|
padding-bottom: 6pt;
|
||||||
|
font-family: "Arial";
|
||||||
|
line-height: 1.15;
|
||||||
|
page-break-after: avoid;
|
||||||
|
orphans: 2;
|
||||||
|
widows: 2;
|
||||||
|
text-align: left
|
||||||
|
}
|
||||||
|
|
||||||
|
.terms h2 {
|
||||||
|
padding-top: 18pt;
|
||||||
|
color: #000000;
|
||||||
|
font-size: 16pt;
|
||||||
|
padding-bottom: 6pt;
|
||||||
|
font-family: "Arial";
|
||||||
|
line-height: 1.15;
|
||||||
|
page-break-after: avoid;
|
||||||
|
orphans: 2;
|
||||||
|
widows: 2;
|
||||||
|
text-align: left
|
||||||
|
}
|
||||||
|
|
||||||
|
.terms h3 {
|
||||||
|
padding-top: 16pt;
|
||||||
|
color: #434343;
|
||||||
|
font-size: 14pt;
|
||||||
|
padding-bottom: 4pt;
|
||||||
|
font-family: "Arial";
|
||||||
|
line-height: 1.15;
|
||||||
|
page-break-after: avoid;
|
||||||
|
orphans: 2;
|
||||||
|
widows: 2;
|
||||||
|
text-align: left
|
||||||
|
}
|
||||||
|
|
||||||
|
.terms h4 {
|
||||||
|
padding-top: 14pt;
|
||||||
|
color: #666666;
|
||||||
|
font-size: 12pt;
|
||||||
|
padding-bottom: 4pt;
|
||||||
|
font-family: "Arial";
|
||||||
|
line-height: 1.15;
|
||||||
|
page-break-after: avoid;
|
||||||
|
orphans: 2;
|
||||||
|
widows: 2;
|
||||||
|
text-align: left
|
||||||
|
}
|
||||||
|
|
||||||
|
.terms h5 {
|
||||||
|
padding-top: 12pt;
|
||||||
|
color: #666666;
|
||||||
|
font-size: 11pt;
|
||||||
|
padding-bottom: 4pt;
|
||||||
|
font-family: "Arial";
|
||||||
|
line-height: 1.15;
|
||||||
|
page-break-after: avoid;
|
||||||
|
orphans: 2;
|
||||||
|
widows: 2;
|
||||||
|
text-align: left
|
||||||
|
}
|
||||||
|
|
||||||
|
.terms h6 {
|
||||||
|
padding-top: 12pt;
|
||||||
|
color: #666666;
|
||||||
|
font-size: 11pt;
|
||||||
|
padding-bottom: 4pt;
|
||||||
|
font-family: "Arial";
|
||||||
|
line-height: 1.15;
|
||||||
|
page-break-after: avoid;
|
||||||
|
font-style: italic;
|
||||||
|
orphans: 2;
|
||||||
|
widows: 2;
|
||||||
|
text-align: left
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
$(document).ready(function () {
|
||||||
|
tickEvent = function (id, data) {
|
||||||
|
if (!pxt.aiTrackEvent) return;
|
||||||
|
if (!data) pxt.aiTrackEvent(id);
|
||||||
|
else {
|
||||||
|
var props = {};
|
||||||
|
var measures = {};
|
||||||
|
for (var k in data)
|
||||||
|
if (typeof data[k] == "string") props[k] = data[k];
|
||||||
|
else measures[k] = data[k];
|
||||||
|
pxt.aiTrackEvent(id, props, measures);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
function agreeCheckboxChanged() {
|
||||||
|
var downloadSegment = document.getElementById("download-segment");
|
||||||
|
downloadSegment.classList.toggle("hidden");
|
||||||
|
}
|
||||||
|
function downloadWin64() {
|
||||||
|
// TODO: Keep this link up-to-date with the desired release version
|
||||||
|
window.open("https://makecode.com/api/release/ev3/v1.0.8/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/v1.0.8/mac64");
|
||||||
|
tickEvent("offlineapp.download", { "target": "ev3", "platform": "mac64" });
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body id="root" class="root">
|
||||||
|
|
||||||
|
<div class="ui inverted vertical center aligned segment content">
|
||||||
|
|
||||||
|
<div class="ui grid topbar">
|
||||||
|
<div class="three wide column">
|
||||||
|
<img class="ui small image left" src="/static//lego_education_logo_white.png" />
|
||||||
|
</div>
|
||||||
|
<div class="ten wide column">
|
||||||
|
<h1 class="ui inverted welcomeheader">MakeCode Offline App</h1>
|
||||||
|
</div>
|
||||||
|
<div class="three wide column">
|
||||||
|
<img class="ui small image right" src="/static//Microsoft-logo_rgb_c-white.png" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="ui compact segments terms-container">
|
||||||
|
<div class="ui secondary center aligned segment">
|
||||||
|
Please read and accept the following terms to download the app.
|
||||||
|
</div>
|
||||||
|
<div class="ui left aligned segment terms">
|
||||||
|
<div class="c17">
|
||||||
|
<p class="c11">
|
||||||
|
<span class="c4 c1">MICROSOFT PRE-RELEASE SOFTWARE LICENSE TERMS</span>
|
||||||
|
</p>
|
||||||
|
<p class="c11">
|
||||||
|
<span class="c4 c1">MICROSOFT MAKECODE FOR LEGO MINDSTORMS EDUCATION EV3</span>
|
||||||
|
</p>
|
||||||
|
<p class="c7">
|
||||||
|
<span class="c4 c1"></span>
|
||||||
|
</p>
|
||||||
|
<p class="c11">
|
||||||
|
<span class="c3 c1">These license terms are an agreement between Microsoft Corporation (or based on where you live, one
|
||||||
|
of its affiliates) and you. They apply to the software named above. The terms also apply to any
|
||||||
|
Microsoft services or updates for the software, except to the extent those have additional terms.</span>
|
||||||
|
</p>
|
||||||
|
<p class="c7">
|
||||||
|
<span class="c3 c1"></span>
|
||||||
|
</p>
|
||||||
|
<p class="c11">
|
||||||
|
<span class="c4 c1">IF YOU COMPLY WITH THESE LICENSE TERMS, YOU HAVE THE RIGHTS BELOW.</span>
|
||||||
|
</p>
|
||||||
|
<p class="c2">
|
||||||
|
<span class="c5 c1">1.</span>
|
||||||
|
<span class="c1"> </span>
|
||||||
|
<span class="c5 c1">INSTALLATION AND USE RIGHTS. </span>
|
||||||
|
<span class="c3 c1">You may install and use any number of copies of the software to evaluate it as you develop and test
|
||||||
|
your software applications for use with Lego Mindstorms Education EV3 hardware.</span>
|
||||||
|
</p>
|
||||||
|
<p class="c2">
|
||||||
|
<span class="c5 c1">2.</span>
|
||||||
|
<span class="c1"> </span>
|
||||||
|
<span class="c5 c1">PRE-RELEASE SOFTWARE. </span>
|
||||||
|
<span class="c3 c1">The software is a pre-release version. It may not work the way a final version of the software will.
|
||||||
|
Microsoft may change it for the final, commercial version. We also may not release a commercial
|
||||||
|
version. Microsoft is not obligated to provide maintenance, technical support or updates to you
|
||||||
|
for the software.</span>
|
||||||
|
</p>
|
||||||
|
<p class="c2">
|
||||||
|
<span class="c5 c1">3.</span>
|
||||||
|
<span class="c1"> </span>
|
||||||
|
<span class="c5 c1">ASSOCIATED ONLINE SERVICES.</span>
|
||||||
|
<span class="c1"> Some features of the software provide access
|
||||||
|
to, or rely on, online services to provide you information about updates to the software or extensions,
|
||||||
|
or to enable you to retrieve content, collaborate with others, or otherwise supplement your development
|
||||||
|
experience. As used throughout these license terms, the term <q>software</q> includes these online
|
||||||
|
services and features. By using these online services and features you consent to the to the
|
||||||
|
transmission of information as described in Section 5, DATA.
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
<p class="c2">
|
||||||
|
<span class="c5 c1">4.</span>
|
||||||
|
<span class="c1"> </span>
|
||||||
|
<span class="c5 c1">LICENSES FOR OTHER COMPONENTS.</span>
|
||||||
|
<span class="c3 c1"> The software may include third party components with separate legal notices or governed by
|
||||||
|
other agreements, as described in the ThirdPartyNotices file accompanying the software. Even
|
||||||
|
if such components are governed by other agreements, the disclaimers and the limitations on and
|
||||||
|
exclusions of damages below also apply.</span>
|
||||||
|
</p>
|
||||||
|
<p class="c2">
|
||||||
|
<span class="c5 c1">5.</span>
|
||||||
|
<span class="c1"> </span>
|
||||||
|
<span class="c1 c4">DATA.</span>
|
||||||
|
</p>
|
||||||
|
<p class="c8">
|
||||||
|
<span class="c5 c1">a.</span>
|
||||||
|
<span class="c1"> </span>
|
||||||
|
<span class="c1 c5">Data Collection. </span>
|
||||||
|
<span class="c1">The software may collect information about you and your use of the software, and send that to Microsoft.
|
||||||
|
Microsoft may use this information to provide services and improve our products and services.
|
||||||
|
You may opt out of many of these scenarios, but not all, as described in the product documentation.
|
||||||
|
In using the software, you must comply with applicable law. You can learn more about data collection
|
||||||
|
and use in the help documentation and the privacy statement at </span>
|
||||||
|
<span class="c14 c1">
|
||||||
|
<a class="c9" href="http://go.microsoft.com/fwlink/?LinkId=398505">http://go.microsoft.com/fwlink/?LinkId=398505</a>
|
||||||
|
</span>
|
||||||
|
<span class="c1">.</span>
|
||||||
|
<span class="c3 c1"> Your use of the software operates as your consent to these practices.</span>
|
||||||
|
</p>
|
||||||
|
<p class="c8">
|
||||||
|
<span class="c5 c1">b.</span>
|
||||||
|
<span class="c1"> </span>
|
||||||
|
<span class="c5 c1">Processing of Personal Data. </span>
|
||||||
|
<span class="c1">To the extent Microsoft is a processor or subprocessor of personal data in connection with the software,
|
||||||
|
Microsoft makes the commitments in the European Union General Data Protection Regulation Terms
|
||||||
|
of the Online Services Terms to all customers effective May 25, 2018, at </span>
|
||||||
|
<span class="c1 c14">
|
||||||
|
<a class="c9" href="http://go.microsoft.com/?linkid=9840733">http://go.microsoft.com/?linkid=9840733</a>
|
||||||
|
</span>
|
||||||
|
<span class="c3 c1">.</span>
|
||||||
|
</p>
|
||||||
|
<p class="c2">
|
||||||
|
<span class="c5 c1">6.</span>
|
||||||
|
<span class="c1"> </span>
|
||||||
|
<span class="c5 c1">FEEDBACK. </span>
|
||||||
|
<span class="c3 c1">If you give feedback about the software to Microsoft, you give to Microsoft, without charge, the
|
||||||
|
right to use, share and commercialize your feedback in any way and for any purpose. You will
|
||||||
|
not give feedback that is subject to a license that requires Microsoft to license its software
|
||||||
|
or documentation to third parties because we include your feedback in them. These rights survive
|
||||||
|
this agreement.</span>
|
||||||
|
</p>
|
||||||
|
<p class="c2">
|
||||||
|
<span class="c5 c1">7.</span>
|
||||||
|
<span class="c1"> </span>
|
||||||
|
<span class="c5 c1">SCOPE OF LICENSE.</span>
|
||||||
|
<span class="c3 c1"> The software is licensed, not sold. This agreement only gives you some rights to use the software.
|
||||||
|
Microsoft reserves all other rights. Unless applicable law gives you more rights despite this
|
||||||
|
limitation, you may use the software only as expressly permitted in this agreement. In
|
||||||
|
doing so, you must comply with any technical limitations in the software that only allow you
|
||||||
|
to use it in certain ways. You may not:</span>
|
||||||
|
</p>
|
||||||
|
<p class="c8">
|
||||||
|
<span class="c3 c1">- work around any technical limitations in the software;</span>
|
||||||
|
</p>
|
||||||
|
<p class="c8">
|
||||||
|
<span class="c3 c1">- reverse engineer, decompile or disassemble the software, or attempt to do so, except
|
||||||
|
and only to the extent required by third party licensing terms governing use of certain open
|
||||||
|
source components that may be included with the software;</span>
|
||||||
|
</p>
|
||||||
|
<p class="c8">
|
||||||
|
<span class="c3 c1">- remove, minimize, block or modify any notices of Microsoft or its suppliers in the
|
||||||
|
software;
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
<p class="c8">
|
||||||
|
<span class="c3 c1">- use the software in any way that is against the law; or</span>
|
||||||
|
</p>
|
||||||
|
<p class="c8">
|
||||||
|
<span class="c3 c1">- share, publish, rent or lease the software, or provide the software as a stand-alone
|
||||||
|
offering for others to use.</span>
|
||||||
|
</p>
|
||||||
|
<p class="c2">
|
||||||
|
<span class="c5 c1">8. UPDATES. </span>
|
||||||
|
<span class="c3 c1">The software may periodically check for updates and download and install them for you. You may obtain
|
||||||
|
updates only from Microsoft or authorized sources. Microsoft may need to update your system to
|
||||||
|
provide you with updates. You agree to receive these automatic updates without any additional
|
||||||
|
notice. Updates may not include or support all existing software features, services, or peripheral
|
||||||
|
devices.
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
<p class="c2">
|
||||||
|
<span class="c5 c1">9.</span>
|
||||||
|
<span class="c1"> </span>
|
||||||
|
<span class="c5 c1">EXPORT RESTRICTIONS.</span>
|
||||||
|
<span class="c3 c1"> You must comply with all domestic and international export laws and regulations that apply
|
||||||
|
to the software, which include restrictions on destinations, end users and end use. For further
|
||||||
|
information on export restrictions, visit (aka.ms/exporting).</span>
|
||||||
|
</p>
|
||||||
|
<p class="c2">
|
||||||
|
<span class="c5 c1">10.</span>
|
||||||
|
<span class="c1"> </span>
|
||||||
|
<span class="c5 c1">SUPPORT SERVICES. </span>
|
||||||
|
<span class="c3 c1">Because the software is “as is,” we may not provide support services for it.</span>
|
||||||
|
</p>
|
||||||
|
<p class="c2">
|
||||||
|
<span class="c5 c1">11.</span>
|
||||||
|
<span class="c1"> </span>
|
||||||
|
<span class="c5 c1">ENTIRE AGREEMENT.</span>
|
||||||
|
<span class="c3 c1"> This agreement, and the terms for supplements, updates, Internet-based services and support
|
||||||
|
services that you use, are the entire agreement for the software and support services.</span>
|
||||||
|
</p>
|
||||||
|
<p class="c2">
|
||||||
|
<span class="c5 c1">12.</span>
|
||||||
|
<span class="c1"> </span>
|
||||||
|
<span class="c5 c1">APPLICABLE LAW. </span>
|
||||||
|
<span class="c3 c1">If you acquired the software in the United States, Washington State law applies to interpretation
|
||||||
|
of and claims for breach of this agreement, and the laws of the state where you live apply to
|
||||||
|
all other claims. If you acquired the software in any other country, its laws apply.</span>
|
||||||
|
</p>
|
||||||
|
<p class="c2">
|
||||||
|
<span class="c5 c1">13.</span>
|
||||||
|
<span class="c1"> </span>
|
||||||
|
<span class="c5 c1">CONSUMER RIGHTS; REGIONAL VARIATIONS. </span>
|
||||||
|
<span class="c3 c1">This agreement describes certain legal rights. You may have other rights, including consumer rights,
|
||||||
|
under the laws of your state or country. Separate and apart from your relationship with Microsoft,
|
||||||
|
you may also have rights with respect to the party from which you acquired the software. This
|
||||||
|
agreement does not change those other rights if the laws of your state or country do not permit
|
||||||
|
it to do so. For example, if you acquired the software in one of the below regions, or mandatory
|
||||||
|
country law applies, then the following provisions apply to you:</span>
|
||||||
|
</p>
|
||||||
|
<p class="c8">
|
||||||
|
<span class="c5 c1">a.</span>
|
||||||
|
<span class="c1"> </span>
|
||||||
|
<span class="c5 c1">Australia. </span>
|
||||||
|
<span class="c3 c1">You have statutory guarantees under the Australian Consumer Law and nothing in this agreement is
|
||||||
|
intended to affect those rights.</span>
|
||||||
|
</p>
|
||||||
|
<p class="c8">
|
||||||
|
<span class="c5 c1">b.</span>
|
||||||
|
<span class="c1"> </span>
|
||||||
|
<span class="c5 c1">Canada. </span>
|
||||||
|
<span class="c3 c1">If you acquired the software in Canada, you may stop receiving updates by turning off the automatic
|
||||||
|
update feature, disconnecting your device from the Internet (if and when you re-connect to the
|
||||||
|
Internet, however, the software will resume checking for and installing updates), or uninstalling
|
||||||
|
the software. The product documentation, if any, may also specify how to turn off updates for
|
||||||
|
your specific device or software.</span>
|
||||||
|
</p>
|
||||||
|
<p class="c8">
|
||||||
|
<span class="c5 c1">c.</span>
|
||||||
|
<span class="c1"> </span>
|
||||||
|
<span class="c5 c1">Germany and Austria</span>
|
||||||
|
<span class="c3 c1">.</span>
|
||||||
|
</p>
|
||||||
|
<p class="c6">
|
||||||
|
<span class="c5 c1">(i)</span>
|
||||||
|
<span class="c1"> </span>
|
||||||
|
<span class="c5 c1">Warranty</span>
|
||||||
|
<span class="c3 c1">. The properly licensed software will perform substantially as described in any Microsoft materials
|
||||||
|
that accompany the software. However, Microsoft gives no contractual guarantee in relation to
|
||||||
|
the licensed software.</span>
|
||||||
|
</p>
|
||||||
|
<p class="c6">
|
||||||
|
<span class="c4 c1"> </span>
|
||||||
|
</p>
|
||||||
|
<p class="c6">
|
||||||
|
<span class="c5 c1">(ii)</span>
|
||||||
|
<span class="c1"> </span>
|
||||||
|
<span class="c5 c1">Limitation of Liability</span>
|
||||||
|
<span class="c3 c1">. In case of intentional conduct, gross negligence, claims based on the Product Liability Act, as
|
||||||
|
well as, in case of death or personal or physical injury, Microsoft is liable according to the
|
||||||
|
statutory law.</span>
|
||||||
|
</p>
|
||||||
|
<p class="c10">
|
||||||
|
<span class="c3 c1">Subject to the foregoing clause (ii), Microsoft will only be liable for slight negligence if Microsoft
|
||||||
|
is in breach of such material contractual obligations, the fulfillment of which facilitate the
|
||||||
|
due performance of this agreement, the breach of which would endanger the purpose of this agreement
|
||||||
|
and the compliance with which a party may constantly trust in (so-called "cardinal obligations").
|
||||||
|
In other cases of slight negligence, Microsoft will not be liable for slight negligence.</span>
|
||||||
|
</p>
|
||||||
|
<p class="c2">
|
||||||
|
<span class="c5 c1">14.</span>
|
||||||
|
<span class="c1"> </span>
|
||||||
|
<span class="c5 c1">LEGAL EFFECT.</span>
|
||||||
|
<span class="c3 c1"> This agreement describes certain legal rights. You may have other rights under the laws of
|
||||||
|
your country. You may also have rights with respect to the party from whom you acquired the software.
|
||||||
|
This agreement does not change your rights under the laws of your country if the laws of your
|
||||||
|
country do not permit it to do so.</span>
|
||||||
|
</p>
|
||||||
|
<p class="c2">
|
||||||
|
<span class="c5 c1">15.</span>
|
||||||
|
<span class="c1"> </span>
|
||||||
|
<span class="c4 c1">DISCLAIMER OF WARRANTY. THE SOFTWARE IS LICENSED “AS-IS.” YOU BEAR THE RISK OF
|
||||||
|
USING IT. MICROSOFT GIVES NO EXPRESS WARRANTIES, GUARANTEES OR CONDITIONS. TO THE EXTENT PERMITTED
|
||||||
|
UNDER YOUR LOCAL LAWS, MICROSOFT EXCLUDES THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.</span>
|
||||||
|
</p>
|
||||||
|
<p class="c2">
|
||||||
|
<span class="c5 c1">16.</span>
|
||||||
|
<span class="c1"> </span>
|
||||||
|
<span class="c4 c1">LIMITATION ON AND EXCLUSION OF DAMAGES. YOU CAN RECOVER FROM MICROSOFT AND ITS SUPPLIERS ONLY DIRECT
|
||||||
|
DAMAGES UP TO U.S. $5.00. YOU CANNOT RECOVER ANY OTHER DAMAGES, INCLUDING CONSEQUENTIAL, LOST
|
||||||
|
PROFITS, SPECIAL, INDIRECT OR INCIDENTAL DAMAGES.</span>
|
||||||
|
</p>
|
||||||
|
<p class="c0">
|
||||||
|
<span class="c3 c1">This limitation applies to (a) anything related to the software, services, content (including code)
|
||||||
|
on third party Internet sites, or third party programs; and (b) claims for breach of contract,
|
||||||
|
breach of warranty, guarantee or condition, strict liability, negligence, or other tort to the
|
||||||
|
extent permitted by applicable law.</span>
|
||||||
|
</p>
|
||||||
|
<p class="c0">
|
||||||
|
<span class="c3 c1">It also applies even if Microsoft knew or should have known about the possibility of the damages.
|
||||||
|
The above limitation or exclusion may not apply to you because your country may not allow the
|
||||||
|
exclusion or limitation of incidental, consequential or other damages.</span>
|
||||||
|
</p>
|
||||||
|
<p class="c12">
|
||||||
|
<span class="c4 c1">Please note: As the software is distributed in Quebec, Canada, some of the clauses in this agreement
|
||||||
|
are provided below in French.</span>
|
||||||
|
</p>
|
||||||
|
<p class="c12">
|
||||||
|
<span class="c4 c1">Remarque : Ce logiciel étant distribué au Québec, Canada, certaines des clauses
|
||||||
|
dans ce contrat sont fournies ci-dessous en français.</span>
|
||||||
|
</p>
|
||||||
|
<p class="c11">
|
||||||
|
<span class="c5 c1">EXONÉRATION DE GARANTIE.</span>
|
||||||
|
<span class="c1 c3"> Le logiciel visé par une licence est offert « tel quel ». Toute utilisation
|
||||||
|
de ce logiciel est à votre seule risque et péril. Microsoft n’accorde aucune
|
||||||
|
autre garantie expresse. Vous pouvez bénéficier de droits additionnels en vertu
|
||||||
|
du droit local sur la protection des consommateurs, que ce contrat ne peut modifier. La ou elles
|
||||||
|
sont permises par le droit locale, les garanties implicites de qualité marchande, d’adéquation
|
||||||
|
à un usage particulier et d’absence de contrefaçon sont exclues.
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
<p class="c11">
|
||||||
|
<span class="c5 c1">LIMITATION DES DOMMAGES-INTÉRÊTS ET EXCLUSION DE RESPONSABILITÉ POUR LES DOMMAGES.</span>
|
||||||
|
<span class="c3 c1"> Vous pouvez obtenir de Microsoft et de ses fournisseurs une indemnisation en cas de dommages
|
||||||
|
directs uniquement à hauteur de 5,00 $ US. Vous ne pouvez prétendre à aucune
|
||||||
|
indemnisation pour les autres dommages, y compris les dommages spéciaux, indirects ou
|
||||||
|
accessoires et pertes de bénéfices.</span>
|
||||||
|
</p>
|
||||||
|
<p class="c12">
|
||||||
|
<span class="c3 c1">Cette limitation concerne :</span>
|
||||||
|
</p>
|
||||||
|
<p class="c2">
|
||||||
|
<span class="c3 c1">- tout ce qui est relié au logiciel, aux services ou au contenu
|
||||||
|
(y compris le code) figurant sur des sites Internet tiers ou dans des programmes tiers ; et</span>
|
||||||
|
</p>
|
||||||
|
<p class="c2">
|
||||||
|
<span class="c3 c1">- les réclamations au titre de violation de contrat ou de garantie,
|
||||||
|
ou au titre de responsabilité stricte, de négligence ou d’une autre faute
|
||||||
|
dans la limite autorisée par la loi en vigueur.</span>
|
||||||
|
</p>
|
||||||
|
<p class="c12">
|
||||||
|
<span class="c3 c1">Elle s’applique également, même si Microsoft connaissait ou devrait connaître
|
||||||
|
l’éventualité d’un tel dommage. Si votre pays n’autorise pas
|
||||||
|
l’exclusion ou la limitation de responsabilité pour les dommages indirects, accessoires
|
||||||
|
ou de quelque nature que ce soit, il se peut que la limitation ou l’exclusion ci-dessus
|
||||||
|
ne s’appliquera pas à votre égard.</span>
|
||||||
|
</p>
|
||||||
|
<p class="c16">
|
||||||
|
<span class="c5 c1">EFFET JURIDIQUE.</span>
|
||||||
|
<span class="c3 c1"> Le présent contrat décrit certains droits juridiques. Vous pourriez avoir d’autres
|
||||||
|
droits prévus par les lois de votre pays. Le présent contrat ne modifie pas les
|
||||||
|
droits que vous confèrent les lois de votre pays si celles-ci ne le permettent pas.</span>
|
||||||
|
</p>
|
||||||
|
<p class="c15">
|
||||||
|
<span class="c3 c1"></span>
|
||||||
|
</p>
|
||||||
|
<p class="c16">
|
||||||
|
<span class="c3 c1"> </span>
|
||||||
|
</p>
|
||||||
|
<p class="c11">
|
||||||
|
<span class="c3 c1">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.</span>
|
||||||
|
</p>
|
||||||
|
<p class="c11">
|
||||||
|
<span class="c3 c1"> </span>
|
||||||
|
</p>
|
||||||
|
<p class="c20">
|
||||||
|
<span class="c5 c1 c13">Remainder of this page intentionally left blank.</span>
|
||||||
|
</p>
|
||||||
|
<p class="c7">
|
||||||
|
<span class="c3 c19"></span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="ui center aligned segment">
|
||||||
|
<input id="agree-checkbox" type="checkbox" autocomplete="off" onchange="agreeCheckboxChanged(this)">
|
||||||
|
<label for="agree-checkbox">I agree to these Microsoft Software License Terms and to the
|
||||||
|
<a href="https://privacy.microsoft.com/en-us/privacystatement">Microsoft Privacy Statement.</a>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div id="download-segment" class="ui center aligned segment hidden">
|
||||||
|
<div class="ui grid">
|
||||||
|
<div class="eight wide column">
|
||||||
|
<h3 class="ui">Windows</h3>
|
||||||
|
<button class="ui icon button" onclick="downloadWin64()">
|
||||||
|
<i class="download icon"></i>
|
||||||
|
makecode-ev3-setup-win64.exe
|
||||||
|
</button>
|
||||||
|
</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>
|
||||||
|
|
||||||
|
<!-- @include footer.html -->
|
||||||
|
<!-- @include tracking.html -->
|
||||||
|
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
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 |
BIN
docs/static/fll/code-js.gif
vendored
Normal file
After Width: | Height: | Size: 349 KiB |
BIN
docs/static/fll/context-help.jpg
vendored
Normal file
After Width: | Height: | Size: 42 KiB |
BIN
docs/static/fll/fll-logo.png
vendored
Normal file
After Width: | Height: | Size: 17 KiB |
BIN
docs/static/fll/import-button.jpg
vendored
Normal file
After Width: | Height: | Size: 74 KiB |
BIN
docs/static/fll/save-project.jpg
vendored
Normal file
After Width: | Height: | Size: 22 KiB |
BIN
docs/static/fll/share-button.jpg
vendored
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
docs/static/fll/share-program.gif
vendored
Normal file
After Width: | Height: | Size: 134 KiB |
BIN
docs/static/fll/share-program.jpg
vendored
Normal file
After Width: | Height: | Size: 55 KiB |
BIN
docs/static/fll/simulator.gif
vendored
Normal file
After Width: | Height: | Size: 294 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 |
@ -86,18 +86,6 @@ Step by step guides to coding your @boardname@.
|
|||||||
}]
|
}]
|
||||||
```
|
```
|
||||||
|
|
||||||
## Ultrasonic Sensor
|
|
||||||
|
|
||||||
```codecard
|
|
||||||
[{
|
|
||||||
"name": "Object Near?",
|
|
||||||
"description": "Build a program that will detect when an object is nearby.",
|
|
||||||
"cardType": "tutorial",
|
|
||||||
"url":"/tutorials/object-near",
|
|
||||||
"imageUrl":"/static/tutorials/object-near.png"
|
|
||||||
}]
|
|
||||||
```
|
|
||||||
|
|
||||||
## Infrared Sensor
|
## Infrared Sensor
|
||||||
|
|
||||||
```codecard
|
```codecard
|
||||||
|
@ -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
|
||||||
|
@ -66,7 +66,7 @@ brick.buttonDown.onEvent(ButtonEvent.Pressed, function () {
|
|||||||
|
|
||||||
## Step 5
|
## Step 5
|
||||||
|
|
||||||
Now, let’s add a Medium motor, and tell it how many rotations we want it to run for. Open the ``||brick:Brick||`` Toolbox drawer. Drag out **2** ``|brick:on button||`` blocks. In the ``||brick:on button||`` blocks, use the drop-down menu to select the ``left`` and ``right`` buttons.
|
Open the ``||brick:Brick||`` Toolbox drawer and drag out **2** ``|brick:on button||`` blocks. In the ``||brick:on button||`` blocks, use the drop-down menu to select the ``left`` and ``right`` buttons.
|
||||||
|
|
||||||
```blocks
|
```blocks
|
||||||
brick.buttonUp.onEvent(ButtonEvent.Pressed, function () {
|
brick.buttonUp.onEvent(ButtonEvent.Pressed, function () {
|
||||||
@ -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 () {
|
||||||
|
@ -16,7 +16,7 @@ brick.showString("Hello world", 1)
|
|||||||
|
|
||||||
## Step 2
|
## Step 2
|
||||||
|
|
||||||
In the ``||brick:show string||`` block, type the text ``"Guess teh animal"`` to replace ``"Hello world"``.
|
In the ``||brick:show string||`` block, type the text ``"Guess the animal"`` to replace ``"Hello world"``.
|
||||||
|
|
||||||
```blocks
|
```blocks
|
||||||
brick.showString("Guess the animal", 1)
|
brick.showString("Guess the animal", 1)
|
||||||
|
33
docs/videos.md
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
# Videos
|
||||||
|
|
||||||
|
## Tutorials
|
||||||
|
|
||||||
|
```codecard
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"name": "",
|
||||||
|
"url": "https://legoeducation.videomarketingplatform.co/v.ihtml/player.html?token=5d009e5f93fbf479c2e5ed2bf87a7990&source=embed&photo%5fid=35719444",
|
||||||
|
"imageUrl": "https://legoeducation.videomarketingplatform.co/27288170/35719444/5d009e5f93fbf479c2e5ed2bf87a7990/thumbnail.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "",
|
||||||
|
"url": "https://legoeducation.videomarketingplatform.co/v.ihtml/player.html?token=2008a566f1fb034d58d5ebe19ba8621f&source=embed&photo%5fid=35719467",
|
||||||
|
"imageUrl": "https://legoeducation.videomarketingplatform.co/27288175/35719467/2008a566f1fb034d58d5ebe19ba8621f/thumbnail.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "",
|
||||||
|
"url": "https://legoeducation.videomarketingplatform.co/v.ihtml/player.html?token=629730c938e452f0fd7653fbc4708166&source=embed&photo%5fid=35719470",
|
||||||
|
"imageUrl": "https://legoeducation.videomarketingplatform.co/27288172/35719470/629730c938e452f0fd7653fbc4708166/thumbnail.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "",
|
||||||
|
"url": "https://legoeducation.videomarketingplatform.co/v.ihtml/player.html?token=3513a83b87fe536b2dc512237465fd1b&source=embed&photo%5fid=35719471",
|
||||||
|
"imageUrl": "https://legoeducation.videomarketingplatform.co/27288172/35719471/3513a83b87fe536b2dc512237465fd1b/thumbnail.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "",
|
||||||
|
"url": "https://legoeducation.videomarketingplatform.co/v.ihtml/player.html?token=5c594c2373367f7870196f519f3bfc7a&source=embed&photo%5fid=35719472",
|
||||||
|
"imageUrl": "https://legoeducation.videomarketingplatform.co/27288175/35719472/5c594c2373367f7870196f519f3bfc7a/thumbnail.png"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
```
|
@ -60,7 +60,7 @@ const rbfTemplate = `
|
|||||||
4c45474f580000006d000100000000001c000000000000000e000000821b038405018130813e8053
|
4c45474f580000006d000100000000001c000000000000000e000000821b038405018130813e8053
|
||||||
74617274696e672e2e2e0084006080XX00448581644886488405018130813e80427965210084000a
|
74617274696e672e2e2e0084006080XX00448581644886488405018130813e80427965210084000a
|
||||||
`
|
`
|
||||||
export function deployCoreAsync(resp: pxtc.CompileResult, isCli = false) {
|
export function deployCoreAsync(resp: pxtc.CompileResult) {
|
||||||
let w: pxt.editor.Ev3Wrapper
|
let w: pxt.editor.Ev3Wrapper
|
||||||
|
|
||||||
let filename = resp.downloadFileBaseName || "pxt"
|
let filename = resp.downloadFileBaseName || "pxt"
|
||||||
@ -98,11 +98,13 @@ export function deployCoreAsync(resp: pxtc.CompileResult, isCli = false) {
|
|||||||
resp.outfiles[pxtc.BINARY_UF2] = btoa(data)
|
resp.outfiles[pxtc.BINARY_UF2] = btoa(data)
|
||||||
|
|
||||||
let saveUF2Async = () => {
|
let saveUF2Async = () => {
|
||||||
if (isCli || !pxt.commands.saveOnlyAsync) {
|
if (pxt.commands && pxt.commands.electronDeployAsync) {
|
||||||
return Promise.resolve()
|
return pxt.commands.electronDeployAsync(resp);
|
||||||
} else {
|
|
||||||
return pxt.commands.saveOnlyAsync(resp)
|
|
||||||
}
|
}
|
||||||
|
if (pxt.commands && pxt.commands.saveOnlyAsync) {
|
||||||
|
return pxt.commands.saveOnlyAsync(resp);
|
||||||
|
}
|
||||||
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (noHID) return saveUF2Async()
|
if (noHID) return saveUF2Async()
|
||||||
@ -119,10 +121,7 @@ export function deployCoreAsync(resp: pxtc.CompileResult, isCli = false) {
|
|||||||
.then(() => w.flashAsync(rbfPath, rbfBIN))
|
.then(() => w.flashAsync(rbfPath, rbfBIN))
|
||||||
.then(() => w.runAsync(rbfPath))
|
.then(() => w.runAsync(rbfPath))
|
||||||
.then(() => {
|
.then(() => {
|
||||||
if (isCli)
|
|
||||||
return w.disconnectAsync()
|
return w.disconnectAsync()
|
||||||
else
|
|
||||||
return Promise.resolve()
|
|
||||||
//return Promise.delay(1000).then(() => w.dmesgAsync())
|
//return Promise.delay(1000).then(() => w.dmesgAsync())
|
||||||
}).catch(e => {
|
}).catch(e => {
|
||||||
// if we failed to initalize, retry
|
// if we failed to initalize, retry
|
||||||
|
@ -28,9 +28,9 @@ pxt.editor.initExtensionsAsync = function (opts: pxt.editor.ExtensionOptions): P
|
|||||||
<div class="ui grid stackable">
|
<div class="ui grid stackable">
|
||||||
<div class="column five wide" style="background-color: #E2E2E2;">
|
<div class="column five wide" style="background-color: #E2E2E2;">
|
||||||
<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.10 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,30 +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",
|
|
||||||
"eventcontext.ts",
|
|
||||||
"serial.cpp",
|
|
||||||
"serial.ts",
|
|
||||||
"fieldeditors.ts"
|
|
||||||
],
|
|
||||||
"testFiles": [
|
|
||||||
"test.ts"
|
|
||||||
],
|
|
||||||
"additionalFilePath": "../../node_modules/pxt-common-packages/libs/base",
|
|
||||||
"public": true,
|
|
||||||
"dependencies": {}
|
|
||||||
}
|
}
|
||||||
|
17
libs/base/shims.d.ts
vendored
@ -142,23 +142,12 @@ declare namespace control {
|
|||||||
//% blockId="control_device_serial_number" block="device serial number" weight=9
|
//% blockId="control_device_serial_number" block="device serial number" weight=9
|
||||||
//% help=control/device-serial-number shim=control::deviceSerialNumber
|
//% help=control/device-serial-number shim=control::deviceSerialNumber
|
||||||
function deviceSerialNumber(): int32;
|
function deviceSerialNumber(): int32;
|
||||||
}
|
|
||||||
declare namespace serial {
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write some text to the serial port.
|
*
|
||||||
*/
|
*/
|
||||||
//% help=serial/write-string
|
//% shim=control::__log
|
||||||
//% weight=87 blockHidden=true
|
function __log(text: string): void;
|
||||||
//% blockId=serial_writestring block="serial|write string %text" shim=serial::writeString
|
|
||||||
function writeString(text: string): void;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send a buffer across the serial connection.
|
|
||||||
*/
|
|
||||||
//% help=serial/write-buffer weight=6 blockHidden=true
|
|
||||||
//% blockId=serial_writebuffer block="serial|write buffer %buffer" shim=serial::writeBuffer
|
|
||||||
function writeBuffer(buffer: Buffer): void;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Auto-generated. Do not edit. Really.
|
// Auto-generated. Do not edit. Really.
|
||||||
|
@ -297,9 +297,22 @@ namespace sensors {
|
|||||||
calibrateLight(mode: LightIntensityMode, deviation: number = 8) {
|
calibrateLight(mode: LightIntensityMode, deviation: number = 8) {
|
||||||
this.calibrating = true; // prevent events
|
this.calibrating = true; // prevent events
|
||||||
|
|
||||||
this.light(mode); // trigger a read
|
const statusLight = brick.statusLight(); // save current status light
|
||||||
pauseUntil(() => this.isActive()); // ensure sensor is live
|
brick.setStatusLight(StatusLight.Orange);
|
||||||
|
|
||||||
|
this.light(mode); // trigger a read
|
||||||
|
pauseUntil(() => this.isActive(), 5000); // ensure sensor is live
|
||||||
|
|
||||||
|
// check sensor is ready
|
||||||
|
if (!this.isActive()) {
|
||||||
|
brick.setStatusLight(StatusLight.RedFlash); // didn't work
|
||||||
|
pause(2000);
|
||||||
|
brick.setStatusLight(statusLight); // restore previous light
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// calibrating
|
||||||
|
brick.setStatusLight(StatusLight.OrangePulse);
|
||||||
|
|
||||||
let vold = 0;
|
let vold = 0;
|
||||||
let vcount = 0;
|
let vcount = 0;
|
||||||
@ -331,6 +344,10 @@ namespace sensors {
|
|||||||
this.thresholdDetector.setLowThreshold(min);
|
this.thresholdDetector.setLowThreshold(min);
|
||||||
this.thresholdDetector.setHighThreshold(max);
|
this.thresholdDetector.setHighThreshold(max);
|
||||||
|
|
||||||
|
brick.setStatusLight(StatusLight.Green); // success
|
||||||
|
pause(1000);
|
||||||
|
brick.setStatusLight(statusLight); // resture previous light
|
||||||
|
|
||||||
this.calibrating = false;
|
this.calibrating = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,6 +13,15 @@ Sometimes when external lighting conditions change, the light sensor measures li
|
|||||||
* **mode**: the type of light threshold to calibrate. This is either ``ambient`` or ``reflected`` light.
|
* **mode**: the type of light threshold to calibrate. This is either ``ambient`` or ``reflected`` light.
|
||||||
* **deviation**: a [number](/types/number) that is the amount of light level change to adjust in a measurement.
|
* **deviation**: a [number](/types/number) that is the amount of light level change to adjust in a measurement.
|
||||||
|
|
||||||
|
## Calibration states
|
||||||
|
|
||||||
|
Calibration happens in the following phases and each phase is tracked by the brick status light.
|
||||||
|
|
||||||
|
* **orange**: sensor initialization. This phase ensures that the sensor is in the desired mode and ready to collect data.
|
||||||
|
* **orange pulse**: data collection. Light information is being collected, move the sensor over the various light sources to detect.
|
||||||
|
* **green**: calibration success. The calibration data has been saved.
|
||||||
|
* **red flash**: sensor failure. We were unable to connect to the sensor.
|
||||||
|
|
||||||
## Example
|
## Example
|
||||||
|
|
||||||
Calibrate the ``dark`` and ``light`` thresholds for the ``color 2`` sensor using reflected light.
|
Calibrate the ``dark`` and ``light`` thresholds for the ``color 2`` sensor using reflected light.
|
||||||
|
@ -247,6 +247,15 @@ namespace brick {
|
|||||||
// the brick starts with the red color
|
// the brick starts with the red color
|
||||||
let currPattern: StatusLight = StatusLight.Off;
|
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.
|
* Set lights.
|
||||||
* @param pattern the lights pattern to use. eg: StatusLight.Orange
|
* @param pattern the lights pattern to use. eg: StatusLight.Orange
|
||||||
|
@ -1,48 +0,0 @@
|
|||||||
/// <reference no-default-lib="true"/>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reading and writing data to the console output.
|
|
||||||
*/
|
|
||||||
//% weight=12 color=#00451A icon="\uf112"
|
|
||||||
//% advanced=true
|
|
||||||
namespace console {
|
|
||||||
type Listener = (text: string) => void;
|
|
||||||
|
|
||||||
const listeners: Listener[] = [
|
|
||||||
(text: string) => serial.writeLine(text)
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Write a line of text to the console output.
|
|
||||||
* @param value to send
|
|
||||||
*/
|
|
||||||
//% weight=90
|
|
||||||
//% help=console/log blockGap=8
|
|
||||||
//% blockId=console_log block="console|log %text"
|
|
||||||
export function log(text: string): void {
|
|
||||||
for (let i = 0; i < listeners.length; ++i)
|
|
||||||
listeners[i](text);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Write a name:value pair as a line of text to the console output.
|
|
||||||
* @param name name of the value stream, eg: "x"
|
|
||||||
* @param value to write
|
|
||||||
*/
|
|
||||||
//% weight=88 blockGap=8
|
|
||||||
//% help=console/log-value
|
|
||||||
//% blockId=console_log_value block="console|log value %name|= %value"
|
|
||||||
export function logValue(name: string, value: number): void {
|
|
||||||
log(`${name}: ${value}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds a listener for the log messages
|
|
||||||
* @param listener
|
|
||||||
*/
|
|
||||||
//%
|
|
||||||
export function addListener(listener: (text: string) => void) {
|
|
||||||
if (!listener) return;
|
|
||||||
listeners.push(listener);
|
|
||||||
}
|
|
||||||
}
|
|
@ -23,3 +23,8 @@ namespace motors {
|
|||||||
return turnratio;
|
return turnratio;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//% icon="\uf112"
|
||||||
|
namespace console {
|
||||||
|
|
||||||
|
}
|
@ -138,6 +138,8 @@ namespace motors {
|
|||||||
private _run: (speed: number) => void;
|
private _run: (speed: number) => void;
|
||||||
private _move: (steps: boolean, stepsOrTime: number, speed: number) => void;
|
private _move: (steps: boolean, stepsOrTime: number, speed: number) => void;
|
||||||
|
|
||||||
|
protected static output_types: number[] = [0x7, 0x7, 0x7, 0x7];
|
||||||
|
|
||||||
constructor(port: Output, init: () => void, run: (speed: number) => void, move: (steps: boolean, stepsOrTime: number, speed: number) => void) {
|
constructor(port: Output, init: () => void, run: (speed: number) => void, move: (steps: boolean, stepsOrTime: number, speed: number) => void) {
|
||||||
super();
|
super();
|
||||||
this._port = port;
|
this._port = port;
|
||||||
@ -321,22 +323,27 @@ namespace motors {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected setOutputType(large: boolean) {
|
protected setOutputType(large: boolean) {
|
||||||
/*
|
|
||||||
Instruction opOutput_Set_Type (LAYER, NO, TYPE)
|
|
||||||
Opcode 0xA1 Arguments (Data8) LAYER – Specify chain layer number [0 - 3]
|
|
||||||
(Data8) NO – Port number [0 - 3]
|
|
||||||
(Data8) TYPE – Output device type, (0x07: Large motor, Medium motor = 0x08) Dispatch status Unchanged
|
|
||||||
Description This function enables specifying the output device type
|
|
||||||
*/
|
|
||||||
for (let i = 0; i < DAL.NUM_OUTPUTS; ++i) {
|
for (let i = 0; i < DAL.NUM_OUTPUTS; ++i) {
|
||||||
if (this._port & (1 << i)) {
|
if (this._port & (1 << i)) {
|
||||||
const b = mkCmd(i, DAL.opOutputSetType, 1)
|
// (0x07: Large motor, Medium motor = 0x08)
|
||||||
b.setNumber(NumberFormat.Int8LE, 2, large ? 0x07 : 0x08)
|
MotorBase.output_types[i] = large ? 0x07 : 0x08;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MotorBase.setTypes();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note, we are having to create our own buffer here as mkCmd creates a buffer with a command
|
||||||
|
// In the case of opOutputSetType, it expects the arguments to be opOutputSetType [type0, type1, type2, type3]
|
||||||
|
static setTypes() {
|
||||||
|
const b = output.createBuffer(5)
|
||||||
|
b.setNumber(NumberFormat.UInt8LE, 0, DAL.opOutputSetType)
|
||||||
|
b.setNumber(NumberFormat.Int8LE, 1, MotorBase.output_types[0]);
|
||||||
|
b.setNumber(NumberFormat.Int8LE, 2, MotorBase.output_types[1]);
|
||||||
|
b.setNumber(NumberFormat.Int8LE, 3, MotorBase.output_types[2]);
|
||||||
|
b.setNumber(NumberFormat.Int8LE, 4, MotorBase.output_types[3]);
|
||||||
writePWM(b)
|
writePWM(b)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//% fixedInstances
|
//% fixedInstances
|
||||||
export class Motor extends MotorBase {
|
export class Motor extends MotorBase {
|
||||||
@ -368,7 +375,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 +384,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,36 +717,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')
|
||||||
writePWM(b)
|
control.dmesg('br ' + opts.useBrake);
|
||||||
}
|
const br = !!opts.useBrake ? 1 : 0;
|
||||||
|
control.dmesg('Step 4.5 ' + br)
|
||||||
const types = [0, 0, 0, 0]
|
b.setNumber(NumberFormat.Int8LE, 4 + 4 * 3, br)
|
||||||
export function setType(out: Output, type: OutputType) {
|
control.dmesg('STEP 5')
|
||||||
let b = mkCmd(out, DAL.opOutputSetType, 3)
|
|
||||||
for (let i = 0; i < 4; ++i) {
|
|
||||||
if (out & (1 << i)) {
|
|
||||||
types[i] = type
|
|
||||||
}
|
|
||||||
b.setNumber(NumberFormat.UInt8LE, i + 1, types[i])
|
|
||||||
}
|
|
||||||
writePWM(b)
|
writePWM(b)
|
||||||
|
control.dmesg('end step')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
1
libs/core/platform.h
Normal file
@ -0,0 +1 @@
|
|||||||
|
// leave empty
|
@ -10,7 +10,6 @@
|
|||||||
"linux.cpp",
|
"linux.cpp",
|
||||||
"mmap.cpp",
|
"mmap.cpp",
|
||||||
"control.cpp",
|
"control.cpp",
|
||||||
"console.ts",
|
|
||||||
"timer.ts",
|
"timer.ts",
|
||||||
"serialnumber.cpp",
|
"serialnumber.cpp",
|
||||||
"buttons.ts",
|
"buttons.ts",
|
||||||
@ -25,7 +24,8 @@
|
|||||||
"enums.d.ts",
|
"enums.d.ts",
|
||||||
"dal.d.ts",
|
"dal.d.ts",
|
||||||
"icons.jres",
|
"icons.jres",
|
||||||
"ns.ts"
|
"ns.ts",
|
||||||
|
"platform.h"
|
||||||
],
|
],
|
||||||
"testFiles": [
|
"testFiles": [
|
||||||
"test.ts"
|
"test.ts"
|
||||||
|
@ -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
|
||||||
|
@ -1,4 +1,8 @@
|
|||||||
// This is the last thing executed before user code
|
// This is the last thing executed before user code
|
||||||
|
|
||||||
|
// pulse green, play startup sound, turn off light
|
||||||
|
brick.setStatusLight(StatusLight.GreenPulse);
|
||||||
// We pause for 100ms to give time to read sensor values, so they work in on_start block
|
// We pause for 100ms to give time to read sensor values, so they work in on_start block
|
||||||
pause(100)
|
pause(400)
|
||||||
|
// and we're ready
|
||||||
|
brick.setStatusLight(StatusLight.Off);
|
||||||
|
@ -22,6 +22,15 @@ To properly reset the gyro, the brick must remain still (undistrurbed) while the
|
|||||||
|
|
||||||
## ~
|
## ~
|
||||||
|
|
||||||
|
## Calibration states
|
||||||
|
|
||||||
|
Calibration happens in the following phases and each phase is tracked by the brick status light.
|
||||||
|
|
||||||
|
* **orange**: sensor initialization. This phase ensures that the sensor is in the desired mode and ready to collect data.
|
||||||
|
* **orange pulse**: data collection. Light information is being collected, move the sensor over the various light sources to detect.
|
||||||
|
* **green**: calibration success. The calibration data has been saved.
|
||||||
|
* **red flash**: sensor failure. We were unable to connect to the sensor.
|
||||||
|
|
||||||
## Example
|
## Example
|
||||||
Set the brick on a flat surface. Reset `gyro 2` and tilt the brick slighly. Reset it again while it's still tilted. Lay the brick down flat again and display the angle measurement.
|
Set the brick on a flat surface. Reset `gyro 2` and tilt the brick slighly. Reset it again while it's still tilted. Lay the brick down flat again and display the angle measurement.
|
||||||
|
|
||||||
|
@ -92,6 +92,9 @@ namespace sensors {
|
|||||||
reset(): void {
|
reset(): void {
|
||||||
if (this.calibrating) return; // already in calibration mode
|
if (this.calibrating) return; // already in calibration mode
|
||||||
|
|
||||||
|
const statusLight = brick.statusLight(); // save current status light
|
||||||
|
brick.setStatusLight(StatusLight.Orange);
|
||||||
|
|
||||||
this.calibrating = true;
|
this.calibrating = true;
|
||||||
// may be triggered by a button click,
|
// may be triggered by a button click,
|
||||||
// give time for robot to settle
|
// give time for robot to settle
|
||||||
@ -101,9 +104,22 @@ namespace sensors {
|
|||||||
// switch back to the desired mode
|
// switch back to the desired mode
|
||||||
this.setMode(this.mode);
|
this.setMode(this.mode);
|
||||||
// wait till sensor is live
|
// wait till sensor is live
|
||||||
pauseUntil(() => this.isActive());
|
pauseUntil(() => this.isActive(), 5000);
|
||||||
|
|
||||||
|
// check sensor is ready
|
||||||
|
if (!this.isActive()) {
|
||||||
|
brick.setStatusLight(StatusLight.RedFlash); // didn't work
|
||||||
|
pause(2000);
|
||||||
|
brick.setStatusLight(statusLight); // restore previous light
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// give it a bit of time to init
|
// give it a bit of time to init
|
||||||
pause(1000)
|
pause(1000)
|
||||||
|
|
||||||
|
// calibrating
|
||||||
|
brick.setStatusLight(StatusLight.OrangePulse);
|
||||||
|
|
||||||
// compute drift
|
// compute drift
|
||||||
this._drift = 0;
|
this._drift = 0;
|
||||||
if (this.mode == GyroSensorMode.Rate) {
|
if (this.mode == GyroSensorMode.Rate) {
|
||||||
@ -113,6 +129,11 @@ namespace sensors {
|
|||||||
}
|
}
|
||||||
this._drift /= 200;
|
this._drift /= 200;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
brick.setStatusLight(StatusLight.Green); // success
|
||||||
|
pause(1000);
|
||||||
|
brick.setStatusLight(statusLight); // resture previous light
|
||||||
|
|
||||||
// and we're done
|
// and we're done
|
||||||
this.calibrating = false;
|
this.calibrating = false;
|
||||||
}
|
}
|
||||||
|
@ -1,19 +1,19 @@
|
|||||||
namespace music {
|
namespace music {
|
||||||
/**
|
/**
|
||||||
* Get the frequency of a note.
|
* Get the frequency of a note.
|
||||||
* @param name the note name, eg: Note.C
|
* @param note the note name, eg: Note.C
|
||||||
*/
|
*/
|
||||||
//% weight=1 help=music/note-frequency
|
//% weight=1 help=music/note-frequency
|
||||||
//% blockId=device_note block="%note"
|
//% blockId=device_note block="%note"
|
||||||
//% shim=TD_ID
|
//% shim=TD_ID
|
||||||
//% color="#FFFFFF" colorSecondary="#FFFFFF" colorTertiary="#D67923"
|
//% color="#FFFFFF" colorSecondary="#FFFFFF" colorTertiary="#D67923"
|
||||||
//% note.fieldEditor="note" note.defl="1046"
|
//% note.fieldEditor="note" note.defl="1046"
|
||||||
//% note.fieldOptions.editorColour="#FF1493" note.fieldOptions.decompileLiterals=true
|
//% note.fieldOptions.editorColour="#D67923" note.fieldOptions.decompileLiterals=true
|
||||||
//% note.fieldOptions.minNote=52 note.fieldOptions.maxNote=75
|
//% note.fieldOptions.minNote=40 note.fieldOptions.maxNote=75
|
||||||
//% useEnumVal=1
|
//% useEnumVal=1
|
||||||
//% weight=10 blockGap=8
|
//% weight=10 blockGap=8
|
||||||
export function noteFrequency(name: Note): number {
|
export function noteFrequency(note: Note): number {
|
||||||
//TODO fill in actual min/max note values
|
//TODO fill in actual min/max note values
|
||||||
return name;
|
return note;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
1
libs/screen/image.d.ts
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
// leave empty
|
@ -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.3.1",
|
"version": "1.0.10",
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "pxt-ev3",
|
"name": "pxt-ev3",
|
||||||
"version": "0.3.1",
|
"version": "1.0.10",
|
||||||
"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.15",
|
"pxt-common-packages": "0.23.56",
|
||||||
"pxt-core": "3.18.17"
|
"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"
|
||||||
|
@ -23,7 +23,6 @@
|
|||||||
"streams": true,
|
"streams": true,
|
||||||
"aspectRatio": 0.5,
|
"aspectRatio": 0.5,
|
||||||
"parts": false,
|
"parts": false,
|
||||||
"enableTrace": true,
|
|
||||||
"boardDefinition": {
|
"boardDefinition": {
|
||||||
"visual": "ev3"
|
"visual": "ev3"
|
||||||
}
|
}
|
||||||
@ -42,7 +41,7 @@
|
|||||||
"useUF2": true,
|
"useUF2": true,
|
||||||
"useELF": true,
|
"useELF": true,
|
||||||
"hasHex": true,
|
"hasHex": true,
|
||||||
"deployDrives": ".*",
|
"deployDrives": "EV3",
|
||||||
"deployFileMarker": "INFO_UF2.TXT",
|
"deployFileMarker": "INFO_UF2.TXT",
|
||||||
"driveName": "EV3",
|
"driveName": "EV3",
|
||||||
"flashCodeAlign": 256,
|
"flashCodeAlign": 256,
|
||||||
@ -79,32 +78,36 @@
|
|||||||
},
|
},
|
||||||
"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",
|
||||||
"organizationUrl": "https://makecode.com/",
|
"organizationUrl": "https://makecode.com/org",
|
||||||
"organizationLogo": "./static/Microsoft-logo_rgb_c-gray-square.png",
|
"organizationLogo": "./static/Microsoft-logo_rgb_c-gray-square.png",
|
||||||
"organizationWideLogo": "./static/Microsoft-logo_rgb_c-gray.png",
|
"organizationWideLogo": "./static/Microsoft-logo_rgb_c-gray.png",
|
||||||
"homeUrl": "https://makecode.legoeducation.com/",
|
"homeUrl": "https://makecode.mindstorms.com/",
|
||||||
"embedUrl": "https://makecode.legoeducation.com/",
|
"embedUrl": "https://makecode.mindstorms.com/",
|
||||||
"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.legoeducation.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,
|
||||||
|
"lightToc": true,
|
||||||
"docMenu": [
|
"docMenu": [
|
||||||
{
|
{
|
||||||
"name": "Support",
|
"name": "Support",
|
||||||
@ -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,8 @@
|
|||||||
"monacoColors": {
|
"monacoColors": {
|
||||||
"editor.background": "#f9f9f9"
|
"editor.background": "#f9f9f9"
|
||||||
},
|
},
|
||||||
"fileNameExclusiveFilter": "[^a-zA-Z]"
|
"fileNameExclusiveFilter": "[^a-zA-Z0-9]",
|
||||||
|
"enableTrace": true
|
||||||
},
|
},
|
||||||
"ignoreDocsErrors": true
|
"ignoreDocsErrors": true
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@ namespace pxsim {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getSpeed() {
|
getSpeed() {
|
||||||
return this.speed * (this.polarity == 0 ? -1 : 1);
|
return this.speed * (!this._synchedMotor && this.polarity == 0 ? -1 : 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
getAngle() {
|
getAngle() {
|
||||||
@ -49,7 +49,7 @@ namespace pxsim {
|
|||||||
// new command TODO: values
|
// new command TODO: values
|
||||||
this.speedCmd = cmd;
|
this.speedCmd = cmd;
|
||||||
this.speedCmdValues = values;
|
this.speedCmdValues = values;
|
||||||
this.speedCmdTacho = this.angle;
|
this.speedCmdTacho = this.tacho;
|
||||||
this.speedCmdTime = pxsim.U.now();
|
this.speedCmdTime = pxsim.U.now();
|
||||||
delete this._synchedMotor;
|
delete this._synchedMotor;
|
||||||
}
|
}
|
||||||
@ -150,7 +150,8 @@ namespace pxsim {
|
|||||||
const step2 = this.speedCmdValues[2];
|
const step2 = this.speedCmdValues[2];
|
||||||
const step3 = this.speedCmdValues[3];
|
const step3 = this.speedCmdValues[3];
|
||||||
const brake = this.speedCmdValues[4];
|
const brake = this.speedCmdValues[4];
|
||||||
const dstep = (this.speedCmd == DAL.opOutputTimePower || this.speedCmd == DAL.opOutputTimeSpeed)
|
const isTimeCommand = this.speedCmd == DAL.opOutputTimePower || this.speedCmd == DAL.opOutputTimeSpeed;
|
||||||
|
const dstep = isTimeCommand
|
||||||
? pxsim.U.now() - this.speedCmdTime
|
? pxsim.U.now() - this.speedCmdTime
|
||||||
: this.tacho - this.speedCmdTacho;
|
: this.tacho - this.speedCmdTacho;
|
||||||
if (dstep < step1) // rampup
|
if (dstep < step1) // rampup
|
||||||
@ -161,6 +162,16 @@ namespace pxsim {
|
|||||||
this.speed = speed * (step1 + step2 + step3 - dstep) / (step1 + step2 + step3);
|
this.speed = speed * (step1 + step2 + step3 - dstep) / (step1 + step2 + step3);
|
||||||
else {
|
else {
|
||||||
if (brake) this.speed = 0;
|
if (brake) this.speed = 0;
|
||||||
|
if (!isTimeCommand) {
|
||||||
|
// we need to patch the actual position of the motor when
|
||||||
|
// finishing the move as our integration step introduce errors
|
||||||
|
const deltaAngle = -Math.sign(speed) * (dstep - (step1 + step2 + step3));
|
||||||
|
if (deltaAngle) {
|
||||||
|
this.angle += deltaAngle;
|
||||||
|
this.tacho -= Math.abs(deltaAngle);
|
||||||
|
this.setChangedState();
|
||||||
|
}
|
||||||
|
}
|
||||||
this.clearSpeedCmd();
|
this.clearSpeedCmd();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -12,9 +12,10 @@
|
|||||||
"Tutorials": "tutorials",
|
"Tutorials": "tutorials",
|
||||||
"Design Engineering": "design-engineering",
|
"Design Engineering": "design-engineering",
|
||||||
"Coding": "coding",
|
"Coding": "coding",
|
||||||
"Maker": "maker"
|
"Maker": "maker",
|
||||||
|
"Videos": "videos"
|
||||||
},
|
},
|
||||||
"electronManifest": {
|
"electronManifest": {
|
||||||
"latest": "v0.1.60"
|
"latest": "v1.0.8"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,11 +33,12 @@
|
|||||||
|
|
||||||
/* Music field editor */
|
/* Music field editor */
|
||||||
|
|
||||||
.blocklyDropdownText {
|
.blocklyMusicFieldOptions .blocklyDropdownText, .blocklyMusicFieldCategories .blocklyDropdownText {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
line-height: 1.5rem;
|
line-height: 1.5rem;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
|
font-size: 13px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.blocklyMusicFieldCategories {
|
.blocklyMusicFieldCategories {
|
||||||
@ -47,6 +48,7 @@
|
|||||||
right: 0;
|
right: 0;
|
||||||
top: 0;
|
top: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
font-size: 13px;
|
||||||
}
|
}
|
||||||
.blocklyMusicFieldOptions {
|
.blocklyMusicFieldOptions {
|
||||||
margin-top: 80px;
|
margin-top: 80px;
|
||||||
|
@ -7,9 +7,6 @@
|
|||||||
@headerFont : "Open Sans","Arial Narrow","Helvetica Neue",Helvetica,Arial,sans-serif;
|
@headerFont : "Open Sans","Arial Narrow","Helvetica Neue",Helvetica,Arial,sans-serif;
|
||||||
@pageFont : "Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;
|
@pageFont : "Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;
|
||||||
|
|
||||||
@emSize : 14px;
|
|
||||||
@fontSize : 13px;
|
|
||||||
|
|
||||||
@primaryColor: @blue;
|
@primaryColor: @blue;
|
||||||
@secondaryColor: @yellow;
|
@secondaryColor: @yellow;
|
||||||
|
|
||||||
@ -31,6 +28,7 @@
|
|||||||
@legoGreyDark: #f4f7f9;
|
@legoGreyDark: #f4f7f9;
|
||||||
|
|
||||||
@grey: @legoGreyLight;
|
@grey: @legoGreyLight;
|
||||||
|
@darkGrey: #999;
|
||||||
|
|
||||||
/* Lego official colors */
|
/* Lego official colors */
|
||||||
|
|
||||||
@ -152,6 +150,8 @@
|
|||||||
@homeScreenBackground: #F2F2F2;
|
@homeScreenBackground: #F2F2F2;
|
||||||
@homeCardBorderColor: #F2F2F2;
|
@homeCardBorderColor: #F2F2F2;
|
||||||
|
|
||||||
|
@homeDetailCloseBackground: @darkGrey;
|
||||||
|
|
||||||
/*-------------------
|
/*-------------------
|
||||||
Editor
|
Editor
|
||||||
--------------------*/
|
--------------------*/
|
||||||
@ -198,3 +198,9 @@
|
|||||||
@serialBackgroundColor: #fff;
|
@serialBackgroundColor: #fff;
|
||||||
@serialGraphBackground: #F2F2F2;
|
@serialGraphBackground: #F2F2F2;
|
||||||
@serialConsoleBackground: @serialGraphBackground;
|
@serialConsoleBackground: @serialGraphBackground;
|
||||||
|
|
||||||
|
/*-------------------
|
||||||
|
Extensions
|
||||||
|
--------------------*/
|
||||||
|
|
||||||
|
@extensionsHeaderBackground: @darkGrey;
|