Compare commits

...

164 Commits

Author SHA1 Message Date
e0aad7227f Add file listing and delete apis 2019-09-03 16:00:46 -07:00
aca1b4a764 Improve naming of command line programs 2019-09-03 16:00:33 -07:00
349caa4aed 1.1.17 2019-09-02 20:58:29 -07:00
56bbcde299 Support for smooth acceleration/deceleration in run (#900)
* removed logging

* removing more logging

* always use step for single/multiple motors

* refactored schedule

* account for accel ramp up and down

* added default acc/decel

* rounding speed/angle

* remove hack

* use acceleration time in run too

* handle missing case

* adding notes on motors

* adding sample

* fixed ramp simulation

* clear defaults

* some docs, more later

* adding basic examples

* remove debug msg

* clean json

* added move schedule

* docs

* basic docs
2019-09-02 20:57:23 -07:00
7e9cc791ec Some edits for the new sensor/motor examples (#901)
* Some edits for the new sensor/motor examples

* article typo

* dark and bright

* fix block styling

* I like 'on'

* more block styling
2019-09-02 04:20:42 -07:00
d5194b8d28 More samples (#896)
* coast or brake

* fix title

* added lesson
2019-08-31 06:05:36 -07:00
12b1eb349b 1.1.16 2019-08-30 16:53:03 -07:00
68dc195ea4 motor tutorials (#895)
* updated pivots

* redirect support to forum

* adding top level FLL link

* updated wording
2019-08-30 16:52:37 -07:00
0251b914f2 color sensor examples (#894)
* tank zigzag

* reflected light measure

* adding links

* added reflected light calibration

* updated summary
2019-08-30 15:03:09 -07:00
1fc818767c added vscode workspace 2019-08-30 13:57:27 -07:00
9aeaec477f updated FLL page 2019-08-30 12:03:43 -07:00
7fc796d2cb 1.1.15 2019-08-30 11:55:49 -07:00
cb1cd2a4b4 Tutorial category breakout (#437)
* Tutorial category breakout

* Put galleries in config

* restore default tutorial

* updated links

* update tutorials pages

* add infrared
2019-08-30 11:54:30 -07:00
39bd7aa0eb 1.1.14 2019-08-30 10:59:15 -07:00
140ba64462 Gyrofix (#893)
* disable drift correction by default

* disable drift correction

* better calibration sequence

* add comments

* updated comment about beta
2019-08-30 10:58:49 -07:00
42fe96aa5a fix link 2019-08-30 09:40:41 -07:00
1a5b42026d adding redirects for missing links 2019-08-30 09:39:28 -07:00
9fe649aa3c fixed extensions.md 2019-08-30 05:48:41 -07:00
a97dfb17b2 1.1.13 2019-08-30 05:41:11 -07:00
277c9903bb Tank fixes (#892)
* fixing turnration computation

* updated tank computation

* fix rendering glitch

* restore tank computation

* rounding errors
2019-08-30 05:40:51 -07:00
0de8a84de2 1.1.12 2019-08-29 13:11:34 -07:00
a302bbfc2b Single tank (#891)
* add note about dual blocks

* fix simulator to match hardware

* updated wording
2019-08-29 13:11:01 -07:00
bcb682b602 1.1.11 2019-08-28 23:00:03 -07:00
e4a7531541 add rgbraw (#890) 2019-08-28 22:59:41 -07:00
348964c888 1.1.10 2019-08-28 22:43:42 -07:00
8b3461bebd Add exitThread() polling the exit button (#888)
* Add exitThread() polling the exit button

* Add missing includes

* Remove redundant code
2019-08-28 22:43:21 -07:00
e511630c2e Update README.md 2019-08-28 16:27:03 -07:00
db156d5df0 Update README.md 2019-08-28 16:24:55 -07:00
93c6975400 1.1.9 2019-08-28 16:21:41 -07:00
abc93dd7da Multi sensor fix (#887)
* more logging

* set uart mode all at once

* updated logging

* pr feedback
2019-08-28 16:21:06 -07:00
85cfc86bf8 1.1.8 2019-08-28 13:36:50 -07:00
b66d4f2d64 enable storage extension (#886)
* enable storage extension

* fix -beta
2019-08-28 13:36:23 -07:00
5843deab11 1.1.7 2019-08-28 11:39:18 -07:00
8d5edc38bb bump common version (#885) 2019-08-28 11:30:59 -07:00
0309e50058 1.1.6 2019-08-28 08:52:24 -07:00
aa40e7b169 Endprogram (#884)
* moving end program logic to c++

* typo

* always stop on reset
2019-08-28 08:52:01 -07:00
75cf8da396 1.1.5 2019-08-27 17:57:44 -07:00
Max
db9b6a995b IIC added (#870)
* IIC added

* Fixed bug with not detecting device
2019-08-27 17:57:21 -07:00
fb255edafe 1.1.4 2019-08-27 17:28:57 -07:00
f4c39f74e8 1.1.3 2019-08-27 17:05:49 -07:00
3e56e2c3e2 Rgb raw tuning of blocs (#883)
* refactor blocks

* make non-private
2019-08-27 17:05:16 -07:00
79b5f8cc88 Add rgb and reflection raw mods for color sensor (#876)
* Add reflection raw value

Add reflection raw value for color sensor

* update

* Combined rgbraw and refraw
2019-08-27 16:45:12 -07:00
312729142f 1.1.2 2019-08-27 16:42:36 -07:00
Max
5bd4aed0e1 Multiple sensors 2 (#877)
* Fixed -1 mode in libs

* Deleted todo
2019-08-27 16:34:55 -07:00
cfaa4ae3ef migrate build to travis 2019-08-27 16:29:18 -07:00
faa839d59f 1.1.1 2019-08-27 16:26:37 -07:00
630687bfce bump to 1.1 2019-08-27 16:26:19 -07:00
2b300a4094 Maximmasterr set settle (#882)
* Added set settle time

* updated blocks
2019-08-27 14:57:28 -07:00
5fb8c0de6e delete package-lock.json 2019-08-27 14:45:25 -07:00
1f65cd59a8 Fixes to "Line Following in Loop" Sample Solutions (#871)
Sample Solutions were wrong for both Methods of Line Following in a Loop
2019-08-27 14:27:20 -07:00
fd75bb61d6 Fix typos in sample programme description (#872)
1500 milliseconds is not one quarter of a second - fixed the text to reflect.
2019-08-06 14:50:19 -07:00
Max
4d2f72575b Fixed multiple sensor bug (#868) 2019-07-15 15:26:25 -07:00
1fe3d3e01a plug in offline page (#836) 2019-03-07 19:40:21 -08:00
0c6e65d828 Updateing Trademark in readme (#834)
* Updateing Trademark in readme

* Removed chat reference
2019-03-04 16:39:23 -08:00
ae9c0603f2 Releasing electron 1.0.11 (#832) 2018-12-06 10:16:17 -08:00
06aeca228a Updating offline-app.html to right version (#833) 2018-12-06 10:15:40 -08:00
31fd4799a5 Hot fix release (v1.0.11) (#831)
* Hot fix release (v1.0.10)
2018-12-04 13:24:06 -08:00
7d8e6891ee 1.0.11 2018-12-04 13:03:59 -08:00
462234b1c0 Re-enable trace from simulator configuration (#830) 2018-12-04 13:03:34 -08:00
dad1bd0cd4 1.0.10 2018-12-03 16:38:08 -08:00
b71bfef418 Call setOutputType with the right arguments (#828)
* Call setOutputType with the right arguments
2018-12-03 16:37:53 -08:00
2e0a34c99b Calibration states (#820)
* color calibration
2018-12-03 16:37:40 -08:00
4133828a10 Update the join up link to the FLL Slack channel (#824) 2018-11-19 19:49:46 -08:00
f0c19bc976 Add LEGO video links to FLL page (#822) 2018-11-12 12:20:37 -08:00
a09b4a083f FLL page changes/add-ons (#821) 2018-11-12 12:02:19 -08:00
15dff9af08 Update fll.md 2018-11-12 07:49:04 -08:00
6fa5c1b688 Update fll.md 2018-11-12 07:47:31 -08:00
d76cea1477 1.0.9 2018-11-06 09:08:51 -08:00
ca09a0a833 Add file delete workaround to 'FLL' page (#816) 2018-11-06 09:08:14 -08:00
fcc864823e Use single sentence 'getting-started' card (#817) 2018-11-05 18:04:42 -08:00
166dc27b93 Add FLL page to SUMMARY (#815) 2018-11-01 17:38:21 -07:00
66e50473c4 FLL info page (#814) 2018-11-01 07:46:43 -07:00
58452e1ca3 Fix for missing CAPS in certain parts of EULA 2018-10-26 09:13:03 -07:00
2b7498ea2d Updating new EULA from legal (#813) 2018-10-26 09:09:11 -07:00
5ab2b97663 Remove titles from videos in homescreen (#812) 2018-10-23 08:44:02 -07:00
ffe0f0fb32 Enable tracing from simulator to appTheme (#810) 2018-10-17 11:33:18 -07:00
f27d13f88e Updating offline docs to new release 1.0.8 (#808) 2018-09-26 16:26:35 -07:00
31067dcef8 enable light toc 2018-09-26 16:13:15 -07:00
123f6c84b2 Release electron for auto update (#807)
This will enable auto update of the packages
2018-09-26 16:11:42 -07:00
c5f07ca67c removing light toc 2018-09-26 15:43:20 -07:00
22fc7dee18 added lighttoc 2018-09-26 15:42:28 -07:00
1f58b649c5 Release of 1.0.8 to live (#806)
Beta->release
2018-09-26 15:41:03 -07:00
fc75fe8e16 fixed video title 2018-09-26 11:31:24 -07:00
b399c37527 adding videos page to home 2018-09-26 11:28:32 -07:00
a054fdd3d3 1.0.8 2018-09-25 16:58:51 -07:00
a239589913 Move back to 4.0.9 2018-09-25 16:58:40 -07:00
98a046237c bump pxt-core to 4.1.1, 2018-09-25 16:56:45 -07:00
eb385ec532 1.0.7 2018-09-25 10:28:59 -07:00
2fdce16685 Update field motors editor to support localized languages (#803)
* Use the value for options, and hardcode localized versions of first dropdown
2018-09-25 10:28:34 -07:00
74eb77a9ae 1.0.6 2018-09-25 08:42:24 -07:00
4fba96588f Bumping pxt-core to 4.0.8 2018-09-25 07:56:19 -07:00
03c07bdcf5 1.0.5 2018-09-21 20:00:18 -07:00
6da1bc3cb1 bump pxt 2018-09-21 18:49:39 -07:00
dfc9ca1db4 fxing leading / in docs 2018-09-21 14:07:11 -07:00
83b64c1e54 1.0.4 2018-09-21 11:25:26 -07:00
a0cf8655f2 updated pxt 2018-09-21 11:25:13 -07:00
e4cf2c99c0 removoing lightToc 2018-09-21 11:07:04 -07:00
076fb8487e 1.0.3 2018-09-21 09:41:31 -07:00
c725561389 bump pxt 2018-09-21 09:41:19 -07:00
3dc781f4fd remove docs in image paths 2018-09-21 09:38:48 -07:00
4456767f2d Change tables to bullet lists for docs (#789) 2018-09-20 17:07:38 -07:00
6dba240899 1.0.2 2018-09-20 14:24:19 -07:00
d7172a1f3a Light theme docs (#786)
* lighttheme toc

* use LEGO edu logo everywhere

* bump pxt
2018-09-20 14:23:08 -07:00
245ff9d5b2 Adding link instructions (#787) 2018-09-20 14:05:59 -07:00
bfb258ce61 Add 'Explorer' section to editor features page (#785) 2018-09-20 07:35:24 -07:00
63beb2cac7 missing github logo 2018-09-19 21:26:35 -07:00
73d3dce139 missing comma 2018-09-19 16:16:37 -07:00
21be8a5021 1.0.1 2018-09-19 16:09:35 -07:00
03a82d6bcd upgrade to pxt v4 (#783)
* upgrade to v4

* Update pxt-common-packages

* bump to 1.0
2018-09-19 16:09:05 -07:00
60ea0f0cd5 allow for numbers in filename filter 2018-09-19 11:27:30 -07:00
f69a0d5289 enable save in menu 2018-09-19 09:50:21 -07:00
e2e8536b37 enable print (#779) 2018-09-19 09:48:48 -07:00
4096875a88 Removing beta tag (#781) 2018-09-19 09:39:12 -07:00
9825a90df2 Buildfix for lego and bumping common-packages to 0.23.54 (#780)
* fixing build failure

* Bumping common-packages to 0.23.54
2018-09-18 16:31:40 -07:00
7ad5d123a3 Replace brick info images (#777) 2018-09-18 15:46:13 -07:00
3599483ed2 Shorten showString and set default tone (#735) 2018-09-11 13:52:09 -07:00
7a6818931f Derive 'base' package file list from pxt-common-packages (#770) 2018-09-04 08:23:11 -07:00
eda38ebbc4 Fix the double entry for 'About' in SUMMARY (#764) 2018-08-10 14:30:44 -07:00
026f7a3180 0.4.3 2018-07-18 11:35:43 -07:00
f58fcb60e2 Enable additional langs for new translations (#760) 2018-07-18 11:35:10 -07:00
dbda86abb5 Release 0.4.2 (#748)
This is release of latest editor
2018-07-13 16:10:05 -07:00
3c13565e7c Beautify the download (#747) 2018-07-13 14:56:08 -07:00
f8524cf1a7 Release app 0.4.2 (#742)
* Add MacOS download link and update Windows download link

* Update electron manifest to latest app
2018-07-13 16:10:01 -04:00
bf4b1090fc 0.4.2 2018-07-13 10:59:44 -07:00
ea4d8cf66a Bumping pxt-core to 3.21.7 and pxt-common-packages to 0.23.45 2018-07-13 10:57:35 -07:00
b32ae4e61a Give a link to the instructions 2018-07-11 11:29:28 -07:00
1df90a6ea3 0.4.1 2018-06-28 15:49:43 -04:00
09ac2a7a47 Run motors tutorial - step 5 fix 2018-06-25 13:15:34 -07:00
06565995d3 fix offline app url 2018-06-22 14:54:08 -07:00
1a73aec74d Release app 0.3.6 (#732) 2018-06-22 14:52:33 -07:00
5516d041d6 Enable offline download page (#733)
* Enable offline download page

* avoid clashing with docs
2018-06-22 14:52:17 -07:00
7aac8ab5f3 Fix typo in what animal am I tutorial (#731) 2018-06-22 07:06:31 -07:00
73da17a395 Set organizationUrl to https://makecode.com/org so that it redirects to the about page, rather than makecode.com 2018-06-21 16:19:31 -07:00
16197f2987 Move to v0.4 2018-06-21 14:53:23 -07:00
5ec7eb6f04 Release v0.3.6 (#730) 2018-06-21 14:50:51 -07:00
f05ad887b8 0.3.6 2018-06-21 14:22:24 -07:00
c8a7b73101 Fix music field editor font size (#728) 2018-06-21 14:21:40 -07:00
0b9d029ecc 0.3.5 2018-06-21 13:24:13 -07:00
d6f0fee300 bump pxt-core to 3.20.11, bump pxt-common-packages to 0.23.39, 2018-06-21 13:24:08 -07:00
d78b4c5ee3 Merge branch 'master' of https://github.com/microsoft/pxt-ev3 2018-06-21 13:12:51 -07:00
13f5ebd6a7 legoeducation.com -> mindstorms.com 2018-06-21 13:12:44 -07:00
ccbebabc55 Update offline page (#719)
* Update offline page

* Remove const
2018-06-21 13:51:09 -04:00
5c61677ab9 0.3.4 2018-06-20 22:08:04 -07:00
21025b5f83 better handling end of integration step 2018-06-20 22:03:48 -07:00
f9a0729b63 0.3.3 2018-06-20 16:49:36 -07:00
8e456f5c3c bump pxt-core to 3.20.8, bump pxt-common-packages to 0.23.38, 2018-06-20 16:49:30 -07:00
e05e147d6a fix for motor driver (#716) 2018-06-20 16:45:02 -07:00
fc83cc5d5b Fix note field editor authoring such that it limits the notes that show up (#715) 2018-06-20 16:29:03 -07:00
7974f36c31 Fix tank and steer blocks in the simulator, making them ignore polarity just like labview (#713) 2018-06-20 16:10:59 -07:00
6513dbc901 Remove object near tutorial, until we fix the issue with variables and decompile blocks (#710) 2018-06-20 16:00:17 -07:00
97215e894a do a single green pulse when starting 2018-06-20 15:21:09 -07:00
1368ee824b restoring consol eicon 2018-06-20 15:18:31 -07:00
f2344ac52e upgrading comm on packages (#708) 2018-06-20 13:59:20 -07:00
299acea61f Offline app download page (#707) 2018-06-20 16:37:15 -04:00
a99f0212ac Fix browser download (#706) 2018-06-20 13:32:58 -07:00
d128dad3dc Startup sequence (#696)
* set light, play sound, show eyes, wait, clear screen, light

* play a sound, turn on lights
2018-06-20 13:32:00 -07:00
3d7ebeb7b7 fixed 1.10 -> 1.10E 2018-06-18 08:16:16 -07:00
304cbb5ee3 Match Color Sensor ports in the 'Try' tutorial (#689) 2018-06-14 15:01:44 -07:00
0f7ec45db4 Fix home screen close icon background color (#687) 2018-06-14 11:55:14 -07:00
2bc2bda502 Fix extensions dialog header color (#686) 2018-06-14 11:03:20 -07:00
51cb7a5299 0.3.2 2018-06-14 13:56:45 -04:00
068eb7017f pxt.commands null check 2018-06-14 13:40:19 -04:00
bb4966dca7 Bump pxt-core to 3.19.4 + Support drive deploy in Electron offline app (#677)
* initial

* Bump pxt-core to 3.19.4 for drive deploy
2018-06-14 13:33:53 -04:00
e981d1b95d Release patch fix with copyright text change (#680) 2018-06-13 16:11:52 -07:00
118 changed files with 2860 additions and 5767 deletions

9
.travis.yml Normal file
View File

@ -0,0 +1,9 @@
language: node_js
node_js:
- "8.9.0"
script:
- "node node_modules/pxt-core/built/pxt.js travis"
sudo: false
cache:
directories:
- node_modules

View File

@ -1,13 +1,8 @@
# LEGO® MINDSTORMS® Education EV3 for Microsoft MakeCode
# LEGO® MINDSTORMS® Education EV3 for Microsoft MakeCode [![Build Status](https://travis-ci.org/microsoft/pxt-ev3.svg?branch=master)](https://travis-ci.org/microsoft/pxt-ev3)
[![Build Status](https://ci2.dot.net/buildStatus/icon?job=Private/pxt_project_rainbow/master/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.mindstorms.com
This repo contains the editor target hosted at https://makecode.legoeducation.com
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
## Local Dev setup
## Local setup
These instructions assume familiarity with dev tools and languages.
@ -15,10 +10,6 @@ These instructions assume familiarity with dev tools and languages.
* install Docker; make sure `docker` command is in your `PATH`
* (optional) install [Visual Studio Code](https://code.visualstudio.com/)
In a common folder,
* clone https://github.com/Microsoft/pxt to ``pxt`` folder
* clone https://github.com/Microsoft/pxt-common-packages to ``pxt-common-packages`` folder
* clone https://github.com/Microsoft/pxt-ev3 to ``pxt-ev3`` folder
* go to ``pxt`` and run
@ -26,6 +17,18 @@ In a common folder,
npm install
```
* to run the local server,
```
pxt serve --cloud
```
## Local Dev setup
In the common folder,
* clone https://github.com/Microsoft/pxt to ``pxt`` folder
* clone https://github.com/Microsoft/pxt-common-packages to ``pxt-common-packages`` folder
* go to ``pxt-common-packages`` and run
```
@ -57,12 +60,12 @@ cd libs/core
pxt deploy
```
### Jenkins build
https://ci2.dot.net/job/Private/job/pxt_project_rainbow/job/master/
## License
MIT
## Trademarks
MICROSOFT, the Microsoft Logo, and MAKECODE are registered trademarks of Microsoft Corporation. They can only be used for the purposes described in and in accordance with Microsofts Trademark and Brand guidelines published at https://www.microsoft.com/en-us/legal/intellectualproperty/trademarks/usage/general.aspx. If the use is not covered in Microsofts published guidelines or you are not sure, please consult your legal counsel or the MakeCode team (makecode@microsoft.com).
## Code of Conduct
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.

View File

@ -11,5 +11,8 @@
<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>
</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>
</footer>

View File

@ -5,6 +5,7 @@
* [Troubleshoot](/troubleshoot)
* [EV3 Manager](https://ev3manager.education.lego.com/)
* [LEGO Support](https://www.lego.com/service/)
* [FIRST LEGO League](/fll)
## Projects #projects
@ -18,11 +19,14 @@
* [What Animal Am I?](/tutorials/what-animal-am-i)
* [Music Brick](/tutorials/music-brick)
* [Run Motors](/tutorials/run-motors)
* [Tank ZigZag](/tutorials/tank-zigzag)
* [Touch to Run](/tutorials/touch-to-run)
* [Touch Sensor Values](/tutorials/touch-sensor-values)
* [What Color?](/tutorials/what-color)
* [Line Following](/tutorials/line-following)
* [Red Light, Green Light](/tutorials/redlight-greenlight)
* [Reflected Light Measure](/tutorials/reflected-light-measure)
* [Reflected Light Calibration](/tutorials/reflected-light-calibration)
* [Object Near?](/tutorials/object-near)
* [Security Alert](/tutorials/security-alert)
@ -82,12 +86,12 @@
* [reset](/reference/sensors/gyro/reset)
* [Ultrasonic](/reference/sensors/ultrasonic)
* [on event](/reference/sensors/ultrasonic/on-event)
* [distance](reference/sensors/ultrasonic/distance)
* [pause until](reference/sensors/ultrasonic/pause-until)
* [distance](/reference/sensors/ultrasonic/distance)
* [pause until](/reference/sensors/ultrasonic/pause-until)
* [Infrared](/reference/sensors/infrared)
* [on event](/reference/sensors/infrared/on-event)
* [distance](reference/sensors/infrared/proximity)
* [pause until](reference/sensors/infrared/pause-until)
* [distance](/reference/sensors/infrared/proximity)
* [pause until](/reference/sensors/infrared/pause-until)
* [Infrared beacon](/reference/sensors/beacon)
* [on event](/reference/sensors/beacon/on-event)
* [pause until](/reference/sensors/beacon/pause-until)
@ -123,3 +127,7 @@
* [log](/reference/console/log)
* [log value](/reference/console/log-value)
* [send to screen](/reference/console/send-to-screen)
## #misc
## devs

View File

@ -70,3 +70,12 @@
| ![Download button](/static/about/download-button.png) |
| Download Button |
#### #explorer-images
| |
|-|
| ![Explorer button](/static/about/explorer-button.png) |
| Explorer Button |
| &nbsp; |
| ![Explorer File View](/static/about/explorer-view.png) |
| Explorer File View |

View File

@ -12,7 +12,7 @@ Design cars that can park themselves safely without driver intervention.
* What would it take to ensure that autonomous cars are safe?
* What types of movements do autonomous cars need to perform?
## Construct
## Construct
### Build
@ -20,6 +20,12 @@ Build a @boardname@ vehicle that can park itself safely without driver intervent
[![EV3- Robot Driving Base](/static/coding/autonomous-parking/ev3-robot-driving-base.jpg)](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
Before you program, check:
@ -28,7 +34,7 @@ Before you program, check:
* Are the wheels correctly installed?
* Are the wheels rotating freely?
### Program
### Program
Write a program that will make the robot turn three times in various ways.
@ -109,7 +115,7 @@ Click Download and follow the instructions to get your code onto your EV3 Brick.
### Differentiation
Create a program that simulates displaying appropriate warning lights while parking.
Create a program that simulates displaying appropriate warning lights while parking.
### ~hint
@ -164,8 +170,8 @@ Click Download and follow the instructions to get your code onto your EV3 Brick.
* Click on the JavaScript tab and experiment with changing the values in the code.
* Add a custom image or sounds from the Brick or Music menus.
* Create a video of your project, especially your final presentation and your robots performance. Explain some important features of your software program.
* Include an image of your program with comments.
* Add a team photograph!
* Create a video of your project, especially your final presentation and your robots performance. Explain some important features of your software program.
* Include an image of your program with comments.
* Add a team photograph!
Congratulations! What will you design next?

View File

@ -24,6 +24,12 @@ Build red and green “lights” for your robot to detect. You can use LEGO bric
[![IMAGE: Color Squares](/static/coding/line-detection/ev3-color-squares.jpg)](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
Before you program, check:
@ -51,7 +57,7 @@ Consider using these blocks in your solution:
```block
loops.forever(function () {
})
motors.largeBC.steer(0, 50)
sensors.color3.pauseUntilColorDetected(ColorSensorColor.Red)
@ -77,9 +83,9 @@ loops.forever(function () {
### Download and test
Click **Download** and follow the instructions to get your code onto your EV3 Brick.
Click **Download** and follow the instructions to get your code onto your EV3 Brick.
Congratulations! Your robot can stop at a red light.
Congratulations! Your robot can stop at a red light.
Now add to your program and have your robot to drive forward again when the light changes from red to green.
@ -102,7 +108,7 @@ loops.forever(function () {
### Download and test
Click **Download** and follow the instructions to get your code onto your EV3 Brick.
Click **Download** and follow the instructions to get your code onto your EV3 Brick.
## Contemplate
@ -116,7 +122,7 @@ Draw a dark line with tape or marker for your robot to cross.
Consider using these blocks in your solution:
```block
```block
motors.largeBC.steer(0, 50)
music.playSoundEffect(sounds.systemGeneralAlert)
```
@ -143,7 +149,7 @@ loops.forever(function () {
#### Download and test
Click **Download** and follow the instructions to get your code onto your EV3 Brick.
Click **Download** and follow the instructions to get your code onto your EV3 Brick.
#### Differentiation
@ -157,7 +163,7 @@ Consider using these blocks in your solution:
```block
while (true) {
}
motors.largeBC.steer(0, 50)
```
@ -166,7 +172,7 @@ motors.largeBC.steer(0, 50)
```block
if (true) {
} else {
}
@ -184,12 +190,10 @@ if (true) {
```blocks
forever(function () {
while (true) {
sensors.color3.pauseUntilColorDetected(ColorSensorColor.Black)
while (sensors.color3.color() == ColorSensorColor.Black) {
motors.largeBC.steer(-30, 50)
}
while (true) {
sensors.color3.pauseUntilColorDetected(ColorSensorColor.White)
while (sensors.color3.color() == ColorSensorColor.White) {
motors.largeBC.steer(30, 50)
}
})
@ -203,11 +207,9 @@ Else the Color Sensor detects the color white, start motors ``B`` and ``C`` (dri
```blocks
forever(function () {
if (true) {
sensors.color3.pauseUntilColorDetected(ColorSensorColor.Black)
if (sensors.color3.color() == ColorSensorColor.Black) {
motors.largeBC.steer(-30, 50)
} else {
sensors.color3.pauseUntilColorDetected(ColorSensorColor.White)
motors.largeBC.steer(30, 50)
}
})
@ -215,7 +217,7 @@ forever(function () {
### Download and test
Click **Download** and follow the instructions to get your code onto your EV3 Brick.
Click **Download** and follow the instructions to get your code onto your EV3 Brick.
### Share
@ -232,8 +234,8 @@ Personalize:
* Click on the **JavaScript** tab and experiment with changing the values in the code.
* Add a custom image or sounds from the ``||brick:Brick||`` or ``||music:Music||`` menus.
* Create a video of your project, especially your final presentation and your robots performance. Explain some important features of your software program.
* Include an image of your program with comments.
* Add a team photograph!
* Create a video of your project, especially your final presentation and your robots performance. Explain some important features of your software program.
* Include an image of your program with comments.
* Add a team photograph!
Congratulations! What will you design next?

View File

@ -4,7 +4,7 @@ Design ways to avoid accidents between vehicles and objects in the road.
![Deer in the road](/static/coding/object-detection/road-deer.jpg)
## Connect
## Connect
Think about:
@ -12,7 +12,7 @@ Think about:
* What do you need to be aware of to avoid collisions with obstacles?
* What causes traffic jams in high density areas?
## Construct
## Construct
### Build
@ -20,10 +20,16 @@ Build a @boardname@ vehicle that can avoid accidents between vehicles and object
[![EV3 Robot Driving Base](/static/coding/object-detection/ev3-robot-driving-base.jpg)](https://le-www-live-s.legocdn.com/sc/media/lessons/mindstorms-ev3/building-instructions/ev3-ultrasonic-sensor-driving-base-61ffdfa461aee2470b8ddbeab16e2070.pdf)
Build an obstacle for your robot to detect. You can build the **cuboid model** out of LEGO bricks or an obstacle of your choice.
Build an obstacle for your robot to detect. You can build the **cuboid model** out of LEGO bricks or an obstacle of your choice.
[![Cubiod block](/static/coding/object-detection/ev3-cuboid.jpg)](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
Before you program, check:
@ -38,7 +44,7 @@ Before you program, check:
* Program your robot to detect any obstacles that might appear while the robot is moving forward (or backward).
* Make the robot stop when it detects an object that is less than 20 cm away.
Before you program, think about:
Before you program, think about:
* How will you program the robot to detect obstacles?
* How will you program the robot to stop at obstacles?
* Which programming blocks will you use?
@ -59,7 +65,7 @@ motors.stopAll()
### ~
### Sample Solution
### Sample Solution
1. Start the program when EV3 ``enter`` button is pressed.
2. Turn motors ``B`` and ``C`` on at speed ``50``.
@ -80,7 +86,7 @@ Click **Download** and follow the instructions to get your code onto your EV3 Br
## Contemplate
On the road, when a driver sees and object, they slow their car down before coming to a full stop.
On the road, when a driver sees and object, they slow their car down before coming to a full stop.
Program your EV3 Driving Base to do the same.
@ -93,7 +99,7 @@ If the Ultrasonic Sensor:
### ~hint
Consider using this block in your solution:
```block
if (true) {
}
@ -101,7 +107,7 @@ if (true) {
### ~
### Sample Solution
### Sample Solution
```blocks
loops.forever(function () {
@ -118,7 +124,7 @@ loops.forever(function () {
Click **Download** and follow the instructions to get your code onto your EV3 Brick. Press the ``center`` button on the EV3 Brick to run the program.
## Continue
## Continue
* Get together with other building teams and make a traffic jam by placing all of your robots in a line with varying amounts of space between them.
* Have everyone start their robots at the same time and see what happens.
@ -130,8 +136,8 @@ Click **Download** and follow the instructions to get your code onto your EV3 Br
* Share what you think “efficiency in programming” means.
* Explore the different solutions other programmers came up with.
* Create a video of your project, especially your final presentation and your robots performance. Explain some important features of your software program.
* Include an image of your program with comments.
* Add a team photograph!
* Create a video of your project, especially your final presentation and your robots performance. Explain some important features of your software program.
* Include an image of your program with comments.
* Add a team photograph!
Congratulations! What will you design next?

View File

@ -1,6 +1,6 @@
# Make A System That Communicates
## Connect
## Connect
### Design Brief
@ -20,10 +20,10 @@ Think about:
* What kind of motorized mechanism can be used to control the movements of a robot?
* How can the robot sense where it is along the path?
* How can the robot communicate its position?
![EV3 + LEGO Bricks](/static/lessons/make-it-communicate/ev3-plus-parts.jpg)
## Construct
## Construct
### Build
@ -37,13 +37,19 @@ More building ideas:
[![Color Sensor 2](/static/lessons/make-it-communicate/ev3-color-sensor2.jpg)](https://le-www-live-s.legocdn.com/sc/media/files/support/mindstorms%20ev3/building-instructions/design%20engineering%20projects/color%20sensor_v2-e7fd54b6fa3cdfe36f414c1d2510f9cb.pdf)
### ~hint
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.
If clicking the above images doesn't open the instructions, right-click on the image and choose "Save link as..." to download the PDF.
### Program
### ~
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.
### Program
Before you program, think about:
Before you program, think about:
* How will you program the robot to follow a path?
* How will you program the robot to communicate its position?
* Which programming blocks will you use?
@ -54,7 +60,7 @@ Explore the different Motor and Sensor blocks in the programming menu.
### ~
### Sample Solution
### Sample Solution
[![Video: EV3 Track Rover](/static/lessons/make-it-communicate/ev3-track-rover.jpg)](https://legoeducation.23video.com/v.ihtml/player.html?token=79c99735f906403a4dd7f2909935983d&source=embed&photo%5fid=19857954)
@ -70,15 +76,21 @@ Two copies of the tracks are built: one for the right side and a mirror image fo
[![Track rover assembled](/static/lessons/make-it-communicate/ev3-track-rover2.jpg)](https://le-www-live-s.legocdn.com/sc/media/lessons/mindstorms-ev3/ev3-dep/building%20instructions/track-rover-bi-6aadb1b053df0c58a0dea108b5ce0eea.pdf)
### Sample Program Solution
### ~hint
This program works with the Track Rover. If you create a different robot, adjust the program to fit your solution.
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 summary:
### ~
### Sample Program Solution
This program works with the Track Rover. If you create a different robot, adjust the program to fit your solution.
Program summary:
* If the Color Sensor sees black, Motor B runs at -50 power and Motor C turns off.
* If the Color Sensor sees white, Motor B turns off and Motor C runs at -50 power.
* If the Color Sensor sees green, all motors stop and the green sound plays.
* If the Color Sensor sees green, all motors stop and the green sound plays.
* The robot waits one second, then motors move forward.
* If the Color Sensor sees red, all motors stop, and the red sound plays.
* The robot waits one second, then motors move forward.
@ -108,44 +120,44 @@ forever(function () {
Click Download and follow the instructions to get your code onto your EV3 Brick. Press the center button on the EV3 Brick to run the program.
## Contemplate
## Contemplate
### Test and Analyze
### Test and Analyze
As you work on your solution:
1. Describe one part of your design that worked especially well.
2. Describe one design change that you had to make.
3. What will you try next?
1. Describe one part of your design that worked especially well.
2. Describe one design change that you had to make.
3. What will you try next?
### Review and Revise
### Review and Revise
Take a moment to reflect on your robot solution.
Take a moment to reflect on your robot solution.
Think about:
* Can the robots movement be more accurate?
* Can the robots movement be more accurate?
* What are some ways that others have solved the problem?
Describe two ways you could improve your robot.
## Continue
## Continue
### Personalize your project
* Add/remove LEGO elements to improve the way your robot moves.
* Add/remove LEGO elements to improve the way your robot moves.
* Click on the JavaScript tab and experiment with changing the values in the code.
* Add a custom image or sounds by adding blocks from the Brick or Music menus.
## Communicate
## Communicate
Here are some ideas:
* Create a video of your project, especially your final presentation and your robots performance.
* Explain some important features of your software program.
* Produce a building guide for your model by taking a series of photographs as you deconstruct it.
* Include an image of your program with comments.
* Add a team photograph!
* Create a video of your project, especially your final presentation and your robots performance.
* Explain some important features of your software program.
* Produce a building guide for your model by taking a series of photographs as you deconstruct it.
* Include an image of your program with comments.
* Add a team photograph!
Congratulations! What will you design next?

View File

@ -30,18 +30,26 @@ If you want some building help you can follow these instructions.
[![Toddle Bot](/static/lessons/make-it-move/toddle-bot.jpg)](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
Before you program, think about:
* How will you program the robot to move?
* How will you program the robot to move?
* How will you program the robot to stop?
* How will you program the robot to display the distance moved?
Which programming blocks will you use:
* To turn on and turn off the motor or motors?
* To display the distance moved?
* To turn on and turn off the motor or motors?
* To display the distance moved?
### Sample Code
@ -49,7 +57,7 @@ Example code of a robot that moves without wheels using one motor:
* The robot moves with ``large motor D`` rotating at ``-100`` speed
* The robot moves for ``30000`` milliseconds (30 seconds)
* The robot stops
* The robot stops
* The robot displays the text ``"30cm"``
```blocks
@ -65,7 +73,7 @@ brick.buttonEnter.onEvent(ButtonEvent.Pressed, function () {
Click **Download** and follow the instructions to get your code onto your EV3 Brick. Press the center button on the EV3 Brick to run the program.
## Contemplate
## Contemplate
### Test and Analyze

View File

@ -1,6 +1,6 @@
# Make It Smarter and Faster
# Make It Smarter and Faster
## Connect
## Connect
### Design Brief
@ -10,52 +10,52 @@ https://www.youtube.com/watch?v=y9-A_C_08KY
* What do the robots in the video need to be able to sense, plan, and act?
* What senses do humans have and why are they important to us?
* How many human-like senses do you see the robots demonstrating?
* How many human-like senses do you see the robots demonstrating?
### Brainstorm
### Brainstorm
Discuss different solutions to the design brief.
Think about:
Think about:
* What kind of creature can it be?
* How can it move?
* What does it need to be aware so that it stays safe, well fed and warm (or cool)?
* Is it looking for food, a safe place to hide or a warm place to soak up the sun?
* Will the creature need to move fast or slow?
* Will it need to turn?
* What kind of creature can it be?
* How can it move?
* What does it need to be aware so that it stays safe, well fed and warm (or cool)?
* Is it looking for food, a safe place to hide or a warm place to soak up the sun?
* Will the creature need to move fast or slow?
* Will it need to turn?
* Will it need to go backward?
![EV3 and bricks](/static/lessons/make-it-smarter/bricks.png)
## Construct
### Build
Think about a creatures movement for inspiration. Your mechanism can be attached or unattached to the EV3 Brick. You can start by tinkering with the LEGO elements in the picture add then build on.
More building ideas:
More building ideas:
| | | | | |
|-|-|-|-|-|
|[![EV3 Frames](/static/lessons/make-it-smarter/ev3-parts-frames.jpg)][EV3 Frames] | |[![EV3 Color Sensor 1](/static/lessons/make-it-smarter/ev3-parts-color-sensor-1.jpg)][Color Sensor 1] | |[![EV3 Gyro Sensor](/static/lessons/make-it-smarter/ev3-parts-gyro-sensor.jpg)][Gyro Sensor] |
| [EV3 Frames] | | [Color Sensor 1] | | [Gyro Sensor] |
<br/>
| | | | | |
|-|-|-|-|-|
|[![EV3 Ultrasonic Sensor](/static/lessons/make-it-smarter/ev3-parts-ultrasonic-sensor.jpg)][Ultrasonic Sensor] | | [![EV3 Touch Sensor](/static/lessons/make-it-smarter/ev3-parts-touch-sensor.jpg)][Touch Sensor] | | [![EV3 Gyro Sensor](/static/lessons/make-it-smarter/ev3-parts-jaw.jpg)][Jaw] |
| [Ultrasonic Sensor] | | [Touch Sensor] | | [Jaw] |
<br/>
* [EV3 Frames]
* [Color Sensor 1]
* [Gyro Sensor]
* [Ultrasonic Sensor]
* [Touch Sensor]
* [Jaw]
* [Leg 1]
* [Leg 2]
* [Leg 3]
| | | | | |
|-|-|-|-|-|
| [![EV3 Leg 1](/static/lessons/make-it-smarter/ev3-parts-leg-1.jpg)][Leg 1] | | [![EV3 Leg 2](/static/lessons/make-it-smarter/ev3-parts-leg-2.jpg)][Leg 2] | | [![EV3 Leg 3](/static/lessons/make-it-smarter/ev3-parts-leg-3.jpg)][Leg 3] |
| [Leg 1] | | [Leg 2] | | [Leg 3] |
### ~hint
### Program
If clicking the above links doesn't open the instructions, right-click on the image and choose "Save link as..." to download the PDF.
Before you program, think about:
### ~
### Program
Before you program, think about:
* How will you program the robot to sense?
* How will you program the robot to respond?
@ -67,7 +67,7 @@ Before you program, think about:
### ~
### Sample Solution
### Sample Solution
The Insect uses its Ultrasonic Sensor to sense danger and move away from a threat.
@ -86,18 +86,24 @@ Building Instructions:
[![Insect robot](/static/lessons/make-it-smarter/insect-bot.jpg)](https://le-www-live-s.legocdn.com/sc/media/files/support/mindstorms%20ev3/building-instructions/design%20engineering%20projects/insect-94b8a46f0dc5082c9d78ddb734626dc9.pdf)
### Sample Solution
### ~hint
This program checks if the Ultrasonic Sensor senses something near.
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.
The blocks inside the ``||loops:forever||`` loop have these actions:
### ~
### Sample Solution
This program checks if the Ultrasonic Sensor senses something near.
The blocks inside the ``||loops:forever||`` loop have these actions:
1. Turn on the ``green`` EV3 Brick Status Light.
2. Wait for Ultrasonic Sensor to detect an object.
3. Turn on Motors ``A`` and ``D`` in opposite directions.
4. Wait for one quarter of a second (``1500`` milli seconds).
4. Wait for one and a half seconds (``1500`` milli seconds).
5. Reverse the direction of Motors ``A`` and ``D``.
6. Wait for one quarter of a second.
6. Wait for one and a half seconds.
7. Stop all motors.
8. Make an insect chirping sound.
9. Loop continuously so that the insect wanders around when the Ultrasonic Sensor is detects something.
@ -119,44 +125,44 @@ forever(function () {
Click **Download** and follow the instructions to get your code onto your EV3 Brick. Press the center button on the EV3 Brick to run the program.
## Contemplate
## Contemplate
### Test and Analyze
### Test and Analyze
As you work on your solution:
1. Describe one part of your design that worked especially well.
2. Describe one design change that you had to make.
3. What will you try next?
As you work on your solution:
1. Describe one part of your design that worked especially well.
2. Describe one design change that you had to make.
3. What will you try next?
### Review and Revise
### Review and Revise
Take a moment to reflect on your robot solution.
Take a moment to reflect on your robot solution.
Think about:
Think about:
* Does your robot move when the sensor is activated?
* If not, what will you change to make the robots ability to sense and respond more obvious?
* What other behaviors can you add to the robot to make it more realistic?
* Does your robot move when the sensor is activated?
* If not, what will you change to make the robots ability to sense and respond more obvious?
* What other behaviors can you add to the robot to make it more realistic?
Describe two ways you could improve your robot.
## Continue
## Continue
Personalize your project:
* Add/remove LEGO elements to improve the way your robot moves.
* Add/remove LEGO elements to improve the way your robot moves.
* Click on the JavaScript tab and experiment with changing the values in the code.
* Add a custom image or sounds by adding blocks from the Brick or Music menus.
* Does your robot resemble a creature? Maybe add more craft materials to your project.
## Communicate
## Communicate
Here are some ideas:
Here are some ideas:
* Create a video of your project, especially your final presentation and your robots performance. Explain some important features of your software program.
* Produce a building guide for your model by taking a series of photographs as you deconstruct it.
* Include an image of your program with comments.
* Add a team photograph!
* Create a video of your project, especially your final presentation and your robots performance. Explain some important features of your software program.
* Produce a building guide for your model by taking a series of photographs as you deconstruct it.
* Include an image of your program with comments.
* Add a team photograph!
Congratulations! What will you design next?

18
docs/extensions.md Normal file
View File

@ -0,0 +1,18 @@
# Extensions
## #gallery
## Using Extensions
In the web editor, click on ``Settings`` then ``Extensions`` to search and add extensions to the project.
The Blocks and JavaScript definitions will be automatically loaded in the editor.
## Custom extensions
The [Build Your Own Extension](https://makecode.com/extensions/getting-started) manual is for advanced users who want to publish their own extension.
## ~ hint
**Extensions** were previously called **Packages** in MakeCode.
## ~

112
docs/fll.md Normal file
View File

@ -0,0 +1,112 @@
# MakeCode for _FIRST_ LEGO League
![FIRST LEGO League logo](/static/fll/fll-logo.png)
**For teams participating in the Open Software Platform Pilot utilizing MakeCode**, weve compiled a list of resources and information that we hope will be helpful for you.
* **Got a question? Post it on the forums** at https://forum.makecode.com/
## FAQ
### I found a bug what do I do?
If you found a bug, please try if it hasn't been fixed yet! Go to https://makecode.mindstorms.com/beta and try if the bug is corrected. Otherwise, please tell us at https://forum.makecode.com/.
### 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.
### Whats 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.
![Select help in context menu for block](/static/fll/context-help.jpg)
### 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.
![Coding in JavaScript](/static/fll/code-js.gif)
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)
})
```
![Simulator demonstration](/static/fll/simulator.gif)
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
![Save project menu selection](/static/fll/save-project.jpg)
* You can import your saved projects by clicking the Import button on the Home Page
![Import button on home screen](/static/fll/import-button.jpg)
### 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.
![Share button in editor](/static/fll/share-button.jpg)
![Share button and dialogs demo](/static/fll/share-program.gif)
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

View File

@ -7,7 +7,7 @@
{
"name": "Prepare",
"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!",
"labelClass": "red ribbon large",
"url": "https://makecode.mindstorms.com/troubleshoot"
@ -25,6 +25,12 @@
"description": "Build a robot and drive into the world of robotics!",
"url": "/getting-started/use",
"cardType": "side"
},
{
"name": "First LEGO League",
"imageUrl": "/static/fll/fll-big.png",
"description": "Information about using MakeCode in FLL competitions",
"url": "/fll"
}
]
```

View File

@ -135,15 +135,15 @@ Keeping the Large Motor connected to **Port D**, connect the Color Sensor to **P
```blocks
brick.buttonEnter.onEvent(ButtonEvent.Pressed, function () {
sensors.color3.pauseUntilColorDetected(ColorSensorColor.Green)
sensors.color4.pauseUntilColorDetected(ColorSensorColor.Green)
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
sensors.color3.pauseUntilColorDetected(ColorSensorColor.Green)
sensors.color4.pauseUntilColorDetected(ColorSensorColor.Green)
```
* Select the color you want to detect (e.g., green).

View File

@ -20,6 +20,12 @@ Build the robot driving base:
[![EV3 Driving Base](/static/lessons/common/ev3-driving-base.jpg)](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
**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:
[![EV3 Ultrasonic Sensor Driving Base Building Instructions Main Image](/static/lessons/common/ev3-ultrasonic-sensor-driving-base.jpg)](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
**Code it:** Create a program that moves the Driving Base and makes it stop ``6`` cm from the Cuboid.

View File

@ -1,3 +1,3 @@
{
"appref": "v0.1.57"
"appref": "v1.0.11"
}

View File

@ -3,7 +3,7 @@
## Objective
Design ways to improve driving safety by helping to prevent drivers from falling asleep and causing an accident.
![Car driving on highway](/static/lessons/line-detection/car-driving.jpg)
## Connect
@ -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.
### ~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.
### ~
![Color sensor on the driving base](/static/lessons/line-detection/color-sensor-driving.jpg)
## Program
@ -44,13 +50,13 @@ Create a program that drives the robot forward until the Color Sensor sees red.
Place a ``||motors:steer large B+C||`` block from ``||motors:Motors||`` under ``||loops:on start||``. Change the speed to 20%.
```blocks
```blocks
motors.largeBC.steer(0, 20)
```
### Step 2
Place a ``||loops:while||`` loop block under ``||motors:steer large B+C||``.
Place a ``||loops:while||`` loop block under ``||motors:steer large B+C||``.
```blocks
motors.largeBC.steer(0, 20)
@ -61,7 +67,7 @@ while (true) {
### Step 3
Place a ``||sensors:pause until color detected||`` from ``||sensors:Sensors||`` inside the ``||loops:while||`` loop block. Change the color to red.
```blocks
motors.largeBC.steer(0, 20)
while (true) {
@ -99,7 +105,7 @@ Place a ``||loops:while||`` loop block under ``||loops:on start||``.
```blocks
while (true) {
}
```
@ -121,7 +127,7 @@ Place a ``||loops:while||`` loop block under the ``||motors:steer large B+C||``
while (true) {
motors.largeBC.steer(0, 20)
while (true) {
}
}
```
@ -141,7 +147,7 @@ while (true) {
### Step 6
Place a ``||motors:stop all motors||`` block under the ``||sensors:pause until color detected||`` block.
Place a ``||motors:stop all motors||`` block under the ``||sensors:pause until color detected||`` block.
```blocks
while (true) {
@ -165,7 +171,7 @@ while (true) {
motors.stopAll()
}
while (true) {
}
}
```
@ -177,7 +183,7 @@ Place a ``||sensors:pause unril color detected||`` block inside the new ``||loop
What do you think the program will do?
**Hint:** The motors will run until the Color Sensor detects the color red, then it will stop all motors. The motors will also run and not stop when the color sensor detects the color green.
```blocks
while (true) {
motors.largeBC.steer(0, 20)
@ -212,7 +218,7 @@ sensors.color3.pauseUntilColorDetected(ColorSensorColor.Yellow)
music.playSoundEffect(sounds.systemGeneralAlert)
}
while (true) {
while (true) {
while (true) {
sensors.color3.pauseUntilLightDetected(LightIntensityMode.Reflected, Light.Bright)
motors.largeB.run(10)
motors.largeC.run(-10)
@ -235,7 +241,7 @@ You will need to constantly debug your program in order to make your robot trave
```blocks
while (true) {
while (true) {
while (true) {
sensors.color3.pauseUntilLightDetected(LightIntensityMode.Reflected, Light.Bright)
motors.largeB.run(10)
motors.largeC.run(-10)
@ -252,10 +258,10 @@ while (true) {
Consider the following questions:
1. What challenged you?
2. Where there any surprises?
1. What challenged you?
2. Where there any surprises?
3. How could you improve your program?
4. Could your program have been more streamlined?
4. Could your program have been more streamlined?
5. Have you used too many blocks?
6. Is there a more efficient way of building your program?
7. How could your program be used in real-world scenarios?

View File

@ -1,4 +1,4 @@
# Make It Move Without Wheels
# Make It Move Without Wheels
## Objective @unplugged
@ -24,7 +24,13 @@ The Walker Bot combines an EV3 Frame and two legs that are mirror-images to crea
The legs in the Walker Bot are designed to show how to change the rotary motion of a motor to reciprocating 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.
### ~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.
### ~
![@boardname@ Walker Bot](/static/lessons/make-it-move/walker-bot.jpg)

View File

@ -1,4 +1,4 @@
# Make It Move Without Wheels
# Make It Move Without Wheels
## Objective
@ -23,7 +23,13 @@ The Walker Bot combines an EV3 Frame and two legs that are mirror-images to crea
The legs in the Walker Bot are designed to show how to change the rotary motion of a motor to reciprocating 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.
### ~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.
### ~
![@boardname@ Walker Bot](/static/lessons/make-it-move/walker-bot.jpg)

View File

@ -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:
| | |
|-|-|
| ![Paper sheet icon](/static/maker/design-process-icons/define-problem.png) | **Define the Problem** |
| ![Lightbulb icon](/static/maker/design-process-icons/brainstorming.png) | **Brainstorming** |
| ![Checkmark icon](/static/maker/design-process-icons/define-criteria.png) | **Define the Design Criteria** |
| ![Connector icon](/static/maker/design-process-icons/go-make.png) | **Go Make** |
| ![Redo icon](/static/maker/design-process-icons/review-revise.png) | **Review and Revise Your Solution** |
| ![Speaker icon](/static/maker/design-process-icons/communicate.png) | **Communicate Your Solution** |
* Define the Problem
* Brainstorming
* Define the Design Criteria
* Go Make
* Review and Revise Your Solution
* Communicate Your Solution
### Defining the Problem

View File

@ -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:
| | |
|-|-|
| ![Paper sheet icon](/static/maker/design-process-icons/define-problem.png) | **Define the Problem** |
| ![Lightbulb icon](/static/maker/design-process-icons/brainstorming.png) | **Brainstorming** |
| ![Checkmark icon](/static/maker/design-process-icons/define-criteria.png) | **Define the Design Criteria** |
| ![Connector icon](/static/maker/design-process-icons/go-make.png) | **Go Make** |
| ![Redo icon](/static/maker/design-process-icons/review-revise.png) | **Review and Revise Your Solution** |
| ![Speaker icon](/static/maker/design-process-icons/communicate.png) | **Communicate Your Solution** |
* Define the Problem
* Brainstorming
* Define the Design Criteria
* Go Make
* Review and Revise Your Solution
* Communicate Your Solution
### Defining the Problem

791
docs/offline-app.html Normal file
View 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.11/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.11/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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>
<span class="c5 c1">ASSOCIATED ONLINE SERVICES.</span>
<span class="c1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>
<span class="c5 c1">LICENSES FOR OTHER COMPONENTS.</span>
<span class="c3 c1">&nbsp;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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>
<span class="c1 c4">DATA.</span>
</p>
<p class="c8">
<span class="c5 c1">a.</span>
<span class="c1">&nbsp; &nbsp;</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">&nbsp;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">&nbsp; &nbsp;</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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>
<span class="c5 c1">SCOPE OF LICENSE.</span>
<span class="c3 c1">&nbsp;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. &nbsp;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">- &nbsp; &nbsp; work around any technical limitations in the software;</span>
</p>
<p class="c8">
<span class="c3 c1">- &nbsp; &nbsp; 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">- &nbsp; &nbsp; remove, minimize, block or modify any notices of Microsoft or its suppliers in the
software;
</span>
</p>
<p class="c8">
<span class="c3 c1">- &nbsp; &nbsp; use the software in any way that is against the law; or</span>
</p>
<p class="c8">
<span class="c3 c1">- &nbsp; &nbsp; 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. &nbsp; 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">&nbsp; &nbsp;</span>
<span class="c5 c1">EXPORT RESTRICTIONS.</span>
<span class="c3 c1">&nbsp;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">&nbsp;</span>
<span class="c5 c1">SUPPORT SERVICES. </span>
<span class="c3 c1">Because the software is &ldquo;as is,&rdquo; we may not provide support services for it.</span>
</p>
<p class="c2">
<span class="c5 c1">11.</span>
<span class="c1">&nbsp;</span>
<span class="c5 c1">ENTIRE AGREEMENT.</span>
<span class="c3 c1">&nbsp;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">&nbsp;</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">&nbsp;</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">&nbsp; &nbsp;</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">&nbsp; &nbsp;</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">&nbsp; &nbsp;</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">&nbsp; &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</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">&nbsp;</span>
</p>
<p class="c6">
<span class="c5 c1">(ii)</span>
<span class="c1">&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</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 &quot;cardinal obligations&quot;).
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">&nbsp;</span>
<span class="c5 c1">LEGAL EFFECT.</span>
<span class="c3 c1">&nbsp;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">&nbsp;</span>
<span class="c4 c1">DISCLAIMER OF WARRANTY. THE SOFTWARE IS LICENSED &ldquo;AS-IS.&rdquo; &nbsp;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">&nbsp;</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 &eacute;tant distribu&eacute; au Qu&eacute;bec, Canada, certaines des clauses
dans ce contrat sont fournies ci-dessous en fran&ccedil;ais.</span>
</p>
<p class="c11">
<span class="c5 c1">EXON&Eacute;RATION DE GARANTIE.</span>
<span class="c1 c3">&nbsp;Le logiciel vis&eacute; par une licence est offert &laquo; tel quel &raquo;. Toute utilisation
de ce logiciel est &agrave; votre seule risque et p&eacute;ril. Microsoft n&rsquo;accorde aucune
autre garantie expresse. Vous pouvez b&eacute;n&eacute;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&eacute; marchande, d&rsquo;ad&eacute;quation
&agrave; un usage particulier et d&rsquo;absence de contrefa&ccedil;on sont exclues.
</span>
</p>
<p class="c11">
<span class="c5 c1">LIMITATION DES DOMMAGES-INT&Eacute;R&Ecirc;TS ET EXCLUSION DE RESPONSABILIT&Eacute; POUR LES DOMMAGES.</span>
<span class="c3 c1">&nbsp;Vous pouvez obtenir de Microsoft et de ses fournisseurs une indemnisation en cas de dommages
directs uniquement &agrave; hauteur de 5,00 $ US. Vous ne pouvez pr&eacute;tendre &agrave; aucune
indemnisation pour les autres dommages, y compris les dommages sp&eacute;ciaux, indirects ou
accessoires et pertes de b&eacute;n&eacute;fices.</span>
</p>
<p class="c12">
<span class="c3 c1">Cette limitation concerne :</span>
</p>
<p class="c2">
<span class="c3 c1">- &nbsp; &nbsp; &nbsp; &nbsp; tout ce qui est reli&eacute; 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">- &nbsp; &nbsp; &nbsp; &nbsp; les r&eacute;clamations au titre de violation de contrat ou de garantie,
ou au titre de responsabilit&eacute; stricte, de n&eacute;gligence ou d&rsquo;une autre faute
dans la limite autoris&eacute;e par la loi en vigueur.</span>
</p>
<p class="c12">
<span class="c3 c1">Elle s&rsquo;applique &eacute;galement, m&ecirc;me si Microsoft connaissait ou devrait conna&icirc;tre
l&rsquo;&eacute;ventualit&eacute; d&rsquo;un tel dommage. Si votre pays n&rsquo;autorise pas
l&rsquo;exclusion ou la limitation de responsabilit&eacute; pour les dommages indirects, accessoires
ou de quelque nature que ce soit, il se peut que la limitation ou l&rsquo;exclusion ci-dessus
ne s&rsquo;appliquera pas &agrave; votre &eacute;gard.</span>
</p>
<p class="c16">
<span class="c5 c1">EFFET JURIDIQUE.</span>
<span class="c3 c1">&nbsp;Le pr&eacute;sent contrat d&eacute;crit certains droits juridiques. Vous pourriez avoir d&rsquo;autres
droits pr&eacute;vus par les lois de votre pays. Le pr&eacute;sent contrat ne modifie pas les
droits que vous conf&egrave;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">&nbsp;</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. &copy;2018 The LEGO Group. All rights reserved.</span>
</p>
<p class="c11">
<span class="c3 c1">&nbsp;</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>

11
docs/offline.md Normal file
View File

@ -0,0 +1,11 @@
# @extends
## Offline app #target-app
The MakeCode editor is available as app which you can install on a computer with Windows or Mac OS. Once installed, the **[MakeCode Offline App](/offline-app)** lets you create, run, and download your projects to the @boardname@. It works the same as the Web application does in your browser but it's a stand-alone application that will work when a connection to the internet is restricted or not available.
### ~ hint
The [MakeCode Offline App](/offline-app) is currently in development and is made available as a **pre-release** version.
### ~

3
docs/packages-ref.json Normal file
View File

@ -0,0 +1,3 @@
{
"redirect": "/extensions"
}

View File

@ -0,0 +1,3 @@
{
"redirect": "https://makecode.com/extensions/approval"
}

View File

@ -0,0 +1,3 @@
{
"redirect": "https://makecode.com/extensions/getting-started"
}

View File

@ -0,0 +1,3 @@
{
"redirect": "https://makecode.com/extensions/versioning"
}

View File

@ -6,9 +6,9 @@ Set the rotation speed of the motor as a percentage of maximum speed.
motors.largeA.run(50)
```
The speed setting is a pecentage of the motor's full speed. Full speed is the speed that the motor runs when the brick supplies maximum output voltage to the port.
The speed setting is a percentage of the motor's full speed. Full speed is the speed that the motor runs when the brick supplies maximum output voltage to the port.
If you use just the **speed** number, the motor runs continously and won't stop unless you tell it to. You can also give a value for a certain amount of distance you want the motor to rotate for. The **value** can be an amount of time, a turn angle in degrees, or a number of full rotations.
If you use just the **speed** number, the motor runs continuously and won't stop unless you tell it to. You can also give a value for a certain amount of distance you want the motor to rotate for. The **value** can be an amount of time, a turn angle in degrees, or a number of full rotations.
If you decide to use a **value** of rotation distance, you need to choose a type of movement **unit**.
@ -30,8 +30,8 @@ Here is how you use each different movement unit to run the motor for a fixed ro
// Run motor for 700 Milliseconds.
motors.largeA.run(25, 700, MoveUnit.MilliSeconds);
// Run motor for 700 Milliseconds again but no units specified.
motors.largeA.run(25, 700);
// Run motors B and C for 700 Milliseconds again but no units specified.
motors.largeBC.run(25, 700);
// Run the motor for 45 seconds
motors.largeA.run(50, 45, MoveUnit.Seconds);
@ -61,6 +61,14 @@ motors.largeB.run(-25)
## ~
## Multiple motors
When using **run** with multiple motors, there is no guarantee that their speed will stay in sync. Use [tank](/reference/motors/tank) or [steer](/reference/motors/steer) for synchronized motor operations.
```blocks
motors.largeBC.run(50)
```
## Examples
### Drive the motor for 20 seconds

View File

@ -0,0 +1,22 @@
# Schedule
Schedules an acceleration, constant and deceleration phase at a given speed.
```sig
motors.largeA.schedule(50, 100, 500, 100)
```
The speed setting is a percentage of the motor's full speed. Full speed is the speed that the motor runs when the brick supplies maximum output voltage to the port.
## Parameters
* **speed**: a [number](/types/number) that is the percentage of full speed. A negative value runs the motor in the reverse direction.
* **acceleration**: the [number](/types/number) of movement units to rotate for while accelerating.
* **value**: the [number](/types/number) of movement units to rotate for.
* **deceleration**: the [number](/types/number) of movement units to rotate for while decelerating.
* **unit**: the movement unit of rotation. This can be `milliseconds`, `seconds`, `degrees`, or `rotations`. If the number for **value** is `0`, this parameter isn't used.
## See also
[tank](/reference/motors/synced/tank), [steer](/reference/motors/synced/steer), [stop](/reference/motors/motor/stop)

View File

@ -0,0 +1,20 @@
# Set Run Acceleration Ramp
```sig
motors.largeD.setRunAccelerationRamp(1, MoveUnit.Seconds)
```
## Examples
```blocks
brick.buttonEnter.onEvent(ButtonEvent.Pressed, function () {
motors.largeB.run(50, 6, MoveUnit.Rotations)
})
brick.buttonLeft.onEvent(ButtonEvent.Pressed, function () {
motors.largeC.run(50, 6, MoveUnit.Seconds)
})
motors.largeB.setRunAccelerationRamp(360, MoveUnit.Degrees)
motors.largeB.setRunDecelerationRamp(360, MoveUnit.Degrees)
motors.largeC.setRunAccelerationRamp(2, MoveUnit.Seconds)
motors.largeC.setRunDecelerationRamp(2, MoveUnit.Seconds)
```

View File

@ -0,0 +1,20 @@
# Set Run Deceleration Ramp
```sig
motors.largeD.setRunDecelerationRamp(1, MoveUnit.Seconds)
```
## Examples
```blocks
brick.buttonEnter.onEvent(ButtonEvent.Pressed, function () {
motors.largeB.run(50, 6, MoveUnit.Rotations)
})
brick.buttonLeft.onEvent(ButtonEvent.Pressed, function () {
motors.largeC.run(50, 6, MoveUnit.Seconds)
})
motors.largeB.setRunAccelerationRamp(360, MoveUnit.Degrees)
motors.largeB.setRunDecelerationRamp(360, MoveUnit.Degrees)
motors.largeC.setRunAccelerationRamp(2, MoveUnit.Seconds)
motors.largeC.setRunDecelerationRamp(2, MoveUnit.Seconds)
```

View File

@ -39,6 +39,13 @@ motors.largeBC.steer(-15, -75)
## ~
## ~ hint
Only one set of synchronized motors will run at the same time. Once you launch tank/steer, it will cancel any existing synchronized speed command.
## ~
## Examples
### Make a slight right
@ -79,6 +86,51 @@ for (let i = 0; i < 4; i++) {
motors.stopAll()
```
### Steer tester
This program lets you change the values of speed and turn ratio with the buttons.
```typescript
let speed = 0;
let turnRatio = 0;
brick.showString(`steer tester`, 1)
brick.showString(`connect motors BC`, 7)
brick.showString(`up/down for speed`, 8)
brick.showString(`left/right for turn ratio`, 9)
forever(function () {
brick.showString(`motor B speed ${motors.largeB.speed()}%`, 4)
brick.showString(`motor C speed ${motors.largeC.speed()}%`, 5)
pause(100)
})
function updateSteer() {
motors.largeBC.steer(turnRatio, speed);
brick.showString(`speed ${speed}%`, 2)
brick.showString(`turnRatio ${turnRatio}`, 3)
}
brick.buttonUp.onEvent(ButtonEvent.Pressed, function () {
speed += 10
updateSteer()
})
brick.buttonDown.onEvent(ButtonEvent.Pressed, function () {
speed -= 10
updateSteer()
})
brick.buttonLeft.onEvent(ButtonEvent.Pressed, function () {
turnRatio -= 10
updateSteer()
})
brick.buttonRight.onEvent(ButtonEvent.Pressed, function () {
turnRatio += 10
updateSteer()
})
updateSteer()
```
## See also
[tank](/reference/motors/synced/tank), [run](/reference/motors/motor/run)

View File

@ -35,6 +35,12 @@ motors.largeBC.tank(-75, -75)
## ~
## ~ hint
Only one set of synchronized motors will run at the same time. Once you launch tank/steer, it will cancel any existing synchronized speed command.
## ~
## Examples
### Tank forward and backward
@ -76,6 +82,51 @@ pause(5000)
motors.stopAll()
```
### Tank tester
This program lets you change the tank values using the brick buttons.
```typescript
let tankB = 0;
let tankC = 0;
brick.showString(`tank tester`, 1)
brick.showString(`connect motors BC`, 7)
brick.showString(`up/down for tank B`, 8)
brick.showString(`left/right for tank C`, 9)
forever(function () {
brick.showString(`motor B speed ${motors.largeB.speed()}%`, 4)
brick.showString(`motor C speed ${motors.largeC.speed()}%`, 5)
pause(100)
})
function updateTank() {
brick.showString(`tank A: ${tankB}%`, 2)
brick.showString(`tank B: ${tankC}%`, 3)
motors.largeBC.tank(tankB, tankC);
}
brick.buttonUp.onEvent(ButtonEvent.Pressed, function () {
tankB += 10
updateTank();
})
brick.buttonDown.onEvent(ButtonEvent.Pressed, function () {
tankB -= 10
updateTank();
})
brick.buttonRight.onEvent(ButtonEvent.Pressed, function () {
tankC += 10
updateTank();
})
brick.buttonLeft.onEvent(ButtonEvent.Pressed, function () {
tankC -= 10
updateTank();
})
updateTank();
```
## See also
[steer](/reference/motors/synced/steer), [run](/reference/motors/motor/run)

BIN
docs/static/about/explorer-button.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

BIN
docs/static/about/explorer-view.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

BIN
docs/static/fll/code-js.gif vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 349 KiB

BIN
docs/static/fll/context-help.jpg vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

BIN
docs/static/fll/fll-big.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

BIN
docs/static/fll/fll-logo.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

BIN
docs/static/fll/import-button.jpg vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

BIN
docs/static/fll/save-project.jpg vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

BIN
docs/static/fll/share-button.jpg vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
docs/static/fll/share-program.gif vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 KiB

BIN
docs/static/fll/share-program.jpg vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

BIN
docs/static/fll/simulator.gif vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 294 KiB

1
docs/static/githubfilelogo.svg vendored Normal file
View 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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 110 KiB

BIN
docs/static/tutorials/coast-or-brake.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
docs/static/tutorials/pivot-turn.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
docs/static/tutorials/smooth-turn.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
docs/static/tutorials/spin-turn.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
docs/static/tutorials/tank-zigzag.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

View File

@ -2,125 +2,41 @@
Step by step guides to coding your @boardname@.
## Brick
## Tutorials
```codecard
[{
"name": "Wake Up!",
"description": "Show different moods on the screen. Is it tired, sleepy, or awake?",
"cardType": "tutorial",
"url":"/tutorials/wake-up",
"name": "Brick",
"description": "Learn how to use the screen and the buttons",
"url":"/tutorials/brick",
"imageUrl":"/static/tutorials/wake-up.png"
}, {
"name": "Make an Animation",
"description": "Create a custom animation on your EV3 Brick Display.",
"cardType": "tutorial",
"url":"/tutorials/make-an-animation",
"imageUrl":"/static/tutorials/make-an-animation.png"
}, {
"name": "What Animal Am I?",
"description": "Create different animal effects and have someone guess what the animal is.",
"cardType": "tutorial",
"url":"/tutorials/what-animal-am-i",
"imageUrl":"/static/tutorials/what-animal-am-i.png"
}, {
"name": "Music Brick",
"description": "Transform the brick into a musical instrument!",
"cardType": "tutorial",
"url":"/tutorials/music-brick",
"imageUrl":"/static/tutorials/music-brick.png"
}]
```
## Motors
```codecard
[{
"name": "Run Motors",
"description": "Use the EV3 Brick buttons to start and stop the Large Motor and Medium Motor.",
"cardType": "tutorial",
"url":"/tutorials/run-motors",
"name": "Motors",
"description": "User motors to move the brick.",
"url":"/tutorials/motors",
"imageUrl":"/static/tutorials/run-motors.png"
}]
```
## Touch Sensor
```codecard
[{
"name": "Touch to Run",
"description": "Press the Touch Sensor and run a motor.",
"cardType": "tutorial",
"url":"/tutorials/touch-to-run",
}, {
"name": "Touch Sensor",
"description": "Use touch sensors in your robot.",
"url":"/tutorials/touch-sensor",
"imageUrl":"/static/tutorials/touch-to-run.png"
}, {
"name": "Touch Sensor Values",
"description": "Check the value of a Touch Sensor and stop a motor if pressed.",
"cardType": "tutorial",
"url":"/tutorials/touch-sensor-values",
"imageUrl":"/static/tutorials/touch-sensor-values.png"
}]
```
## Color Sensor
```codecard
[{
"name": "What Color?",
"description": "Use the Color Sensor to detect different colors.",
"cardType": "tutorial",
"url":"/tutorials/what-color",
"name": "Color Sensor",
"description": "Use the color sensor to follow line or detect colors",
"url":"/tutorials/color-sensor",
"imageUrl":"/static/tutorials/what-color.png"
}, {
"name": "Line Following",
"description": "Use the Color Sensor to make a robot follow a line.",
"cardType": "tutorial",
"url":"/tutorials/line-following",
"imageUrl":"/static/tutorials/line-following.png"
}, {
"name": "Red Light, Green Light",
"description": "Play Red Light, Green Light using the Color Sensor and the robot.",
"cardType": "tutorial",
"url":"/tutorials/redlight-greenlight",
"imageUrl":"/static/tutorials/redlight-greenlight.png"
}]
```
## 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
```codecard
[{
"name": "Security Alert",
"description": "Build an security alert using the Infrared Sensor.",
"cardType": "tutorial",
"url":"/tutorials/security-alert",
"name": "Infrared Sensor",
"description": "Use the infrared sensor to detect objects",
"url":"/tutorials/infrared-sensor",
"imageUrl":"/static/tutorials/security-alert.png"
}]
```
## See Also
[Wake Up!](/tutorials/wake-up),
[Make An Animation](/tutorials/make-an-animation),
[What Animal Am I?](/tutorials/what-animal-am-i),
[Music Brick](/tutorials/music-brick),
[Run Motors](/tutorials/run-motors),
[Touch to Run](/tutorials/touch-to-run),
[Touch Sensor Values](/tutorials/touch-sensor-values),
[What Color?](/tutorials/what-color),
[Line Following](/tutorials/line-following),
[Red Light, Green Light](/tutorials/redlight-greenlight),
[Object Near?](/tutorials/object-near),
[Security Alert](/tutorials/security-alert)
[Brick tutorials](/tutorials/brick),
[Motors tutorials](/tutorials/motors),
[Touch sensor tutorials](/tutorials/touch-sensor),
[Color sensor tutorials](/tutorials/color-sensor),
[Infrared sensor tutorials](/tutorials/infrared-sensor)

38
docs/tutorials/brick.md Normal file
View File

@ -0,0 +1,38 @@
# Brick Tutorials
## Tutorials
```codecard
[{
"name": "Wake Up!",
"description": "Show different moods on the screen. Is it tired, sleepy, or awake?",
"cardType": "tutorial",
"url":"/tutorials/wake-up",
"imageUrl":"/static/tutorials/wake-up.png"
}, {
"name": "Make an Animation",
"description": "Create a custom animation on your EV3 Brick Display.",
"cardType": "tutorial",
"url":"/tutorials/make-an-animation",
"imageUrl":"/static/tutorials/make-an-animation.png"
}, {
"name": "What Animal Am I?",
"description": "Create different animal effects and have someone guess what the animal is.",
"cardType": "tutorial",
"url":"/tutorials/what-animal-am-i",
"imageUrl":"/static/tutorials/what-animal-am-i.png"
}, {
"name": "Music Brick",
"description": "Transform the brick into a musical instrument!",
"cardType": "tutorial",
"url":"/tutorials/music-brick",
"imageUrl":"/static/tutorials/music-brick.png"
}]
```
## See Also
[Wake Up!](/tutorials/wake-up),
[Make An Animation](/tutorials/make-an-animation),
[What Animal Am I?](/tutorials/what-animal-am-i),
[Music Brick](/tutorials/music-brick),

View File

@ -0,0 +1,16 @@
# Coast or Brake
This code example will set the brake when button **A** is pressed or let the motor coast (turn freely when not running) when button **B** is pressed. The motor is turned by one rotation to cause motion.
```blocks
brick.buttonLeft.onEvent(ButtonEvent.Pressed, function () {
// tell motor to brake once the run command is done
motors.largeB.setBrake(true)
motors.largeB.run(100, 1, MoveUnit.Rotations)
})
brick.buttonRight.onEvent(ButtonEvent.Pressed, function () {
// tell motor to coast once the run command is done
motors.largeB.setBrake(false)
motors.largeB.run(100, 1, MoveUnit.Rotations)
})
```

View File

@ -0,0 +1,43 @@
# Color Sensor
## Tutorials
```codecard
[{
"name": "What Color?",
"description": "Use the Color Sensor to detect different colors.",
"cardType": "tutorial",
"url":"/tutorials/what-color",
"imageUrl":"/static/tutorials/what-color.png"
}, {
"name": "Line Following",
"description": "Use the Color Sensor to make a robot follow a line.",
"cardType": "tutorial",
"url":"/tutorials/line-following",
"imageUrl":"/static/tutorials/line-following.png"
}, {
"name": "Red Light, Green Light",
"description": "Play Red Light, Green Light using the Color Sensor and the robot.",
"cardType": "tutorial",
"url":"/tutorials/redlight-greenlight",
"imageUrl":"/static/tutorials/redlight-greenlight.png"
}, {
"name": "Reflected Light Measure",
"description": "Teach the sensor what light or dark is.",
"cardType": "example",
"url":"/tutorials/reflected-light-measure",
"imageUrl":"/static/tutorials/reflected-light-measure.png"
}, {
"name": "Reflected Light Calibration",
"description": "Use the auto-calibration feature to setup the dark and bright values.",
"cardType": "example",
"url":"/tutorials/reflected-light-calibration",
"imageUrl":"/static/tutorials/reflected-light-calibration.png"
}]
```
## See Also
[What Color?](/tutorials/what-color),
[Line Following](/tutorials/line-following),
[Red Light, Green Light](/tutorials/redlight-greenlight),

View File

@ -0,0 +1,24 @@
# Infrared sensor
## Tutorials
```codecard
[{
"name": "Object Near",
"description": "Detect if objects are near.",
"cardType": "tutorial",
"url":"/tutorials/object-near",
"imageUrl":"/static/tutorials/object-near.png"
}, {
"name": "Security Alert",
"description": "Build an security alert using the Infrared Sensor.",
"cardType": "tutorial",
"url":"/tutorials/security-alert",
"imageUrl":"/static/tutorials/security-alert.png"
}]
```
## See Also
[Object Near?](/tutorials/object-near),
[Security Alert](/tutorials/security-alert)

52
docs/tutorials/motors.md Normal file
View File

@ -0,0 +1,52 @@
# Motors
## Tutorials
```codecard
[{
"name": "Run Motors",
"description": "Use the EV3 Brick buttons to start and stop the Large Motor and Medium Motor.",
"cardType": "tutorial",
"url":"/tutorials/run-motors",
"imageUrl":"/static/tutorials/run-motors.png"
}, {
"name": "Spin Turn",
"description": "Turn the driving base around its center.",
"cardType": "example",
"url":"/tutorials/spin-turn",
"imageUrl":"/static/tutorials/spin-turn.png"
}, {
"name": "Pivot Turn",
"description": "Turn the driving base around a wheel.",
"cardType": "example",
"url":"/tutorials/pivot-turn",
"imageUrl":"/static/tutorials/pivot-turn.png"
}, {
"name": "Smooth Turn",
"description": "Turn the driving base in a smooth, steering motion.",
"cardType": "example",
"url":"/tutorials/smooth-turn",
"imageUrl":"/static/tutorials/smooth-turn.png"
}, {
"name": "Tank ZigZag",
"description": "Use the tank block to keep motors in sync.",
"cardType": "example",
"url":"/tutorials/tank-zigzag",
"imageUrl":"/static/tutorials/tank-zigzag.png"
}, {
"name": "Coast Or Brake",
"description": "Tell motors to coast or brake once the run command is done.",
"cardType": "example",
"url":"/tutorials/coast-or-brake",
"imageUrl":"/static/tutorials/coast-or-brake.png"
}]
```
## See Also
[Run Motors](/tutorials/run-motors),
[Spin Turn](/tutorials/spin-turn),
[Pivot Turn](/tutorials/pivot-turn),
[Smooth Turn](/tutorials/smooth-turn),
[Tank ZigZag](/tutorials/tank-zigzag),
[Coast Or Brake](/tutorials/coast-or-brake)

View File

@ -17,10 +17,10 @@ brick.showString("Hello world", 1)
## 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
brick.showString("Press my buttons to make music!", 1)
brick.showString("Press my buttons!", 1)
```
## Step 3
@ -31,7 +31,7 @@ Open the ``||brick:Brick||`` Toolbox drawer. From the **Buttons** section, drag
brick.buttonEnter.onEvent(ButtonEvent.Pressed, function () {
})
brick.showString("Press my buttons to make music!", 1)
brick.showString("Press my buttons!", 1)
```
## Step 4
@ -40,13 +40,13 @@ Open the ``||music:Music||`` Toolbox drawer. Drag out **5** ``||music:play tone|
```blocks
brick.buttonEnter.onEvent(ButtonEvent.Pressed, function () {
music.playTone(0, music.beat(BeatFraction.Half))
music.playTone(0, music.beat(BeatFraction.Half))
music.playTone(0, music.beat(BeatFraction.Half))
music.playTone(0, music.beat(BeatFraction.Half))
music.playTone(0, music.beat(BeatFraction.Half))
music.playTone(262, music.beat(BeatFraction.Half))
music.playTone(262, music.beat(BeatFraction.Half))
music.playTone(262, music.beat(BeatFraction.Half))
music.playTone(262, 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
@ -63,7 +63,7 @@ brick.buttonEnter.onEvent(ButtonEvent.Pressed, function () {
music.playTone(196, music.beat(BeatFraction.Half))
music.playTone(294, music.beat(BeatFraction.Whole))
})
brick.showString("Press my buttons to make music!", 1)
brick.showString("Press my buttons!", 1)
```
## Step 6

View File

@ -0,0 +1,9 @@
# Pause Until Pressed
This is a code example to detect contact or collision with another object. It uses a touch sensor to detect hitting a wall or other obstacle. The motors are run and then stopped when the sensor is pressed.
```blocks
motors.largeBC.tank(50, 50)
sensors.touch1.pauseUntil(ButtonEvent.Pressed)
motors.largeBC.stop()
```

View File

@ -0,0 +1,12 @@
# Pivot Turn
A **pivot turn** happens when a [EV3 Driving Base](https://le-www-live-s.legocdn.com/sc/media/lessons/mindstorms-ev3/building-instructions/ev3-rem-driving-base-79bebfc16bd491186ea9c9069842155e.pdf) turns around the wheel on the inside of the turn by spinning just the single wheel at the outside of the turn.
You can make a turn happen with either a ``||motors:tank||`` or a ``||motors:steer||`` block.
```blocks
forever(function() {
motors.largeBC.tank(50, 0, 2, MoveUnit.Rotations)
motors.largeBC.tank(0, 50, 2, MoveUnit.Rotations)
})
```

View File

@ -0,0 +1,24 @@
# Reflected light calibration
The ``||sensors:calibrateLight||`` blocks allows you to calibrate the reflected light of the color sensor in one block. At the time you run the block, move the sensor over a dark surface and a bright surface; then stop moving it.
```blocks
sensors.color3.onLightDetected(LightIntensityMode.Reflected, Light.Dark, function () {
brick.showString("dark", 2)
})
sensors.color3.onLightDetected(LightIntensityMode.Reflected, Light.Bright, function () {
brick.showString("bright", 2)
})
console.sendToScreen()
console.log("move color sensor")
console.log("over DARK and BRIGHT color")
console.log("and stop moving when done")
console.log("press ENTER when ready")
brick.buttonEnter.pauseUntil(ButtonEvent.Pressed)
sensors.color3.calibrateLight(LightIntensityMode.Reflected)
brick.showValue("dark", sensors.color3.threshold(Light.Dark), 4)
brick.showValue("bright", sensors.color3.threshold(Light.Bright), 5)
forever(function () {
brick.showValue("reflected light", sensors.color3.light(LightIntensityMode.Reflected), 1)
})
```

View File

@ -0,0 +1,29 @@
# Reflected light measure
This example uses a color sensor to measure the reflected light from a dark and light surface
and sets the light/dark thresholds.
```blocks
sensors.color3.onLightDetected(LightIntensityMode.Reflected, Light.Dark, function () {
brick.showString("dark", 2)
})
sensors.color3.onLightDetected(LightIntensityMode.Reflected, Light.Bright, function () {
brick.showString("bright", 2)
})
console.sendToScreen()
console.log("move color sensor")
console.log("over DARK color")
console.log("press ENTER when ready")
brick.buttonEnter.pauseUntil(ButtonEvent.Pressed)
sensors.color3.setThreshold(Light.Dark, sensors.color3.light(LightIntensityMode.Reflected) + 5)
console.logValue("dark", sensors.color3.threshold(Light.Dark))
console.log("move color sensor")
console.log("over BRIGHT color")
console.log("press ENTER when ready")
brick.buttonEnter.pauseUntil(ButtonEvent.Pressed)
sensors.color3.setThreshold(Light.Bright, sensors.color3.light(LightIntensityMode.Reflected) - 5)
console.logValue("bright", sensors.color3.threshold(Light.Bright))
forever(function () {
brick.showValue("reflected light", sensors.color3.light(LightIntensityMode.Reflected), 1)
})
```

View File

@ -66,7 +66,7 @@ brick.buttonDown.onEvent(ButtonEvent.Pressed, function () {
## Step 5
Now, lets 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
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``.
| | | |
|-|-|-|
| ![Select a motor type dropdown](/static/tutorials/run-motors/run-motor-dropdown.png) | | | ![Select a motor port dropdown](/static/tutorials/run-motors/motor-port-dropdown.png) |
![Select a motor type dropdown](/static/tutorials/run-motors/run-motor-dropdown.png)
<br/>
![Select a motor port dropdown](/static/tutorials/run-motors/motor-port-dropdown.png)
```blocks
brick.buttonUp.onEvent(ButtonEvent.Pressed, function () {

View File

@ -0,0 +1,12 @@
# Smooth Turn
A **smooth turn** happens when a [EV3 Driving Base](https://le-www-live-s.legocdn.com/sc/media/lessons/mindstorms-ev3/building-instructions/ev3-rem-driving-base-79bebfc16bd491186ea9c9069842155e.pdf) makes a turn by spinning both both wheels but with each running at a different speed.
You can make a turn happen with either a ``||motors:tank||`` or a ``||motors:steer||`` block.
```blocks
forever(function() {
motors.largeBC.tank(50, 20, 2, MoveUnit.Rotations)
motors.largeBC.tank(20, 50, 2, MoveUnit.Rotations)
})
```

View File

@ -0,0 +1,12 @@
# Spin Turn
A **spin turn** happens when a [EV3 Driving Base](https://le-www-live-s.legocdn.com/sc/media/lessons/mindstorms-ev3/building-instructions/ev3-rem-driving-base-79bebfc16bd491186ea9c9069842155e.pdf) turns, or rotates, on a single spot by spinning both wheels, but with each turning in opposite directions.
You can make a turn happen with either a ``||motors:tank||`` or a ``||motors:steer||`` block.
```blocks
forever(function() {
motors.largeBC.tank(50, -50, 2, MoveUnit.Rotations)
motors.largeBC.tank(-50, 50, 2, MoveUnit.Rotations)
})
```

View File

@ -0,0 +1,17 @@
# Tank ZigZag
This example shows how to use the [tank](/reference/motors/tank) block to keep the speed of 2 large motors synchronized. The [EV3 Driving Base](https://le-www-live-s.legocdn.com/sc/media/lessons/mindstorms-ev3/building-instructions/ev3-rem-driving-base-79bebfc16bd491186ea9c9069842155e.pdf)
) will move in a zig zag pattern.
```blocks
/**
* Use the tank block to keep large motors synched.
Use this code with a EV3 driving base.
*/
forever(function () {
brick.showImage(images.eyesMiddleRight)
motors.largeBC.tank(50, 10, 2, MoveUnit.Rotations)
brick.showImage(images.eyesMiddleLeft)
motors.largeBC.tank(10, 50, 2, MoveUnit.Rotations)
})
```

View File

@ -0,0 +1,31 @@
# Touch Sensor
## Tutorials
```codecard
[{
"name": "Touch to Run",
"description": "Press the Touch Sensor and run a motor.",
"cardType": "tutorial",
"url":"/tutorials/touch-to-run",
"imageUrl":"/static/tutorials/touch-to-run.png"
}, {
"name": "Sensor Values",
"description": "Check the value of a Touch Sensor and stop a motor if pressed.",
"cardType": "tutorial",
"url":"/tutorials/touch-sensor-values",
"imageUrl":"/static/tutorials/touch-sensor-values.png"
}, {
"name": "Pause Until Pressed",
"description": "Waits for the sensor to be pressed before continuing the program",
"cardType": "tutorial",
"url":"/tutorials/pause-until-pressed",
"imageUrl":"/static/tutorials/pause-until-pressed.png"
}]
```
## See Also
[Touch to Run](/tutorials/touch-to-run),
[Touch Sensor Values](/tutorials/touch-sensor-values),
[Pause Until Pressed](/tutorials/pause-until-pressed)

View File

@ -16,7 +16,7 @@ brick.showString("Hello world", 1)
## 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
brick.showString("Guess the animal", 1)

33
docs/videos.md Normal file
View 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"
}
]
```

View File

@ -60,10 +60,12 @@ const rbfTemplate = `
4c45474f580000006d000100000000001c000000000000000e000000821b038405018130813e8053
74617274696e672e2e2e0084006080XX00448581644886488405018130813e80427965210084000a
`
export function deployCoreAsync(resp: pxtc.CompileResult, isCli = false) {
export function deployCoreAsync(resp: pxtc.CompileResult) {
let w: pxt.editor.Ev3Wrapper
let filename = resp.downloadFileBaseName || "pxt"
const origElfUF2 = UF2.parseFile(pxt.U.stringToUint8Array(ts.pxtc.decodeBase64(resp.outfiles[pxt.outputName()])))
let filename = resp.downloadFileBaseName || (origElfUF2[0].filename || "").replace(/^Projects\//, "").replace(/\.elf$/, "") || "pxt"
filename = filename.replace(/^lego-/, "")
let fspath = "../prjs/BrkProg_SAVE/"
@ -77,8 +79,6 @@ export function deployCoreAsync(resp: pxtc.CompileResult, isCli = false) {
let rbfBIN = pxt.U.fromHex(rbfHex)
pxt.HF2.write16(rbfBIN, 4, rbfBIN.length)
let origElfUF2 = UF2.parseFile(pxt.U.stringToUint8Array(ts.pxtc.decodeBase64(resp.outfiles[pxt.outputName()])))
let mkFile = (ext: string, data: Uint8Array = null) => {
let f = UF2.newBlockFile()
f.filename = "Projects/" + filename + ext
@ -98,11 +98,13 @@ export function deployCoreAsync(resp: pxtc.CompileResult, isCli = false) {
resp.outfiles[pxtc.BINARY_UF2] = btoa(data)
let saveUF2Async = () => {
if (isCli || !pxt.commands.saveOnlyAsync) {
return Promise.resolve()
} else {
return pxt.commands.saveOnlyAsync(resp)
if (pxt.commands && pxt.commands.electronDeployAsync) {
return pxt.commands.electronDeployAsync(resp);
}
if (pxt.commands && pxt.commands.saveOnlyAsync) {
return pxt.commands.saveOnlyAsync(resp);
}
return Promise.resolve();
}
if (noHID) return saveUF2Async()
@ -119,10 +121,7 @@ export function deployCoreAsync(resp: pxtc.CompileResult, isCli = false) {
.then(() => w.flashAsync(rbfPath, rbfBIN))
.then(() => w.runAsync(rbfPath))
.then(() => {
if (isCli)
return w.disconnectAsync()
else
return Promise.resolve()
return w.disconnectAsync()
//return Promise.delay(1000).then(() => w.dmesgAsync())
}).catch(e => {
// if we failed to initalize, retry

View File

@ -28,9 +28,9 @@ pxt.editor.initExtensionsAsync = function (opts: pxt.editor.ExtensionOptions): P
<div class="ui grid stackable">
<div class="column five wide" style="background-color: #E2E2E2;">
<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;">
<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>
<a href="/troubleshoot" target="_blank">${lf("Check your firmware version here and update if needed")}</a>
</div>
@ -42,7 +42,7 @@ pxt.editor.initExtensionsAsync = function (opts: pxt.editor.ExtensionOptions): P
<div class="column">
<div class="ui">
<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 class="content">
<div class="description">
@ -57,7 +57,7 @@ pxt.editor.initExtensionsAsync = function (opts: pxt.editor.ExtensionOptions): P
<div class="column">
<div class="ui">
<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 class="content">
<div class="description">

13
ev3.code-workspace Normal file
View File

@ -0,0 +1,13 @@
{
"folders": [
{
"path": "."
},
{
"path": "../pxt-common-packages"
},
{
"path": "../pxt"
}
]
}

View File

@ -133,14 +133,27 @@ export class FieldMotors extends Blockly.FieldDropdown implements Blockly.FieldC
this.setText(text);
}
getFirstValue(text: string) {
// Get first set of words up until last space
return this.normalizeText_(text.substring(0, text.lastIndexOf(' ')));
getFirstValue(value: string) {
const typeValue = value.indexOf('large') != -1 ? 'large' : 'medium';
const portValue = this.getSecondValue(value);
const isDual = portValue.length > 1;
return `${typeValue} motor${isDual ? 's' : ''}`;
}
getSecondValue(text: string) {
// Get last word
return this.normalizeText_(text.match(/\S*$/)[0]);
getSecondValue(value: string) {
return (value.indexOf('large') != -1) ?
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) {
@ -198,8 +211,8 @@ export class FieldMotors extends Blockly.FieldDropdown implements Blockly.FieldC
if (text === null) {
return text;
}
if (text.indexOf(' ') == -1) {
text = `large motors ${text}`;
if (text.indexOf('|') == -1) {
text = this.sourceBlock_.RTL ? `${text}|${lf("large motors")}` : `${lf("large motors")}|${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.textElement2_));
var text = this.text_;
text = this.patchDualMotorText(text);
// 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);
// Second dropdown
// Second dropdown, no need to translate. Only port numbers
if (this.textElement2_) {
const textNode2 = document.createTextNode(this.getSecondValue(text));
const textNode2 = document.createTextNode(this.getSecondValue(this.value_));
this.textElement2_.appendChild(textNode2);
}
this.updateWidth();
@ -402,29 +413,28 @@ export class FieldMotors extends Blockly.FieldDropdown implements Blockly.FieldC
contentDiv.setAttribute('aria-haspopup', 'true');
let options = this.getOptions();
// Hashmap of options
let opts = {};
let conts = {};
let vals = {};
// Go through all option values and split them into groups
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 firstValue = this.getFirstValue(text);
const secondValue = this.getSecondValue(text);
if (!opts[firstValue]) opts[firstValue] = [secondValue];
else opts[firstValue].push(secondValue);
// Store a hash of the original key value pairs for later
const motorValue = value.substring(value.indexOf('.') + 1);
const typeValue = motorValue.indexOf('large') == 0 ? 'large' : 'medium';
const portValue = motorValue.indexOf('large') == 0 ? motorValue.substring(5) : motorValue.substring(6);
const isDual = portValue.length > 1;
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];
vals[text] = value;
}
const currentFirst = this.getFirstValue(this.text_);
const currentSecond = this.getSecondValue(this.text_);
const currentFirst = this.getFirstValue(this.value_);
const currentSecond = this.getSecondValue(this.value_);
if (!this.isFirst_) {
options = opts[currentFirst];
@ -432,9 +442,7 @@ export class FieldMotors extends Blockly.FieldDropdown implements Blockly.FieldC
options = Object.keys(opts);
// Flip the first and second options to make it sorted the way we want it (medium, large, dual)
if (options.length == 3) {
const temp = options[1];
options[1] = options[0];
options[0] = temp;
options = [lf("medium motor"), lf("large motor"), lf("large motors")];
} else {
options.reverse();
}
@ -448,7 +456,7 @@ export class FieldMotors extends Blockly.FieldDropdown implements Blockly.FieldC
const columns = options.length;
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, ' ');
const content: any = conts[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('role', 'menuitem');
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.height = ((this.itemWidth_) - 8) + 'px';
let backgroundColor = this.backgroundColour_;
@ -495,7 +503,15 @@ export class FieldMotors extends Blockly.FieldDropdown implements Blockly.FieldC
contentDiv.removeAttribute('aria-activedescendant');
});
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;
// 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.

View File

@ -20,7 +20,7 @@ export class FieldMusic extends pxtblockly.FieldImages implements Blockly.FieldC
private categoriesCache_: string[];
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.width_ = parseInt(options.width) || 380;

View File

@ -11,7 +11,7 @@ export class FieldPorts extends pxtblockly.FieldImages implements Blockly.FieldC
public isFieldCustom_ = true;
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.width_ = parseInt(options.width) || 300;

View File

@ -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()
}
}
}

View File

@ -1,41 +0,0 @@
import jobs.generation.Utilities;
import jobs.generation.InternalUtilities;
def project = GithubProject
def projectName = "pxt-ev3"
[true, false].each { isPR ->
def newJobName = projectName
if (isPR) {
newJobName += "_PR"
} else {
newJobName += "_Push"
}
def newJob = job(newJobName) {
steps {
shell("chmod +x ./jenkins.sh")
shell("./jenkins.sh ${isPR}")
}
if (!isPR) {
wrappers {
credentialsBinding {
string("PXT_ACCESS_TOKEN", "pxt_access_token")
string("PXT_RELEASE_REPO", "pxt_release_repo_ev3")
string("CROWDIN_KEY", "pxt_crowdin_key")
}
}
}
}
Utilities.setMachineAffinity(newJob, "Ubuntu", "20161020")
InternalUtilities.standardJobSetup(newJob, project, isPR, "*/*")
if (isPR) {
Utilities.addGithubPRTrigger(newJob, "Default Testing")
} else {
Utilities.addGithubPushTrigger(newJob)
}
}

View File

@ -1,56 +0,0 @@
#!/usr/bin/env bash
# Set up NVM
export NVM_DIR="/home/dotnet-bot/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
nvm install 8
# Set up build environment variables
echo ---------- Setting build environment variables
echo Git branch: $GIT_BRANCH
echo isPR: $1
originRegex="^origin/.*"
branchRegex="^origin/\K.*(?=$)"
releaseBranchRegex="^(master|v\d+)$"
if [[ "$GIT_BRANCH" =~ $originRegex ]]; then
branchName=$(echo ${GIT_BRANCH} | grep -oP $branchRegex)
echo Setting TRAVIS_BRANCH to ${branchName}
export TRAVIS_BRANCH=${branchName}
else
echo Setting TRAVIS_BRANCH to $GIT_BRANCH
export TRAVIS_BRANCH=$GIT_BRANCH
fi
if [ "$1" == "false" ]; then
echo Setting TRAVIS_PULL_REQUEST to false
export TRAVIS_PULL_REQUEST=false
if [[ "$TRAVIS_BRANCH" =~ $releaseBranchRegex ]]; then
if [[ -z $PXT_RELEASE_REPO ]]; then
echo Cannot find release repo\; skipping tag checks
else
gitTag=$(git describe --tags --exact-match 2> /dev/null)
builtTag=$(git ls-remote --tags $PXT_RELEASE_REPO | grep -o "refs/tags/$gitTag$")
echo Current tag: $gitTag
echo Built tag: $builtTag
if [[ ! -z $gitTag && -z $builtTag ]]; then
echo Built tag not found\; building tag
echo Setting TRAVIS_BRANCH to $gitTag
export TRAVIS_BRANCH=$gitTag
echo Setting TRAVIS_TAG to $gitTag
export TRAVIS_TAG=$gitTag
else
echo Not a tag build
fi
fi
fi
fi
# Perform build
npm install
npm test

View File

@ -1,30 +1,3 @@
{
"name": "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": {}
"additionalFilePath": "../../node_modules/pxt-common-packages/libs/base"
}

17
libs/base/shims.d.ts vendored
View File

@ -142,23 +142,12 @@ declare namespace control {
//% blockId="control_device_serial_number" block="device serial number" weight=9
//% help=control/device-serial-number shim=control::deviceSerialNumber
function deviceSerialNumber(): int32;
}
declare namespace serial {
/**
* Write some text to the serial port.
*
*/
//% help=serial/write-string
//% weight=87 blockHidden=true
//% 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;
//% shim=control::__log
function __log(text: string): void;
}
// Auto-generated. Do not edit. Really.

View File

@ -1,5 +1,5 @@
const enum ColorSensorMode {
None = -1,
None = 0,
//% block="reflected light intensity"
ReflectedLightIntensity = 0,
//% block="ambient light intensity"
@ -15,7 +15,9 @@ enum LightIntensityMode {
//% block="reflected light"
Reflected = ColorSensorMode.ReflectedLightIntensity,
//% block="ambient light"
Ambient = ColorSensorMode.AmbientLightIntensity
Ambient = ColorSensorMode.AmbientLightIntensity,
//% block="reflected light (raw)"
ReflectedRaw = ColorSensorMode.RefRaw
}
const enum ColorSensorColor {
@ -93,6 +95,8 @@ namespace sensors {
|| this.mode == ColorSensorMode.AmbientLightIntensity
|| this.mode == ColorSensorMode.ReflectedLightIntensity)
return this.getNumber(NumberFormat.UInt8LE, 0)
if (this.mode == ColorSensorMode.RefRaw || this.mode == ColorSensorMode.RgbRaw)
return this.getNumber(NumberFormat.UInt16LE, 0)
return 0
}
@ -114,7 +118,7 @@ namespace sensors {
_update(prev: number, curr: number) {
if (this.calibrating) return; // simply ignore data updates while calibrating
if (this.mode == ColorSensorMode.Color)
if (this.mode == ColorSensorMode.Color || this.mode == ColorSensorMode.RgbRaw || this.mode == ColorSensorMode.RefRaw)
control.raiseEvent(this._id, this._colorEventValue(curr));
else
this.thresholdDetector.setLevel(curr);
@ -179,6 +183,23 @@ namespace sensors {
return this.getNumber(NumberFormat.UInt8LE, 0)
}
/**
* Get the current raw rgb values as an array from the color sensor.
* @param sensor the color sensor to query the request
*/
//% help=sensors/color-sensor/rgbraw
//% blockId=colorRgbRaw block="**color sensor** %this| RGB raw"
//% parts="colorsensor"
//% blockNamespace=sensors
//% this.fieldEditor="ports"
//% weight=1
//% group="Color Sensor"
//% blockGap=8
rgbRaw(): number[] {
this.setMode(ColorSensorMode.RgbRaw);
return [this.getNumber(NumberFormat.UInt16LE, 0), this.getNumber(NumberFormat.UInt16LE, 2), this.getNumber(NumberFormat.UInt16LE, 4)];
}
/**
* Registers code to run when the ambient light changes.
* @param condition the light condition
@ -225,11 +246,16 @@ namespace sensors {
//% parts="colorsensor"
//% blockNamespace=sensors
//% this.fieldEditor="ports"
//% weight=87
//% weight=87 blockGap=8
//% group="Color Sensor"
light(mode: LightIntensityMode) {
this.setMode(<ColorSensorMode><number>mode)
return this.getNumber(NumberFormat.UInt8LE, 0)
switch(mode) {
case LightIntensityMode.ReflectedRaw:
return this.reflectedLightRaw();
default:
return this.getNumber(NumberFormat.UInt8LE, 0)
}
}
/**
@ -248,6 +274,15 @@ namespace sensors {
return this.light(LightIntensityMode.Reflected);
}
/**
* Gets the raw reflection light value
*/
//%
reflectedLightRaw(): number {
this.setMode(ColorSensorMode.RefRaw);
return this.getNumber(NumberFormat.UInt16LE, 0);
}
/**
* Set a threshold value
* @param condition the dark or bright light condition
@ -297,9 +332,22 @@ namespace sensors {
calibrateLight(mode: LightIntensityMode, deviation: number = 8) {
this.calibrating = true; // prevent events
this.light(mode); // trigger a read
pauseUntil(() => this.isActive()); // ensure sensor is live
const statusLight = brick.statusLight(); // save current status light
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 vcount = 0;
@ -331,6 +379,10 @@ namespace sensors {
this.thresholdDetector.setLowThreshold(min);
this.thresholdDetector.setHighThreshold(max);
brick.setStatusLight(StatusLight.Green); // success
pause(1000);
brick.setStatusLight(statusLight); // resture previous light
this.calibrating = false;
}

View File

@ -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.
* **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
Calibrate the ``dark`` and ``light`` thresholds for the ``color 2`` sensor using reflected light.
@ -23,4 +32,4 @@ sensors.color2.calibrateLight(LightIntensityMode.Reflected)
## See also
[set threshold](/reference/sensors/color-sensor/set-threshold)
[set threshold](/reference/sensors/color-sensor/set-threshold)

View File

@ -159,12 +159,6 @@ namespace brick {
if (sl[i])
ret |= 1 << i
}
// this needs to be done in query(), which is run without the main JS execution mutex
// otherwise, while(true){} will lock the device
if (ret & DAL.BUTTON_ID_ESCAPE) {
motors.stopAll(); // ensuring that all motors are off
control.reset()
}
return ret
}
@ -247,6 +241,15 @@ namespace brick {
// the brick starts with the red color
let currPattern: StatusLight = StatusLight.Off;
/**
* Gets the current light pattern.
*/
//% weight=99 group="Buttons"
//% help=brick/status-light
export function statusLight() {
return currPattern;
}
/**
* Set lights.
* @param pattern the lights pattern to use. eg: StatusLight.Orange

View File

@ -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);
}
}

View File

@ -25,8 +25,17 @@ namespace sensors.internal {
})
}
export function bufferToString(buf: Buffer): string {
let s = ''
for (let i = 0; i < buf.length; i++)
s += String.fromCharCode(buf[i])
return s
}
let analogMM: MMap
let uartMM: MMap
let IICMM: MMap
let devcon: Buffer
let sensorInfos: SensorInfo[]
@ -36,11 +45,13 @@ namespace sensors.internal {
sensors: Sensor[]
connType: number
devType: number
iicid: string
constructor(p: number) {
this.port = p
this.connType = DAL.CONN_NONE
this.devType = DAL.DEVICE_TYPE_NONE
this.iicid = ''
this.sensors = []
}
}
@ -57,20 +68,21 @@ namespace sensors.internal {
uartMM = control.mmap("/dev/lms_uart", UartOff.Size, 0)
if (!uartMM) control.fail("no uart sensor")
forever(() => {
detectDevices()
pause(500)
})
IICMM = control.mmap("/dev/lms_iic", IICOff.Size, 0)
if (!IICMM) control.fail("no iic sensor")
for (let info_ of sensorInfos) {
let info = info_
unsafePollForChanges(500,
() => { return hashDevices(); },
(prev, curr) => { detectDevices();
});
sensorInfos.forEach(info => {
unsafePollForChanges(50, () => {
if (info.sensor) return info.sensor._query()
return 0
}, (prev, curr) => {
if (info.sensor) info.sensor._update(prev, curr)
})
}
})
}
@ -89,6 +101,15 @@ namespace sensors.internal {
//serial.writeLine("UART " + port + " / " + mode + " - " + info)
}
export function readIICID(port: number) {
const buf = output.createBuffer(IICStr.Size)
buf[IICStr.Port] = port
IICMM.ioctl(IO.IIC_READ_TYPE_INFO, buf)
const manufacturer = bufferToString(buf.slice(IICStr.Manufacturer, 8))
const sensorType = bufferToString(buf.slice(IICStr.SensorType, 8))
return manufacturer + sensorType;
}
export function getBatteryInfo(): { temp: number; current: number } {
init();
return {
@ -97,52 +118,87 @@ namespace sensors.internal {
}
}
function detectDevices() {
let conns = analogMM.slice(AnalogOff.InConn, DAL.NUM_INPUTS)
let numChanged = 0
function hashDevices(): number {
const conns = analogMM.slice(AnalogOff.InConn, DAL.NUM_INPUTS)
let r = 0;
for(let i = 0; i < conns.length; ++i) {
r = (r << 8 | conns[i]);
}
return r;
}
for (let info of sensorInfos) {
let newConn = conns[info.port]
if (newConn == info.connType)
continue
let nonActivated = 0;
function detectDevices() {
//control.dmesg(`detect devices (${nonActivated} na)`)
const conns = analogMM.slice(AnalogOff.InConn, DAL.NUM_INPUTS)
let numChanged = 0;
const uartSensors: SensorInfo[] = [];
for (const sensorInfo of sensorInfos) {
const newConn = conns[sensorInfo.port]
if (newConn == sensorInfo.connType) {
// control.dmesg(`connection unchanged ${newConn} at ${sensorInfo.port}`)
continue;
}
numChanged++
info.connType = newConn
info.devType = DAL.DEVICE_TYPE_NONE
sensorInfo.connType = newConn
sensorInfo.devType = DAL.DEVICE_TYPE_NONE
if (newConn == DAL.CONN_INPUT_UART) {
control.dmesg(`new UART connection at ${info.port}`)
setUartMode(info.port, 0)
let uinfo = readUartInfo(info.port, 0)
info.devType = uinfo[TypesOff.Type]
control.dmesg(`UART type ${info.devType}`)
control.dmesg(`new UART connection at ${sensorInfo.port}`)
updateUartMode(sensorInfo.port, 0);
uartSensors.push(sensorInfo);
} else if (newConn == DAL.CONN_NXT_IIC) {
control.dmesg(`new IIC connection at ${sensorInfo.port}`)
sensorInfo.devType = DAL.DEVICE_TYPE_IIC_UNKNOWN
sensorInfo.iicid = readIICID(sensorInfo.port)
control.dmesg(`IIC ID ${sensorInfo.iicid.length}`)
} else if (newConn == DAL.CONN_INPUT_DUMB) {
control.dmesg(`new DUMB connection at ${info.port}`)
control.dmesg(`new DUMB connection at ${sensorInfo.port}`)
// TODO? for now assume touch
info.devType = DAL.DEVICE_TYPE_TOUCH
sensorInfo.devType = DAL.DEVICE_TYPE_TOUCH
} else if (newConn == DAL.CONN_NONE || newConn == 0) {
control.dmesg(`disconnect at ${info.port}`)
control.dmesg(`disconnect at port ${sensorInfo.port}`)
} else {
control.dmesg(`unknown connection type: ${newConn} at ${info.port}`)
control.dmesg(`unknown connection type: ${newConn} at ${sensorInfo.port}`)
}
}
if (numChanged == 0)
if (uartSensors.length > 0) {
setUartModes();
for (const sensorInfo of uartSensors) {
let uinfo = readUartInfo(sensorInfo.port, 0)
sensorInfo.devType = uinfo[TypesOff.Type]
control.dmesg(`UART type ${sensorInfo.devType}`)
}
}
if (numChanged == 0 && nonActivated == 0)
return
for (let si of sensorInfos) {
if (si.sensor && si.sensor._deviceType() != si.devType) {
si.sensor = null
}
if (si.devType != DAL.DEVICE_TYPE_NONE) {
// TODO figure out compiler problem when '|| null' is added here!
si.sensor = si.sensors.filter(s => s._deviceType() == si.devType)[0]
if (si.sensor == null) {
control.dmesg(`sensor not found for type=${si.devType} at ${si.port}`)
control.dmesg(`updating sensor status`)
nonActivated = 0;
for (const sensorInfo of sensorInfos) {
if (sensorInfo.devType == DAL.DEVICE_TYPE_IIC_UNKNOWN) {
sensorInfo.sensor = sensorInfo.sensors.filter(s => s._IICId() == sensorInfo.iicid)[0]
if (!sensorInfo.sensor) {
control.dmesg(`sensor not found for iicid=${sensorInfo.iicid} at ${sensorInfo.port}`)
nonActivated++;
} else {
control.dmesg(`sensor connected type=${si.devType} at ${si.port}`)
si.sensor._activated()
control.dmesg(`sensor connected iicid=${sensorInfo.iicid} at ${sensorInfo.port}`)
sensorInfo.sensor._activated()
}
} else if (sensorInfo.devType != DAL.DEVICE_TYPE_NONE) {
sensorInfo.sensor = sensorInfo.sensors.filter(s => s._deviceType() == sensorInfo.devType)[0]
if (!sensorInfo.sensor) {
control.dmesg(`sensor not found for type=${sensorInfo.devType} at ${sensorInfo.port}`)
nonActivated++;
} else {
control.dmesg(`sensor connected type=${sensorInfo.devType} at ${sensorInfo.port}`)
sensorInfo.sensor._activated()
}
}
}
//control.dmesg(`detect devices done`)
}
export class Sensor extends control.Component {
@ -187,6 +243,10 @@ namespace sensors.internal {
_deviceType() {
return 0
}
_IICId() {
return ''
}
}
export class AnalogSensor extends Sensor {
@ -207,12 +267,11 @@ namespace sensors.internal {
constructor(port: number) {
super(port)
this.mode = 0
this.realmode = -1
this.realmode = 0
}
_activated() {
this.realmode = 0
// uartReset(this.port) // TODO is it ever needed?
this._setMode(this.mode)
}
@ -243,6 +302,55 @@ namespace sensors.internal {
}
}
export class IICSensor extends Sensor {
protected mode: number // the mode user asked for
protected realmode: number // the mode the hardware is in
private readLength: number
constructor(port: number) {
super(port)
this.mode = 0
this.realmode = 0
this.readLength = 1;
}
_activated() {
this.realmode = 0
this._setMode(this.mode)
}
protected _setMode(m: number) {
let v = m | 0
this.mode = v
if (!this.isActive()) return
if (this.realmode != this.mode) {
this.realmode = v
setIICMode(this._port, this._deviceType(), v)
}
}
getBytes(): Buffer {
return getIICBytes(this.isActive() ? this._port : -1, this.readLength)
}
getNumber(fmt: NumberFormat, off: number) {
if (!this.isActive())
return 0
return getIICNumber(this.readLength, fmt, off, this._port)
}
transaction(deviceAddress: number, write: number[], read: number) {
this.readLength = read;
transactionIIC(this._port, deviceAddress, write, read)
}
_deviceType() {
return DAL.DEVICE_TYPE_IIC_UNKNOWN
}
}
export const iicsensor = new IICSensor(3)
function uartReset(port: number) {
if (port < 0) return
control.dmesg(`UART reset at ${port}`)
@ -267,6 +375,7 @@ namespace sensors.internal {
}
function uartClearChange(port: number) {
control.dmesg(`UART clear change`);
const UART_DATA_READY = 8
const UART_PORT_CHANGED = 1
while (true) {
@ -288,20 +397,43 @@ namespace sensors.internal {
}
}
function setUartModes() {
control.dmesg(`UART set modes`)
uartMM.ioctl(IO.UART_SET_CONN, devcon)
const ports: number[] = [];
for (let port = 0; port < DAL.NUM_INPUTS; ++port) {
if (devcon.getNumber(NumberFormat.Int8LE, DevConOff.Connection + port) == DAL.CONN_INPUT_UART) {
ports.push(port);
}
}
while (ports.length) {
const port = ports.pop();
const status = waitNonZeroUartStatus(port)
control.dmesg(`UART set mode ${status} at ${port}`);
}
}
function updateUartMode(port: number, mode: number) {
control.dmesg(`UART set mode to ${mode} at ${port}`)
devcon.setNumber(NumberFormat.Int8LE, DevConOff.Connection + port, DAL.CONN_INPUT_UART)
devcon.setNumber(NumberFormat.Int8LE, DevConOff.Type + port, 33)
devcon.setNumber(NumberFormat.Int8LE, DevConOff.Mode + port, mode)
}
function setUartMode(port: number, mode: number) {
const UART_PORT_CHANGED = 1
while (true) {
if (port < 0) return
control.dmesg(`UART set mode to ${mode} at ${port}`)
devcon.setNumber(NumberFormat.Int8LE, DevConOff.Connection + port, DAL.CONN_INPUT_UART)
devcon.setNumber(NumberFormat.Int8LE, DevConOff.Type + port, 33)
devcon.setNumber(NumberFormat.Int8LE, DevConOff.Mode + port, mode)
updateUartMode(port, mode);
uartMM.ioctl(IO.UART_SET_CONN, devcon)
let status = waitNonZeroUartStatus(port)
if (status & UART_PORT_CHANGED) {
control.dmesg(`UART clear changed at ${port}`)
uartClearChange(port)
} else {
break
control.dmesg(`UART status ${status}`);
break;
}
pause(10)
}
@ -322,6 +454,48 @@ namespace sensors.internal {
UartOff.Raw + DAL.MAX_DEVICE_DATALENGTH * 300 * port + DAL.MAX_DEVICE_DATALENGTH * index + off)
}
export function setIICMode(port: number, type: number, mode: number) {
if (port < 0) return;
devcon.setNumber(NumberFormat.Int8LE, DevConOff.Connection + port, DAL.CONN_NXT_IIC)
devcon.setNumber(NumberFormat.Int8LE, DevConOff.Type + port, type)
devcon.setNumber(NumberFormat.Int8LE, DevConOff.Mode + port, mode)
IICMM.ioctl(IO.IIC_SET_CONN, devcon)
}
export function transactionIIC(port: number, deviceAddress: number, writeBuf: number[], readLen: number) {
if (port < 0) return;
let iicdata = output.createBuffer(IICDat.Size)
iicdata.setNumber(NumberFormat.Int8LE, IICDat.Port, port)
iicdata.setNumber(NumberFormat.Int8LE, IICDat.Repeat, 0)
iicdata.setNumber(NumberFormat.Int16LE, IICDat.Time, 0)
iicdata.setNumber(NumberFormat.Int8LE, IICDat.WrLng, writeBuf.length + 1)
for (let i = 0; i < writeBuf.length; i++)
iicdata.setNumber(NumberFormat.Int8LE, IICDat.WrData + i + 1, writeBuf[i])
iicdata.setNumber(NumberFormat.Int8LE, IICDat.WrData, deviceAddress)
iicdata.setNumber(NumberFormat.Int8LE, IICDat.RdLng, readLen)
IICMM.ioctl(IO.IIC_SETUP, iicdata)
}
export function getIICBytes(port: number, length: number) {
if (port < 0) return output.createBuffer(length);
let index = IICMM.getNumber(NumberFormat.UInt16LE, IICOff.Actual + port * 2);
let buf = IICMM.slice(
IICOff.Raw + DAL.MAX_DEVICE_DATALENGTH * 300 * port + DAL.MAX_DEVICE_DATALENGTH * index,
length
);
// Reverse
for (let i = 0; i < length / 2; i++) {
let c = buf[i]
buf[i] = buf[length - i - 1]
buf[length - i - 1] = c
}
return buf;
}
export function getIICNumber(length: number, format: NumberFormat, off: number, port: number) {
return getIICBytes(port, length).getNumber(format, off)
}
const enum NxtColOff {
Calibration = 0, // uint32[4][3]
@ -405,6 +579,52 @@ namespace sensors.internal {
Size = 58
}
const enum IICOff {
TypeData = 0, // Types[8][4]
Repeat = 1792, // uint16[300][4]
Raw = 4192, // int8[32][300][4]
Actual = 42592, // uint16[4]
LogIn = 42600, // uint16[4]
Status = 42608, // int8[4]
Output = 42612, // int8[32][4]
OutputLength = 42740, // int8[4]
Size = 42744
}
const enum IICCtlOff {
TypeData = 0, // Types
Port = 56, // int8
Mode = 57, // int8
Size = 58
}
const enum IICDat {
Result = 0, // result
Port = 4, // int8
Repeat = 5, // int8
Time = 6, // int16
WrLng = 8, // int8
WrData = 9, // int8[32]
RdLng = 41, // int8
RdData = 42, //int8[32]
Size = 74,
}
const enum IICStr {
Port = 0, // int8
Time = 2, // int16
Type = 4, // int8
Mode = 5, // int8
Manufacturer = 6, // int8[9]
SensorType = 15, // int[9]
SetupLng = 24, // int8
SetupString = 28, // ulong
PollLng = 32, // int8
PollString = 36, // ulong
ReadLng = 40, // int8
Size = 44
}
const enum IO {
UART_SET_CONN = 0xc00c7500,
UART_READ_MODE_INFO = 0xc03c7501,
@ -472,7 +692,7 @@ namespace sensors {
}
public threshold(t: ThresholdState): number {
switch(t) {
switch (t) {
case ThresholdState.High: return this.highThreshold;
case ThresholdState.Low: return this.lowThreshold;
default: return (this.max - this.min) / 2;
@ -512,5 +732,5 @@ namespace sensors {
break;
}
}
}
}
}
}

View File

@ -14,12 +14,19 @@
#include <errno.h>
#include <fcntl.h>
#include <malloc.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include "ev3const.h"
#define THREAD_DBG(...)
#define MALLOC_LIMIT (8 * 1024 * 1024)
#define MALLOC_CHECK_PERIOD (1024 * 1024)
namespace Array_ {
RefCollection *mk(unsigned flags);
}
void *xmalloc(size_t sz) {
static size_t allocBytes = 0;
allocBytes += sz;
@ -144,6 +151,29 @@ static void startUsb() {
pthread_detach(pid);
}
static void *exitThread(void *) {
int fd = open("/dev/lms_ui", O_RDWR, 0666);
if (fd < 0)
return 0;
uint8_t *data =
(uint8_t *)mmap(NULL, NUM_BUTTONS, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (data == MAP_FAILED) {
close(fd);
return 0;
}
for (;;) {
if (data[5])
target_reset();
sleep_core_us(50000);
}
}
static void startExitThread() {
pthread_t pid;
pthread_create(&pid, NULL, exitThread, NULL);
pthread_detach(pid);
}
void sendUsb(uint16_t code, const char *data, int len) {
while (len > 0) {
int sz = len;
@ -450,7 +480,7 @@ void stopLMS() {
if (!pid)
continue;
char namebuf[100];
snprintf(namebuf, 1000, "/proc/%d/cmdline", pid);
snprintf(namebuf, 100, "/proc/%d/cmdline", pid);
FILE *f = fopen(namebuf, "r");
if (f) {
fread(namebuf, 1, 99, f);
@ -489,14 +519,22 @@ void runLMS() {
}
void stopMotors() {
uint8_t cmd[2] = { 0xA3, 0x0F };
uint8_t cmd[3] = {opOutputStop, 0x0F, 0};
int fd = open("/dev/lms_pwm", O_RDWR);
write(fd, cmd, 2);
write(fd, cmd, 3);
close(fd);
}
void stopProgram() {
uint8_t cmd[1] = {opOutputProgramStop};
int fd = open("/dev/lms_pwm", O_RDWR);
write(fd, cmd, 1);
close(fd);
}
extern "C" void target_reset() {
stopMotors();
stopProgram();
if (lmsPid)
runLMS();
else
@ -510,6 +548,7 @@ void initRuntime() {
DMESG("runtime starting...");
stopLMS();
startUsb();
startExitThread();
pthread_t disp;
pthread_create(&disp, NULL, evtDispatcher, NULL);
pthread_detach(disp);
@ -555,4 +594,66 @@ void dmesg(const char *format, ...) {
fflush(dmesgFile);
fdatasync(fileno(dmesgFile));
}
const char *progPath = "/mnt/ramdisk/prjs/BrkProg_SAVE";
//%
void deleteAllPrograms() {
char buf[1024];
struct dirent *ent;
DIR *dir;
dir = opendir(progPath);
if (dir == NULL)
return;
while ((ent = readdir(dir)) != NULL) {
if (ent->d_name[0] == '.')
continue;
snprintf(buf, sizeof(buf), "%s/%s", progPath, ent->d_name);
DMESG("FN: %s", ent->d_name);
// unlink(buf);
}
closedir(dir);
}
//%
void deletePrjFile(String filename) {
if (strlen(filename->data) > 500 || strchr(filename->data, '/'))
return;
char buf[1024];
snprintf(buf, sizeof(buf), "%s/%s", progPath, filename->data);
unlink(buf);
}
//%
RefCollection *listPrjFiles() {
auto res = Array_::mk(0);
//registerGCObj(res);
auto dp = opendir(progPath);
for (;;) {
dirent *ep = dp ? readdir(dp) : NULL;
if (!ep)
break;
if (ep->d_name[0] == '.')
continue;
auto str = mkString(ep->d_name, -1);
//registerGCObj(str);
res->push((TValue)str);
//unregisterGCObj(str);
}
if (dp)
closedir(dp);
//unregisterGCObj(res);
return res;
}
} // namespace pxt

View File

@ -22,4 +22,9 @@ namespace motors {
export function __turnRatioPicker(turnratio: number): number {
return turnratio;
}
}
//% icon="\uf112"
namespace console {
}

View File

@ -127,27 +127,43 @@ namespace motors {
reset(Output.ALL)
}
interface MoveSchedule {
speed: number;
useSteps: boolean;
steps: number[];
}
//% fixedInstances
export class MotorBase extends control.Component {
protected _port: Output;
protected _portName: string;
protected _brake: boolean;
protected _regulated: boolean;
private _pauseOnRun: boolean;
private _initialized: boolean;
private _brakeSettleTime: number;
private _init: () => void;
private _run: (speed: number) => void;
private _move: (steps: boolean, stepsOrTime: number, speed: number) => void;
private _accelerationSteps: number;
private _accelerationTime: number;
private _decelerationSteps: number;
private _decelerationTime: number;
constructor(port: Output, init: () => void, run: (speed: number) => void, move: (steps: boolean, stepsOrTime: number, speed: number) => void) {
protected static output_types: number[] = [0x7, 0x7, 0x7, 0x7];
constructor(port: Output, init: () => void) {
super();
this._port = port;
this._portName = outputToName(this._port);
this._brake = false;
this._regulated = true;
this._pauseOnRun = true;
this._initialized = false;
this._brakeSettleTime = 10;
this._init = init;
this._run = run;
this._move = move;
this._accelerationSteps = 0;
this._accelerationTime = 0;
this._decelerationSteps = 0;
this._decelerationTime = 0;
}
/**
@ -202,6 +218,20 @@ namespace motors {
writePWM(b)
}
/**
* Set the settle time after braking in milliseconds (default is 10ms).
*/
//% blockId=motorSetBrakeSettleTime block="set %motor|brake settle time %millis|ms"
//% motor.fieldEditor="motors"
//% weight=1 blockGap=8
//% group="Properties"
//% millis.defl=200 millis.min=0 millis.max=500
setBrakeSettleTime(millis: number) {
this.init();
// ensure in [0,500]
this._brakeSettleTime = Math.max(0, Math.min(500, millis | 0))
}
/**
* Stops the motor(s).
*/
@ -219,8 +249,8 @@ namespace motors {
protected settle() {
// if we've recently completed a motor command with brake
// allow 500ms for robot to settle
if (this._brake)
pause(500);
if (this._brake && this._brakeSettleTime > 0)
pause(this._brakeSettleTime);
}
protected pauseOnRun(stepsOrTime: number) {
@ -245,6 +275,34 @@ namespace motors {
reset(this._port);
}
private normalizeSchedule(speed: number, step1: number, step2: number, step3: number, unit: MoveUnit): MoveSchedule {
const r: MoveSchedule = {
speed: Math.clamp(-100, 100, speed >> 0),
useSteps: true,
steps: [step1, step2, step3]
}
let scale = 1;
switch (unit) {
case MoveUnit.Rotations:
scale = 360;
r.useSteps = true;
break;
case MoveUnit.Degrees:
r.useSteps = true;
break;
case MoveUnit.Seconds:
scale = 1000;
r.useSteps = false;
break;
default:
r.useSteps = false;
break;
}
for (let i = 0; i < r.steps.length; ++i)
r.steps[i] = Math.max(0, (r.steps[i] * scale) | 0);
return r;
}
/**
* Runs the motor at a given speed for limited time or distance.
* @param speed the speed from ``100`` full forward to ``-100`` full backward, eg: 50
@ -259,41 +317,162 @@ namespace motors {
//% help=motors/motor/run
run(speed: number, value: number = 0, unit: MoveUnit = MoveUnit.MilliSeconds) {
this.init();
speed = Math.clamp(-100, 100, speed >> 0);
const schedule = this.normalizeSchedule(speed, 0, value, 0, unit);
// stop if speed is 0
if (!speed) {
if (!schedule.speed) {
this.stop();
return;
}
// special: 0 is infinity
if (value == 0) {
this._run(speed);
if (schedule.steps[0] + schedule.steps[1] + schedule.steps[2] == 0) {
this._run(schedule.speed);
return;
}
// timed motor moves
const steps = schedule.steps;
const useSteps = schedule.useSteps;
// compute ramp up and down
steps[0] = (useSteps ? this._accelerationSteps : this._accelerationTime) || 0;
steps[2] = (useSteps ? this._decelerationSteps : this._decelerationTime) || 0;
if (steps[0] + steps[2] > steps[1]) {
// rescale
const r = steps[1] / (steps[0] + steps[2]);
steps[0] = Math.floor(steps[0] * r);
steps[2] *= Math.floor(steps[2] * r);
}
steps[1] -= (steps[0] + steps[2]);
// send ramped command
this._schedule(schedule);
this.pauseOnRun(steps[0] + steps[1] + steps[2]);
}
/**
* Schedules a run of the motor with an acceleration, constant and deceleration phase.
* @param speed the speed from ``100`` full forward to ``-100`` full backward, eg: 50
* @param acceleration acceleration phase measured distance or rotation
* @param value measured distance or rotation
* @param deceleration deceleration phase measured distance or rotation
* @param unit (optional) unit of the value
*/
//% blockId=motorSchedule block="schedule %motor at %speed=motorSpeedPicker|\\%|for %acceleration|%value|%deceleration||%unit"
//% weight=99 blockGap=8
//% group="Move"
//% motor.fieldEditor="motors"
//% help=motors/motor/schedule
//% inlineInputMode=inline
schedule(speed: number, acceleration: number, value: number, deceleration: number, unit: MoveUnit = MoveUnit.MilliSeconds) {
this.init();
const schedule = this.normalizeSchedule(speed, acceleration, value, deceleration, unit);
// stop if speed is 0
if (!schedule.speed) {
this.stop();
return;
}
// special case: do nothing
if (schedule.steps[0] + schedule.steps[1] + schedule.steps[2] == 0) {
return;
}
// timed motor moves
let useSteps: boolean;
let stepsOrTime: number;
const steps = schedule.steps;
// send ramped command
this._schedule(schedule);
this.pauseOnRun(steps[0] + steps[1] + steps[2]);
}
/**
* Specifies the amount of rotation or time for the acceleration
* of run commands.
*/
//% blockId=outputMotorsetRunAcceleration block="set %motor|run acceleration to $value||$unit"
//% motor.fieldEditor="motors"
//% weight=21 blockGap=8
//% group="Properties"
//% help=motors/motor/set-run-acceleration-ramp
setRunAccelerationRamp(value: number, unit: MoveUnit = MoveUnit.MilliSeconds) {
switch (unit) {
case MoveUnit.Rotations:
stepsOrTime = (value * 360) >> 0;
useSteps = true;
this._accelerationSteps = Math.max(0, (value * 360) | 0);
break;
case MoveUnit.Degrees:
stepsOrTime = value >> 0;
useSteps = true;
this._accelerationSteps = Math.max(0, value | 0);
break;
case MoveUnit.Seconds:
stepsOrTime = (value * 1000) >> 0;
useSteps = false;
this._accelerationTime = Math.max(0, (value * 1000) | 0);
break;
default:
stepsOrTime = value;
useSteps = false;
case MoveUnit.MilliSeconds:
this._accelerationTime = Math.max(0, value | 0);
break;
}
}
this._move(useSteps, stepsOrTime, speed);
this.pauseOnRun(stepsOrTime);
/**
* Specifies the amount of rotation or time for the acceleration
* of run commands.
*/
//% blockId=outputMotorsetRunDeceleration block="set %motor|run deceleration ramp to $value||$unit"
//% motor.fieldEditor="motors"
//% weight=20 blockGap=8
//% group="Properties"
//% help=motors/motor/set-run-deceleration-ramp
setRunDecelerationRamp(value: number, unit: MoveUnit = MoveUnit.MilliSeconds) {
switch (unit) {
case MoveUnit.Rotations:
this._decelerationSteps = Math.max(0, (value * 360) | 0);
break;
case MoveUnit.Degrees:
this._decelerationSteps = Math.max(0, value | 0);
break;
case MoveUnit.Seconds:
this._decelerationTime = Math.max(0, (value * 1000) | 0);
break;
case MoveUnit.MilliSeconds:
this._decelerationTime = Math.max(0, value | 0);
break;
}
}
private _run(speed: number) {
// ramp up acceleration
if (this._accelerationTime) {
this._schedule({ speed: speed, useSteps: false, steps: [this._accelerationTime, 100, 0] });
pause(this._accelerationTime);
}
// keep going
const b = mkCmd(this._port, this._regulated ? DAL.opOutputSpeed : DAL.opOutputPower, 1)
b.setNumber(NumberFormat.Int8LE, 2, speed)
writePWM(b)
if (speed) {
writePWM(mkCmd(this._port, DAL.opOutputStart, 0))
}
}
private _schedule(schedule: MoveSchedule) {
const p = {
useSteps: schedule.useSteps,
step1: schedule.steps[0],
step2: schedule.steps[1],
step3: schedule.steps[2],
speed: this._regulated ? schedule.speed : undefined,
power: this._regulated ? undefined : schedule.speed,
useBrake: this._brake
};
step(this._port, p)
}
/**
* Indicates if the motor(s) speed should be regulated. Default is true.
* @param value true for regulated motor
*/
//% blockId=outputMotorSetRegulated block="set %motor|regulated %value=toggleOnOff"
//% motor.fieldEditor="motors"
//% weight=58 blockGap=8
//% group="Properties"
//% help=motors/motor/set-regulated
setRegulated(value: boolean) {
this._regulated = value;
}
/**
@ -320,33 +499,40 @@ namespace motors {
pauseUntil(() => this.isReady(), timeOut);
}
setRunSmoothness(accelerationPercent: number, decelerationPercent: number) {
}
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) {
if (this._port & (1 << i)) {
const b = mkCmd(i, DAL.opOutputSetType, 1)
b.setNumber(NumberFormat.Int8LE, 2, large ? 0x07 : 0x08)
writePWM(b)
// (0x07: Large motor, Medium motor = 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)
}
}
//% fixedInstances
export class Motor extends MotorBase {
private _large: boolean;
private _regulated: boolean;
constructor(port: Output, large: boolean) {
super(port, () => this.__init(), (speed) => this.__setSpeed(speed), (steps, stepsOrTime, speed) => this.__move(steps, stepsOrTime, speed));
super(port, () => this.__init());
this._large = large;
this._regulated = true;
this.markUsed();
}
@ -358,40 +544,6 @@ namespace motors {
this.setOutputType(this._large);
}
private __setSpeed(speed: number) {
const b = mkCmd(this._port, this._regulated ? DAL.opOutputSpeed : DAL.opOutputPower, 1)
b.setNumber(NumberFormat.Int8LE, 2, speed)
writePWM(b)
if (speed) {
writePWM(mkCmd(this._port, DAL.opOutputStart, 0))
}
}
private __move(steps: boolean, stepsOrTime: number, speed: number) {
step(this._port, {
useSteps: steps,
step1: 0,
step2: stepsOrTime,
step3: 0,
speed: this._regulated ? speed : undefined,
power: this._regulated ? undefined : speed,
useBrake: this._brake
})
}
/**
* Indicates if the motor speed should be regulated. Default is true.
* @param value true for regulated motor
*/
//% blockId=outputMotorSetRegulated block="set %motor|regulated %value=toggleOnOff"
//% motor.fieldEditor="motors"
//% weight=58
//% group="Properties"
//% help=motors/motor/set-regulated
setRegulated(value: boolean) {
this._regulated = value;
}
/**
* Gets motor actual speed.
* @param motor the port which connects to the motor
@ -479,7 +631,7 @@ namespace motors {
export class SynchedMotorPair extends MotorBase {
constructor(ports: Output) {
super(ports, () => this.__init(), (speed) => this.__setSpeed(speed), (steps, stepsOrTime, speed) => this.__move(steps, stepsOrTime, speed));
super(ports, () => this.__init());
this.markUsed();
}
@ -491,24 +643,6 @@ namespace motors {
this.setOutputType(true);
}
private __setSpeed(speed: number) {
syncMotors(this._port, {
speed: speed,
turnRatio: 0, // same speed
useBrake: !!this._brake
})
}
private __move(steps: boolean, stepsOrTime: number, speed: number) {
syncMotors(this._port, {
useSteps: steps,
speed: speed,
turnRatio: 0, // same speed
stepsOrTime: stepsOrTime,
useBrake: this._brake
});
}
/**
* The Move Tank block can make a robot drive forward, backward, turn, or stop.
* Use the Move Tank block for robot vehicles that have two Large Motors,
@ -534,10 +668,12 @@ namespace motors {
speedRight = Math.clamp(-100, 100, speedRight >> 0);
const speed = Math.abs(speedLeft) > Math.abs(speedRight) ? speedLeft : speedRight;
const turnRatio = speedLeft == speed
? (100 - speedRight / speedLeft * 100)
: (speedLeft / speedRight * 100 - 100);
let turnRatio = speedLeft == speed
? speedLeft == 0 ? 0 : (100 - speedRight / speedLeft * 100)
: speedRight == 0 ? 0 : (speedLeft / speedRight * 100 - 100);
turnRatio = Math.floor(turnRatio);
//control.dmesg(`tank ${speedLeft} ${speedRight} => ${turnRatio} ${speed}`)
this.steer(turnRatio, speed, value, unit);
}
@ -706,35 +842,24 @@ namespace motors {
}
function step(out: Output, opts: StepOptions) {
control.dmesg('step')
let op = opts.useSteps ? DAL.opOutputStepSpeed : DAL.opOutputTimeSpeed
let speed = opts.speed
if (speed == null) {
if (undefined == speed) {
speed = opts.power
op = opts.useSteps ? DAL.opOutputStepPower : DAL.opOutputTimePower
if (speed == null)
if (undefined == speed)
return
}
speed = Math.clamp(-100, 100, speed)
let b = mkCmd(out, op, 15)
b.setNumber(NumberFormat.Int8LE, 2, speed)
// note that b[3] is padding
b.setNumber(NumberFormat.Int32LE, 4 + 4 * 0, opts.step1)
b.setNumber(NumberFormat.Int32LE, 4 + 4 * 1, opts.step2)
b.setNumber(NumberFormat.Int32LE, 4 + 4 * 2, opts.step3)
b.setNumber(NumberFormat.Int8LE, 4 + 4 * 3, opts.useBrake ? 1 : 0)
writePWM(b)
}
const types = [0, 0, 0, 0]
export function setType(out: Output, type: OutputType) {
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])
}
const br = !!opts.useBrake ? 1 : 0;
b.setNumber(NumberFormat.Int8LE, 4 + 4 * 3, br)
writePWM(b)
}
}

1
libs/core/platform.h Normal file
View File

@ -0,0 +1 @@
// leave empty

View File

@ -10,7 +10,6 @@
"linux.cpp",
"mmap.cpp",
"control.cpp",
"console.ts",
"timer.ts",
"serialnumber.cpp",
"buttons.ts",
@ -25,7 +24,8 @@
"enums.d.ts",
"dal.d.ts",
"icons.jres",
"ns.ts"
"ns.ts",
"platform.h"
],
"testFiles": [
"test.ts"

View File

@ -1,9 +1,16 @@
#ifndef __PXTCORE_H
#define __PXTCORE_H
#include <stdio.h>
namespace pxt {
void dmesg(const char *fmt, ...);
#define DMESG pxt::dmesg
}
static inline void itoa(int v, char *dst) {
snprintf(dst, 30, "%d", v);
}
#endif

View File

@ -1,4 +1,8 @@
// 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
pause(100)
pause(400)
// and we're ready
brick.setStatusLight(StatusLight.Off);

View File

@ -3,6 +3,7 @@
```cards
sensors.gyro1.angle();
sensors.gyro1.rate();
sensors.gyro1.calibrate();
sensors.gyro1.reset();
```
@ -10,4 +11,6 @@ sensors.gyro1.reset();
[angle](/reference/sensors/gyro/angle),
[rate](/reference/sensors/gyro/rate),
[reset](/reference/sensors/gyro/calibrate),
[reset](/reference/sensors/gyro/reset)

View File

@ -12,7 +12,7 @@ When the brick changes its position, it's moved in the direction of one of the a
## Accuracy and calibration
Gyro sensors aren't perfectly accurate. Sometimes, because of temperature and changes in the way elecricity behaves in the sensor, the gyro returns a small error in it's measurement. This causes the gyro sensor to return an incorrect value for the amount of angle it detected. This might make your robot drive off course and not go to where you want it to.
Gyro sensors aren't perfectly accurate. Sometimes, because of temperature and changes in the way electricity behaves in the sensor, the gyro returns a small error in it's measurement. This causes the gyro sensor to return an incorrect value for the amount of angle it detected. This might make your robot drive off course and not go to where you want it to.
### Drift
@ -20,7 +20,7 @@ If you want to turn the tank or robot you built to the left by 45 degrees, you m
The problem is that when you need to read the angle measurement frequently, the amount of error in the angle measurement may continue to increase. If the sensor thought it moved by 45 degrees the first time instead of really 49 degrees, your second turn will put you at 98 degrees when the sensor said 90 degrees. If you want a robot to turn right 90 degrees and drive for 5 meters, it might actually turn 98 degrees and drive 0.7 meters off course before it stops. This error in the sensor's measurement is called _drift_.
### Time to reset
### Calibration
If errors in the angle values returned by the gyro sensor are making your project not work right, then it's time to **[reset](/reference/sensors/gyro/reset)**. A reset will return the gyro sensor's current angle value back to `0` and _calibrate_ for drift. Calibration is the process of finding out how much error there is in a sensor's measurement and then removing the error from the value returned to your program.
@ -42,7 +42,14 @@ Turn the brick and press ENTER to see the current rotation angle of `gyro 2`.
```blocks
brick.buttonEnter.onEvent(ButtonEvent.Pressed, function () {
brick.showNumber(sensors.gyro2.angle(), 1)
sensors.gyro2.reset()
})
brick.buttonLeft.onEvent(ButtonEvent.Pressed, function () {
sensors.gyro2.calibrate()
})
forever(function () {
brick.showNumber(control.millis(), 1)
brick.showNumber(sensors.gyro2.angle(), 2)
})
```

Some files were not shown because too many files have changed in this diff Show More