Compare commits
329 Commits
Author | SHA1 | Date | |
---|---|---|---|
fd06fae050 | |||
7fbb056edf | |||
06758863fb | |||
ad8af16a5a | |||
70dd6bcac5 | |||
b103423a53 | |||
a82a44e587 | |||
e6f612283f | |||
fcd60876ab | |||
5daa9a0bb6 | |||
4fb3926073 | |||
73932f4619 | |||
c99138b02e | |||
64d584681a | |||
9788dd49cc | |||
9d15c4e270 | |||
fe7b06d763 | |||
0e0275e496 | |||
ffd4d96539 | |||
a6b4c9645a | |||
a9141d027f | |||
807e581c3d | |||
41a4dfeb68 | |||
4430391e87 | |||
81667f4df5 | |||
835048132c | |||
00217305c2 | |||
85e8a70f76 | |||
bbdf27de5a | |||
3e63d4083e | |||
d1b8e3c752 | |||
1164feb754 | |||
9ebd9d4f04 | |||
9fd2a3a3e6 | |||
7f40889103 | |||
ee37b4a959 | |||
99d05ec91b | |||
412e5bd034 | |||
141420d337 | |||
084f83ba1b | |||
8601eff170 | |||
5da4d74a2a | |||
4215574a7c | |||
da9d986a3e | |||
7481b9c24c | |||
de5def8dde | |||
dd011b977a | |||
20d0dd91ad | |||
825c6d57e7 | |||
b3edb81d3c | |||
78089da134 | |||
3aef765d35 | |||
f4727f12c9 | |||
a36cb65aa5 | |||
3b16e59ee1 | |||
f2c43c74ac | |||
1c4c93dc60 | |||
d73847bfba | |||
4e46682489 | |||
ab7aa00747 | |||
2bebb6056d | |||
22046c417c | |||
dc8afa6d45 | |||
22e2ab5ad9 | |||
f365726a8e | |||
e329b3bd2e | |||
d7b709e97b | |||
9714ec46e9 | |||
20ef54f565 | |||
554df0bce9 | |||
6c89dddef6 | |||
23f91895f7 | |||
3f83cda087 | |||
7e79635413 | |||
56e1cf91ac | |||
f9f96f33f0 | |||
0b33073be1 | |||
65594842fc | |||
c6ed665f84 | |||
79462deb24 | |||
5c05f3e241 | |||
4f7dd75fbe | |||
338e507b51 | |||
601231a5dc | |||
f0850336e5 | |||
a6b2187ec5 | |||
28ae4f4230 | |||
09933b6a8d | |||
45bb6e7cb3 | |||
33c234a87e | |||
e9aa343d67 | |||
d83039430c | |||
5b2e877aef | |||
c5b28f5b8e | |||
e765021bf9 | |||
dbcd9e535c | |||
cff88d67ad | |||
3f241e8bc9 | |||
69c3d2d249 | |||
bc04d30595 | |||
63a26835b1 | |||
79113115e0 | |||
573ed7f6f2 | |||
61da1032d6 | |||
36d455c693 | |||
42c766b6d7 | |||
6f00384891 | |||
8440f7c763 | |||
8a8e864f99 | |||
7a3402b782 | |||
5e9a5b29f4 | |||
aff9d1ee60 | |||
8add7e8efb | |||
e7dfd0531b | |||
d2b1f70ce2 | |||
fbf7513c44 | |||
e9bdc26d15 | |||
52fafe9359 | |||
971dca6c96 | |||
a761c27b19 | |||
a062a85c7f | |||
a9865a731a | |||
ba4095ac9c | |||
8606a00701 | |||
bf57ba2902 | |||
4cd61cd96a | |||
c4139a862f | |||
ca3cd1de22 | |||
d7f22bc8e6 | |||
28b28d0b52 | |||
0ee2b285c0 | |||
d5cb085264 | |||
c055a5d329 | |||
8fe8b78f4c | |||
f627f125c0 | |||
7d3254477a | |||
3149ed4c1d | |||
baeafcdebe | |||
12754acc54 | |||
329baaf9a4 | |||
47efcfb41f | |||
e2d1b8a55c | |||
579eb29ce3 | |||
ada9560642 | |||
7b352b3a58 | |||
a5d5836ea2 | |||
57dc26a127 | |||
3e37b03808 | |||
d035713786 | |||
6e4a71b2f4 | |||
0b4dd534ab | |||
ed07f0baad | |||
004d34b5df | |||
aa380baf1c | |||
5123a962d9 | |||
7dcd770508 | |||
ead4d32446 | |||
a51a14022a | |||
05098252ed | |||
8e74965964 | |||
63913c2182 | |||
c55716e148 | |||
dd94442555 | |||
56f6a2fa56 | |||
4ca9df141c | |||
a29e06abce | |||
43e4d06fd9 | |||
3c8027425a | |||
3f66870688 | |||
1f32a4851e | |||
478b1c84de | |||
20ac14fdf6 | |||
c805d67cf6 | |||
943c2e7716 | |||
298a37e576 | |||
327d52014c | |||
6a5cfae5ff | |||
64ebb5c8c3 | |||
bb97b57b01 | |||
534e3723d2 | |||
ad6ef04b1f | |||
2c09b7794f | |||
4941ce1694 | |||
aa6a965f59 | |||
1831c30050 | |||
df5989760c | |||
e942fb5733 | |||
6a7f65894c | |||
f56e9369dd | |||
e23c5e019f | |||
1aa08f63fe | |||
8ef94d2854 | |||
797474063d | |||
b76622542b | |||
6a1415b3e1 | |||
2d09aef287 | |||
3ce1fa9b6e | |||
155bbb25f7 | |||
5fb3da5a77 | |||
5b682cd8d9 | |||
4755f0953c | |||
bdcd299805 | |||
3e23fe4814 | |||
3782d26e64 | |||
84a29eec65 | |||
299efaf0f2 | |||
33c60b467b | |||
81f74f07b2 | |||
583b08df28 | |||
01f80b67bc | |||
a890d2a357 | |||
0d1b91afc3 | |||
5c0d37d718 | |||
c81e56613e | |||
4cc7215d35 | |||
8751d2aaa1 | |||
af91622dda | |||
45d4caf595 | |||
a8e1d2a86c | |||
5099b11823 | |||
37e0307698 | |||
1b15eefa5a | |||
a4eccaf4f9 | |||
5981863e3f | |||
9ac7a4c522 | |||
9f1c3ee13c | |||
8b9c3d71d5 | |||
6d726b7499 | |||
b5da5afd1d | |||
420898e98c | |||
f6b392356c | |||
f4896f8d7c | |||
4dbd691146 | |||
2742dba0c4 | |||
5bea47a094 | |||
835a4b5cf0 | |||
055704b3ef | |||
60107aa7ce | |||
787ab021a7 | |||
f56a70f502 | |||
4ec6749ee6 | |||
8413b61397 | |||
ecbb970983 | |||
36e6570296 | |||
92c63b615a | |||
f71267c988 | |||
38fc0f8099 | |||
8c7238eab3 | |||
2baca30184 | |||
ac56979142 | |||
ff72858c42 | |||
deac587164 | |||
7a0a2fbd0a | |||
79c32097b5 | |||
26c20d9fc3 | |||
fe826a508a | |||
62d2140d24 | |||
499d619faf | |||
c178e58260 | |||
d242501fe6 | |||
37a438735d | |||
b862cfc4ec | |||
31002ae1a8 | |||
e8a3a2f676 | |||
e6baf8c35e | |||
b72ff9fe4f | |||
58f79ea617 | |||
ed6d343992 | |||
92b46d5c7b | |||
9cf7f08ae2 | |||
3b05b8f2f6 | |||
774d614d79 | |||
545f715eeb | |||
45b480c6dd | |||
7cc93507d9 | |||
80d3f67e6c | |||
dfbea2719b | |||
ce5da6bf80 | |||
d8d2129685 | |||
5dd37a1494 | |||
6cfe39dac3 | |||
660b22b398 | |||
b9a24a4542 | |||
af5bf6e04e | |||
ecc71a3295 | |||
0834402b18 | |||
8edd8ac73a | |||
1207a91a7f | |||
727490668c | |||
f068b3d204 | |||
205a486e58 | |||
f3bfd41a75 | |||
8d5c5daaaf | |||
83cfe8f534 | |||
9378e5e90c | |||
8617f0f3b4 | |||
0ecf3dc2b4 | |||
76005841fa | |||
7bf00ff139 | |||
82e34d852c | |||
7cd8ee1e23 | |||
a91a87b628 | |||
9d71f46e78 | |||
ccf405e64c | |||
c0a75d1845 | |||
e65a521bd4 | |||
1f203269ff | |||
18feea45bb | |||
597f0c895b | |||
5f21789d90 | |||
64826db4aa | |||
b150ee873f | |||
34effcefc6 | |||
68be2384d9 | |||
2629192bdb | |||
67b5afd73a | |||
5d8193301c | |||
adf21fee6f | |||
20f3e1d24e | |||
bf8f38fe38 | |||
3e3b8ebec5 | |||
8faeeffecf | |||
343968cf09 | |||
ca92f787e8 | |||
49a67e73be | |||
11af897c3d | |||
08cd04b2c8 | |||
c1656cf441 | |||
8f3c585588 |
7
.gitignore
vendored
7
.gitignore
vendored
@ -1,16 +1,21 @@
|
||||
node_modules
|
||||
yotta_modules
|
||||
yotta_targets
|
||||
pxt_modules
|
||||
built
|
||||
typings
|
||||
tmp
|
||||
temp
|
||||
projects/**
|
||||
clients/win10/app/AppPackages
|
||||
clients/win10/app/BundlePackages
|
||||
clients/win10/app/BundleArtifacts
|
||||
clients/win10/app/bin
|
||||
clients/win10/app/bld
|
||||
clients/win10/*.opendb
|
||||
clients/**/bin/**
|
||||
clients/**/obj/**
|
||||
clients/electron/projects
|
||||
|
||||
*.user
|
||||
*.sw?
|
||||
@ -18,4 +23,4 @@ clients/**/obj/**
|
||||
*.tgz
|
||||
*.db
|
||||
*.suo
|
||||
*.log
|
||||
*.log
|
||||
|
@ -4,8 +4,12 @@ node_js:
|
||||
script:
|
||||
- "node node_modules/pxt-core/built/pxt.js travis"
|
||||
- "(cd libs/lang-test0; node ../../node_modules/pxt-core/built/pxt.js run)"
|
||||
- "(cd libs/lang-test1; node ../../node_modules/pxt-core/built/pxt.js run)"
|
||||
- "(cd libs/lang-test0; node ../../node_modules/pxt-core/built/pxt.js test)"
|
||||
- "(cd libs/lang-test1; node ../../node_modules/pxt-core/built/pxt.js test)"
|
||||
- "node node_modules/pxt-core/built/pxt.js testdir tests"
|
||||
- "node node_modules/pxt-core/built/pxt.js uploaddoc"
|
||||
- "(cd libs/hello; node ../../node_modules/pxt-core/built/pxt.js testconv ../../testconv.json)"
|
||||
- "(cd libs/hello; node ../../node_modules/pxt-core/built/pxt.js testconv https://az851932.vo.msecnd.net/files/td-converter-tests-v0.json)"
|
||||
sudo: false
|
||||
notifications:
|
||||
email:
|
||||
@ -14,4 +18,5 @@ cache:
|
||||
directories:
|
||||
- node_modules
|
||||
- built/cache
|
||||
- libs/hello/built/cache
|
||||
|
||||
|
42
README.md
42
README.md
@ -3,18 +3,25 @@
|
||||
This target allow to program a [BBC micro:bit](https://www.microbit.co.uk/) using
|
||||
PXT ([Microsoft Programming Experience Toolkit](https://github.com/Microsoft/pxt)).
|
||||
|
||||
* [Try it live](https://m.pxt.io)
|
||||
* [Try it live](https://codethemicrobit.com)
|
||||
|
||||
[](https://travis-ci.org/Microsoft/pxt-microbit)
|
||||
|
||||
## Local server
|
||||
|
||||
The local server allows to run the editor and the documentation from your computer.
|
||||
|
||||
### Setup
|
||||
|
||||
The following commands are a 1-time setup after synching the repo on your machine.
|
||||
|
||||
* clone this repo to your computer
|
||||
* install the PXT command line
|
||||
* if not yet installed, install [Node.js 4.4.5 or higher](https://nodejs.org/en/download/)
|
||||
* [clone this repo](https://help.github.com/articles/cloning-a-repository/) to your computer and go in the project folder
|
||||
```
|
||||
git clone https://github.com/microsoft/pxt-microbit
|
||||
cd pxt-microbit
|
||||
```
|
||||
* install the PXT command line (add ``sudo`` for Mac/Linux shells).
|
||||
```
|
||||
npm install -g pxt
|
||||
```
|
||||
@ -37,7 +44,9 @@ If you need modify the `.cpp` files, turn on yotta compilation with the ``-yt``
|
||||
pxt serve -yt
|
||||
```
|
||||
|
||||
To make sure you're running the latest tools, run (add ``sudo`` for Mac/Linux shells)
|
||||
## Updates
|
||||
|
||||
To update your PXT version and make sure you're running the latest tools, run (add ``sudo`` for Mac/Linux shells)
|
||||
```
|
||||
pxt update
|
||||
```
|
||||
@ -47,9 +56,30 @@ More instructions at https://github.com/Microsoft/pxt#running-a-target-from-loca
|
||||
## Universal Windows App
|
||||
|
||||
The Windows 10 app is a [Universal Windows Hosted Web App](https://microsoftedge.github.io/WebAppsDocs/en-US/win10/CreateHWA.htm)
|
||||
that wraps ``m.pxt.io`` and provides additional features.
|
||||
that wraps ``codethemicrobit.com`` and provides additional features.
|
||||
|
||||
### Building
|
||||
|
||||
* Install Visual Studio 2015 Update 2 or higher. Make sure the Windows 10 templates are installed.
|
||||
* open the ``win10/app.sln`` solution and launch the ``m.pxt.io`` project.
|
||||
* open the ``win10/app.sln`` solution and launch the ``codethemicrobit`` project.
|
||||
|
||||
## Testing
|
||||
|
||||
The build automatically runs the following:
|
||||
|
||||
* make sure the built-in packages compile
|
||||
* `pxt run` in `libs/lang-test*` - this will run the test in command line runner;
|
||||
there is a number of asserts in both of these
|
||||
* `pxt testdir` in `tests` - this makes sure all the files compile and generates .hex files
|
||||
* run the TD->TS converter on a number of test scripts from `microbit.co.uk` and make sure the results compile
|
||||
|
||||
To test something on the device:
|
||||
|
||||
* do a `pxt deploy` in `libs/lang-test*` - they should show `1` or `2` on the screen (and not unhappy face)
|
||||
* run `pxt testdir` in `tests` and deploy some of the hex files from `tests/built`
|
||||
|
||||
The `lang-test0` source comes from the `pxt-core` package. It's also tested with `pxt run` there.
|
||||
|
||||
## 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.
|
||||
|
26
clients/chrome/README.md
Normal file
26
clients/chrome/README.md
Normal file
@ -0,0 +1,26 @@
|
||||
# microbit-chrome
|
||||
Prototype chrome addon that exposes the micro:bit's serial output to webpages.
|
||||
* watch the [demo video](https://vimeo.com/146207766)
|
||||
|
||||
# Installation
|
||||
See [developer.chrome.com](https://developer.chrome.com/extensions/getstarted#unpacked)
|
||||
for instructions on how to install the local version into your chrome browser.
|
||||
|
||||
# Requirements
|
||||
* Chrome 48 or later.
|
||||
|
||||
# Sample page
|
||||
The `demo.html` webpage goes along with the
|
||||
https://github.com/Microsoft/microbit-touchdevelop/blob/master/examples/tcs34725.cpp
|
||||
program. Run `http-server` from this directory, then visit
|
||||
http://localhost:8080/demo.html
|
||||
(keep in mind that pages served from `file://` cannot open ports).
|
||||
|
||||
# Building
|
||||
|
||||
Open a command prompt and run the following commands.
|
||||
|
||||
````
|
||||
npm install
|
||||
typings update
|
||||
````
|
68
clients/chrome/background.js
Normal file
68
clients/chrome/background.js
Normal file
@ -0,0 +1,68 @@
|
||||
///<reference path='typings/browser.d.ts'/>
|
||||
var connections = [];
|
||||
// A list of "ports", i.e. connected clients (such as web pages). Multiple web
|
||||
// pages can connect to our service: they all receive the same data.
|
||||
var ports = [];
|
||||
function byPath(path) {
|
||||
return connections.filter(function (x) { return x.path == path; });
|
||||
}
|
||||
function byId(id) {
|
||||
return connections.filter(function (x) { return x.id == id; });
|
||||
}
|
||||
function onReceive(data, id) {
|
||||
if (ports.length == 0)
|
||||
return;
|
||||
var view = new DataView(data);
|
||||
var decoder = new TextDecoder("utf-8");
|
||||
var decodedString = decoder.decode(view);
|
||||
ports.forEach(function (port) { return port.postMessage({
|
||||
type: "serial",
|
||||
data: decodedString,
|
||||
id: id
|
||||
}); });
|
||||
}
|
||||
function findNewDevices() {
|
||||
chrome.serial.getDevices(function (serialPorts) {
|
||||
serialPorts.forEach(function (serialPort) {
|
||||
if (byPath(serialPort.path).length == 0 &&
|
||||
serialPort.displayName == "mbed Serial Port") {
|
||||
chrome.serial.connect(serialPort.path, { bitrate: 115200 }, function (info) {
|
||||
// In case the [connect] operation takes more than five seconds...
|
||||
if (info && byPath(serialPort.path).length == 0)
|
||||
connections.push({
|
||||
id: info.connectionId,
|
||||
path: serialPort.path
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
function main() {
|
||||
// Register new clients in the [ports] global variable.
|
||||
chrome.runtime.onConnectExternal.addListener(function (port) {
|
||||
if (/^(micro:bit|touchdevelop|yelm|pxt|codemicrobit|codethemicrobit)$/.test(port.name)) {
|
||||
ports.push(port);
|
||||
port.onDisconnect.addListener(function () {
|
||||
ports = ports.filter(function (x) { return x != port; });
|
||||
});
|
||||
}
|
||||
});
|
||||
// When receiving data for one of the connections that we're tracking, forward
|
||||
// it to all connected clients.
|
||||
chrome.serial.onReceive.addListener(function (info) {
|
||||
if (byId(info.connectionId).length > 0)
|
||||
onReceive(info.data, info.connectionId);
|
||||
});
|
||||
// When it looks like we've been disconnected, drop the corresponding
|
||||
// connection object from the [connections] global variable.
|
||||
chrome.serial.onReceiveError.addListener(function (info) {
|
||||
if (info.error == "system_error" || info.error == "disconnected" || info.error == "device_lost")
|
||||
connections = connections.filter(function (x) { return x.id != info.connectionId; });
|
||||
});
|
||||
// Probe serial connections at regular intervals. In case we find an mbed port
|
||||
// we haven't yet connected to, connect to it.
|
||||
setInterval(findNewDevices, 5000);
|
||||
findNewDevices();
|
||||
}
|
||||
document.addEventListener("DOMContentLoaded", main);
|
92
clients/chrome/background.ts
Normal file
92
clients/chrome/background.ts
Normal file
@ -0,0 +1,92 @@
|
||||
// A list of: {
|
||||
// id: number;
|
||||
// path: string;
|
||||
// } where [id] is the [connectionId] (internal to Chrome) and [path] is the
|
||||
// OS' name for the device (e.g. "COM4").
|
||||
interface Connection {
|
||||
id: string;
|
||||
path: string;
|
||||
}
|
||||
let connections: Connection[] = [];
|
||||
|
||||
// A list of "ports", i.e. connected clients (such as web pages). Multiple web
|
||||
// pages can connect to our service: they all receive the same data.
|
||||
let ports = [];
|
||||
|
||||
interface Message {
|
||||
type: string;
|
||||
data: string;
|
||||
id: string;
|
||||
}
|
||||
|
||||
function byPath(path: string): Connection[] {
|
||||
return connections.filter((x) => x.path == path);
|
||||
}
|
||||
|
||||
function byId(id: string): Connection[] {
|
||||
return connections.filter((x) => x.id == id);
|
||||
}
|
||||
|
||||
function onReceive(data, id: string) {
|
||||
if (ports.length == 0) return;
|
||||
|
||||
let view = new DataView(data);
|
||||
let decoder = new TextDecoder("utf-8");
|
||||
let decodedString = decoder.decode(view);
|
||||
ports.forEach(port => port.postMessage(<Message>{
|
||||
type: "serial",
|
||||
data: decodedString,
|
||||
id: id,
|
||||
}));
|
||||
}
|
||||
|
||||
function findNewDevices() {
|
||||
chrome.serial.getDevices(function (serialPorts) {
|
||||
serialPorts.forEach(function (serialPort) {
|
||||
if (byPath(serialPort.path).length == 0 &&
|
||||
serialPort.displayName == "mbed Serial Port") {
|
||||
chrome.serial.connect(serialPort.path, { bitrate: 115200 }, function (info) {
|
||||
// In case the [connect] operation takes more than five seconds...
|
||||
if (info && byPath(serialPort.path).length == 0)
|
||||
connections.push({
|
||||
id: info.connectionId,
|
||||
path: serialPort.path
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function main() {
|
||||
// Register new clients in the [ports] global variable.
|
||||
chrome.runtime.onConnectExternal.addListener(function (port) {
|
||||
if (/^(micro:bit|touchdevelop|yelm|pxt|codemicrobit|codethemicrobit)$/.test(port.name)) {
|
||||
ports.push(port);
|
||||
port.onDisconnect.addListener(function () {
|
||||
ports = ports.filter(function (x) { return x != port });
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// When receiving data for one of the connections that we're tracking, forward
|
||||
// it to all connected clients.
|
||||
chrome.serial.onReceive.addListener(function (info) {
|
||||
if (byId(info.connectionId).length > 0)
|
||||
onReceive(info.data, info.connectionId);
|
||||
});
|
||||
|
||||
// When it looks like we've been disconnected, drop the corresponding
|
||||
// connection object from the [connections] global variable.
|
||||
chrome.serial.onReceiveError.addListener(function (info) {
|
||||
if (info.error == "system_error" || info.error == "disconnected" || info.error == "device_lost")
|
||||
connections = connections.filter((x) => x.id != info.connectionId);
|
||||
});
|
||||
|
||||
// Probe serial connections at regular intervals. In case we find an mbed port
|
||||
// we haven't yet connected to, connect to it.
|
||||
setInterval(findNewDevices, 5000);
|
||||
findNewDevices();
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", main);
|
BIN
clients/chrome/logo128.png
Normal file
BIN
clients/chrome/logo128.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.9 KiB |
BIN
clients/chrome/logo48.png
Normal file
BIN
clients/chrome/logo48.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.2 KiB |
30
clients/chrome/manifest.json
Normal file
30
clients/chrome/manifest.json
Normal file
@ -0,0 +1,30 @@
|
||||
{
|
||||
"app": {
|
||||
"background": {
|
||||
"scripts": [ "background.js" ]
|
||||
}
|
||||
},
|
||||
|
||||
"manifest_version": 2,
|
||||
"name": "code the micro:bit",
|
||||
"version": "0.6.0",
|
||||
"author": "Microsoft Corporation",
|
||||
"short_name": "code the micro:bit",
|
||||
|
||||
"description": "Extension for https://codethemicrobit.com.",
|
||||
"homepage_url": "https://codethemicrobit.com",
|
||||
"offline_enabled": "true",
|
||||
"icons": {
|
||||
"48": "logo48.png",
|
||||
"128": "logo128.png"
|
||||
},
|
||||
|
||||
"permissions": [
|
||||
"serial",
|
||||
"usb"
|
||||
],
|
||||
|
||||
"externally_connectable": {
|
||||
"matches": [ "*://localhost/*", "https://codethemicrobit.com/*", "https://*.codethemicrobit.com/*" ]
|
||||
}
|
||||
}
|
BIN
clients/chrome/screenshot.png
Normal file
BIN
clients/chrome/screenshot.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 138 KiB |
7
clients/chrome/tsconfig.json
Normal file
7
clients/chrome/tsconfig.json
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"compiler-options": {
|
||||
"target": "ES5",
|
||||
"module": "amd",
|
||||
"sourceMap": false
|
||||
}
|
||||
}
|
67
clients/electron/main.js
Normal file
67
clients/electron/main.js
Normal file
@ -0,0 +1,67 @@
|
||||
const electron = require('electron')
|
||||
// Module to control application life.
|
||||
const app = electron.app
|
||||
// Module to create native browser window.
|
||||
const BrowserWindow = electron.BrowserWindow
|
||||
// pxt toolchain
|
||||
const pxt = require('pxt-core')
|
||||
|
||||
// Keep a global reference of the window object, if you don't, the window will
|
||||
// be closed automatically when the JavaScript object is garbage collected.
|
||||
let mainWindow
|
||||
|
||||
function createWindow() {
|
||||
console.log('starting app...')
|
||||
// Create the browser window.
|
||||
mainWindow = new BrowserWindow({
|
||||
width: 800, height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: false,
|
||||
}
|
||||
})
|
||||
|
||||
ts.pxt.Util.debug = true;
|
||||
pxt.mainCli("C:/gh/pxt-microbit/clients/electron/node_modules/pxt-microbit", ["serve", "-just"]);
|
||||
|
||||
// no menu
|
||||
mainWindow.setMenu(null);
|
||||
|
||||
// and load the index.html of the app.
|
||||
mainWindow.loadURL(`http://localhost:3232/#local_token=08ba9b8f-6ccb-4202-296d-28fac7a553d9`)
|
||||
|
||||
// Open the DevTools.
|
||||
mainWindow.webContents.openDevTools()
|
||||
|
||||
// Emitted when the window is closed.
|
||||
mainWindow.on('closed', function () {
|
||||
// Dereference the window object, usually you would store windows
|
||||
// in an array if your app supports multi windows, this is the time
|
||||
// when you should delete the corresponding element.
|
||||
mainWindow = null
|
||||
})
|
||||
}
|
||||
|
||||
// This method will be called when Electron has finished
|
||||
// initialization and is ready to create browser windows.
|
||||
// Some APIs can only be used after this event occurs.
|
||||
app.on('ready', createWindow)
|
||||
|
||||
// Quit when all windows are closed.
|
||||
app.on('window-all-closed', function () {
|
||||
// On OS X it is common for applications and their menu bar
|
||||
// to stay active until the user quits explicitly with Cmd + Q
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', function () {
|
||||
// On OS X it's common to re-create a window in the app when the
|
||||
// dock icon is clicked and there are no other windows open.
|
||||
if (mainWindow === null) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
|
||||
// In this file you can include the rest of your app's specific main process
|
||||
// code. You can also put them in separate files and require them here.
|
19
clients/electron/package.json
Normal file
19
clients/electron/package.json
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"name": "codethemicrobit",
|
||||
"version": "0.1.0",
|
||||
"description": "A Blocks / JavaScript editor for the micro:bit",
|
||||
"main": "main.js",
|
||||
"scripts": {
|
||||
"start": "electron ."
|
||||
},
|
||||
"author": "Microsoft",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"electron-prebuilt": "^1.2.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"typescript": "1.8.7",
|
||||
"pxt-core": "*",
|
||||
"pxt-microbit": "*"
|
||||
}
|
||||
}
|
@ -20,22 +20,18 @@
|
||||
<ProjectConfiguration Include="Release|AnyCPU">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>AnyCPU</Platform>
|
||||
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|ARM">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>ARM</Platform>
|
||||
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x86">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x86</Platform>
|
||||
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
48
clients/win10/app/codethemicrobitapp.sln
Normal file
48
clients/win10/app/codethemicrobitapp.sln
Normal file
@ -0,0 +1,48 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 14
|
||||
VisualStudioVersion = 14.0.25123.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{262852C6-CD72-467D-83FE-5EEB1973A190}") = "codethemicrobitapp", "codethemicrobitapp.jsproj", "{39122940-AB16-4CD4-A0CE-79A3EB863ECF}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Debug|ARM = Debug|ARM
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|Any CPU = Release|Any CPU
|
||||
Release|ARM = Release|ARM
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
|
||||
{39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Debug|ARM.ActiveCfg = Debug|ARM
|
||||
{39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Debug|ARM.Build.0 = Debug|ARM
|
||||
{39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Debug|ARM.Deploy.0 = Debug|ARM
|
||||
{39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Debug|x64.Build.0 = Debug|x64
|
||||
{39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Debug|x64.Deploy.0 = Debug|x64
|
||||
{39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Debug|x86.Build.0 = Debug|x86
|
||||
{39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Debug|x86.Deploy.0 = Debug|x86
|
||||
{39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Release|Any CPU.Deploy.0 = Release|Any CPU
|
||||
{39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Release|ARM.ActiveCfg = Release|ARM
|
||||
{39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Release|ARM.Build.0 = Release|ARM
|
||||
{39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Release|ARM.Deploy.0 = Release|ARM
|
||||
{39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Release|x64.ActiveCfg = Release|x64
|
||||
{39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Release|x64.Build.0 = Release|x64
|
||||
{39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Release|x64.Deploy.0 = Release|x64
|
||||
{39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Release|x86.ActiveCfg = Release|x86
|
||||
{39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Release|x86.Build.0 = Release|x86
|
||||
{39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Release|x86.Deploy.0 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
@ -14,13 +14,13 @@
|
||||
<Resource Language="x-generate" />
|
||||
</Resources>
|
||||
<Applications>
|
||||
<Application Id="App" StartPage="https://m.pxt.io/">
|
||||
<Application Id="App" StartPage="https://codethemicrobit.com">
|
||||
<uap:ApplicationContentUriRules>
|
||||
<uap:Rule Match="https://m.pxt.io/" Type="include" WindowsRuntimeAccess="all" />
|
||||
<uap:Rule Match="https://codemicrobit.com/" Type="include" WindowsRuntimeAccess="all" />
|
||||
<uap:Rule Match="https://codethemicrobit.com/" Type="include" WindowsRuntimeAccess="all" />
|
||||
</uap:ApplicationContentUriRules>
|
||||
<uap:VisualElements DisplayName="codethemicrobit" Description="Code editors for the BBC micro:bit" BackgroundColor="white" Square150x150Logo="images\Square150x150Logo.png" Square44x44Logo="images\Square44x44Logo.png">
|
||||
<uap:VisualElements DisplayName="code the micro:bit" Description="A code editor for the BBC micro:bit with Blocks or Javascript." BackgroundColor="white" Square150x150Logo="images\Square150x150Logo.png" Square44x44Logo="images\Square44x44Logo.png">
|
||||
<uap:DefaultTile Wide310x150Logo="images\Wide310x150Logo.png" ShortName="code the micro:bit">
|
||||
</uap:DefaultTile>
|
||||
<uap:SplashScreen Image="images\splashscreen.png" />
|
||||
|
BIN
clients/win10/store/desktopblocks1366x768.png
Normal file
BIN
clients/win10/store/desktopblocks1366x768.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 172 KiB |
BIN
clients/win10/store/desktopjavascript1366x768.png
Normal file
BIN
clients/win10/store/desktopjavascript1366x768.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 121 KiB |
BIN
clients/win10/store/mobileblocks480x800.png
Normal file
BIN
clients/win10/store/mobileblocks480x800.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 54 KiB |
@ -1,22 +0,0 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 14
|
||||
VisualStudioVersion = 14.0.25123.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeTheMicrobit.Uploader", "Microbit.Uploader\CodeTheMicrobit.Uploader.csproj", "{7DC6CA45-FD75-44BC-805E-708C812CD4BF}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{7DC6CA45-FD75-44BC-805E-708C812CD4BF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{7DC6CA45-FD75-44BC-805E-708C812CD4BF}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{7DC6CA45-FD75-44BC-805E-708C812CD4BF}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{7DC6CA45-FD75-44BC-805E-708C812CD4BF}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
66
clients/winuploader/CodeTheMicroBit.sln
Normal file
66
clients/winuploader/CodeTheMicroBit.sln
Normal file
@ -0,0 +1,66 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 14
|
||||
VisualStudioVersion = 14.0.25123.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeTheMicrobit", "Microbit.Uploader\CodeTheMicrobit.csproj", "{7DC6CA45-FD75-44BC-805E-708C812CD4BF}"
|
||||
EndProject
|
||||
Project("{262852C6-CD72-467D-83FE-5EEB1973A190}") = "codethemicrobitapp", "..\win10\app\codethemicrobitapp.jsproj", "{39122940-AB16-4CD4-A0CE-79A3EB863ECF}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Debug|ARM = Debug|ARM
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|Any CPU = Release|Any CPU
|
||||
Release|ARM = Release|ARM
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{7DC6CA45-FD75-44BC-805E-708C812CD4BF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{7DC6CA45-FD75-44BC-805E-708C812CD4BF}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{7DC6CA45-FD75-44BC-805E-708C812CD4BF}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{7DC6CA45-FD75-44BC-805E-708C812CD4BF}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||
{7DC6CA45-FD75-44BC-805E-708C812CD4BF}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{7DC6CA45-FD75-44BC-805E-708C812CD4BF}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{7DC6CA45-FD75-44BC-805E-708C812CD4BF}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{7DC6CA45-FD75-44BC-805E-708C812CD4BF}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{7DC6CA45-FD75-44BC-805E-708C812CD4BF}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{7DC6CA45-FD75-44BC-805E-708C812CD4BF}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{7DC6CA45-FD75-44BC-805E-708C812CD4BF}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{7DC6CA45-FD75-44BC-805E-708C812CD4BF}.Release|ARM.Build.0 = Release|Any CPU
|
||||
{7DC6CA45-FD75-44BC-805E-708C812CD4BF}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{7DC6CA45-FD75-44BC-805E-708C812CD4BF}.Release|x64.Build.0 = Release|Any CPU
|
||||
{7DC6CA45-FD75-44BC-805E-708C812CD4BF}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{7DC6CA45-FD75-44BC-805E-708C812CD4BF}.Release|x86.Build.0 = Release|Any CPU
|
||||
{39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
|
||||
{39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Debug|ARM.ActiveCfg = Debug|ARM
|
||||
{39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Debug|ARM.Build.0 = Debug|ARM
|
||||
{39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Debug|ARM.Deploy.0 = Debug|ARM
|
||||
{39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Debug|x64.Build.0 = Debug|x64
|
||||
{39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Debug|x64.Deploy.0 = Debug|x64
|
||||
{39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Debug|x86.Build.0 = Debug|x86
|
||||
{39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Debug|x86.Deploy.0 = Debug|x86
|
||||
{39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Release|Any CPU.Deploy.0 = Release|Any CPU
|
||||
{39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Release|ARM.ActiveCfg = Release|ARM
|
||||
{39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Release|ARM.Build.0 = Release|ARM
|
||||
{39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Release|ARM.Deploy.0 = Release|ARM
|
||||
{39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Release|x64.ActiveCfg = Release|x64
|
||||
{39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Release|x64.Build.0 = Release|x64
|
||||
{39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Release|x64.Deploy.0 = Release|x64
|
||||
{39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Release|x86.ActiveCfg = Release|x86
|
||||
{39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Release|x86.Build.0 = Release|x86
|
||||
{39122940-AB16-4CD4-A0CE-79A3EB863ECF}.Release|x86.Deploy.0 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
@ -8,7 +8,7 @@
|
||||
<OutputType>WinExe</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Microsoft.MicroBit</RootNamespace>
|
||||
<AssemblyName>Microbit.Uploader</AssemblyName>
|
||||
<AssemblyName>CodeTheMicrobit</AssemblyName>
|
||||
<TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
@ -79,7 +79,7 @@
|
||||
this.MinimizeBox = false;
|
||||
this.Name = "LicenseDialog";
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
|
||||
this.Text = "code the micro:bit uploader Terms Of Use";
|
||||
this.Text = "code the micro:bit terms of use";
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
@ -116,6 +116,7 @@
|
||||
this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
|
||||
this.pictureBox1.TabIndex = 5;
|
||||
this.pictureBox1.TabStop = false;
|
||||
this.pictureBox1.Click += new System.EventHandler(this.pictureBox1_Click);
|
||||
//
|
||||
// linkLabel1
|
||||
//
|
||||
@ -148,7 +149,7 @@
|
||||
this.ShowInTaskbar = false;
|
||||
this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide;
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
|
||||
this.Text = "code the micro:bit uploader";
|
||||
this.Text = "code the micro:bit";
|
||||
this.Load += new System.EventHandler(this.MainForm_Load);
|
||||
((System.ComponentModel.ISupportInitialize)(this.backgroundPictureBox)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
|
||||
|
@ -243,11 +243,7 @@ namespace Microsoft.MicroBit
|
||||
|
||||
private void backgroundPictureBox_Click(object sender, EventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
Process.Start("https://codethemicrobit.com");
|
||||
}
|
||||
catch (IOException) { }
|
||||
this.openEditor();
|
||||
}
|
||||
|
||||
private void SettingsLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
|
||||
@ -262,5 +258,10 @@ namespace Microsoft.MicroBit
|
||||
{
|
||||
this.openEditor();
|
||||
}
|
||||
|
||||
private void pictureBox1_Click(object sender, EventArgs e)
|
||||
{
|
||||
this.openEditor();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
10
cmds/cmds.ts
10
cmds/cmds.ts
@ -6,6 +6,8 @@ import * as child_process from "child_process";
|
||||
|
||||
let writeFileAsync: any = Promise.promisify(fs.writeFile)
|
||||
let execAsync: (cmd: string, options?: { cwd?: string }) => Promise<Buffer> = Promise.promisify(child_process.exec)
|
||||
let readDirAsync = Promise.promisify(fs.readdir)
|
||||
|
||||
|
||||
export function deployCoreAsync(res: ts.pxt.CompileResult) {
|
||||
return getBitDrivesAsync()
|
||||
@ -26,17 +28,23 @@ export function deployCoreAsync(res: ts.pxt.CompileResult) {
|
||||
|
||||
function getBitDrivesAsync(): Promise<string[]> {
|
||||
if (process.platform == "win32") {
|
||||
let rx = new RegExp("^([A-Z]:).* " + pxt.appTarget.compile.deployDrives)
|
||||
return execAsync("wmic PATH Win32_LogicalDisk get DeviceID, VolumeName, FileSystem")
|
||||
.then(buf => {
|
||||
let res: string[] = []
|
||||
buf.toString("utf8").split(/\n/).forEach(ln => {
|
||||
let m = /^([A-Z]:).* MICROBIT/.exec(ln)
|
||||
let m = rx.exec(ln)
|
||||
if (m) {
|
||||
res.push(m[1] + "/")
|
||||
}
|
||||
})
|
||||
return res
|
||||
})
|
||||
}
|
||||
else if (process.platform == "darwin") {
|
||||
let rx = new RegExp(pxt.appTarget.compile.deployDrives)
|
||||
return readDirAsync("/Volumes")
|
||||
.then(lst => lst.filter(s => rx.test(s)).map(s => "/Volumes/" + s + "/"))
|
||||
} else {
|
||||
return Promise.resolve([])
|
||||
}
|
||||
|
@ -31,33 +31,33 @@ Just like Arduino, the micro:bit can be connected to and interact with sensors,
|
||||
|
||||
## Hardware: The Device
|
||||
|
||||
Learn about about the [hardware components](/device) of the micro:bit to make the most of it!
|
||||
Learn about the [hardware components](/device) of the micro:bit to make the most of it!
|
||||
|
||||
## Programming: Blocks or JavaScript
|
||||
|
||||
The student can program the BBC micro:bit using [Blocks](/blocks) or [JavaScript](/javascript), via the [micro:bit APIs](/reference):
|
||||
You can program the micro:bit using [Blocks](/blocks) or [JavaScript](/javascript), via the [micro:bit APIs](/reference):
|
||||
|
||||
```blocks
|
||||
basic.showString("Hi!");
|
||||
input.onButtonPressed(Button.A, () => {
|
||||
basic.showString("Hi!");
|
||||
})
|
||||
```
|
||||
|
||||
## Compile and Flash: Your Program!
|
||||
|
||||
When a user has her code ready, she can connect her BBC micro:bit to a computer via a USB cable, so it appears as a mounted drive (named MICROBIT).
|
||||
When you have your code ready, you connect your micro:bit to a computer via a USB cable, so it appears as a mounted drive (named MICROBIT).
|
||||
|
||||
Compilation to ARM thumb machine code from [Blocks](/blocks) or [JavaScript](/javascript) happens in the browser.
|
||||
|
||||
The student is prompted to save the ARM binary program to a file, which she then simply drags to the micro:bit mounted drive,
|
||||
which flashes the micro:bit device with the new program.
|
||||
Compilation to ARM thumb machine code from [Blocks](/blocks) or [JavaScript](/javascript) happens in the browser. You save the ARM binary
|
||||
program to a file, which you then copy to the micro:bit drive, which flashes the micro:bit device with the new program.
|
||||
|
||||
## Simulator: Test Your Code
|
||||
|
||||
Before a student compiles her code for the micro:bit, she can run it using the micro:bit simulator, all within the confines of a web browser.
|
||||
You can run your code using the micro:bit simulator, all within the confines of a web browser.
|
||||
The simulator has support for the LED screen, buttons, as well as compass, accelerometer, and digital I/O pins.
|
||||
|
||||
## C++ Runtime
|
||||
|
||||
The [C++ BBC micro:bit runtime](http://lancaster-university.github.io/microbit-docs/), created at [Lancaster University](http://www.lancaster.ac.uk/), provides access to the hardware functions of the micro:bit,
|
||||
The [C++ micro:bit runtime](http://lancaster-university.github.io/microbit-docs/), created at [Lancaster University](http://www.lancaster.ac.uk/), provides access to the hardware functions of the micro:bit,
|
||||
as well as a set of helper functions (such as displaying a number/image/string on the LED screen).
|
||||
|
||||
The [micro:bit library](/reference) mirrors the functions of the C++ library.
|
||||
@ -65,4 +65,4 @@ When code is compiled to ARM machine code, the calls to JavaScript micro:bit fun
|
||||
|
||||
## Open Source
|
||||
|
||||
The editor for the BBC micro:bit is [open source](/open-source) on GitHub. Contributors are welcome!
|
||||
The code for the micro:bit is [open source](/open-source) on GitHub. Contributors are welcome!
|
||||
|
@ -5,4 +5,8 @@ for (let i = 0;i<5;++i) {}
|
||||
if (true){}
|
||||
let x = 0;
|
||||
Math.random(5);
|
||||
```
|
||||
```
|
||||
|
||||
## See Also
|
||||
|
||||
[logic](/blocks/logic), [loops](/blocks/loops), [math](/blocks/math), [variables](/blocks/variables)
|
@ -86,7 +86,7 @@ if (led.point(1,1) && led.point(2,2)) {
|
||||
When you compare two Numbers, you get a Boolean value, such as the comparison `x < 5` in the code below:
|
||||
|
||||
```blocks
|
||||
let x = math.random(5)
|
||||
let x = Math.random(5)
|
||||
if(x < 5) {
|
||||
basic.showString("low");
|
||||
} else {
|
||||
|
@ -1,4 +1,4 @@
|
||||
## Variables
|
||||
# Variables
|
||||
|
||||
[Assign](/blocks/variables/assign) (set) a variable's value
|
||||
|
||||
|
@ -46,7 +46,7 @@ basic.showNumber(counter);
|
||||
|
||||
To change the contents of a variable use the assignment operator. The following code sets `counter` to 1 and then increments `counter` by 10:
|
||||
|
||||
```blocks
|
||||
```blocks
|
||||
let counter = 1;
|
||||
counter = counter + 10;
|
||||
basic.showNumber(counter);
|
||||
|
@ -1,6 +1,6 @@
|
||||
# Device
|
||||
|
||||
All the bits and pieces that make up your BBC micro:bit
|
||||
All the bits and pieces that make up the BBC micro:bit
|
||||
|
||||

|
||||
|
||||
@ -23,13 +23,13 @@ When you have downloaded and run your code onto your micro:bit, press Button R t
|
||||
|
||||
### USB connection
|
||||
|
||||
When you plug in your micro:bit, it should appear as MICROBIT.
|
||||
When you plug in your micro:bit, it should appear as ``MICROBIT``.
|
||||
If you accidentally hold down the reset button as you’re plugging in your micro:bit,
|
||||
the micro:bit will appear as a MAINTENANCE drive instead of MICROBIT. This is known as maintenance mode.**
|
||||
the micro:bit will appear as a MAINTENANCE drive instead of ``MICROBIT``. This is known as maintenance mode.**
|
||||
|
||||
To continue programming your micro:bit YOU MUST unplug your USB and reconnect it. Check that the drive now shows as MICROBIT.
|
||||
To continue programming your micro:bit YOU MUST unplug your USB and reconnect it. Check that the drive now shows as ``MICROBIT``.
|
||||
|
||||
**Use with caution. If you click on the drive while it shows as MAINTENANCE,
|
||||
**Use with caution. If you click on the drive while it shows as ``MAINTENANCE``,
|
||||
you can see which version of firmware you have running on your micro:bit.
|
||||
Firmware on your micro:bit should be up-to-date already.
|
||||
You can find the version of firmware in the 'version.txt' file on the micro:bit. Further information on the firmware can be found here:
|
||||
@ -55,6 +55,10 @@ The pins can be a form of input or output.
|
||||
There are labels for the input/output pins P0, P1, P2, which you can attach external sensors to such as thermometers or moisture detectors.
|
||||
You can read more about large and small pins [here](/device/pins).
|
||||
|
||||
### Light level
|
||||
|
||||
The screen can also be used a light level sensor (it's a really cool trick).
|
||||
|
||||
### How do I connect the micro:bit to my computer?
|
||||
|
||||
Your micro:bit can be connected to your computer via a micro USB cable.
|
||||
@ -73,7 +77,7 @@ You can attach an external device such as a motor to these and power it using th
|
||||
|
||||
### Serial Communication
|
||||
|
||||
The BBC micro:bit can send an receive data via [serial communication](/device/serial). The serial data can be transfered via USB or BlE.
|
||||
The micro:bit can send an receive data via [serial communication](/device/serial). The serial data can be transfered via USB or BLE.
|
||||
|
||||
### Bluetooth Low Energy (BLE) Antenna
|
||||
|
||||
|
@ -48,41 +48,45 @@ The micro:bit’s *scheduler* provides the capability to concurrently execute di
|
||||
|
||||
The first job of the scheduler is to allow multiple *subprograms* to be queued up for later execution . For our purposes, a subprogram is just a statement or sequence of statements in the context of a larger program. Consider the Touch Develop program below for counting button presses.
|
||||
|
||||
```
|
||||
export function countButtonPresses() {
|
||||
input.onButtonPressed(Button.A, () => {
|
||||
count = count + 1
|
||||
})
|
||||
basic.forever(() => {
|
||||
basic.showNumber(count, 150)
|
||||
})
|
||||
count = 0
|
||||
}
|
||||
```
|
||||
|
||||
The program above contains three statements that execute in order from top to bottom. The first statement
|
||||
|
||||
```
|
||||
```blocks
|
||||
let count = 0
|
||||
input.onButtonPressed(Button.A, () => {
|
||||
count = count + 1
|
||||
count++;
|
||||
})
|
||||
```
|
||||
|
||||
informs the scheduler that on each and every event of the A button being pressed, a subprogram (called the event handler) should be queued for execution. The event handler is demarcated by the do/end keywords; it increments the global variable `count` by one. The second statement
|
||||
|
||||
```
|
||||
basic.forever(() => {
|
||||
basic.showNumber(count, 150)
|
||||
})
|
||||
```
|
||||
|
||||
queues a `forever` loop for later execution by the scheduler; the body of this loop (between the do/end keywords) displays the current value of global variable `count` on the LED screen. The third statement
|
||||
The program above contains three statements that execute in order from top to bottom.
|
||||
The first statement initializes the global variable `count` to zero.
|
||||
|
||||
```
|
||||
count = 0
|
||||
```blocks
|
||||
let count = 0
|
||||
```
|
||||
|
||||
initializes the global variable `count` to zero. The function ends after the execution of these three statements, but this is not the end of program execution! That’s because the function queued the `forever` loop for execution by the scheduler.
|
||||
The second statement informs the scheduler that on each and every event of the A button being pressed, a subprogram (called the event handler) should be queued for execution. The event handler is demarcated by the do/end keywords; it increments the global variable `count` by one.
|
||||
|
||||
```blocks
|
||||
let count = 0
|
||||
// ...
|
||||
input.onButtonPressed(Button.A, () => {
|
||||
count++;
|
||||
})
|
||||
```
|
||||
|
||||
The third statement queues a `forever` loop for later execution by the scheduler; the body of this loop (between the do/end keywords) displays the current value of global variable `count` on the LED screen. The third statement
|
||||
|
||||
```blocks
|
||||
let count = 0
|
||||
// ...
|
||||
basic.forever(() => {
|
||||
basic.showNumber(count, 150)
|
||||
})
|
||||
```
|
||||
|
||||
|
||||
The function ends after the execution of these three statements, but this is not the end of program execution! That’s because the function queued the `forever` loop for execution by the scheduler.
|
||||
|
||||
The second job of the scheduler is to periodically interrupt execution to read (poll) the various inputs to the micro:bit (the buttons, pins, etc.) and fire off events (such as “button A pressed”). Recall that the firing of an event causes the event handler subprogram associated with that event to be queued for later execution. The scheduler uses a timer built into the micro:bit hardware to interrupt execution every 6 milliseconds and poll the inputs, which is more than fast enough to catch the quickest press of a button.
|
||||
|
||||
@ -96,9 +100,18 @@ If you hadn’t guessed already, a footballer represents subprogram and dribblin
|
||||
|
||||
We will call this “passing control of execution” rather than “passing the ball”. However, in the world of the micro:bit, the concurrently executing subprograms are not aware of each other, so they don’t actually pass control directly to one another. Rather they pass control of execution back to the scheduler and the scheduler determines the subprogram to pass control to next. The programmer inserts a call to the `pause` function to indicate a point in the subprogram where control of execution passes to the scheduler. Also, when a subprogram ends execution, control passes to the scheduler.
|
||||
|
||||
Let’s take a look at the implementation of the `forever` statement to see an example of cooperative scheduling:
|
||||
Let’s take a look at the implementation of the `basic.forever` function to see an example of cooperative scheduling:
|
||||
|
||||

|
||||
```typescript
|
||||
function forever(body: () => void) {
|
||||
control.inBackground(() => {
|
||||
while(true) {
|
||||
body()
|
||||
basic.pause(20)
|
||||
}
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
The `forever` loop actually is a function that takes a subprogram (an *Action* in Touch Develop) as a parameter. The function uses the `control -> in background` function of the micro:bit runtime to queue a `while true` loop for execution by the scheduler. The while loop has two statements. The first statement runs the subprogram represented by the `body` parameter. The second statement passes control to the scheduler (requesting to “sleep” for 20 milliseconds).
|
||||
|
||||
@ -128,15 +141,15 @@ Through this example, we have seen that the micro:bit scheduler enables you to c
|
||||
|
||||
As a result, you can easily add a new capability to the micro:bit by just adding a new subprogram. For example, if you want to add a reset feature to the counter program, all you need to do is add a new event handler for a press of button B that sets the global variable "count" to zero, as shown below:
|
||||
|
||||
```
|
||||
```typescript
|
||||
export function countButtonPressesWithReset() {
|
||||
let count = 0
|
||||
input.onButtonPressed(Button.A, () => {
|
||||
count = count + 1
|
||||
})
|
||||
basic.forever(() => {
|
||||
basic.showNumber(count, 150)
|
||||
})
|
||||
count = 0
|
||||
input.onButtonPressed(Button.B, () => {
|
||||
count = 0
|
||||
})
|
||||
|
@ -29,13 +29,21 @@ Unfortunately, using the serial library requires quite a bit of a setup.
|
||||
If you are using the Google Chrome browser, you can use our extension to get serial data streaming in the editor.
|
||||
|
||||
* Install the [Extension for BBC micro:bit](https://chrome.google.com/webstore/detail/extension-for-bbc-microbi/cihhkhnngbjlhahcfmhekmbnnjcjdbge?hl=en-US) on the Chrome Web Store.
|
||||
* Restart Chrome and open the web editor.
|
||||
* Restart Chrome and open the [web editor](https://codethemicrobit.com)
|
||||
* The serial data will show below the simulator
|
||||
|
||||
### Windows
|
||||
|
||||
You must install a device driver (for the computer to recognize the serial interface of the micro:bit); then, you must also install a terminal emulator (which is going to connect to the micro:bit and read its output). Here's how to do it:
|
||||
You must install a device driver (for the computer to recognize the
|
||||
serial interface of the micro:bit); then, you must also install a
|
||||
terminal emulator (which is going to connect to the micro:bit and read
|
||||
its output).
|
||||
|
||||
* Follow instructions at https://developer.mbed.org/handbook/Windows-serial-configuration in order to install the device driver
|
||||
* Follow the instructions at
|
||||
https://developer.mbed.org/handbook/Windows-serial-configuration to
|
||||
install the device driver.
|
||||
|
||||
* Instructions for installing a terminal emulator are below.
|
||||
|
||||
#### Windows > Tera Term
|
||||
|
||||
@ -66,14 +74,16 @@ If you prefer another terminal emulator (such as [PuTTY](http://www.putty.org/))
|
||||
|
||||
### Linux
|
||||
|
||||
(Untested).
|
||||
* Install the program `screen` if it is not already installed.
|
||||
* Plug in the micro:bit.
|
||||
* Open a terminal.
|
||||
* Find which device node the micro:bit was assigned to with the command `ls /dev/ttyACM*`.
|
||||
* If it was `/dev/ttyACM0`, type the command `screen /dev/ttyACM0 115200`. If it was some other device node,
|
||||
use that one in the command instead. **Note:** You may need root access to run `screen`
|
||||
successfully. You can probably use the command `sudo` like this: `sudo screen /dev/ttyACM0 115200`.
|
||||
* To exit `screen`, type `Ctrl-A` `Ctrl-D`.
|
||||
|
||||
* Plug in the micro:bit
|
||||
* Open a terminal
|
||||
* `dmesg | tail` will show you which `/dev/` node the micro:bit was assigned (e.g. `/dev/ttyUSB0`)
|
||||
* Then, do: `screen /dev/ttyUSB0 115200` (install the `screen` program if you don't have it). To exit, run `Ctrl-A` `Ctrl-D`.
|
||||
|
||||
Alternative programs include minicom, etc.
|
||||
Alternative programs include `minicom` and so on.
|
||||
|
||||
### Mac OS
|
||||
|
||||
|
50
docs/docs.md
50
docs/docs.md
@ -1,36 +1,26 @@
|
||||
# Documentation
|
||||
|
||||
```sim
|
||||
basic.forever(() => {
|
||||
basic.showString("DOCS ");
|
||||
})
|
||||
input.onButtonPressed(Button.A, () => {
|
||||
led.stopAnimation();
|
||||
basic.showLeds(`
|
||||
. . . . .
|
||||
. # . # .
|
||||
. . . . .
|
||||
# . . . #
|
||||
. # # # .`);
|
||||
});
|
||||
input.onButtonPressed(Button.B, () => {
|
||||
led.stopAnimation();
|
||||
basic.showLeds(`
|
||||
. # . # .
|
||||
# . # . #
|
||||
# . . . #
|
||||
. # . # .
|
||||
. . # . .`);
|
||||
});
|
||||
```
|
||||
### Things to do
|
||||
|
||||
* **[getting started](/getting-started)**
|
||||
* Get started with [projects](/projects)
|
||||
* Browse the [micro:bit APIs](/reference)
|
||||
* Learn more about the [micro:bit device](/device)
|
||||
* Frequently Asked Question [faq](/faq)
|
||||
* Follow up with the [release notes](/release-notes)
|
||||
* **[Getting Started](/getting-started)**
|
||||
* [Ten projects](/projects)
|
||||
|
||||
### Micro:bit reference
|
||||
|
||||
* [The micro:bit APIs](/reference)
|
||||
* [The micro:bit device](/device)
|
||||
|
||||
### Language and data reference
|
||||
|
||||
* [Blocks language](/blocks)
|
||||
* [JavaScript language](/javascript)
|
||||
* [Streaming data](/streaming)
|
||||
|
||||
### More questions?
|
||||
|
||||
* [Frequently Asked Question](/faq)
|
||||
* [Release notes](/release-notes)
|
||||
|
||||
### Developers
|
||||
|
||||
* Learn about [packages](/packages) (possibly using C++ or ARM thumb)
|
||||
* Learn about [packages](/packages)
|
||||
|
@ -2,18 +2,13 @@
|
||||
|
||||
## ~avatar
|
||||
|
||||
Are you ready to build cool BBC micro:bit programs?
|
||||
|
||||
Here are some challenges for you. Arrange the blocks in the editor
|
||||
to make real programs that work!
|
||||
|
||||
## ~
|
||||
|
||||
### Happy face
|
||||
|
||||
Use the **Basic** drawer in the editor (to the left)
|
||||
to drag out and arrange three blocks (two `show leds` and one `forever` block)
|
||||
to create this program:
|
||||
Use the **Basic** drawer in the editor
|
||||
to drag out and arrange three blocks to create this program:
|
||||
|
||||
```blocks
|
||||
basic.forever(() => {
|
||||
@ -34,470 +29,13 @@ basic.forever(() => {
|
||||
});
|
||||
```
|
||||
|
||||
When you run this program (click the **Play** button) you will see a smiley face, then a blank
|
||||
When this program runs, you will see a smiley face, then a blank
|
||||
screen, then a smiley again -- it never stops! (That's because of the
|
||||
``forever`` block.)
|
||||
|
||||
Click **Compile** to move your program to the BBC micro:bit!
|
||||
Click **Compile** to move your program to the BBC micro:bit!
|
||||
Make sure to follow the instructions.
|
||||
|
||||
### Happy unhappy face
|
||||
|
||||
Draw an unhappy face instead of the blank screen. Click on the dots
|
||||
in the second ``show leds`` block until it matches the blocks below.
|
||||
Now you have an **animation** (cartoon) that shows a happy face,
|
||||
then an unhappy one, then a happy one again, forever (or until
|
||||
you turn off your micro:bit)!
|
||||
|
||||
```blocks
|
||||
basic.forever(() => {
|
||||
basic.showLeds(`
|
||||
. . . . .
|
||||
. # . # .
|
||||
. . . . .
|
||||
# . . . #
|
||||
. # # # .
|
||||
`)
|
||||
basic.showLeds(`
|
||||
. . . . .
|
||||
. # . # .
|
||||
. . . . .
|
||||
. # # # .
|
||||
# . . . #
|
||||
`)
|
||||
});
|
||||
```
|
||||
Click **Compile** to move your program to the BBC micro:bit!
|
||||
|
||||
### Your turn!
|
||||
|
||||
Pile up more ``show leds`` blocks to create an animation! Create an
|
||||
animation with at least 5 pictures. What does this animation show?
|
||||
|
||||
```blocks
|
||||
basic.forever(() => {
|
||||
basic.showLeds(`
|
||||
. . . . .
|
||||
. # . # .
|
||||
. . . . .
|
||||
# . . . #
|
||||
. # # # .
|
||||
`)
|
||||
basic.showLeds(`
|
||||
. . . . .
|
||||
. # . # .
|
||||
. . . . .
|
||||
# # # # #
|
||||
. . . . .
|
||||
`)
|
||||
basic.showLeds(`
|
||||
. . . . .
|
||||
. # . # .
|
||||
. . . . .
|
||||
. # # # .
|
||||
# . . . #
|
||||
`)
|
||||
basic.showLeds(`
|
||||
. . . . .
|
||||
. # . # .
|
||||
. . . . .
|
||||
# # # # #
|
||||
. . . # #
|
||||
`)
|
||||
basic.showLeds(`
|
||||
. . . . .
|
||||
# . # . .
|
||||
. . . . .
|
||||
# . . . #
|
||||
. # # # .
|
||||
`)
|
||||
basic.showLeds(`
|
||||
. . . . .
|
||||
. . # . #
|
||||
. . . . .
|
||||
# . . . #
|
||||
. # # # .
|
||||
`)
|
||||
});
|
||||
```
|
||||
Click **Compile** to move your program to the BBC micro:bit!
|
||||
|
||||
#### ~hint
|
||||
|
||||
You can find the ``show leds`` block in the **Basic** part of the editor.
|
||||
|
||||
#### ~
|
||||
|
||||
### Button A and button B
|
||||
|
||||
This program will show the word **ANTEATER** on the LED
|
||||
screen when you press button `A`.
|
||||
|
||||
```blocks
|
||||
input.onButtonPressed(Button.A, () => {
|
||||
basic.showString("ANTEATER");
|
||||
});
|
||||
```
|
||||
|
||||
#### ~hint
|
||||
|
||||
The ``showString`` block can show letters, numbers, and punctuation
|
||||
on the micro:bit screen.
|
||||
|
||||
#### ~
|
||||
|
||||
Now try to unscramble these blocks in the editor so that the micro:bit
|
||||
shows **BANANA** when you press button `B`.
|
||||
|
||||
```shuffle
|
||||
input.onButtonPressed(Button.B, () => {
|
||||
basic.showString("BANANA");
|
||||
});
|
||||
```
|
||||
#### ~hint
|
||||
|
||||
You can find the letter `B` by clicking the letter `A` on the
|
||||
``onButtonPressed`` block.
|
||||
|
||||
#### ~
|
||||
|
||||
Click **Compile** to move your program to the BBC micro:bit!
|
||||
|
||||
#### Your turn!
|
||||
|
||||
Can you combine these blocks so your program shows your real name
|
||||
instead of **ANTEATER** when you press `A`, but _your secret agent
|
||||
name_ instead of **BANANA** when you press `B`?
|
||||
|
||||
### Shake
|
||||
|
||||
You can find when someone is shaking the BBC micro:bit by checking its
|
||||
**accelerometer** (it finds whether the micro:bit is speeding up or
|
||||
slowing down).
|
||||
|
||||
Unscramble these blocks in the editor to show a frownie when someone
|
||||
shakes the micro:bit. (Ouch!)
|
||||
|
||||
```shuffle
|
||||
input.onGesture(Gesture.Shake, () => {
|
||||
basic.showLeds(`
|
||||
. . . . .
|
||||
. # . # .
|
||||
. . . . .
|
||||
. # # # .
|
||||
# . . . #`);
|
||||
});
|
||||
```
|
||||
Click **Compile** to move your program to the BBC micro:bit!
|
||||
|
||||
### Pins
|
||||
|
||||
You can also use the pins as buttons. (The pins are the holes in the
|
||||
metal stripe at the bottom of the micro:bit board.) For example, hold
|
||||
the ``GND`` button with one hand and touch the ``0`` pin (called
|
||||
``P0``) with your other hand to tell the micro:bit you're pressing it.
|
||||
|
||||
Unscramble the blocks in the editor to show a heart when you touch
|
||||
pin ``P0``.
|
||||
|
||||
```shuffle
|
||||
input.onPinPressed(TouchPin.P0, () => {
|
||||
basic.showLeds(`
|
||||
. # . # .
|
||||
# . # . #
|
||||
# . . . #
|
||||
. # . # .
|
||||
. . # . .`);
|
||||
});
|
||||
```
|
||||
Click **Compile** to move your program to the BBC micro:bit!
|
||||
|
||||
## ~hint
|
||||
|
||||
Try this experiment: find a friend and hold hands. Touch the ``GND``
|
||||
pin while your friend presses the ``P0`` pin. You should see the
|
||||
heart! The electric current is going through your bodies and across
|
||||
your handshake to make it happen!
|
||||
|
||||
## ~
|
||||
|
||||
## The amazing coin flipper
|
||||
|
||||
### ~avatar avatar
|
||||
|
||||
Are you trying to choose whether to play soccer or go to the movies
|
||||
instead, or which toppings to have on your pizza? Build a coin
|
||||
flipping machine with the BBC micro:bit to choose for you!
|
||||
|
||||
### ~
|
||||
|
||||
Here are the blocks to make your coin flipper. When you press button
|
||||
`B`, the coin flipper will show either `H` for heads or `T` for tails
|
||||
on the LED screen.
|
||||
|
||||
```blocks
|
||||
input.onButtonPressed(Button.B, () => {
|
||||
if (Math.randomBoolean()) {
|
||||
basic.showString("H");
|
||||
} else {
|
||||
basic.showString("T");
|
||||
}
|
||||
});
|
||||
```
|
||||
### ~hint
|
||||
|
||||
The ``pick random true or false`` block randomly tells the ``if``
|
||||
block `true` or `false`. If the ``pick`` block picked `true`, the
|
||||
``if`` block shows the letter `H`. Otherwise, it shows the letter `T`.
|
||||
|
||||
That's it!
|
||||
|
||||
### ~
|
||||
|
||||
### Keeping score
|
||||
|
||||
#### ~avatar
|
||||
|
||||
To keep track out of how many guesses you've won,
|
||||
add these blocks to your coin flipper:
|
||||
|
||||
#### ~
|
||||
|
||||
```blocks
|
||||
input.onButtonPressed(Button.A, () => {
|
||||
game.addScore(1);
|
||||
});
|
||||
input.onButtonPressed(Button.AB, () => {
|
||||
basic.showNumber(game.score());
|
||||
});
|
||||
```
|
||||
|
||||
These blocks mean that if you press button `A`, you will add `1` to
|
||||
your score, and if you press `A` and `B` together, the micro:bit will
|
||||
show your score.
|
||||
|
||||
When you're done, your coin flipping program should look like this:
|
||||
|
||||
```blocks
|
||||
input.onButtonPressed(Button.B, () => {
|
||||
if (Math.randomBoolean()) {
|
||||
basic.showString("H");
|
||||
} else {
|
||||
basic.showString("T");
|
||||
}
|
||||
});
|
||||
input.onButtonPressed(Button.A, () => {
|
||||
game.addScore(1);
|
||||
});
|
||||
input.onButtonPressed(Button.AB, () => {
|
||||
basic.showNumber(game.score());
|
||||
});
|
||||
```
|
||||
|
||||
Flip until your thumbs get tired!
|
||||
|
||||
## Let's play Rock Paper Scissors!
|
||||
|
||||
### ~avatar avatar
|
||||
|
||||
Build a Rock Paper Scissors game with the BBC micro:bit! You can play
|
||||
the game with a friend who has it on a micro:bit. You can also play
|
||||
it with friends who are just using their hands. (The game is built
|
||||
like a coin flipper, but with three choices instead of two.)
|
||||
|
||||
### ~
|
||||
|
||||
## Step 1: Getting started
|
||||
|
||||
We want the micro:bit to choose rock, paper, or scissors when you
|
||||
shake it. Try creating an ``on shake`` block so when you shake the
|
||||
micro:bit, it will run part of a program.
|
||||
|
||||
Clear up the blocks and add the blocks below.
|
||||
|
||||
```blocks
|
||||
input.onGesture(Gesture.Shake, () => {
|
||||
|
||||
})
|
||||
```
|
||||
|
||||
Next, when you shake the micro:bit, it should pick a random number from `0` to `2`
|
||||
and store it in the variable `item`.
|
||||
|
||||
Add a ``set`` block with a variable. Then add a ``pick random`` block,
|
||||
and store the random number in the variable,
|
||||
like this:
|
||||
|
||||
```blocks
|
||||
input.onGesture(Gesture.Shake, () => {
|
||||
let item = Math.random(3)
|
||||
})
|
||||
|
||||
```
|
||||
|
||||
### ~hint
|
||||
No one can predict random numbers. That's what makes them great for Rock Paper Scissors!
|
||||
### ~
|
||||
|
||||
Each possible number these blocks can make (`0`, `1`, or `2`) means a different picture.
|
||||
We will show the right picture for that number on the LED screen.
|
||||
|
||||
|
||||
## Step 2: Picking paper
|
||||
|
||||
Put an ``if`` block after the ``let`` block that checks whether
|
||||
`item` is `0`. Make sure the ``if`` block has an ``else if`` part
|
||||
and an ``else`` part.
|
||||
|
||||
Next, add a ``show leds`` block that shows a
|
||||
picture of a piece of paper:
|
||||
|
||||
```blocks
|
||||
input.onGesture(Gesture.Shake, () => {
|
||||
let item = Math.random(3)
|
||||
if (item == 0) {
|
||||
basic.showLeds(`
|
||||
# # # # #
|
||||
# . . . #
|
||||
# . . . #
|
||||
# . . . #
|
||||
# # # # #
|
||||
`)
|
||||
} else if (false) {
|
||||
|
||||
} else {
|
||||
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
## Step 3: A random rock
|
||||
|
||||
Now we are going to add a new picture for the micro:bit to show
|
||||
when another random number comes up.
|
||||
|
||||
Make the ``else if`` part check if the variable `item` is `1`.
|
||||
Then add a ``show leds`` block with a picture of a rock.
|
||||
|
||||
```blocks
|
||||
input.onGesture(Gesture.Shake, () => {
|
||||
let item = Math.random(3)
|
||||
if (item == 0) {
|
||||
basic.showLeds(`
|
||||
# # # # #
|
||||
# . . . #
|
||||
# . . . #
|
||||
# . . . #
|
||||
# # # # #
|
||||
`)
|
||||
} else if (item == 1) {
|
||||
basic.showLeds(`
|
||||
. . . . .
|
||||
. # # # .
|
||||
. # # # .
|
||||
. # # # .
|
||||
. . . . .
|
||||
`)
|
||||
} else {
|
||||
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
## Step 4: Suddenly scissors
|
||||
|
||||
Add a ``show leds`` block with a picture of scissors to the ``else`` part:
|
||||
|
||||
```blocks
|
||||
input.onGesture(Gesture.Shake, () => {
|
||||
let item = Math.random(3)
|
||||
if (item == 0) {
|
||||
basic.showLeds(`
|
||||
# # # # #
|
||||
# . . . #
|
||||
# . . . #
|
||||
# . . . #
|
||||
# # # # #
|
||||
`)
|
||||
|
||||
} else if (item == 1) {
|
||||
basic.showLeds(`
|
||||
. . . . .
|
||||
. # # # .
|
||||
. # # # .
|
||||
. # # # .
|
||||
. . . . .
|
||||
`)
|
||||
} else {
|
||||
basic.showLeds(`
|
||||
# # . . #
|
||||
# # . # .
|
||||
. . # . .
|
||||
# # . # .
|
||||
# # . . #
|
||||
`)
|
||||
}
|
||||
})
|
||||
|
||||
```
|
||||
|
||||
### ~hint
|
||||
|
||||
You don't need to check if `item` is `2` because `2` is the only number left out of `0`, `1`, and `2`.
|
||||
That's why you can use an ``else`` instead of an ``else if``.
|
||||
|
||||
### ~
|
||||
|
||||
Your game is ready!
|
||||
|
||||
Click **Compile** to move your program to the BBC micro:bit!
|
||||
|
||||
Have fun!
|
||||
|
||||
## Step 5: Are you the greatest?
|
||||
|
||||
Here is a way you can make your Rock Paper Scissors game better.
|
||||
When button ``A`` is pressed,
|
||||
the micro:bit will add `1` to your score.
|
||||
|
||||
Open the ``Game`` drawer, and then add the block ``change score by 1`` to your program,
|
||||
like this:
|
||||
|
||||
```blocks
|
||||
input.onButtonPressed(Button.A, () => {
|
||||
game.addScore(1)
|
||||
})
|
||||
|
||||
```
|
||||
|
||||
## Step 6: Prove you're the greatest!
|
||||
|
||||
After your micro:bit can add `1` to the score, show how many wins you have.
|
||||
|
||||
```blocks
|
||||
input.onButtonPressed(Button.A, () => {
|
||||
game.addScore(1)
|
||||
basic.showString("WINS:")
|
||||
basic.showNumber(game.score())
|
||||
})
|
||||
```
|
||||
## Step 7: Staying honest
|
||||
|
||||
Success! Your micro:bit can track wins!
|
||||
But what about losses?
|
||||
Use the ``Game`` drawer to subtract `1` from your score when you press button `B`.
|
||||
|
||||
Here are all the blocks you will need:
|
||||
|
||||
```shuffle
|
||||
input.onButtonPressed(Button.B, () => {
|
||||
game.addScore(-1)
|
||||
basic.showString("LOSSES:")
|
||||
basic.showNumber(game.score())
|
||||
})
|
||||
```
|
||||
Click **Compile** to move your program to the BBC micro:bit!
|
||||
|
||||
|
||||
# Want to do more?
|
||||
|
||||
There are [10 great projects](/projects) waiting for you.
|
||||
### ~button /getting-started/screen
|
||||
NEXT: THE SCREEN
|
||||
### ~
|
81
docs/getting-started/buttons.md
Normal file
81
docs/getting-started/buttons.md
Normal file
@ -0,0 +1,81 @@
|
||||
# Button A and button B
|
||||
|
||||
### ~avatar avatar
|
||||
|
||||
Buttons are great to build games!
|
||||
|
||||
### ~
|
||||
|
||||
This program will show the word **ANTEATER** on the LED
|
||||
screen when you press button `A`.
|
||||
|
||||
```blocks
|
||||
input.onButtonPressed(Button.A, () => {
|
||||
basic.showString("ANTEATER");
|
||||
});
|
||||
```
|
||||
|
||||
#### ~hint
|
||||
|
||||
The ``showString`` block can show letters, numbers, and punctuation
|
||||
on the micro:bit screen.
|
||||
|
||||
#### ~
|
||||
|
||||
Now try to unscramble these blocks in the editor so that the micro:bit
|
||||
shows **BANANA** when you press button `B`.
|
||||
|
||||
```shuffle
|
||||
input.onButtonPressed(Button.B, () => {
|
||||
basic.showString("BANANA");
|
||||
});
|
||||
```
|
||||
#### ~hint
|
||||
|
||||
You can find the letter `B` by clicking the letter `A` on the
|
||||
``onButtonPressed`` block.
|
||||
|
||||
#### ~
|
||||
|
||||
Click **Compile** to move your program to the BBC micro:bit!
|
||||
|
||||
#### Your turn!
|
||||
|
||||
Can you combine these blocks so your program shows your real name
|
||||
instead of **ANTEATER** when you press `A`, but _your secret agent
|
||||
name_ instead of **BANANA** when you press `B`?
|
||||
|
||||
### Pins
|
||||
|
||||
You can also use the pins as buttons. (The pins are the holes in the
|
||||
metal stripe at the bottom of the micro:bit board.) For example, hold
|
||||
the ``GND`` button with one hand and touch the ``0`` pin (called
|
||||
``P0``) with your other hand to tell the micro:bit you're pressing it.
|
||||
|
||||
Unscramble the blocks in the editor to show a heart when you touch
|
||||
pin ``P0``.
|
||||
|
||||
```shuffle
|
||||
input.onPinPressed(TouchPin.P0, () => {
|
||||
basic.showLeds(`
|
||||
. # . # .
|
||||
# . # . #
|
||||
# . . . #
|
||||
. # . # .
|
||||
. . # . .`);
|
||||
});
|
||||
```
|
||||
Click **Compile** to move your program to the BBC micro:bit!
|
||||
|
||||
## ~hint
|
||||
|
||||
Try this experiment: find a friend and hold hands. Touch the ``GND``
|
||||
pin while your friend presses the ``P0`` pin. You should see the
|
||||
heart! The electric current is going through your bodies and across
|
||||
your handshake to make it happen!
|
||||
|
||||
## ~
|
||||
|
||||
### ~button /getting-started/shake
|
||||
NEXT: SHAKE
|
||||
### ~
|
78
docs/getting-started/coin-flipper.md
Normal file
78
docs/getting-started/coin-flipper.md
Normal file
@ -0,0 +1,78 @@
|
||||
# The amazing coin flipper
|
||||
|
||||
### ~avatar avatar
|
||||
|
||||
Are you trying to choose whether to play soccer or go to the movies
|
||||
instead, or which toppings to have on your pizza? Build a coin
|
||||
flipping machine with the BBC micro:bit to choose for you!
|
||||
|
||||
### ~
|
||||
|
||||
Here are the blocks to make your coin flipper. When you press button
|
||||
`B`, the coin flipper will show either `H` for heads or `T` for tails
|
||||
on the LED screen.
|
||||
|
||||
```blocks
|
||||
input.onButtonPressed(Button.B, () => {
|
||||
if (Math.randomBoolean()) {
|
||||
basic.showString("H");
|
||||
} else {
|
||||
basic.showString("T");
|
||||
}
|
||||
});
|
||||
```
|
||||
### ~hint
|
||||
|
||||
The ``pick random true or false`` block randomly tells the ``if``
|
||||
block `true` or `false`. If the ``pick`` block picked `true`, the
|
||||
``if`` block shows the letter `H`. Otherwise, it shows the letter `T`.
|
||||
|
||||
That's it!
|
||||
|
||||
### ~
|
||||
|
||||
### Keeping score
|
||||
|
||||
#### ~avatar
|
||||
|
||||
To keep track out of how many guesses you've won,
|
||||
add these blocks to your coin flipper:
|
||||
|
||||
#### ~
|
||||
|
||||
```blocks
|
||||
input.onButtonPressed(Button.A, () => {
|
||||
game.addScore(1);
|
||||
});
|
||||
input.onButtonPressed(Button.AB, () => {
|
||||
basic.showNumber(game.score());
|
||||
});
|
||||
```
|
||||
|
||||
These blocks mean that if you press button `A`, you will add `1` to
|
||||
your score, and if you press `A` and `B` together, the micro:bit will
|
||||
show your score.
|
||||
|
||||
When you're done, your coin flipping program should look like this:
|
||||
|
||||
```blocks
|
||||
input.onButtonPressed(Button.B, () => {
|
||||
if (Math.randomBoolean()) {
|
||||
basic.showString("H");
|
||||
} else {
|
||||
basic.showString("T");
|
||||
}
|
||||
});
|
||||
input.onButtonPressed(Button.A, () => {
|
||||
game.addScore(1);
|
||||
});
|
||||
input.onButtonPressed(Button.AB, () => {
|
||||
basic.showNumber(game.score());
|
||||
});
|
||||
```
|
||||
|
||||
Flip until your thumbs get tired!
|
||||
|
||||
### ~button /getting-started/rock-paper-scissors
|
||||
NEXT: ROCK PAPER SCISSORS
|
||||
### ~
|
205
docs/getting-started/rock-paper-scissors.md
Normal file
205
docs/getting-started/rock-paper-scissors.md
Normal file
@ -0,0 +1,205 @@
|
||||
# Rock Paper Scissors
|
||||
|
||||
### ~avatar avatar
|
||||
|
||||
Build a Rock Paper Scissors game with the BBC micro:bit! You can play
|
||||
the game with a friend who has it on a micro:bit. You can also play
|
||||
it with friends who are just using their hands. (The game is built
|
||||
like a coin flipper, but with three choices instead of two.)
|
||||
|
||||
### ~
|
||||
|
||||
## Step 1: Getting started
|
||||
|
||||
We want the micro:bit to choose rock, paper, or scissors when you
|
||||
shake it. Try creating an ``on shake`` block so when you shake the
|
||||
micro:bit, it will run part of a program.
|
||||
|
||||
Clear up the blocks and add the blocks below.
|
||||
|
||||
```blocks
|
||||
input.onGesture(Gesture.Shake, () => {
|
||||
|
||||
})
|
||||
```
|
||||
|
||||
Next, when you shake the micro:bit, it should pick a random number from `0` to `2`
|
||||
and store it in the variable `item`.
|
||||
|
||||
Add a ``set`` block with a variable. Then add a ``pick random`` block,
|
||||
and store the random number in the variable,
|
||||
like this:
|
||||
|
||||
```blocks
|
||||
input.onGesture(Gesture.Shake, () => {
|
||||
let item = Math.random(3)
|
||||
})
|
||||
|
||||
```
|
||||
|
||||
### ~hint
|
||||
No one can predict random numbers. That's what makes them great for Rock Paper Scissors!
|
||||
### ~
|
||||
|
||||
Each possible number these blocks can make (`0`, `1`, or `2`) means a different picture.
|
||||
We will show the right picture for that number on the LED screen.
|
||||
|
||||
|
||||
## Step 2: Picking paper
|
||||
|
||||
Put an ``if`` block after the ``let`` block that checks whether
|
||||
`item` is `0`. Make sure the ``if`` block has an ``else if`` part
|
||||
and an ``else`` part.
|
||||
|
||||
Next, add a ``show leds`` block that shows a
|
||||
picture of a piece of paper:
|
||||
|
||||
```blocks
|
||||
input.onGesture(Gesture.Shake, () => {
|
||||
let item = Math.random(3)
|
||||
if (item == 0) {
|
||||
basic.showLeds(`
|
||||
# # # # #
|
||||
# . . . #
|
||||
# . . . #
|
||||
# . . . #
|
||||
# # # # #
|
||||
`)
|
||||
} else if (false) {
|
||||
|
||||
} else {
|
||||
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
## Step 3: A random rock
|
||||
|
||||
Now we are going to add a new picture for the micro:bit to show
|
||||
when another random number comes up.
|
||||
|
||||
Make the ``else if`` part check if the variable `item` is `1`.
|
||||
Then add a ``show leds`` block with a picture of a rock.
|
||||
|
||||
```blocks
|
||||
input.onGesture(Gesture.Shake, () => {
|
||||
let item = Math.random(3)
|
||||
if (item == 0) {
|
||||
basic.showLeds(`
|
||||
# # # # #
|
||||
# . . . #
|
||||
# . . . #
|
||||
# . . . #
|
||||
# # # # #
|
||||
`)
|
||||
} else if (item == 1) {
|
||||
basic.showLeds(`
|
||||
. . . . .
|
||||
. # # # .
|
||||
. # # # .
|
||||
. # # # .
|
||||
. . . . .
|
||||
`)
|
||||
} else {
|
||||
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
## Step 4: Suddenly scissors
|
||||
|
||||
Add a ``show leds`` block with a picture of scissors to the ``else`` part:
|
||||
|
||||
```blocks
|
||||
input.onGesture(Gesture.Shake, () => {
|
||||
let item = Math.random(3)
|
||||
if (item == 0) {
|
||||
basic.showLeds(`
|
||||
# # # # #
|
||||
# . . . #
|
||||
# . . . #
|
||||
# . . . #
|
||||
# # # # #
|
||||
`)
|
||||
|
||||
} else if (item == 1) {
|
||||
basic.showLeds(`
|
||||
. . . . .
|
||||
. # # # .
|
||||
. # # # .
|
||||
. # # # .
|
||||
. . . . .
|
||||
`)
|
||||
} else {
|
||||
basic.showLeds(`
|
||||
# # . . #
|
||||
# # . # .
|
||||
. . # . .
|
||||
# # . # .
|
||||
# # . . #
|
||||
`)
|
||||
}
|
||||
})
|
||||
|
||||
```
|
||||
|
||||
### ~hint
|
||||
|
||||
You don't need to check if `item` is `2` because `2` is the only number left out of `0`, `1`, and `2`.
|
||||
That's why you can use an ``else`` instead of an ``else if``.
|
||||
|
||||
### ~
|
||||
|
||||
Your game is ready!
|
||||
|
||||
Click **Compile** to move your program to the BBC micro:bit!
|
||||
|
||||
Have fun!
|
||||
|
||||
## Step 5: Are you the greatest?
|
||||
|
||||
Here is a way you can make your Rock Paper Scissors game better.
|
||||
When button ``A`` is pressed,
|
||||
the micro:bit will add `1` to your score.
|
||||
|
||||
Open the ``Game`` drawer, and then add the block ``change score by 1`` to your program,
|
||||
like this:
|
||||
|
||||
```blocks
|
||||
input.onButtonPressed(Button.A, () => {
|
||||
game.addScore(1)
|
||||
})
|
||||
|
||||
```
|
||||
|
||||
## Step 6: Prove you're the greatest!
|
||||
|
||||
After your micro:bit can add `1` to the score, show how many wins you have.
|
||||
|
||||
```blocks
|
||||
input.onButtonPressed(Button.A, () => {
|
||||
game.addScore(1)
|
||||
basic.showString("WINS:")
|
||||
basic.showNumber(game.score())
|
||||
})
|
||||
```
|
||||
## Step 7: Staying honest
|
||||
|
||||
Success! Your micro:bit can track wins!
|
||||
But what about losses?
|
||||
Use the ``Game`` drawer to subtract `1` from your score when you press button `B`.
|
||||
|
||||
Here are all the blocks you will need:
|
||||
|
||||
```shuffle
|
||||
input.onButtonPressed(Button.B, () => {
|
||||
game.addScore(-1)
|
||||
basic.showString("LOSSES:")
|
||||
basic.showNumber(game.score())
|
||||
})
|
||||
```
|
||||
Click **Compile** to move your program to the BBC micro:bit!
|
||||
|
||||
### ~button /projects
|
||||
NEXT: PROJECTS!
|
||||
### ~
|
98
docs/getting-started/screen.md
Normal file
98
docs/getting-started/screen.md
Normal file
@ -0,0 +1,98 @@
|
||||
# Screen
|
||||
|
||||
### ~avatar avatar
|
||||
|
||||
There are 25 bright LEDs on the micro:bit screen. Let's use them to create some cool animations!
|
||||
|
||||
### ~
|
||||
|
||||
### Happy unhappy face
|
||||
|
||||
Draw an unhappy face instead of the blank screen. Click on the dots
|
||||
in the second ``show leds`` block until it matches the blocks below.
|
||||
Now you have an **animation** (cartoon) that shows a happy face,
|
||||
then an unhappy one, then a happy one again, forever (or until
|
||||
you turn off your micro:bit)!
|
||||
|
||||
```blocks
|
||||
basic.forever(() => {
|
||||
basic.showLeds(`
|
||||
. . . . .
|
||||
. # . # .
|
||||
. . . . .
|
||||
# . . . #
|
||||
. # # # .
|
||||
`)
|
||||
basic.showLeds(`
|
||||
. . . . .
|
||||
. # . # .
|
||||
. . . . .
|
||||
. # # # .
|
||||
# . . . #
|
||||
`)
|
||||
});
|
||||
```
|
||||
Click **Compile** to move your program to the BBC micro:bit!
|
||||
|
||||
### Your turn!
|
||||
|
||||
Pile up more ``show leds`` blocks to create an animation! Create an
|
||||
animation with at least 5 pictures. What does this animation show?
|
||||
|
||||
```blocks
|
||||
basic.forever(() => {
|
||||
basic.showLeds(`
|
||||
. . . . .
|
||||
. # . # .
|
||||
. . . . .
|
||||
# . . . #
|
||||
. # # # .
|
||||
`)
|
||||
basic.showLeds(`
|
||||
. . . . .
|
||||
. # . # .
|
||||
. . . . .
|
||||
# # # # #
|
||||
. . . . .
|
||||
`)
|
||||
basic.showLeds(`
|
||||
. . . . .
|
||||
. # . # .
|
||||
. . . . .
|
||||
. # # # .
|
||||
# . . . #
|
||||
`)
|
||||
basic.showLeds(`
|
||||
. . . . .
|
||||
. # . # .
|
||||
. . . . .
|
||||
# # # # #
|
||||
. . . # #
|
||||
`)
|
||||
basic.showLeds(`
|
||||
. . . . .
|
||||
# . # . .
|
||||
. . . . .
|
||||
# . . . #
|
||||
. # # # .
|
||||
`)
|
||||
basic.showLeds(`
|
||||
. . . . .
|
||||
. . # . #
|
||||
. . . . .
|
||||
# . . . #
|
||||
. # # # .
|
||||
`)
|
||||
});
|
||||
```
|
||||
Click **Compile** to move your program to the BBC micro:bit!
|
||||
|
||||
#### ~hint
|
||||
|
||||
You can find the ``show leds`` block in the **Basic** part of the editor.
|
||||
|
||||
#### ~
|
||||
|
||||
### ~button /getting-started/buttons
|
||||
NEXT: BUTTONS
|
||||
### ~
|
24
docs/getting-started/shake.md
Normal file
24
docs/getting-started/shake.md
Normal file
@ -0,0 +1,24 @@
|
||||
# Shake
|
||||
|
||||
You can find when someone is shaking the BBC micro:bit by checking its
|
||||
**accelerometer** (it finds whether the micro:bit is speeding up or
|
||||
slowing down).
|
||||
|
||||
Unscramble these blocks in the editor to show a frownie when someone
|
||||
shakes the micro:bit. (Ouch!)
|
||||
|
||||
```shuffle
|
||||
input.onGesture(Gesture.Shake, () => {
|
||||
basic.showLeds(`
|
||||
. . . . .
|
||||
. # . # .
|
||||
. . . . .
|
||||
. # # # .
|
||||
# . . . #`);
|
||||
});
|
||||
```
|
||||
Click **Compile** to move your program to the BBC micro:bit!
|
||||
|
||||
### ~button /getting-started/coin-flipper
|
||||
NEXT: COIN FLIPPER GAME
|
||||
### ~
|
@ -1,75 +1,41 @@
|
||||
# JavaScript
|
||||
# JavaScript and TypeScript
|
||||
|
||||
You can write micro:bit programs in a subset of [TypeScript](https://www.typescriptlang.org), a superset of JavaScript.
|
||||
Many micro:bit programs, especially at the beginner's level, are just plain JavaScript. TypeScript introduces class-based
|
||||
object-oriented programming, such as:
|
||||
Visit the cards below to starting programming JavaScript and TypeScript with the micro:bit:
|
||||
|
||||
```typescript
|
||||
class Greeter {
|
||||
greeting: string;
|
||||
constructor(message: string) {
|
||||
this.greeting = message;
|
||||
}
|
||||
greet() {
|
||||
return "Hello, " + this.greeting;
|
||||
}
|
||||
```codecard
|
||||
[{
|
||||
"name": "Calling",
|
||||
"url": "/js/call"
|
||||
},{
|
||||
"name": "Sequencing",
|
||||
"url": "/js/sequence"
|
||||
},{
|
||||
"name": "Variables",
|
||||
"url": "/js/variables"
|
||||
},{
|
||||
"name": "Operators",
|
||||
"url": "/js/operators"
|
||||
},{
|
||||
"name": "Statements",
|
||||
"url": "/js/statements"
|
||||
},{
|
||||
"name": "Functions",
|
||||
"url": "/js/functions"
|
||||
},{
|
||||
"name": "Types",
|
||||
"url": "/js/types"
|
||||
},{
|
||||
"name": "Classes",
|
||||
"url": "/js/classes"
|
||||
},{
|
||||
"name": "FAQ",
|
||||
"url": "/js/faq"
|
||||
}
|
||||
]
|
||||
|
||||
let greeter = new Greeter("world");
|
||||
basic.showString(greeter.greet())
|
||||
```
|
||||
|
||||
This site is meant for teaching programming first, and JavaScript second. For this
|
||||
reason, we have stayed away from concepts that are specific to JavaScript (for
|
||||
example, prototype inheritance), and instead focused on ones common to most
|
||||
modern programming languages (for example, loops, lexically scoped variables,
|
||||
functions, classes, lambdas).
|
||||
### See Also
|
||||
|
||||
We leverage TypeScript's [type inference](http://www.typescriptlang.org/docs/handbook/type-inference.html) so that
|
||||
students need not specify types when clear from context.
|
||||
|
||||
## Supported language features
|
||||
|
||||
* top-level code in the file: "Hello world!" really is just `basic.showString("Hello world!")`
|
||||
* [basic types](http://www.typescriptlang.org/docs/handbook/basic-types.html)
|
||||
* [variable declarations](http://www.typescriptlang.org/docs/handbook/variable-declarations.html): `let`, `const`, and `var`
|
||||
* [functions](http://www.typescriptlang.org/docs/handbook/functions.html) with lexical scoping and recursion
|
||||
|
||||
### User-defined types and modules
|
||||
|
||||
* [classes](http://www.typescriptlang.org/docs/handbook/classes.html) with fields, methods and constructors; `new` keyword
|
||||
* [enums](http://www.typescriptlang.org/docs/handbook/enums.html)
|
||||
* [namespaces](http://www.typescriptlang.org/docs/handbook/namespaces.html) (a form of modules)
|
||||
|
||||
### Control-flow constructs
|
||||
|
||||
* `if ... else if ... else` statements
|
||||
* `while` and `do ... while` loops
|
||||
* `for(;;)` loops (see below about `for ... in/of`)
|
||||
* `break/continue`; also with labeled loops
|
||||
* `switch` statement (on numbers only)
|
||||
* `debugger` statement for breakpoints
|
||||
|
||||
### Expressions
|
||||
|
||||
* conditional operator `? :`; lazy boolean operators
|
||||
* all arithmetic operators (including bitwise operators); note that in microcontroller targets
|
||||
all arithmetic is performed on integers, also when simulating in the browser
|
||||
* strings (with a few common methods)
|
||||
* [string templates](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals) (`` `x is ${x}` ``)
|
||||
* arrow functions `() => ...`
|
||||
* array literals `[1, 2, 3]`
|
||||
|
||||
|
||||
## Unsupported language features
|
||||
|
||||
We generally stay away from the more dynamic parts of JavaScript.
|
||||
Things you may miss and we may implement:
|
||||
|
||||
* exceptions (`throw`, `try ... catch`, `try ... finally`)
|
||||
* `for ... of` statements
|
||||
* object literals `{ foo: 1, bar: "two" }`
|
||||
* method-like properties (get/set accessors)
|
||||
* class inheritance
|
||||
|
||||
If there is something you'd like to see, please file an issue at [GitHub](http://github.com/microsoft/pxt/issues).
|
||||
[calling](/js/call), [sequencing](/js/sequence), [variables](/js/variables), [operators](/js/operators), [statements](/js/statements), [functions](/js/functions),
|
||||
[types](/js/types), [classes](/js/classes), [FAQ](/js/faq)
|
58
docs/js/call.md
Normal file
58
docs/js/call.md
Normal file
@ -0,0 +1,58 @@
|
||||
# Call a function
|
||||
|
||||
The simplest way to get started in JavaScript with your micro:bit is to
|
||||
call one of the micro:bit's built-in JavaScript functions. Just like Blocks
|
||||
are organized into categories/drawers, the micro:bit functions are organized by
|
||||
namespaces, with names corresponding to the drawer names. The `basic` namespace
|
||||
contains a number of helpful functions, such as:
|
||||
|
||||
```typescript
|
||||
basic.showString("Hello!")
|
||||
```
|
||||
|
||||
If you want to see all functions available in the `basic` namespace, simply type `basic`
|
||||
followed by `.` and a list of all the functions will appear.
|
||||
|
||||

|
||||
|
||||
This feature is known as "Intellisense". Continue typing to select one of the functions,
|
||||
or click on one of the functions to select. You also narrow down the set of functions by typing, as below:
|
||||
|
||||

|
||||
|
||||
You can type anything to see what Intellisense will find for you. Here's an example
|
||||
of what happens when you type the word `for`:
|
||||

|
||||
|
||||
## Function parameter values
|
||||
|
||||
You might have noticed that the call `showString` above takes one parameter value,
|
||||
the string to be scrolled on the LED screen. There is a second (optional)
|
||||
parameter that controls the speed of the scroll. Try this:
|
||||
|
||||
```typescript
|
||||
basic.showString("Hello!",50)
|
||||
```
|
||||
|
||||
Intellisense shows all the available parameters for a function.
|
||||
|
||||
## Left and right parentheses, please!
|
||||
|
||||
Whenever you want to call a function, you give the name of the function
|
||||
followed by `(` and ending with `)`. Inbetween the left and right
|
||||
parentheses go the function arguments. If a function has zero arguments, you still
|
||||
need the parentheses in order to call the function. For example
|
||||
|
||||
```typescript
|
||||
basic.clearScreen()
|
||||
```
|
||||
|
||||
It's a syntax error to have a left parenthesis without the "closing" right parenthesis:
|
||||
|
||||
```
|
||||
basic.clearScreen(
|
||||
```
|
||||
|
||||
### ~button /js/sequence
|
||||
NEXT: Sequencing Commands
|
||||
### ~
|
268
docs/js/classes.md
Normal file
268
docs/js/classes.md
Normal file
@ -0,0 +1,268 @@
|
||||
# Classes
|
||||
|
||||
Traditional JavaScript focuses on functions and prototype-based inheritance as the basic means of building up reusable components,
|
||||
but this may feel a bit awkward to programmers more comfortable with an object-oriented approach, where classes inherit functionality
|
||||
and objects are built from these classes.
|
||||
|
||||
Starting with ECMAScript 2015, also known as ECMAScript 6, JavaScript programmers will be able to build their applications using
|
||||
this object-oriented class-based approach. TypeScript, allows you to use these techniques now, compiling them
|
||||
down to JavaScript that works across all major browsers and platforms, without having to wait for the next version of JavaScript.
|
||||
|
||||
Let's take a look at a simple class-based example:
|
||||
|
||||
```ts
|
||||
class Greeter {
|
||||
greeting: string;
|
||||
constructor(message: string) {
|
||||
this.greeting = message;
|
||||
}
|
||||
greet() {
|
||||
return "Hello, " + this.greeting;
|
||||
}
|
||||
}
|
||||
|
||||
let greeter = new Greeter("world");
|
||||
```
|
||||
|
||||
We declare a new class `Greeter`. This class has three members: a property called `greeting`, a constructor, and a method `greet`.
|
||||
|
||||
You'll notice that in the class when we refer to one of the members of the class we prepend `this.`.
|
||||
This denotes that it's a member access.
|
||||
|
||||
In the last line we construct an instance of the `Greeter` class using `new`.
|
||||
This calls into the constructor we defined earlier, creating a new object with the `Greeter` shape, and running the constructor to initialize it.
|
||||
|
||||
# Inheritance
|
||||
|
||||
### ~hint
|
||||
### Inheritance is not supported yet for the micro:bit. Coming soon...
|
||||
### ~
|
||||
|
||||
In TypeScript, we can use common object-oriented patterns.
|
||||
Of course, one of the most fundamental patterns in class-based programming is being able to extend existing classes to create new ones using inheritance.
|
||||
|
||||
Let's take a look at an example:
|
||||
|
||||
```ts-ignore
|
||||
class Animal {
|
||||
name: string;
|
||||
constructor(theName: string) { this.name = theName; }
|
||||
move(distanceInMeters: number = 0) {
|
||||
console.log(`${this.name} moved ${distanceInMeters}m.`);
|
||||
}
|
||||
}
|
||||
|
||||
class Snake extends Animal {
|
||||
constructor(name: string) { super(name); }
|
||||
move(distanceInMeters = 5) {
|
||||
console.log("Slithering...");
|
||||
super.move(distanceInMeters);
|
||||
}
|
||||
}
|
||||
|
||||
class Horse extends Animal {
|
||||
constructor(name: string) { super(name); }
|
||||
move(distanceInMeters = 45) {
|
||||
console.log("Galloping...");
|
||||
super.move(distanceInMeters);
|
||||
}
|
||||
}
|
||||
|
||||
let sam = new Snake("Sammy the Python");
|
||||
let tom: Animal = new Horse("Tommy the Palomino");
|
||||
|
||||
sam.move();
|
||||
tom.move(34);
|
||||
```
|
||||
|
||||
This example covers quite a few of the inheritance features in TypeScript that are common to other languages.
|
||||
Here we see the `extends` keywords used to create a subclass.
|
||||
You can see this where `Horse` and `Snake` subclass the base class `Animal` and gain access to its features.
|
||||
|
||||
Derived classes that contain constructor functions must call `super()` which will execute the constructor function on the base class.
|
||||
|
||||
The example also shows how to override methods in the base class with methods that are specialized for the subclass.
|
||||
Here both `Snake` and `Horse` create a `move` method that overrides the `move` from `Animal`, giving it functionality specific to each class.
|
||||
Note that even though `tom` is declared as an `Animal`, since its value is a `Horse`, when `tom.move(34)` calls the overriding method in `Horse`:
|
||||
|
||||
```Text
|
||||
Slithering...
|
||||
Sammy the Python moved 5m.
|
||||
Galloping...
|
||||
Tommy the Palomino moved 34m.
|
||||
```
|
||||
|
||||
# Public, private, and protected modifiers
|
||||
|
||||
## Public by default
|
||||
|
||||
In our examples, we've been able to freely access the members that we declared throughout our programs.
|
||||
If you're familiar with classes in other languages, you may have noticed in the above examples
|
||||
we haven't had to use the word `public` to accomplish this; for instance,
|
||||
C# requires that each member be explicitly labeled `public` to be visible.
|
||||
In TypeScript, each member is `public` by default.
|
||||
|
||||
You may still mark a member `public` explicitly.
|
||||
We could have written the `Animal` class from the previous section in the following way:
|
||||
|
||||
```ts-ignore
|
||||
class Animal {
|
||||
public name: string;
|
||||
public constructor(theName: string) { this.name = theName; }
|
||||
public move(distanceInMeters: number) {
|
||||
console.log(`${this.name} moved ${distanceInMeters}m.`);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Understanding `private`
|
||||
|
||||
When a member is marked `private`, it cannot be accessed from outside of its containing class. For example:
|
||||
|
||||
```ts-ignore
|
||||
class Animal {
|
||||
private name: string;
|
||||
constructor(theName: string) { this.name = theName; }
|
||||
}
|
||||
|
||||
new Animal("Cat").name; // Error: 'name' is private;
|
||||
```
|
||||
|
||||
TypeScript is a structural type system.
|
||||
When we compare two different types, regardless of where they came from, if the types of all members are compatible, then we say the types themselves are compatible.
|
||||
|
||||
However, when comparing types that have `private` and `protected` members, we treat these types differently.
|
||||
For two types to be considered compatible, if one of them has a `private` member,
|
||||
then the other must have a `private` member that originated in the same declaration.
|
||||
The same applies to `protected` members.
|
||||
|
||||
Let's look at an example to better see how this plays out in practice:
|
||||
|
||||
```ts-ignore
|
||||
class Animal {
|
||||
private name: string;
|
||||
constructor(theName: string) { this.name = theName; }
|
||||
}
|
||||
|
||||
class Rhino extends Animal {
|
||||
constructor() { super("Rhino"); }
|
||||
}
|
||||
|
||||
class Employee {
|
||||
private name: string;
|
||||
constructor(theName: string) { this.name = theName; }
|
||||
}
|
||||
|
||||
let animal = new Animal("Goat");
|
||||
let rhino = new Rhino();
|
||||
let employee = new Employee("Bob");
|
||||
|
||||
animal = rhino;
|
||||
animal = employee; // Error: 'Animal' and 'Employee' are not compatible
|
||||
```
|
||||
|
||||
In this example, we have an `Animal` and a `Rhino`, with `Rhino` being a subclass of `Animal`.
|
||||
We also have a new class `Employee` that looks identical to `Animal` in terms of shape.
|
||||
We create some instances of these classes and then try to assign them to each other to see what will happen.
|
||||
Because `Animal` and `Rhino` share the `private` side of their shape from the same declaration of
|
||||
`private name: string` in `Animal`, they are compatible. However, this is not the case for `Employee`.
|
||||
When we try to assign from an `Employee` to `Animal` we get an error that these types are not compatible.
|
||||
Even though `Employee` also has a `private` member called `name`, it's not the one we declared in `Animal`.
|
||||
|
||||
## Understanding `protected`
|
||||
|
||||
The `protected` modifier acts much like the `private` modifier with the exception that members
|
||||
declared `protected` can also be accessed by instances of deriving classes. For example,
|
||||
|
||||
```ts-ignore
|
||||
class Person {
|
||||
protected name: string;
|
||||
constructor(name: string) { this.name = name; }
|
||||
}
|
||||
|
||||
class Employee extends Person {
|
||||
private department: string;
|
||||
|
||||
constructor(name: string, department: string) {
|
||||
super(name);
|
||||
this.department = department;
|
||||
}
|
||||
|
||||
public getElevatorPitch() {
|
||||
return `Hello, my name is ${this.name} and I work in ${this.department}.`;
|
||||
}
|
||||
}
|
||||
|
||||
let howard = new Employee("Howard", "Sales");
|
||||
console.log(howard.getElevatorPitch());
|
||||
console.log(howard.name); // error
|
||||
```
|
||||
|
||||
Notice that while we can't use `name` from outside of `Person`,
|
||||
we can still use it from within an instance method of `Employee` because `Employee` derives from `Person`.
|
||||
|
||||
A constructor may also be marked `protected`.
|
||||
This means that the class cannot be instantiated outside of its containing class, but can be extended. For example,
|
||||
|
||||
```ts-ignore
|
||||
class Person {
|
||||
protected name: string;
|
||||
protected constructor(theName: string) { this.name = theName; }
|
||||
}
|
||||
|
||||
// Employee can extend Person
|
||||
class Employee extends Person {
|
||||
private department: string;
|
||||
|
||||
constructor(name: string, department: string) {
|
||||
super(name);
|
||||
this.department = department;
|
||||
}
|
||||
|
||||
public getElevatorPitch() {
|
||||
return `Hello, my name is ${this.name} and I work in ${this.department}.`;
|
||||
}
|
||||
}
|
||||
|
||||
let howard = new Employee("Howard", "Sales");
|
||||
let john = new Person("John"); // Error: The 'Person' constructor is protected
|
||||
```
|
||||
|
||||
# Readonly modifier
|
||||
|
||||
You can make properties readonly by using the `readonly` keyword.
|
||||
Readonly properties must be initialized at their declaration or in the constructor.
|
||||
|
||||
```ts-ignore
|
||||
class Octopus {
|
||||
readonly name: string;
|
||||
readonly numberOfLegs: number = 8;
|
||||
constructor (theName: string) {
|
||||
this.name = theName;
|
||||
}
|
||||
}
|
||||
let dad = new Octopus("Man with the 8 strong legs");
|
||||
dad.name = "Man with the 3-piece suit"; // error! name is readonly.
|
||||
```
|
||||
|
||||
## Parameter properties
|
||||
|
||||
In our last example, we had to declare a readonly member `name` and a constructor parameter `theName` in the `Octopus` class, and we then immediately set `name` to `theName`.
|
||||
This turns out to be a very common practice.
|
||||
*Parameter properties* let you create and initialize a member in one place.
|
||||
Here's a further revision of the previous `Octopus` class using a parameter property:
|
||||
|
||||
```ts-ignore
|
||||
class Octopus {
|
||||
readonly numberOfLegs: number = 8;
|
||||
constructor(readonly name: string) {
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Notice how we dropped `theName` altogether and just use the shortened `readonly name: string` parameter on the constructor to create and initialize the `name` member.
|
||||
We've consolidated the declarations and assignment into one location.
|
||||
|
||||
Parameter properties are declared by prefixing a constructor parameter with an accessibility modifier or `readonly`, or both.
|
||||
Using `private` for a parameter property declares and initializes a private member; likewise, the same is done for `public`, `protected`, and `readonly`.
|
||||
|
58
docs/js/faq.md
Normal file
58
docs/js/faq.md
Normal file
@ -0,0 +1,58 @@
|
||||
# Frequently asked questions
|
||||
|
||||
# What is the language supported for the micro:bit?
|
||||
|
||||
For the micro:bit, we support a "static" subset of TypeScript (itself a superset of JavaScript):
|
||||
|
||||
## Supported language features
|
||||
|
||||
* variables with `let`, `const`, and `var`
|
||||
* functions with lexical scoping and recursion
|
||||
* top-level code in the file; hello world really is `console.log("Hello world")`
|
||||
* `if ... else if ... else` statements
|
||||
* `while` and `do ... while` loops
|
||||
* `for(;;)` loops (see below about `for ... in/of`)
|
||||
* `break/continue`; also with labeled loops
|
||||
* `switch` statement (on numbers only)
|
||||
* `debugger` statement for breakpoints
|
||||
* conditional operator `? :`; lazy boolean operators
|
||||
* namespaces (a form of modules)
|
||||
* all arithmetic operators (including bitwise operators); note that in microcontroller targets
|
||||
all arithmetic is performed on integers, also when simulating in the browser
|
||||
* strings (with a few common methods)
|
||||
* [string templates](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals) (`` `x is ${x}` ``)
|
||||
* arrow functions `() => ...`
|
||||
* classes with fields, methods and constructors; `new` keyword
|
||||
* array literals `[1, 2, 3]`
|
||||
* enums
|
||||
|
||||
## Unsupported language features
|
||||
|
||||
We generally stay away from the more dynamic parts of JavaScript.
|
||||
Things you may miss and we may implement:
|
||||
|
||||
* exceptions (`throw`, `try ... catch`, `try ... finally`)
|
||||
* `for ... of` statements
|
||||
* object literals `{ foo: 1, bar: "two" }`
|
||||
* method-like properties (get/set accessors)
|
||||
* class inheritance
|
||||
|
||||
For JS-only targets we may implement the following:
|
||||
|
||||
* regular expressions
|
||||
* classes implementing interfaces
|
||||
|
||||
Things that we are not very likely to implement:
|
||||
|
||||
* file-based modules (`import * from ...`, `module.exports` etc); we do support namespaces
|
||||
* spread operator
|
||||
* `yield` expression and ``function*``
|
||||
* `await` expression and `async function`
|
||||
* `typeof` expression
|
||||
* tagged templates ``tag `text ${expression} more text` ``; regular templates are supported
|
||||
* binding with arrays or objects: `let [a, b] = ...; let { x, y } = ...`
|
||||
* `with` statement
|
||||
* `eval`
|
||||
* `delete` statement
|
||||
* `for ... in` statements
|
||||
* JSX (HTML as part of JavaScript)
|
161
docs/js/functions.md
Normal file
161
docs/js/functions.md
Normal file
@ -0,0 +1,161 @@
|
||||
# Functions
|
||||
|
||||
Functions are the fundamental building block of programs. Here is the simplest
|
||||
way to make a function that adds two numbers:
|
||||
|
||||
```ts
|
||||
// Named function
|
||||
function add(x : number, y : number) {
|
||||
return x + y;
|
||||
}
|
||||
|
||||
basic.showNumber(add(1, 2))
|
||||
```
|
||||
|
||||
### ~ hint
|
||||
For the micro:bit, you must specify a [type](/js/types) for each function parameter.
|
||||
### ~
|
||||
|
||||
Functions can refer to variables outside of the function body.
|
||||
When they do so, they're said to `capture` these variables.
|
||||
|
||||
```ts
|
||||
let z = 100;
|
||||
|
||||
function addToZ(x: number, y: number) {
|
||||
return x + y + z;
|
||||
}
|
||||
|
||||
basic.showNumber(addToZ(1, 2))
|
||||
```
|
||||
|
||||
## Typing the function
|
||||
|
||||
Let's add a return type to our add function:
|
||||
|
||||
```ts
|
||||
function add(x: number, y: number): number {
|
||||
return x + y;
|
||||
}
|
||||
```
|
||||
|
||||
TypeScript can figure the return type out by looking at the return statements, so you can optionally leave this off in many cases.
|
||||
|
||||
# Optional and Default Parameters
|
||||
|
||||
In TypeScript, the number of arguments given to a function has to match the number of parameters the function expects.
|
||||
|
||||
```ts-ignore
|
||||
function buildName(firstName: string, lastName: string) {
|
||||
return firstName + " " + lastName;
|
||||
}
|
||||
|
||||
let result1 = buildName("Bob"); // error, too few parameters
|
||||
let result2 = buildName("Bob", "Adams", "Sr."); // error, too many parameters
|
||||
let result3 = buildName("Bob", "Adams"); // ah, just right
|
||||
```
|
||||
|
||||
In JavaScript, every parameter is optional, and users may leave them off as they see fit.
|
||||
When they do, their value is `undefined`.
|
||||
We can get this functionality in TypeScript by adding a `?` to the end of parameters we want to be optional.
|
||||
For example, let's say we want the last name parameter from above to be optional:
|
||||
|
||||
```ts-ignore
|
||||
function buildName(firstName: string, lastName?: string) {
|
||||
if (lastName)
|
||||
return firstName + " " + lastName;
|
||||
else
|
||||
return firstName;
|
||||
}
|
||||
|
||||
let result1 = buildName("Bob"); // works correctly now
|
||||
let result2 = buildName("Bob", "Adams", "Sr."); // error, too many parameters
|
||||
let result3 = buildName("Bob", "Adams"); // ah, just right
|
||||
```
|
||||
|
||||
Any optional parameters must follow required parameters.
|
||||
Had we wanted to make the first name optional rather than the last name, we would need to change the order of parameters in the function, putting the first name last in the list.
|
||||
|
||||
In TypeScript, we can also set a value that a parameter will be assigned if the user does not provide one, or if the user passes `undefined` in its place.
|
||||
These are called default-initialized parameters.
|
||||
Let's take the previous example and default the last name to `"Smith"`.
|
||||
|
||||
```ts-ignore
|
||||
function buildName(firstName: string, lastName = "Smith") {
|
||||
return firstName + " " + lastName;
|
||||
}
|
||||
|
||||
let result1 = buildName("Bob"); // works correctly now, returns "Bob Smith"
|
||||
let result2 = buildName("Bob", undefined); // still works, also returns "Bob Smith"
|
||||
let result3 = buildName("Bob", "Adams", "Sr."); // error, too many parameters
|
||||
let result4 = buildName("Bob", "Adams"); // ah, just right
|
||||
```
|
||||
|
||||
Default-initialized parameters that come after all required parameters are treated as optional, and just like optional parameters, can be omitted when calling their respective function.
|
||||
This means optional parameters and trailing default parameters will share commonality in their types, so both
|
||||
|
||||
```ts
|
||||
function buildName(firstName: string, lastName?: string) {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
and
|
||||
|
||||
```ts
|
||||
function buildName(firstName: string, lastName = "Smith") {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
share the same type `(firstName: string, lastName?: string) => string`.
|
||||
The default value of `lastName` disappears in the type, only leaving behind the fact that the parameter is optional.
|
||||
|
||||
Unlike plain optional parameters, default-initialized parameters don't *need* to occur after required parameters.
|
||||
If a default-initialized parameter comes before a required parameter, users need to explicitly pass `undefined` to get the default initialized value.
|
||||
For example, we could write our last example with only a default initializer on `firstName`:
|
||||
|
||||
```ts-ignore
|
||||
function buildName(firstName = "Will", lastName: string) {
|
||||
return firstName + " " + lastName;
|
||||
}
|
||||
|
||||
let result1 = buildName("Bob"); // error, too few parameters
|
||||
let result2 = buildName("Bob", "Adams", "Sr."); // error, too many parameters
|
||||
let result3 = buildName("Bob", "Adams"); // okay and returns "Bob Adams"
|
||||
let result4 = buildName(undefined, "Adams"); // okay and returns "Will Adams"
|
||||
```
|
||||
|
||||
# Rest Parameters
|
||||
|
||||
Required, optional, and default parameters all have one thing in common: they talk about one parameter at a time.
|
||||
Sometimes, you want to work with multiple parameters as a group, or you may not know how many parameters a function will ultimately take.
|
||||
In JavaScript, you can work with the arguments directly using the `arguments` variable that is visible inside every function body.
|
||||
|
||||
In TypeScript, you can gather these arguments together into a variable:
|
||||
|
||||
```ts-ignore
|
||||
function buildName(firstName: string, ...restOfName: string[]) {
|
||||
return firstName + " " + restOfName.join(" ");
|
||||
}
|
||||
|
||||
let employeeName = buildName("Joseph", "Samuel", "Lucas", "MacKinzie");
|
||||
```
|
||||
|
||||
*Rest parameters* are treated as a boundless number of optional parameters.
|
||||
When passing arguments for a rest parameter, you can use as many as you want; you can even pass none.
|
||||
The compiler will build an array of the arguments passed in with the name given after the ellipsis (`...`), allowing you to use it in your function.
|
||||
|
||||
The ellipsis is also used in the type of the function with rest parameters:
|
||||
|
||||
```ts-ignore
|
||||
function buildName(firstName: string, ...restOfName: string[]) {
|
||||
return firstName + " " + restOfName.join(" ");
|
||||
}
|
||||
|
||||
let buildNameFun: (fname: string, ...rest: string[]) => string = buildName;
|
||||
```
|
||||
|
||||
### ~button /js/types
|
||||
NEXT: Types
|
||||
### ~
|
0
docs/js/inference.md
Normal file
0
docs/js/inference.md
Normal file
30
docs/js/operators.md
Normal file
30
docs/js/operators.md
Normal file
@ -0,0 +1,30 @@
|
||||
## Operators
|
||||
|
||||
The following JavaScript operators are supported for the micro:bit.
|
||||
|
||||
### ~hint
|
||||
Note that for the micro:bit all arithmetic is performed on integers, rather than floating point.
|
||||
This also is true when simulating in the browser.
|
||||
### ~
|
||||
|
||||
# Assignment, arithmetic and bitwise
|
||||
|
||||
* assignment operators - [read more](http://devdocs.io/javascript/operators/assignment_operators)
|
||||
* arithmetic operators - [read more](http://devdocs.io/javascript/operators/arithmetic_operators)
|
||||
* bitwise operators - [read more](http://devdocs.io/javascript/operators/bitwise_operators)
|
||||
|
||||
# Comparision and conditional
|
||||
|
||||
* comparison operators - [read more](http://devdocs.io/javascript/operators/comparison_operators)
|
||||
* conditional operator - [read more](http://devdocs.io/javascript/operators/conditional_operator)
|
||||
|
||||
## More
|
||||
|
||||
* lambda functions `() => { ... }`
|
||||
* array literals `[1, 2, 3]`
|
||||
* strings, with a few common methods
|
||||
* [string templates](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals) (`` `x is ${x}` ``)
|
||||
|
||||
### ~button /js/statements
|
||||
NEXT: Statements
|
||||
### ~
|
63
docs/js/sequence.md
Normal file
63
docs/js/sequence.md
Normal file
@ -0,0 +1,63 @@
|
||||
# Sequencing
|
||||
|
||||
By calling one function after another, in sequence, you can create an animation:
|
||||
|
||||
```typescript
|
||||
basic.showLeds(`
|
||||
. # . # .
|
||||
. . . . .
|
||||
. . # . .
|
||||
# . . . #
|
||||
. # # # .
|
||||
`);
|
||||
basic.showLeds(`
|
||||
. # . # .
|
||||
. . . . .
|
||||
. . . . .
|
||||
. # # # .
|
||||
# . . . #
|
||||
`);
|
||||
```
|
||||
|
||||
### The semicolon
|
||||
|
||||
In JavaScript, the semicolon (;) is used to terminate (or end) a statement. However, in most
|
||||
cases, the semicolon is optional and can be omitted. So both code sequences below are
|
||||
legal:
|
||||
|
||||
```typescript
|
||||
basic.showNumber(1)
|
||||
basic.showNumber(2)
|
||||
```
|
||||
|
||||
```typescript
|
||||
basic.showNumber(1);
|
||||
basic.showNumber(2);
|
||||
```
|
||||
|
||||
### The empty statement
|
||||
|
||||
In JavaScript, there is the concept of an *empty statement*, which is whitespace followed by
|
||||
a semicolon in the context where a statement is expected.
|
||||
So, the following code is an infinite loop
|
||||
followed by a call to `showNumber` that will never execute:
|
||||
```typescript
|
||||
while(true) ;
|
||||
basic.showNumber(1);
|
||||
```
|
||||
|
||||
|
||||
### ~hint
|
||||
For the micro:bit, we don't allow a program to contain an empty statement, such as shown above.
|
||||
If you really want an empty statement, you need to use curly braces to delimit an empty statement block:
|
||||
```typescript
|
||||
while(true) { }
|
||||
basic.showNumber(1);
|
||||
```
|
||||
### ~
|
||||
|
||||
[Read more](http://inimino.org/~inimino/blog/javascript_semicolons) about semicolons in JavaScript.
|
||||
|
||||
### ~button /js/variables
|
||||
NEXT: Variable Declarations
|
||||
### ~
|
33
docs/js/statements.md
Normal file
33
docs/js/statements.md
Normal file
@ -0,0 +1,33 @@
|
||||
# Statements
|
||||
|
||||
The following JavaScript statements are supported for the micro:bit:
|
||||
|
||||
## Variable declarations
|
||||
* `const` statement - [read more](http://devdocs.io/javascript/statements/const)
|
||||
* `let` statement - [read more](http://devdocs.io/javascript/statements/let)
|
||||
* `var` statement - [read more](http://devdocs.io/javascript/statements/var)
|
||||
|
||||
## Block-structured statements
|
||||
|
||||
* `{ }` block statement - [read more](http://devdocs.io/javascript/statements/block)
|
||||
* `if-else` conditional statement - [read more](http://devdocs.io/javascript/statements/if...else)
|
||||
* `while` loop - [read more](http://devdocs.io/javascript/statements/do...while)
|
||||
* `do-while` loop - [read more](http://devdocs.io/javascript/statements/do...while)
|
||||
* `for(;;)` loop - [read more](http://devdocs.io/javascript/statements/for)
|
||||
* `switch` statement (on numbers only) - [read more](http://devdocs.io/javascript/statements/switch)
|
||||
|
||||
## Control-flow commands
|
||||
|
||||
* `break` statement - [read more](http://devdocs.io/javascript/statements/break)
|
||||
* `continue` statement - [read more](http://devdocs.io/javascript/statements/continue)
|
||||
* `return` statement - [read more](http://devdocs.io/javascript/statements/return)
|
||||
* `debugger` statement for breakpoints - [read more](http://devdocs.io/javascript/statements/debugger)
|
||||
|
||||
## Labelling statements
|
||||
|
||||
* labelled statement - [read more](http://devdocs.io/javascript/statements/label)
|
||||
* `default` statement - [read more](http://devdocs.io/javascript/statements/default)
|
||||
|
||||
### ~button /js/functions
|
||||
NEXT: Functions
|
||||
### ~
|
140
docs/js/types.md
Normal file
140
docs/js/types.md
Normal file
@ -0,0 +1,140 @@
|
||||
# Types
|
||||
|
||||
For programs to be useful, we need to be able to work with some of the simplest units of data:
|
||||
numbers, strings, structures, boolean values, and the like.
|
||||
|
||||
# Boolean
|
||||
|
||||
The most basic datatype is the simple true/false value, which is called a `boolean` value.
|
||||
|
||||
```ts
|
||||
let isDone: boolean = false;
|
||||
```
|
||||
|
||||
# Number
|
||||
|
||||
### ~ hint
|
||||
In JavaScript, `numbers` are floating point values.
|
||||
However, for the micro:bit, `numbers` are integer values.
|
||||
### ~
|
||||
|
||||
Integer values can be specified via decimal, hexadecimal and octal notation:
|
||||
|
||||
```ts
|
||||
let decimal: number = 42;
|
||||
let hex: number = 0xf00d;
|
||||
let binary: number = 0b1010;
|
||||
let octal: number = 0o744;
|
||||
```
|
||||
|
||||
# String
|
||||
|
||||
As in other languages, we use the type `string` to refer to textual data.
|
||||
Use double quotes (`"`) or single quotes (`'`) to surround string data.
|
||||
|
||||
```ts
|
||||
let color: string = "blue";
|
||||
color = 'red';
|
||||
```
|
||||
|
||||
You can also use *template strings*, which can span multiple lines and have embedded expressions.
|
||||
These strings are surrounded by the backtick/backquote (`` ` ``) character, and embedded expressions are of the form `${ expr }`.
|
||||
|
||||
```ts
|
||||
let fullName: string = `Bob Bobbington`;
|
||||
let age: number = 37;
|
||||
let sentence: string = `Hello, my name is ${ fullName }.
|
||||
|
||||
I'll be ${ age + 1 } years old next month.`
|
||||
```
|
||||
|
||||
This is equivalent to declaring `sentence` like so:
|
||||
|
||||
```ts
|
||||
let sentence: string = "Hello, my name is " + fullName + ".\n\n" +
|
||||
"I'll be " + (age + 1) + " years old next month."
|
||||
```
|
||||
|
||||
# Array
|
||||
|
||||
Arrays allow you to work with an expandable sequence of values, addressed by an integer-valued index.
|
||||
Array types can be written in one of two ways.
|
||||
In the first, you use the type of the elements followed by `[]` to denote an array of that element type:
|
||||
|
||||
```ts
|
||||
let list: number[] = [1, 2, 3];
|
||||
```
|
||||
|
||||
The second way uses a generic array type, `Array<elemType>`:
|
||||
|
||||
```ts
|
||||
let list: Array<number> = [1, 2, 3];
|
||||
```
|
||||
|
||||
### ~hint
|
||||
For the micro:bit, all elements of an array must have the same type.
|
||||
### ~
|
||||
|
||||
|
||||
# Enum
|
||||
|
||||
A helpful addition to the standard set of datatypes from JavaScript is the `enum`.
|
||||
As in languages like C#, an enum is a way of giving more friendly names to sets of numeric values.
|
||||
|
||||
```ts
|
||||
enum Color {Red, Green, Blue};
|
||||
let c: Color = Color.Green;
|
||||
```
|
||||
|
||||
By default, enums begin numbering their members starting at `0`.
|
||||
You can change this by manually setting the value of one of its members.
|
||||
For example, we can start the previous example at `1` instead of `0`:
|
||||
|
||||
```ts
|
||||
enum Color {Red = 1, Green, Blue};
|
||||
let c: Color = Color.Green;
|
||||
```
|
||||
|
||||
Or, even manually set all the values in the enum:
|
||||
|
||||
```ts
|
||||
enum Color {Red = 1, Green = 2, Blue = 4};
|
||||
let c: Color = Color.Green;
|
||||
```
|
||||
|
||||
# Any
|
||||
|
||||
The TypeScript type `any` is not supported in the micro:bit.
|
||||
|
||||
|
||||
# Void
|
||||
|
||||
`void` is the absence of having any type at all.
|
||||
You may commonly see this as the return type of functions that do not return a value:
|
||||
|
||||
```ts
|
||||
function warnUser(): void {
|
||||
basic.showString("This is my warning message");
|
||||
}
|
||||
```
|
||||
|
||||
Declaring variables of type `void` is not useful.
|
||||
|
||||
# Type Inference
|
||||
|
||||
In TypeScript, there are several places where type inference is used to provide type information when there is
|
||||
no explicit type annotation. For example, in this code
|
||||
|
||||
```ts
|
||||
let x = 3;
|
||||
let y = x + 3
|
||||
```
|
||||
|
||||
The type of the `x` variable is inferred to be `number`. Similarly, the type of `y` variable also is inferred to be `number`.
|
||||
This kind of inference takes place when initializing variables and members,
|
||||
setting parameter default values, and determining function return types.
|
||||
|
||||
|
||||
### ~button /js/classes
|
||||
NEXT: Classes
|
||||
### ~
|
121
docs/js/variables.md
Normal file
121
docs/js/variables.md
Normal file
@ -0,0 +1,121 @@
|
||||
# Variable Declarations
|
||||
|
||||
Declaring a variable in JavaScript has always traditionally been done with the `var` keyword.
|
||||
|
||||
```typescript
|
||||
var a = 10;
|
||||
```
|
||||
|
||||
The `var` construct has some [problems](http://www.typescriptlang.org/docs/handbook/variable-declarations.html),
|
||||
which is why `let` statements were introduced. Apart from the keyword used, `let` statements are written
|
||||
the same way `var` statements are.
|
||||
|
||||
```typescript
|
||||
let a = 10;
|
||||
```
|
||||
|
||||
The key difference is not in the syntax, but in the semantics, which we'll now dive into.
|
||||
|
||||
## Block-scoping
|
||||
|
||||
When a variable is declared using `let`, it uses what some call *lexical-scoping* or *block-scoping*.
|
||||
Unlike variables declared with `var` whose scopes leak out to their containing function,
|
||||
block-scoped variables are not visible outside of their nearest containing block or `for`-loop.
|
||||
|
||||
```typescript
|
||||
function f(input: boolean) {
|
||||
let a = 100;
|
||||
|
||||
if (input) {
|
||||
// Still okay to reference 'a'
|
||||
let b = a + 1;
|
||||
return b;
|
||||
}
|
||||
|
||||
// Error: 'b' doesn't exist here
|
||||
return b;
|
||||
}
|
||||
```
|
||||
|
||||
Here, we have two local variables `a` and `b`.
|
||||
`a`'s scope is limited to the body of `f` while `b`'s scope is limited to the containing `if` statement's block.
|
||||
|
||||
Another property of block-scoped variables is that they can't be read or written to before they're actually declared.
|
||||
While these variables are "present" throughout their scope, all points up until their declaration are part of their *temporal dead zone*.
|
||||
This is just a sophisticated way of saying you can't access them before the `let` statement, and luckily TypeScript will let you know that.
|
||||
|
||||
```typescript-ignore
|
||||
a++; // illegal to use 'a' before it's declared;
|
||||
let a;
|
||||
```
|
||||
|
||||
## Re-declarations
|
||||
|
||||
With `var` declarations, it doesn't matter how many times you declare your variables, you just get one:
|
||||
|
||||
```typescript
|
||||
var x = 10;
|
||||
var x = 20;
|
||||
```
|
||||
|
||||
In the above example, all declarations of `x` actually refer to the *same* `x`, and this is perfectly valid.
|
||||
This often ends up being a source of bugs. Thankfully, `let` declarations are not as forgiving.
|
||||
|
||||
```typescript
|
||||
let x = 10;
|
||||
let x = 20; // error: can't re-declare 'x' in the same scope
|
||||
```
|
||||
|
||||
## Shadowing
|
||||
|
||||
The act of introducing a new name in a more deeply nested scope is called *shadowing*.
|
||||
It is a bit of a double-edged sword in that it can introduce certain bugs on its own in the
|
||||
event of accidental shadowing, while also preventing certain bugs.
|
||||
For instance, imagine a `sumMatrix` function using `let` variables.
|
||||
|
||||
```typescript
|
||||
function sumMatrix(matrix: number[][]) {
|
||||
let sum = 0;
|
||||
for (let i = 0; i < matrix.length; i++) {
|
||||
var currentRow = matrix[i];
|
||||
for (let i = 0; i < currentRow.length; i++) {
|
||||
sum += currentRow[i];
|
||||
}
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
```
|
||||
|
||||
This version of the loop will actually perform the summation correctly because the inner loop's `i` shadows `i` from the outer loop.
|
||||
Shadowing should *usually* be avoided in the interest of write clearer code, such as
|
||||
|
||||
```typescript
|
||||
function sumMatrix(matrix: number[][]) {
|
||||
let sum = 0;
|
||||
for (let i = 0; i < matrix.length; i++) {
|
||||
var currentRow = matrix[i];
|
||||
for (let j = 0; j < currentRow.length; j++) {
|
||||
sum += currentRow[j];
|
||||
}
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
```
|
||||
While there are some scenarios where it may be fitting to take advantage of it, you should use your best judgement.
|
||||
|
||||
# `const` declarations
|
||||
|
||||
`const` declarations are another way of declaring variables.
|
||||
|
||||
```typescript
|
||||
const numLivesForCat = 9;
|
||||
```
|
||||
|
||||
They are like `let` declarations but, as their name implies, their value cannot be changed once they are bound.
|
||||
In other words, they have the same scoping rules as `let`, but you can't re-assign to them.
|
||||
|
||||
### ~button /js/operators
|
||||
NEXT: Operators
|
||||
### ~
|
@ -41,7 +41,7 @@ Now let's add some more types of instructions for the player to follow. Let's ad
|
||||
/**
|
||||
* {highlight}
|
||||
*/
|
||||
export function newAction_() {
|
||||
export function newAction() {
|
||||
action = Math.random(4) // ***
|
||||
if (action == 0) {
|
||||
basic.showString("PUSH A", 150) // ***
|
||||
@ -62,7 +62,7 @@ export function newAction_() {
|
||||
|
||||
Now let's implement `PRESS PIN 0` in the main. Create a condition of `input->on pin pressed("P0")` that will add one to the score and calls the method `new action`.
|
||||
|
||||
```
|
||||
```blocks
|
||||
// **. . .**
|
||||
input.onButtonPressed(Button.B, () => {
|
||||
basic.showNumber(game.score(), 150) // ***
|
||||
|
@ -86,3 +86,7 @@ Have fun reviewing your simulation and analyze the acceleration by chart the Exc
|
||||
* The first person and second person take turns tilting the micro:bit in the "x" direction while the other player charts the data on the micro:bit!
|
||||
* Review and analyze the actual micro:bit device acceleration data on Excel
|
||||
* Display acceleration with y or z using plot bar graph by changing acceleration from "x" to "y" or "z"
|
||||
|
||||
```package
|
||||
microbit-radio
|
||||
```
|
@ -34,8 +34,7 @@ Let's code the third part of Happy Birthday!
|
||||
|
||||
To do this, you need to add blocks after the last line of the `play` blocks. We want to continue to adding musical chords with the `play` block. Then insert the appropriate chord blocks `G`, `E`, `C`, `B`, `A` to complete the third part of the song. Modify your code so that your code looks like this.
|
||||
|
||||
``` blocks
|
||||
|
||||
```blocks
|
||||
music.playTone(music.noteFrequency(Note.C), music.beat(BeatFraction.Quater));
|
||||
music.playTone(music.noteFrequency(Note.C), music.beat(BeatFraction.Quater));
|
||||
music.playTone(music.noteFrequency(Note.D), music.beat(BeatFraction.Quater));
|
||||
@ -57,8 +56,7 @@ music.playTone(music.noteFrequency(Note.F), music.beat(BeatFraction.Quater));
|
||||
music.playTone(music.noteFrequency(Note.E), music.beat(BeatFraction.Quater));
|
||||
music.playTone(music.noteFrequency(Note.D), music.beat(BeatFraction.Quater));
|
||||
basic.pause(100);
|
||||
|
||||
```
|
||||
```
|
||||
|
||||
* click *run * to see if the code works as expected.
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
Your beginning code should look like this:
|
||||
|
||||
```blocks
|
||||
let coll = (<string[]>[])
|
||||
let coll: string[] = []
|
||||
coll.push("puppy")
|
||||
coll.push("clock")
|
||||
coll.push("night")
|
||||
@ -27,7 +27,7 @@ game.startCountdown(30000)
|
||||
Let's add more words for the player to act out! But first, we need to increase the time in one round to give the player more time get through all the words. Let's change the `game->start countdown` statement.
|
||||
|
||||
```blocks
|
||||
let coll = (<string[]>[])
|
||||
let coll: string[] = []
|
||||
coll.push("puppy")
|
||||
coll.push("clock")
|
||||
coll.push("night")
|
||||
@ -52,7 +52,8 @@ game.startCountdown(60000)
|
||||
Now let's add 5 more words to our list of charade words. Right above the the line `word:=coll->at(index)` add 5 lines that say `coll->add("")`. In this example, we will add the words **bicycle, telephone, sun, car, and ant** but you can add whatever words you like.
|
||||
|
||||
```blocks
|
||||
let coll.push("puppy")
|
||||
let coll: string[] = []
|
||||
coll.push("puppy")
|
||||
coll.push("clock")
|
||||
coll.push("night")
|
||||
coll.push("cat")
|
||||
|
@ -19,7 +19,7 @@ A 'collection' is a group of variables of the same type stored together. A 'coll
|
||||
## 2. Consider the following lines of code.
|
||||
|
||||
```blocks
|
||||
let coll = (<string[]>[])
|
||||
let coll: string[] = []
|
||||
coll.push("puppy")
|
||||
coll.push("clock")
|
||||
```
|
||||
@ -35,7 +35,7 @@ basic.showString(coll[0], 150)
|
||||
## 3. Consider the following lines of code.
|
||||
|
||||
```blocks
|
||||
let coll = (<string[]>[])
|
||||
let coll: string[] = []
|
||||
coll.push("puppy")
|
||||
coll.push("clock")
|
||||
coll.push("cat")
|
||||
@ -52,7 +52,7 @@ basic.showString(coll[2], 150)
|
||||
## 4. Consider the following line of code.
|
||||
|
||||
```blocks
|
||||
let coll = (<string[]>[])
|
||||
let coll: string[] = []
|
||||
```
|
||||
|
||||
Write the five (5) lines of code that will add the following five words to `data->coll`: puppy, clock, night, cat, cow.
|
||||
@ -60,7 +60,8 @@ Write the five (5) lines of code that will add the following five words to `data
|
||||
<br/>
|
||||
|
||||
```blocks
|
||||
let coll.push("puppy")
|
||||
let coll: string[] = []
|
||||
coll.push("puppy")
|
||||
coll.push("clock")
|
||||
coll.push("night")
|
||||
coll.push("cat")
|
||||
@ -72,6 +73,7 @@ coll.push("cow")
|
||||
<br/>
|
||||
|
||||
```blocks
|
||||
let coll: string[] = []
|
||||
let index = Math.random(coll.length)
|
||||
let word = coll[index]
|
||||
```
|
||||
|
@ -39,7 +39,7 @@ coll.push("cat")
|
||||
|
||||
## 4. Write the five (5) lines of code that will add the following five words to `data->coll`: puppy, clock, night, cat, cow.
|
||||
|
||||
```
|
||||
```ts
|
||||
let coll = (<string[]>[])
|
||||
```
|
||||
|
||||
|
@ -211,7 +211,7 @@ Let's setup the logic for the food and the ghost to be in different quadrants. F
|
||||
let hero = game.createSprite(2, 2);
|
||||
let food = game.createSprite(4, 4);
|
||||
let ghost = game.createSprite(0, 0);
|
||||
let ghost.change(LedSpriteProperty.Blink, 100);
|
||||
ghost.change(LedSpriteProperty.Blink, 100);
|
||||
food = led.brightness() == 8;
|
||||
while (true) {
|
||||
basic.pause(400);
|
||||
@ -265,7 +265,7 @@ while (true) {
|
||||
}
|
||||
|
||||
}
|
||||
0.set(LedSpriteProperty.X, 4);
|
||||
ghost.set(LedSpriteProperty.X, 4);
|
||||
|
||||
|
||||
```
|
||||
|
@ -42,3 +42,7 @@ radio.onDataReceived(() => { })
|
||||
* learn how to conditionally run code depending on whether a condition is true or not
|
||||
* learn how to run code when an input button is pressed
|
||||
* learn how to pause your code for the specified number of milliseconds
|
||||
|
||||
```package
|
||||
microbit-radio
|
||||
```
|
@ -162,3 +162,7 @@ radio.onDataReceived(() => {
|
||||
Connect the first micro:bit to your computer using your USB cable and run the pogo script on it.
|
||||
Connect the second micro:bit to your computer using your USB cable and run the pogo script on it.
|
||||
The first person and second person take turns jumping in the “y” direction while the other player uses the micro:bit to track the results on the micro:bit!
|
||||
|
||||
```package
|
||||
microbit-radio
|
||||
```
|
@ -33,3 +33,7 @@ radio.receiveNumber();
|
||||
* learn how to return the sum of the two numbers
|
||||
* learn how to get acceleration value in milli-gravitys
|
||||
* learn how to read the connector value as analog as a value comprised between 0 and 1023
|
||||
|
||||
```package
|
||||
microbit-radio
|
||||
```
|
@ -195,4 +195,6 @@ Let's select Style 10 as an example.
|
||||
* The first person and second person take shaking or moving the micor:bit in any direction while the other player charts the data on the micro:bit!
|
||||
* Review and analyze the actual micro:bit device acceleration data on Excel
|
||||
|
||||
|
||||
```package
|
||||
microbit-radio
|
||||
```
|
@ -21,10 +21,10 @@ let count = 0
|
||||
## 3. If the rectangle below represents the BBC micro:bit, shade the areas that will be displayed after two button presses on Button A. Explain why that particular area is shaded.
|
||||
|
||||
```blocks
|
||||
let count_ = 0
|
||||
let count = 0
|
||||
input.onButtonPressed(Button.A, () => {
|
||||
count_ = count_ + 1
|
||||
basic.showNumber(count_, 100)
|
||||
count = count + 1
|
||||
basic.showNumber(count, 100)
|
||||
})
|
||||
```
|
||||
|
||||
@ -37,10 +37,10 @@ After two button presses, **count** will be equal to 2.
|
||||
## 5. If the rectangle below represents the BBC micro:bit, shade the areas that will be displayed after five button presses on Button A. Explain why that particular area is shaded.
|
||||
|
||||
```blocks
|
||||
let count_ = 0
|
||||
let count = 0
|
||||
input.onButtonPressed(Button.A, () => {
|
||||
count_ = count_ + 1
|
||||
basic.showNumber(count_, 100)
|
||||
count = count + 1
|
||||
basic.showNumber(count, 100)
|
||||
})
|
||||
```
|
||||
|
||||
|
@ -23,10 +23,10 @@ let count = 0
|
||||
## 3. Draw which LED is ON after running this code and pressing Button A twice. Explain why you chose to draw that number
|
||||
|
||||
```blocks
|
||||
let count_ = 0
|
||||
let count = 0
|
||||
input.onButtonPressed(Button.A, () => {
|
||||
count_ = count_ + 1
|
||||
basic.showNumber(count_, 100)
|
||||
count = count + 1
|
||||
basic.showNumber(count, 100)
|
||||
})
|
||||
```
|
||||
|
||||
@ -37,10 +37,10 @@ input.onButtonPressed(Button.A, () => {
|
||||
## 4. Draw which LED is ON after running this code and pressing Button A five times. Explain why you chose to draw that number.
|
||||
|
||||
```blocks
|
||||
let count_ = 0
|
||||
let count = 0
|
||||
input.onButtonPressed(Button.A, () => {
|
||||
count_ = count_ + 1
|
||||
basic.showNumber(count_, 100)
|
||||
count = count + 1
|
||||
basic.showNumber(count, 100)
|
||||
})
|
||||
```
|
||||
|
||||
|
@ -15,7 +15,7 @@ Write the line of code to measure the acceleration and then store in it a variab
|
||||
<br/>
|
||||
|
||||
```blocks
|
||||
let accX_ = input.acceleration("x")
|
||||
let accX = input.acceleration("x")
|
||||
```
|
||||
|
||||
Note: acceleration does not have be measured in the "x" direction. It can also be in the "y" or "z" direction.
|
||||
|
@ -2,8 +2,13 @@
|
||||
|
||||
The editor is open source on GitHub under the MIT license. Contributions are welcome, please check our GitHub repos.
|
||||
|
||||
### Repos
|
||||
### Source Code
|
||||
|
||||
* [microsoft/pxt-microbit](https://github.com/Microsoft/pxt-microbit), PXT target for BBC micro:bit, also includes the documentation.
|
||||
* [microbit/pxt](https://github.com/Microsoft/pxt), programming experience toolkit (PXT)
|
||||
* [microsoft/pxt-microbit-core](https://github.com/Microsoft/pxt-microbit-core), Yotta module used to build the BBC micro:bit runtime
|
||||
|
||||
## C++ Runtime
|
||||
|
||||
The [C++ micro:bit runtime](http://lancaster-university.github.io/microbit-docs/), created at [Lancaster University](http://www.lancaster.ac.uk/), provides access to the hardware functions of the micro:bit,
|
||||
as well as a set of helper functions (such as displaying a number/image/string on the LED screen).
|
||||
|
@ -1,11 +1,7 @@
|
||||
# Ten Projects
|
||||
|
||||
### ~avatar avatar
|
||||
# Projects
|
||||
|
||||
Here are some cool projects that you can build with your micro:bit!
|
||||
|
||||
### ~
|
||||
|
||||
|
||||
```codecard
|
||||
[{
|
||||
@ -18,7 +14,7 @@ Here are some cool projects that you can build with your micro:bit!
|
||||
"imageUrl": "/static/mb/projects/a2-buttons.png"
|
||||
},{
|
||||
"name": "Love Meter",
|
||||
"url":"/projects/lover-meter",
|
||||
"url":"/projects/love-meter",
|
||||
"imageUrl":"/static/mb/projects/a3-pins.png"
|
||||
},{
|
||||
"name": "Rock Paper Scissors",
|
||||
@ -51,5 +47,6 @@ Here are some cool projects that you can build with your micro:bit!
|
||||
}]
|
||||
```
|
||||
|
||||
### See Also
|
||||
|
||||
|
||||
[Flashing Heart](/projects/flashing-heart), [Smiley Buttons](/projects/smiley-buttons), [Love Meter](/projects/love-meter), [Rock Paper Scissors](/projects/rock-paper-scissors), [Compass](/projects/compass), [Hack your headphones](/projects/hack-your-headphones), [Banana keyboard](/projects/banana-keyboard), [Telegraph](/projects/telegraph), [Radio](/projects/radio), [Watch](/projects/the-watch)
|
@ -59,5 +59,6 @@ input.onPinPressed(TouchPin.P2, () => {
|
||||
|
||||
* click *run* to see if the code works as expected.
|
||||
|
||||
|
||||
|
||||
### ~button /projects/telegraph
|
||||
NEXT: Telegraph
|
||||
### ~
|
@ -104,3 +104,6 @@ basic.forever(() => {
|
||||
});
|
||||
```
|
||||
|
||||
### ~button /projects/hack-your-headphones
|
||||
NEXT: Hack Your Headphones
|
||||
### ~
|
@ -112,4 +112,8 @@ basic.pause(500);
|
||||
basic.clearScreen();
|
||||
basic.pause(500);
|
||||
})
|
||||
```
|
||||
```
|
||||
|
||||
### ~button /projects/smiley-buttons
|
||||
NEXT: Smiley Buttons
|
||||
### ~
|
@ -71,3 +71,6 @@ input.onButtonPressed(Button.A, () => {
|
||||
|
||||
* click *compile* and run your code on the micro:bit.
|
||||
|
||||
### ~button /projects/banana-keyboard
|
||||
NEXT: Banana Keyboard
|
||||
### ~
|
@ -47,4 +47,8 @@ input.onPinPressed(TouchPin.P2, () => {
|
||||
. . # . .
|
||||
`);
|
||||
});
|
||||
```
|
||||
```
|
||||
|
||||
### ~button /projects/rock-paper-scissors
|
||||
NEXT: Rock Paper Scissors
|
||||
### ~
|
65
docs/projects/messenger.md
Normal file
65
docs/projects/messenger.md
Normal file
@ -0,0 +1,65 @@
|
||||
# messenger
|
||||
|
||||

|
||||
|
||||
Use the radio to create an app that sends "YO" messages.
|
||||
|
||||
## Step 1
|
||||
|
||||
Use [on button pressed](/reference/input/on-button-pressed) to send the number "0" over radio.
|
||||
|
||||
```blocks
|
||||
input.onButtonPressed(Button.A, () => {
|
||||
radio.sendNumber(0);
|
||||
});
|
||||
```
|
||||
|
||||
## Step 2
|
||||
|
||||
Use [radio on data received](/reference/radio/on-data-received) display "YO" when the number ``0`` is received
|
||||
by radio.
|
||||
|
||||
```blocks
|
||||
let message = 0;
|
||||
radio.onDataReceived(() => {
|
||||
message = radio.receiveNumber();
|
||||
if (message == 0) {
|
||||
basic.showString("YO")
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
Compile the program and **upload the same .hex file to 2 devices!**
|
||||
|
||||
## Step 3
|
||||
|
||||
Use [on button pressed](/reference/input/on-button-pressed) to send the number "1" over radio.
|
||||
|
||||
```blocks
|
||||
input.onButtonPressed(Button.B, () => {
|
||||
radio.sendNumber(1);
|
||||
});
|
||||
```
|
||||
|
||||
## Step 4
|
||||
|
||||
Add blocks in [radio on data received](/reference/radio/on-data-received) to display "BYE" when the number ``1`` is received
|
||||
by radio.
|
||||
|
||||
```blocks
|
||||
let message = 0;
|
||||
radio.onDataReceived(() => {
|
||||
message = radio.receiveNumber();
|
||||
if (message == 0) {
|
||||
basic.showString("YO")
|
||||
}
|
||||
if (message == 1) {
|
||||
basic.showString("BYE")
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
|
||||
```package
|
||||
microbit-radio
|
||||
```
|
@ -86,3 +86,11 @@ Have fun reviewing your simulation and analyze the acceleration by chart the Exc
|
||||
* The first person and second person take turns tilting the micro:bit in the "x" direction while the other player charts the data on the micro:bit!
|
||||
* Review and analyze the actual micro:bit device acceleration data on Excel
|
||||
* Display acceleration with y or z using plot bar graph by changing acceleration from "x" to "y" or "z"
|
||||
|
||||
### ~button /projects/the-watch
|
||||
NEXT: The Watch
|
||||
### ~
|
||||
|
||||
```package
|
||||
microbit-radio
|
||||
```
|
@ -235,3 +235,7 @@ input.onButtonPressed(Button.B, () => {
|
||||
|
||||
How else can you make your game better?
|
||||
Ever hear of [Rock Paper Scissors Spock Lizard](http://www.samkass.com/theories/RPSSL.html)?
|
||||
|
||||
### ~button /projects/compass
|
||||
NEXT: Compass
|
||||
### ~
|
@ -66,4 +66,8 @@ input.onButtonPressed(Button.B, () => {
|
||||
# . . . #
|
||||
. # # # .`);
|
||||
});
|
||||
```
|
||||
```
|
||||
|
||||
### ~button /projects/love-meter
|
||||
NEXT: Love Meter
|
||||
### ~
|
@ -1,12 +1,12 @@
|
||||
# telegraph activity
|
||||
|
||||
Build a telgraph.
|
||||
Build a telegraph.
|
||||
|
||||
# micro:bit telegraph
|
||||
|
||||
Have you ever tried to communicate through a telegraph? Let's try coding a "Telegraph" on two BBC micro:bits !
|
||||
|
||||
Complete the following [guided tutorial](/projects/telegraph), your hack should look like this:
|
||||
Complete the following [tutorial](/projects/telegraph), your hack should look like this:
|
||||
|
||||

|
||||
|
||||
@ -108,3 +108,7 @@ Your telegraph is ready!
|
||||
* Connect the first micro:bit to your computer using your USB cable and put the telegraph script on it.
|
||||
* Connect the second micro:bit to your computer using your USB cable and run the telegraph script on it.
|
||||
* The first person and second person take turns pressing button A to play the telegraph game!
|
||||
|
||||
### ~button /projects/radio
|
||||
NEXT: Radio
|
||||
### ~
|
@ -148,12 +148,6 @@ Trim any leftover fabric, threads or tape.
|
||||
|
||||
Your watch is ready!
|
||||
|
||||
### ~avatar avatar
|
||||
|
||||
Excellent, you're ready to continue with the [challenges](/projects/rock-paper-scissors)!
|
||||
|
||||
### ~
|
||||
|
||||
### Acknowledgements
|
||||
|
||||
Artistic design by Melinda Hoeneisen.
|
||||
|
@ -21,4 +21,20 @@ serial.writeNumber(0);
|
||||
control.inBackground(() => {
|
||||
|
||||
});
|
||||
```
|
||||
```
|
||||
## Advanced
|
||||
|
||||
```namespaces
|
||||
devices.tellCameraTo(MesCameraEvent.TakePhoto);
|
||||
bluetooth.onBluetoothConnected(() => {});
|
||||
```
|
||||
|
||||
```package
|
||||
microbit-radio
|
||||
microbit-devices
|
||||
microbit-bluetooth
|
||||
```
|
||||
|
||||
### See Also
|
||||
|
||||
[basic](/reference/basic), [input](/reference/input), [music](/reference/music), [led](/reference/led), [Math (blocks)](/blocks/math), [String](/reference/types/string), [game](/reference/game), [images](/reference/images), [pins](/reference/pins), [serial](/reference/serial), [control](/reference/control), [radio](/reference/radio), [devices](/reference/devices), [bluetooth](/reference/bluetooth)
|
||||
|
@ -3,3 +3,7 @@
|
||||
```cards
|
||||
String.fromCharCode(0);
|
||||
```
|
||||
|
||||
### See Also
|
||||
|
||||
[fromCharCode](/reference//math/string-from-char-code)
|
||||
|
@ -32,3 +32,7 @@ basic.showAnimation(`
|
||||
. . . . .
|
||||
`);
|
||||
```
|
||||
|
||||
### See Also
|
||||
|
||||
[showNumber](/reference/basic/show-number), [showLeds](/reference/basic/show-leds), [showString](/reference/basic/show-string), [clearScreen](/reference/basic/clear-screen), [forever](/reference/basic/forever), [pause](/reference/basic/pause), [plotLeds](/reference/basic/plot-leds), [showAnimation](/reference/basic/show-animation)
|
||||
|
@ -23,7 +23,7 @@ In this animation, each row is 15 spaces wide because
|
||||
there are three frames in the animation, and each frame is
|
||||
five spaces wide, just like the screen on the BBC micro:bit.
|
||||
|
||||
```
|
||||
```blocks
|
||||
basic.showAnimation(`
|
||||
. . # . . . # # # . . # # # .
|
||||
. # # . . . . . # . . . . # .
|
||||
@ -47,7 +47,7 @@ In this animation, each row is 30 spaces wide because
|
||||
there are six frames in the animation, and each frame is
|
||||
five spaces wide, just like the screen.
|
||||
|
||||
```
|
||||
```blocks
|
||||
basic.showAnimation(`
|
||||
. . . . . # . . . . . . . . . . . . . # . . . . . # . . . .
|
||||
. . # . . . . . . . . . # . . . . . . . . . # . . . . . . .
|
||||
|
@ -9,7 +9,7 @@ basic.showString("Hello!")
|
||||
### Parameters
|
||||
|
||||
* `text` is a [String](/reference/types/string). It can contain letters, numbers, and punctuation.
|
||||
* `ms` is an optional [Number](/reference/types/number). It means the number of milliseconds before sliding the [String](/reference/types/string) left by one LED each time. Bigger intervals make the sliding slower.
|
||||
* `interval` is an optional [Number](/reference/types/number). It means the number of milliseconds before sliding the [String](/reference/types/string) left by one LED each time. Bigger intervals make the sliding slower.
|
||||
|
||||
### Examples:
|
||||
|
||||
|
28
docs/reference/bluetooth.md
Normal file
28
docs/reference/bluetooth.md
Normal file
@ -0,0 +1,28 @@
|
||||
# Bluetooth
|
||||
|
||||
Support for additional Bluetooth services.
|
||||
|
||||
```cards
|
||||
bluetooth.startAccelerometerService();
|
||||
bluetooth.startButtonService();
|
||||
bluetooth.startIOPinService();
|
||||
bluetooth.startLEDService();
|
||||
bluetooth.startMagnetometerService();
|
||||
bluetooth.startTemperatureService();
|
||||
bluetooth.uartRead("");
|
||||
bluetooth.uartWrite("");
|
||||
bluetooth.onBluetoothConnected(() => {
|
||||
|
||||
});
|
||||
bluetooth.onBluetoothDisconnected(() => {
|
||||
|
||||
});
|
||||
```
|
||||
|
||||
```package
|
||||
microbit-bluetooth
|
||||
```
|
||||
|
||||
### See Also
|
||||
|
||||
[startAccelerometerService](/reference/bluetooth/start-accelerometer-service), [startButtonService](/reference/bluetooth/start-button-service), [startIOPinService](/reference/bluetooth/start-io-pin-service), [startLEDService](/reference/bluetooth/start-led-service), [startMagnetometerService](/reference/bluetooth/start-magnetometer-service), [startTemperatureService](/reference/bluetooth/start-temperature-service), [uartRead](/reference/bluetooth/uart-read), [uartWrite](/reference/bluetooth/uart-write), [onBluetoothConnected](/reference/bluetooth/on-bluetooth-connected), [onBluetoothDisconnected](/reference/bluetooth/on-bluetooth-disconnected)
|
99
docs/reference/bluetooth/about-bluetooth.md
Executable file
99
docs/reference/bluetooth/about-bluetooth.md
Executable file
@ -0,0 +1,99 @@
|
||||
# About Bluetooth
|
||||
|
||||

|
||||
|
||||
## Introduction
|
||||
|
||||
Bluetooth is a wireless communications technology which allows devices to communicate with each other without the need for a central device like a router or access point.
|
||||
|
||||
Bluetooth has a special "low energy feature" which means it can be used without requiring much power from the devices using it. It's the Bluetooth low energy feature which the micro:bit uses.
|
||||
|
||||
In the world of Bluetooth low energy, a device has something called a "profile" which defines the way other devices are able to communicate over Bluetooth with it. In a way, the Bluetooth profile defines the way a device appears to other devices in terms of its features and the things it can do.
|
||||
|
||||
To put it another way, a Bluetooth profile is really an interface specification. It defines the data which a device has, what another device can do with that data over a Bluetooth connection and how the device with the profile should respond when a connected device acts upon its data in some way. Let's look at that description in a little more technical detail.
|
||||
|
||||
## Basic Concepts
|
||||
|
||||
A Bluetooth device contains a table of data called an Attribute Table which can be accessed by other connected devices in various possible ways. That table of data and the ways in which it can be exploited falls into a technical area of Bluetooth called the Generic Attribute profile or "GATT" for short and you may see the term GATT in some of the documentation for APIs such as those provided by the Android platform.
|
||||
|
||||
The Attribute Table contains something like a series of records of various types. The main types are called Services, Characteristics and Descriptors. Let's look at each of these terms in turn.
|
||||
|
||||
### Attributes
|
||||
|
||||
Services, Characteristics and Descriptors are all types of Attribute. Hence Generic Attribute Profile, Attribute Table and something called the Attribute Protocol. All attributes have a type which is identified by a UUID (Universally Unique Identifer). Some Attributes are defined by the Bluetooth SIG, the technical standards body for Bluetooth and these have UUIDs which are 16 bits in length. Some Attributes are custom designed for a particular device by the product team and these have 128 bit UUIDs. The micro:bit uses a mixture of 16 bit and 128 bit UUIDs.
|
||||
|
||||
### Structure
|
||||
|
||||
Services, Characteristics and Descriptors are organised in a hierarchy with Services at the top and Descriptors at the bottom. Services contain one or more Characteristics. A Characteristic owns zero or more Descriptors. Zero because Descriptors are completely optional whereas a Service must contain at least one Characteristic.
|
||||
|
||||

|
||||
|
||||
### Services
|
||||
|
||||
A Service is a container for logically related Bluetooth data items. Those data items are in fact called Characteristics. A Service can be thought of as the owner of the Characteristics inside it. Often a Service represents a particular feature (e.g. a hardware feature) of a device like the buttons or a particular sensor. An example of a Bluetooth SIG defined Service is the Device Information Service which, as the name suggests, is a container for various items of information about the device such as its manufacturer and serial number. The micro:bit has this service.
|
||||
|
||||
### Characteristics
|
||||
|
||||
Characteristics are items of data which relate to a particular internal state of the device or perhaps some state of the environment which the device can measure using a sensor. The current battery level is an example of internal state data whereas the ambient temperature could perhaps be measured by a sensor. Sometimes Characteristics represent configuration data such as the frequency at which you want something to be measured. In any of these cases, the way a device can expose such data to other devices to use via Bluetooth is by making them available as a Characteristic. An example of a Bluetooth SIG defined Characteristic is the Serial Number String which you'll find inside the Device Information service.
|
||||
|
||||
Characteristics contain various parts. They have a type, a value, some properties and some permissions.
|
||||
|
||||
Type is something already explained above, a UUID value which indicates which particular type of Characteristic an Attribute is. Value is the value of the associated state data item.
|
||||
|
||||
Properties define what another device can do with the characteristic over Bluetooth in terms of various defined operations such as READ, WRITE or NOTIFY. Reading a characteristic means transferring its current value from the attribute table to the connected device over Bluetooth. Writing allows the connected device to change that value in the state table. Notifications are a special message type which a device like the micro:bit can send to a connected device whenever the value of the associated characteristic changes or perhaps periodically, controlled by a timer. Not all Characteristics support all operations. The Characteristic's properties tell you which operations are supported.
|
||||
|
||||
Sometimes the device will have been programmed to respond in a special way when it processes an operation like reading or writing a value from the attribute table so operations can result in more happening than simply transferring data across the connection. Perhaps changing the value of a Characteristic will result in the device changing the frequency with which it samples readings from the device accelerometer for example.
|
||||
|
||||
Permissions are to do with security and further describe the security conditions that must be met before read or write access to the characteristic is to be granted.
|
||||
|
||||
### Descriptors
|
||||
|
||||
Descriptors contain meta data which either augments the details relating to the Characteristic which the Descriptor belongs to or allows the configuration of a behaviour involving that Characteristic. Notification messages are switched on or off using a special descriptor called the Client Characteristic Configuration Descriptor for example.
|
||||
|
||||
### Profile
|
||||
|
||||
A Bluetooth profile is a specification which pulls together all the required information about how a device behaves, how it can be accessed in terms of its services, characteristics and descriptors, security rules, concurrency limitations and so on.
|
||||
|
||||
## Client Server Architecture
|
||||
|
||||
When a smartphone application interacts with a device like the micro:bit over a Bluetooth connection we have a client/server architecture. The phone application is usually the GATT client and the micro:bit is usually the GATT server. They communicate using a protocol called the Attribute Protocol or just ATT for short. As a smartphone developer you work with APIs and do not have to worry about formulating ATT protocol data units and so on.
|
||||
|
||||

|
||||
|
||||
## Device Discovery
|
||||
|
||||
Everything described above relates to devices which are connected and communicating as GATT client and server. But there's a stage which precedes this where the two devices are not yet connected. How do they find each other and connect? The answer to this question is termed 'Device Discovery' and is the responsibility of another part of the Bluetooth architecture called the Generic Access Profile (GAP).
|
||||
|
||||
In GAP, one devices advertises, emitting small packets of data periodically. These packets contain information about the device doing the advertising. Other devices looking for devices to connect to perform something called scanning, receiving and processing advertising packets and filtering out those that come from devices of a type that are not of interest. Usually the user is given information about devices which are discovered and they then select one to be connected to. The device which advertises is called a Bluetooth Peripheral whereas the one doing the scanning is a Bluetooth Central device. micro:bit is a Bluetooth peripheral.
|
||||
|
||||
Bluetooth on the BBC micro:bit
|
||||
|
||||
Full documentation for the BBC micro:bit Bluetooth profile as used by this application can be found at the [Lancaster University documentation](http://lancaster-university.github.io/microbit-docs/ble/profile/) web site.
|
||||
|
||||
The micro:bit's accelerometer (motion detector), magnetometer (digital compass), two buttons on the front, LED Display, IO pins on the edge connector, internal message bus and internal temperature sensor are all exposed as Services so that applications can exploit these features of the device. In addition:
|
||||
|
||||
* the Bluetooth SIG defined Device Information Service is included to allow applications to obtain information such as firmware version details over Bluetooth
|
||||
* there's a Device Firmware Update (DFU) service which allows new micro:bit code to be flahsed to the device over Bluetooth instead of over USB
|
||||
* there's a UART service which allows arbitrary data to be exchanged with the micro:bit in a way resembling traditional serial communications.
|
||||
|
||||
Everything you can do with the micro:bit over Bluetooth is achieved through read, write and notify operations. Not all characteristics support all three so check the profile documentation. Often there are Characteristics whose purpose is to allow you to write configuration values which control other behviours. Technically these are called Control Points. For example you can specify the frequency with which accelerometer data is sampled before it is transmitted as a Notification message to your application.
|
||||
|
||||
## Want to Know More?
|
||||
|
||||
The Bluetooth SIG web site at http://www.bluetooth.com is a good place for further information about Bluetooth in general. You'll find all the SIG defined profiles, services, characteristics and descriptors there as well as the core specification for all Bluetooth technology.
|
||||
|
||||
That's it! Enjoy using Bluetooth on the BBC micro:bit!
|
||||
|
||||
Martin Woolley, Bluetooth SIG. Twitter: @bluetooth_mdw
|
||||
|
||||
#### Video
|
||||
https://www.youtube.com/watch?v=aep_GVowKfs
|
||||
|
||||
|
||||
### See also
|
||||
|
||||
[About Bluetooth](/reference/bluetooth/about-bluetooth), [micro:bit Bluetooth profile overview ](http://lancaster-university.github.io/microbit-docs/ble/profile/), [micro:bit Bluetooth profile reference](http://lancaster-university.github.io/microbit-docs/resources/bluetooth/microbit-profile-V1.9-Level-2.pdf), [Bluetooth on micro:bit resources](http://bluetooth-mdw.blogspot.co.uk/p/bbc-microbit.html), [Bluetooth SIG](https://www.bluetooth.com)
|
||||
|
||||
```package
|
||||
microbit-bluetooth
|
||||
```
|
100
docs/reference/bluetooth/bluetooth-pairing.md
Executable file
100
docs/reference/bluetooth/bluetooth-pairing.md
Executable file
@ -0,0 +1,100 @@
|
||||
# Bluetooth Pairing
|
||||
|
||||
### ~hint
|
||||

|
||||
|
||||
For another device like a smartphone to use any of the Bluetooth "services" which the micro:bit has, it must first be [paired with the micro:bit](/reference/bluetooth/bluetooth-pairing). Once paired, the other device may connect to the micro:bit and exchange data relating to many of the micro:bit's features.
|
||||
|
||||
### ~
|
||||
|
||||
### What is 'pairing'?
|
||||
|
||||
'Pairing' is what you have to do to have your micro:bit trust another device like a smartphone and similarly, have your smartphone trust your micro:bit. Why 'trust'? Well, pairing is all about security. You wouldn't usually want just anyone's smartphone connecting to your micro:bit and making it do things so by pairing *your* smartphone with *your* micro:bit you ensure that only your devices can talk to each other.
|
||||
|
||||
Once you've paired your micro:bit with another device it also means that they are able to exchange information privately, without someone else being able to "see" the data they're exchanging over the air using Bluetooth. This is accomplished by data being [encrypted](https://en.wikipedia.org/wiki/Encryption) and pairing makes it possible for devices who trust each other to encrypt and decrypt data from each other.
|
||||
|
||||
# How do you pair your micro:bit with another device?
|
||||
|
||||
Making your micro:bit pair requires you to follow some simple steps which will be described shortly. What you do with the device you're pairing it to will vary slightly depending on what that device is. We'll look at how it's done with common smartphones and tablets here too.
|
||||
|
||||
To get your micro:bit ready for pairing do the following:
|
||||
|
||||
1. Hold down buttons A and B on the front of your micro:bit together. The front is the side with two buttons and the LED display. Keep the two buttons held down. Don't let go of them yet!
|
||||
2. While still holding down buttons A and B, press and then release the reset button on the back of the micro:bit. Keep holding down buttons A and B.
|
||||
3. You should see "PAIRING MODE!" start to scroll across the micro:bit display. When you see this message start to appear you can release buttons A and B.
|
||||
4. Eventually you'll see a strange pattern on your micro:bit display. This is like your micro:bit's signature. Other people's micro:bits will probably display a different pattern.
|
||||
|
||||
Your micro:bit is now ready to be paired with the other device. Read the section below which relates to your 'other' device and watch the video too.
|
||||
|
||||
### How do you pair your micro:bit with a Windows smartphone or tablet?
|
||||
|
||||
1. Go into Settings
|
||||
2. Select Bluetooth
|
||||
3. Switch your micro:bit into 'pairing mode' using the steps above
|
||||
4. Wait until 'PAIRING MODE!' has finished scrolling across the micro:bit display. You should see your micro:bit listed on your Windows smartphone with a name something like 'BBC micro:bit [zatig]'. Note that the 5 characters in brackets at the end will vary.
|
||||
5. On the Windows smartphone, tap the micro:bit named in the device list. This will initiate the pairing process.
|
||||
6. The micro:bit will display a left pointing arrow and the Windows smartphone will pop up a box into which you will be invited to enter a "pin" (Personal Identity Number).
|
||||
7. Press button A on the micro:bit and watch carefully as the micro:bit displays a sequence of 6 random numbers. You may find it easier to write them down than to remember them.
|
||||
8. Enter the 6 digits which the micro:bit displayed into your Windows smartphone in the pop-up box provided and then select "done".
|
||||
9. If you entered the right number the micro:bit will display a tick / check mark. If you made a mistake it will display a cross or X and you should repeat the process to try again.
|
||||
|
||||
#### Video
|
||||
https://www.youtube.com/watch?v=AoW3mit7jIg
|
||||
|
||||
|
||||
### How do you pair your micro:bit with an Android smartphone or tablet?
|
||||
|
||||
1. Go into Settings
|
||||
2. Select Bluetooth
|
||||
3. Switch your micro:bit into 'pairing mode' using the steps above
|
||||
4. Wait until 'PAIRING MODE!' has finished scrolling across the micro:bit display. You should see your micro:bit listed on your Android smartphone under the heading "Available devices" with a name something like 'BBC micro:bit [zatig]'. Note that the 5 characters in brackets at the end will vary.
|
||||
5. On the Android smartphone, tap the micro:bit named in the Available devices list. This will initiate the pairing process.
|
||||
6. The micro:bit will display a left pointing arrow and the Android smartphone will pop up a box into which you will be invited to enter a "pin" (Personal Identity Number).
|
||||
7. Press button A on the micro:bit and watch carefully as the micro:bit displays a sequence of 6 random numbers. You may find it easier to write them down than to remember them.
|
||||
8. Enter the 6 digits which the micro:bit displayed into your Android smartphone in the pop-up box provided and then select "done".
|
||||
9. If you entered the right number the micro:bit will display a tick / check mark. If you made a mistake it will display a cross or X and you should repeat the process to try again.
|
||||
|
||||
#### Video
|
||||
https://www.youtube.com/watch?v=7hLBfdAGkZI
|
||||
|
||||
### How do you pair your micro:bit with an Apple iOS smartphone or tablet?
|
||||
|
||||
The steps to pair with an Apple iOS device are different to those followed for an Android or Windows device. To trigger pairing you need an application which will try to interact with your micro:bit and it's that interaction that triggers the iOS pairing process. There are many you could use but for the purposes of this documentation we'll suggest you install the "nRF Master Control Panel" (nRF MCP) application from Nordic Semiconductor. You'll find it in the Apple app store. It's a really useful Bluetooth application which will help you learn about Bluetooth as well as it having the ability to trigger the pairing process. After installing nRF MCP you should follow these steps to pair with your micro:bit:
|
||||
|
||||
1. Switch your micro:bit into 'pairing mode' using the steps above
|
||||
2. Wait until 'PAIRING MODE!' has finished scrolling across the micro:bit display.
|
||||
3. Launch the nRF MCP application. Your micro:bit should be listed and have a "Connect" button next to it.
|
||||
4. Select "Connect" to connect your Apple device to the micro:bit. This will trigger the pairing process.
|
||||
5. The micro:bit will display a left pointing arrow and the Apple device will pop up a box into which you will be invited to enter a "pin" (Personal Identity Number).
|
||||
6. Press button A on the micro:bit and watch carefully as the micro:bit displays a sequence of 6 random numbers. You may find it easier to write them down than to remember them.
|
||||
7. Enter the 6 digits which the micro:bit displayed into your Apple device in the pop-up box provided and then select "Pair".
|
||||
8. If you entered the right number the micro:bit will display a tick / check mark. If you made a mistake it will display a cross or X and you should repeat the process to try again.
|
||||
|
||||
#### Video
|
||||
https://www.youtube.com/watch?v=wslwyAMwMhs
|
||||
|
||||
|
||||
### How often do I need to pair my micro:bit with my phone?
|
||||
|
||||
You do *not* need to pair your micro:bit and smartphone or tablet every time you use them together. Pairing establishes 'trust' which will be retained until it is somehow lost. When another device wants to talk to your micro:bit it must connect to it but connecting and pairing are not the same thing.
|
||||
|
||||
There are circumstances which will result in pairing data being lost however and when this happens you will need to pair again.
|
||||
|
||||
Currently, flashing new code via a USB cable causes the micro:bit's Bluetooth pairing data to be lost. Consequently, if you do flash new code to your micro:bit using a USB cable you will need to pair again.
|
||||
|
||||
In contrast if you upload new code to your micro:bit over Bluetooth, using for example the Samsung micro:bit application for Android devices, you will not need to pair again.
|
||||
|
||||
If you do find yourself needing to pair again you will first need to remove the pairing from your other device (i.e. smartphone or tablet):
|
||||
|
||||
* On Android go into Settings/Bluetooth, select the 'cog' next to your micro:bit and then select FORGET
|
||||
* On iOS go into Settings/Bluetooth, select your micro:bit and then select Forget This Device
|
||||
* On a Windows device go into Settings/Bluetooth. Press and hold the micro:bit entry on the Windows device. A pop-up will appear with the option "delete". Select "delete" to unpair your micro:bit.
|
||||
|
||||
### See also
|
||||
|
||||
[About Bluetooth](/reference/bluetooth/about-bluetooth), [micro:bit Bluetooth profile overview ](http://lancaster-university.github.io/microbit-docs/ble/profile/), [micro:bit Bluetooth profile reference](http://lancaster-university.github.io/microbit-docs/resources/bluetooth/microbit-profile-V1.9-Level-2.pdf), [Bluetooth on micro:bit resources](http://bluetooth-mdw.blogspot.co.uk/p/bbc-microbit.html), [Bluetooth SIG](https://www.bluetooth.com)
|
||||
|
||||
|
||||
```package
|
||||
microbit-bluetooth
|
||||
```
|
37
docs/reference/bluetooth/on-bluetooth-connected.md
Executable file
37
docs/reference/bluetooth/on-bluetooth-connected.md
Executable file
@ -0,0 +1,37 @@
|
||||
# On Bluetooth Connected
|
||||
|
||||
### ~hint
|
||||

|
||||
|
||||
For another device like a smartphone to use any of the Bluetooth "services" which the micro:bit has, it must first be [paired with the micro:bit](/reference/bluetooth/bluetooth-pairing). Once paired, the other device may connect to the micro:bit and exchange data relating to many of the micro:bit's features.
|
||||
|
||||
### ~
|
||||
|
||||
This block starts an [event handler](/reference/event-handler) which in this case will run
|
||||
when something connects to your micro:bit using Bluetooth.
|
||||
|
||||
```sig
|
||||
bluetooth.onBluetoothConnected(() => {});
|
||||
```
|
||||
|
||||
### Example
|
||||
|
||||
You could use this event handler to display a letter "C" on the micro:bit LED grid so you know you have a Bluetooth connection. Or you might want to send some data you've been accumulating to your smartphone as soon as it connects to your micro:bit. Maybe you've been using the accelerometer in your micro:bit to count your steps for example. Using this event handler you could send the accumulated step count to your phone when it establishes a Bluetooth connection.
|
||||
|
||||
```blocks
|
||||
bluetooth.onBluetoothConnected(() => {
|
||||
basic.showString("C");
|
||||
});
|
||||
```
|
||||
|
||||
### Video - on Bluetooth connected
|
||||
|
||||
http://www.youtube.com/watch?v=HyBcsD9Eh6I
|
||||
|
||||
### See also
|
||||
|
||||
[About Bluetooth](/reference/bluetooth/about-bluetooth), [micro:bit Bluetooth profile overview ](http://lancaster-university.github.io/microbit-docs/ble/profile/), [micro:bit Bluetooth profile reference](http://lancaster-university.github.io/microbit-docs/resources/bluetooth/microbit-profile-V1.9-Level-2.pdf), [Bluetooth on micro:bit resources](http://bluetooth-mdw.blogspot.co.uk/p/bbc-microbit.html), [Bluetooth SIG](https://www.bluetooth.com)
|
||||
|
||||
```package
|
||||
microbit-bluetooth
|
||||
```
|
37
docs/reference/bluetooth/on-bluetooth-disconnected.md
Executable file
37
docs/reference/bluetooth/on-bluetooth-disconnected.md
Executable file
@ -0,0 +1,37 @@
|
||||
# On Bluetooth Disconnected
|
||||
|
||||
### ~hint
|
||||

|
||||
|
||||
For another device like a smartphone to use any of the Bluetooth "services" which the micro:bit has, it must first be [paired with the micro:bit](/reference/bluetooth/bluetooth-pairing). Once paired, the other device may connect to the micro:bit and exchange data relating to many of the micro:bit's features.
|
||||
|
||||
### ~
|
||||
|
||||
This block starts an [event handler](/reference/event-handler) which in this case will run when a device which is connected to your micro:bit over Bluetooth disconnects.
|
||||
|
||||
You could use this event handler to display a letter "D" on the micro:bit LED grid so you know that the Bluetooth connection has been closed.
|
||||
|
||||
```sig
|
||||
bluetooth.onBluetoothDisconnected(() => {
|
||||
});
|
||||
```
|
||||
|
||||
### Example: Displaying "D" when a Bluetooth connection to the micro:bit is closed
|
||||
|
||||
```blocks
|
||||
bluetooth.onBluetoothDisconnected(() => {
|
||||
basic.showString("D");
|
||||
});
|
||||
```
|
||||
|
||||
### Video - on Bluetooth disconnected
|
||||
|
||||
http://www.youtube.com/watch?v=HyBcsD9Eh6I
|
||||
|
||||
### See also
|
||||
|
||||
[About Bluetooth](/reference/bluetooth/about-bluetooth), [micro:bit Bluetooth profile overview ](http://lancaster-university.github.io/microbit-docs/ble/profile/), [micro:bit Bluetooth profile reference](http://lancaster-university.github.io/microbit-docs/resources/bluetooth/microbit-profile-V1.9-Level-2.pdf), [Bluetooth on micro:bit resources](http://bluetooth-mdw.blogspot.co.uk/p/bbc-microbit.html), [Bluetooth SIG](https://www.bluetooth.com)
|
||||
|
||||
```package
|
||||
microbit-bluetooth
|
||||
```
|
42
docs/reference/bluetooth/start-accelerometer-service.md
Executable file
42
docs/reference/bluetooth/start-accelerometer-service.md
Executable file
@ -0,0 +1,42 @@
|
||||
# Bluetooth Accelerometer Service
|
||||
|
||||
### ~hint
|
||||

|
||||
|
||||
For another device like a smartphone to use any of the Bluetooth "services" which the micro:bit has, it must first be [paired with the micro:bit](/reference/bluetooth/bluetooth-pairing). Once paired, the other device may connect to the micro:bit and exchange data relating to many of the micro:bit's features.
|
||||
|
||||
### ~
|
||||
|
||||
The Bluetooth accelerometer service allows another device such as a smartphone to wirelessly receive data from the micro:bit's accelerometer. An accelerometer detects motion. More precisely, it measures acceleration in one or more of three directions which we call X, Y and Z.
|
||||
|
||||
Using the Bluetooth accelerometer service you could, for example, create a smartphone application which makes a loud noise whenever your micro:bit (or the important thing you've attached it to) is moved. Or you could use your micro:bit to control the movement of a cartoon character in a game on your smartphone just by tilting the micro:bit in the direction you want the character to move in.
|
||||
|
||||
No additional code is needed on the micro:bit to use the Bluetooth accelerometer service from another device.
|
||||
|
||||
```sig
|
||||
bluetooth.startAccelerometerService();
|
||||
```
|
||||
|
||||
### Example: Starting the Bluetooth accelerometer service
|
||||
|
||||
The following code shows the Bluetooth accelerometer service being started:
|
||||
|
||||
```blocks
|
||||
bluetooth.startAccelerometerService();
|
||||
```
|
||||
|
||||
### Video - Accelerometer service demo - Starts at 0:18
|
||||
|
||||
http://www.youtube.com/watch?v=aep_GVowKfs#t=18s
|
||||
|
||||
### Advanced
|
||||
|
||||
For more advanced information on the micro:bit Bluetooth accelerometer service including information on using a smartphone, see the [Lancaster University micro:bit runtime technical documentation](http://lancaster-university.github.io/microbit-docs/ble/accelerometer-service/)
|
||||
|
||||
### See also
|
||||
|
||||
[About Bluetooth](/reference/bluetooth/about-bluetooth), [micro:bit Bluetooth profile overview ](http://lancaster-university.github.io/microbit-docs/ble/profile/), [micro:bit Bluetooth profile reference](http://lancaster-university.github.io/microbit-docs/resources/bluetooth/microbit-profile-V1.9-Level-2.pdf), [Bluetooth on micro:bit resources](http://bluetooth-mdw.blogspot.co.uk/p/bbc-microbit.html), [Bluetooth SIG](https://www.bluetooth.com)
|
||||
|
||||
```package
|
||||
microbit-bluetooth
|
||||
```
|
46
docs/reference/bluetooth/start-button-service.md
Executable file
46
docs/reference/bluetooth/start-button-service.md
Executable file
@ -0,0 +1,46 @@
|
||||
# Bluetooth Button Service
|
||||
|
||||
### ~hint
|
||||

|
||||
|
||||
For another device like a smartphone to use any of the Bluetooth "services" which the micro:bit has, it must first be [paired with the micro:bit](/reference/bluetooth/bluetooth-pairing). Once paired, the other device may connect to the micro:bit and exchange data relating to many of the micro:bit's features.
|
||||
|
||||
### ~
|
||||
|
||||
The Bluetooth button service makes it possible for another device such as a smartphone to be notified wirelessly whenever a button on the front of a micro:bit is pressed. Each of the two micro:bit buttons can be in one of three possible states:
|
||||
|
||||
* Not pressed
|
||||
* Pressed
|
||||
* Long press - pressed and held down for at least 2 seconds
|
||||
|
||||
The button service allows you to make other things which are connected to your micro:bit using Bluetooth respond in some way when you press either of the buttons. You could, for example, hide your smartphone somewhere in the room and have it make an amusing noise when you press either of the buttons on your micro:bit. We'll leave it to you to decide what would be amusing.
|
||||
|
||||
No additional code is needed on the micro:bit to use the Bluetooth button service from another device.
|
||||
|
||||
```sig
|
||||
bluetooth.startButtonService();
|
||||
```
|
||||
|
||||
### Example: Starting the Bluetooth button service
|
||||
|
||||
The following code shows the Bluetooth button service being started:
|
||||
|
||||
```blocks
|
||||
bluetooth.startButtonService();
|
||||
```
|
||||
|
||||
### Video - Button service demo - Starts at 0:59
|
||||
|
||||
http://www.youtube.com/watch?v=aep_GVowKfs
|
||||
|
||||
### Advanced
|
||||
|
||||
For more advanced information on the micro:bit Bluetooth button service including information on using a smartphone, see the [Lancaster University micro:bit runtime technical documentation](http://lancaster-university.github.io/microbit-docs/ble/button-service/)
|
||||
|
||||
### See also
|
||||
|
||||
[About Bluetooth](/reference/bluetooth/about-bluetooth), [micro:bit Bluetooth profile overview ](http://lancaster-university.github.io/microbit-docs/ble/profile/), [micro:bit Bluetooth profile reference](http://lancaster-university.github.io/microbit-docs/resources/bluetooth/microbit-profile-V1.9-Level-2.pdf), [Bluetooth on micro:bit resources](http://bluetooth-mdw.blogspot.co.uk/p/bbc-microbit.html), [Bluetooth SIG](https://www.bluetooth.com)
|
||||
|
||||
```package
|
||||
microbit-bluetooth
|
||||
```
|
@ -1,28 +1,31 @@
|
||||
# Bluetooth IO Pin Service
|
||||
|
||||
### ~hint
|
||||

|
||||
|
||||
For another device like a smartphone to use any of the Bluetooth "services" which the micro:bit has, it must first be [paired with the micro:bit](/reference/bluetooth/bluetooth-pairing). Once paired, the other device may connect to the micro:bit and exchange data relating to many of the micro:bit's features.
|
||||
|
||||
### ~
|
||||
|
||||
The Bluetooth IO pin service makes it possible for another device such as a smartphone to communicate with other electronic 'things' connected to a micro:bit's edge connector. You could for example, use your smartphone to switch on or off a light which is connected to the micro:bit or your smartphone could receive data collected from a sensor connected to the micro:bit. In fact you could do both of these things at the same time since the Bluetooth IO pin service lets you interact with multiple 'pins' on the edge conector in different ways all at the same time.
|
||||
|
||||
No additional code is needed on the micro:bit to use the Bluetooth IO pin service from another device.
|
||||
|
||||
~~~~sig
|
||||
```sig
|
||||
bluetooth.startIOPinService();
|
||||
~~~~
|
||||
```
|
||||
|
||||
### Example: Starting the Bluetooth IO pin service
|
||||
|
||||
The following code shows the Bluetooth IO pin service being started:
|
||||
|
||||
~~~~blocks
|
||||
```blocks
|
||||
bluetooth.startIOPinService();
|
||||
~~~~
|
||||
```
|
||||
|
||||
### Video - IO pin service demo starts at 3:49
|
||||
|
||||
[](
|
||||
http://www.youtube.com/watch?v=aep_GVowKfs "Click to launch YouTube video"
|
||||
)
|
||||
http://www.youtube.com/watch?v=aep_GVowKfs
|
||||
|
||||
### Advanced
|
||||
|
||||
@ -30,7 +33,8 @@ For more advanced information on the micro:bit Bluetooth IO pin service includin
|
||||
|
||||
### See also
|
||||
|
||||
[Bluetooth SIG](https://www.bluetooth.com)
|
||||
|
||||
[Bluetooth on micro:bit resources](http://bluetooth-mdw.blogspot.co.uk/p/bbc-microbit.html)
|
||||
[About Bluetooth](/reference/bluetooth/about-bluetooth), [micro:bit Bluetooth profile overview ](http://lancaster-university.github.io/microbit-docs/ble/profile/), [micro:bit Bluetooth profile reference](http://lancaster-university.github.io/microbit-docs/resources/bluetooth/microbit-profile-V1.9-Level-2.pdf), [Bluetooth on micro:bit resources](http://bluetooth-mdw.blogspot.co.uk/p/bbc-microbit.html), [Bluetooth SIG](https://www.bluetooth.com)
|
||||
|
||||
```package
|
||||
microbit-bluetooth
|
||||
```
|
||||
|
42
docs/reference/bluetooth/start-led-service.md
Executable file
42
docs/reference/bluetooth/start-led-service.md
Executable file
@ -0,0 +1,42 @@
|
||||
# Bluetooth LED Service
|
||||
|
||||
### ~hint
|
||||

|
||||
|
||||
For another device like a smartphone to use any of the Bluetooth "services" which the micro:bit has, it must first be [paired with the micro:bit](/reference/bluetooth/bluetooth-pairing). Once paired, the other device may connect to the micro:bit and exchange data relating to many of the micro:bit's features.
|
||||
|
||||
### ~
|
||||
|
||||
The Bluetooth LED service allows another device such as a smartphone to send short text strings or patterns over a Bluetooth connection to a micro:bit for display on its LED matrix. Text will scroll across the micro:bit and the speed at which it scrolls can also be controlled using the Bluetooth LED service. Devices using the LED service may also read the current state of the micro:bit's LED matrix.
|
||||
|
||||
So you could, for example, draw a smiley face in a smartphone app and at the press of a button, have it magically appear on your micro:bit on the other side of the room. Or you could program your smartphone to send a message to your micro:bit whenever your phone receives an email, SMS or social media message so you could wear your micro:bit like a smart watch and leave your phone in your bag.
|
||||
|
||||
No additional code is needed on the micro:bit to use the Bluetooth LED service from another device.
|
||||
|
||||
```sig
|
||||
bluetooth.startLEDService();
|
||||
```
|
||||
|
||||
### Example: Starting the Bluetooth LED service
|
||||
|
||||
The following code shows the Bluetooth LED service being started:
|
||||
|
||||
```blocks
|
||||
bluetooth.startLEDService();
|
||||
```
|
||||
|
||||
### Video - LED service demo starts at 2:00
|
||||
|
||||
http://www.youtube.com/watch?v=aep_GVowKfs
|
||||
|
||||
### Advanced
|
||||
|
||||
For more advanced information on the micro:bit Bluetooth LED service including information on using a smartphone, see the [Lancaster University micro:bit runtime technical documentation](http://lancaster-university.github.io/microbit-docs/ble/led-service/)
|
||||
|
||||
### See also
|
||||
|
||||
[About Bluetooth](/reference/bluetooth/about-bluetooth), [micro:bit Bluetooth profile overview ](http://lancaster-university.github.io/microbit-docs/ble/profile/), [micro:bit Bluetooth profile reference](http://lancaster-university.github.io/microbit-docs/resources/bluetooth/microbit-profile-V1.9-Level-2.pdf), [Bluetooth on micro:bit resources](http://bluetooth-mdw.blogspot.co.uk/p/bbc-microbit.html), [Bluetooth SIG](https://www.bluetooth.com)
|
||||
|
||||
```package
|
||||
microbit-bluetooth
|
||||
```
|
43
docs/reference/bluetooth/start-magnetometer-service.md
Executable file
43
docs/reference/bluetooth/start-magnetometer-service.md
Executable file
@ -0,0 +1,43 @@
|
||||
# Bluetooth Magnetometer Service
|
||||
|
||||
### ~hint
|
||||

|
||||
|
||||
For another device like a smartphone to use any of the Bluetooth "services" which the micro:bit has, it must first be [paired with the micro:bit](/reference/bluetooth/bluetooth-pairing). Once paired, the other device may connect to the micro:bit and exchange data relating to many of the micro:bit's features.
|
||||
|
||||
### ~
|
||||
|
||||
The Bluetooth magnetometer service allows another device such as a smartphone to wirelessly receive data from the micro:bit's magnetometer. The magnetometer measures the strength and direction of magnetic fields including the earth's and so it can be used as a digital compass and indicate the way the micro:bit is pointing relative to magnetic north.
|
||||
|
||||
Using the Bluetooth magnetometer service you could, for example, create a smartphone application which displays your direction of travel, updating it in real time.
|
||||
|
||||
No additional code is needed on the micro:bit to use the Bluetooth magnetometer service from another device.
|
||||
|
||||
```sig
|
||||
bluetooth.startMagnetometerService();
|
||||
```
|
||||
|
||||
### Example: Starting the Bluetooth magnetometer service
|
||||
|
||||
The following code shows the Bluetooth magnetometer service being started:
|
||||
|
||||
```blocks
|
||||
bluetooth.startMagnetometerService();
|
||||
```
|
||||
|
||||
### Video - Magnetometer service demo
|
||||
|
||||
http://www.youtube.com/watch?v=C_0VL4Gp4_U
|
||||
|
||||
### Advanced
|
||||
|
||||
For more advanced information on the micro:bit Bluetooth magnetometer service including information on using a smartphone, see the [Lancaster University micro:bit runtime technical documentation](http://lancaster-university.github.io/microbit-docs/ble/magnetometer-service/)
|
||||
|
||||
### See also
|
||||
|
||||
[About Bluetooth](/reference/bluetooth/about-bluetooth), [micro:bit Bluetooth profile overview ](http://lancaster-university.github.io/microbit-docs/ble/profile/), [micro:bit Bluetooth profile reference](http://lancaster-university.github.io/microbit-docs/resources/bluetooth/microbit-profile-V1.9-Level-2.pdf), [Bluetooth on micro:bit resources](http://bluetooth-mdw.blogspot.co.uk/p/bbc-microbit.html), [Bluetooth SIG](https://www.bluetooth.com)
|
||||
|
||||
|
||||
```package
|
||||
microbit-bluetooth
|
||||
```
|
44
docs/reference/bluetooth/start-temperature-service.md
Executable file
44
docs/reference/bluetooth/start-temperature-service.md
Executable file
@ -0,0 +1,44 @@
|
||||
# Bluetooth Temperature Service
|
||||
|
||||
### ~hint
|
||||

|
||||
|
||||
For another device like a smartphone to use any of the Bluetooth "services" which the micro:bit has, it must first be [paired with the micro:bit](/reference/bluetooth/bluetooth-pairing). Once paired, the other device may connect to the micro:bit and exchange data relating to many of the micro:bit's features.
|
||||
|
||||
### ~
|
||||
|
||||
A micro:bit is able to provide a rough measure of the current environmental temperature. It's an approximation only as in fact the temperature value is inferred from the temperature of its main processor. The Bluetooth temperature service allows another device such as a smartphone to wirelessly find out the micro:bit's current temperature reading or to receive a constant stream of temperature data values. Temperature values are expressed in degrees celsius.
|
||||
|
||||
Using the Bluetooth temperature service you could turn your smartphone or tablet into a graphical thermometer using your micro:bit as the sensor.
|
||||
|
||||
No additional code is needed on the micro:bit to use the Bluetooth temperature service from another device.
|
||||
|
||||
```sig
|
||||
bluetooth.startTemperatureService();
|
||||
```
|
||||
|
||||
### Example: Starting the Bluetooth temperature service
|
||||
|
||||
The following code shows the Bluetooth temperature service being started:
|
||||
|
||||
```blocks
|
||||
bluetooth.startTemperatureService();
|
||||
```
|
||||
|
||||
### Video - Temperature service demo - Starts at 3:05
|
||||
|
||||
http://www.youtube.com/watch?v=aep_GVowKfs
|
||||
|
||||
### Advanced
|
||||
|
||||
For more advanced information on the micro:bit Bluetooth temperature service including information on using a smartphone, see the [Lancaster University micro:bit runtime technical documentation](http://lancaster-university.github.io/microbit-docs/ble/temperature-service/)
|
||||
|
||||
### See also
|
||||
|
||||
[About Bluetooth](/reference/bluetooth/about-bluetooth), [micro:bit Bluetooth profile overview ](http://lancaster-university.github.io/microbit-docs/ble/profile/), [micro:bit Bluetooth profile reference](http://lancaster-university.github.io/microbit-docs/resources/bluetooth/microbit-profile-V1.9-Level-2.pdf), [Bluetooth on micro:bit resources](http://bluetooth-mdw.blogspot.co.uk/p/bbc-microbit.html), [Bluetooth SIG](https://www.bluetooth.com)
|
||||
|
||||
|
||||
```package
|
||||
microbit-bluetooth
|
||||
```
|
||||
|
44
docs/reference/bluetooth/start-uart-service.md
Executable file
44
docs/reference/bluetooth/start-uart-service.md
Executable file
@ -0,0 +1,44 @@
|
||||
# Bluetooth UART Service
|
||||
|
||||
### ~hint
|
||||

|
||||
|
||||
For another device like a smartphone to use any of the Bluetooth "services" which the micro:bit has, it must first be [paired with the micro:bit](/reference/bluetooth/bluetooth-pairing). Once paired, the other device may connect to the micro:bit and exchange data relating to many of the micro:bit's features.
|
||||
|
||||
### ~
|
||||
|
||||
The Bluetooth UART service allows another device such as a smartphone to exchange any data it wants to with the micro:bit, in small chunks which are intended to be joined together. [UART[(https://en.wikipedia.org/wiki/Universal_asynchronous_receiver/transmitter) stands for Universal Asynchronous Receiver Transmitter and is one way in which serial data communications can be performed, usually between two devices connected by a physical, wired connection. The Bluetooth UART service emulates the behaviour of a physical UART system and allows the exchange of a maximum of 20 bytes of data at a time in either direction.
|
||||
|
||||
When this service is used, the micro:bit sets up a 60 byte buffer and data it receives will be accumulated in the buffer until it is full. When using the UART service from your micro:bit code, you can indicate a special character which will be used to mean that the entire message in at most three chunks has now been sent by the other, connected device, at which point the micro:bit will release the entire contents of its buffer to any code trying to read it. In other words this special character, known as a 'delimiter' is used by the device connected to the micro:bit to mean "I've sent my whole message, you can now use it".
|
||||
|
||||
You could use the UART service for many things. It doesn't care what you put in messages which makes it very flexible. You could create a guessing game, with questions and answers passing between micro:bit and a smartphone or you could connect a camera to the micro:bit and transmit image data obtained from the edge connector, in chunks over Bluetooth to a smartphone. There are a great many possibilities.
|
||||
|
||||
To use the Bluetooth UART service from another device you'll need additional micro:bit code which reads and uses data from the UART buffer and / or writes data to the buffer for transmission over Bluetooth to another device.
|
||||
|
||||
```sig
|
||||
bluetooth.startUartService();
|
||||
```
|
||||
|
||||
### Example: Starting the Bluetooth UART service
|
||||
|
||||
The following code shows the Bluetooth UART service being started:
|
||||
|
||||
```blocks
|
||||
bluetooth.startUartService();
|
||||
```
|
||||
|
||||
### Video - UART service guessing game
|
||||
|
||||
https://www.youtube.com/watch?v=PgGeWddMAZ0
|
||||
|
||||
### Advanced
|
||||
|
||||
For more advanced information on the micro:bit Bluetooth UART service including information on using a smartphone, see the [Lancaster University micro:bit runtime technical documentation](http://lancaster-university.github.io/microbit-docs/ble/uart-service/)
|
||||
|
||||
### See also
|
||||
|
||||
[About Bluetooth](/reference/bluetooth/about-bluetooth), [micro:bit Bluetooth profile overview ](http://lancaster-university.github.io/microbit-docs/ble/profile/), [micro:bit Bluetooth profile reference](http://lancaster-university.github.io/microbit-docs/resources/bluetooth/microbit-profile-V1.9-Level-2.pdf), [Bluetooth on micro:bit resources](http://bluetooth-mdw.blogspot.co.uk/p/bbc-microbit.html), [Bluetooth SIG](https://www.bluetooth.com)
|
||||
|
||||
```package
|
||||
microbit-bluetooth
|
||||
```
|
52
docs/reference/bluetooth/uart-read.md
Executable file
52
docs/reference/bluetooth/uart-read.md
Executable file
@ -0,0 +1,52 @@
|
||||
# UART Read
|
||||
|
||||
### ~hint
|
||||

|
||||
|
||||
For another device like a smartphone to use any of the Bluetooth "services" which the micro:bit has, it must first be [paired with the micro:bit](/reference/bluetooth/bluetooth-pairing). Once paired, the other device may connect to the micro:bit and exchange data relating to many of the micro:bit's features.
|
||||
|
||||
### ~
|
||||
|
||||
The [Bluetooth UART service](start-uart-service.md) allows another device such as a smartphone to exchange any data it wants to with the micro:bit, in small chunks.
|
||||
|
||||
With the Bluetooth UART service running, this block allows a micro:bit to read data which has been received from a Bluetooth connected device, terminating reading and returning the value obtained as soon as a specified delimiter character is encountered. This means that connected devices can send data to the micro:bit and indicate that the complete message has been sent by appending the message with the delimiter character.
|
||||
|
||||
```sig
|
||||
bluetooth.uartRead("");
|
||||
```
|
||||
|
||||
### Example: Starting the Bluetooth UART service and then reading data received from another device which is terminated by ":" character and then displaying it
|
||||
|
||||
```blocks
|
||||
let uartData = "";
|
||||
let connected = 0;
|
||||
basic.showString("UART");
|
||||
bluetooth.onBluetoothConnected(() => {
|
||||
basic.showString("C");
|
||||
connected = 1;
|
||||
while (connected == 1) {
|
||||
uartData = bluetooth.uartRead(":");
|
||||
basic.showString(uartData);
|
||||
}
|
||||
});
|
||||
bluetooth.onBluetoothDisconnected(() => {
|
||||
basic.showString("D");
|
||||
});
|
||||
|
||||
```
|
||||
|
||||
### Video - UART service guessing game
|
||||
|
||||
https://www.youtube.com/watch?v=PgGeWddMAZ0
|
||||
|
||||
### Advanced
|
||||
|
||||
For more advanced information on the micro:bit Bluetooth UART service including information on using a smartphone, see the [Lancaster University micro:bit runtime technical documentation](http://lancaster-university.github.io/microbit-docs/ble/uart-service/)
|
||||
|
||||
### See also
|
||||
|
||||
[About Bluetooth](/reference/bluetooth/about-bluetooth), [micro:bit Bluetooth profile overview ](http://lancaster-university.github.io/microbit-docs/ble/profile/), [micro:bit Bluetooth profile reference](http://lancaster-university.github.io/microbit-docs/resources/bluetooth/microbit-profile-V1.9-Level-2.pdf), [Bluetooth on micro:bit resources](http://bluetooth-mdw.blogspot.co.uk/p/bbc-microbit.html), [Bluetooth SIG](https://www.bluetooth.com)
|
||||
|
||||
```package
|
||||
microbit-bluetooth
|
||||
```
|
51
docs/reference/bluetooth/uart-write.md
Executable file
51
docs/reference/bluetooth/uart-write.md
Executable file
@ -0,0 +1,51 @@
|
||||
# UART Write
|
||||
|
||||
### ~hint
|
||||

|
||||
|
||||
For another device like a smartphone to use any of the Bluetooth "services" which the micro:bit has, it must first be [paired with the micro:bit](/reference/bluetooth/bluetooth-pairing). Once paired, the other device may connect to the micro:bit and exchange data relating to many of the micro:bit's features.
|
||||
|
||||
### ~
|
||||
|
||||
The [Bluetooth UART service](start-uart-service.md) allows another device such as a smartphone to exchange any data it wants to with the micro:bit, in small chunks.
|
||||
|
||||
With the Bluetooth UART service running, this block allows a micro:bit to send data to a Bluetooth connected device.
|
||||
|
||||
```sig
|
||||
bluetooth.uartWrite("");
|
||||
```
|
||||
|
||||
### Example: Starting the Bluetooth UART service and then sending "HELLO" whenever button A is pressed and another device has connected over Bluetooth
|
||||
|
||||
```blocks
|
||||
let connected = 0;
|
||||
bluetooth.onBluetoothConnected(() => {
|
||||
basic.showString("C");
|
||||
connected = 1;
|
||||
});
|
||||
bluetooth.onBluetoothDisconnected(() => {
|
||||
basic.showString("D");
|
||||
connected = 0;
|
||||
});
|
||||
input.onButtonPressed(Button.A, () => {
|
||||
if (connected == 1) {
|
||||
bluetooth.uartWrite("HELLO");
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
### Video - UART service guessing game
|
||||
|
||||
https://www.youtube.com/watch?v=PgGeWddMAZ0
|
||||
|
||||
### Advanced
|
||||
|
||||
For more advanced information on the micro:bit Bluetooth UART service including information on using a smartphone, see the [Lancaster University micro:bit runtime technical documentation](http://lancaster-university.github.io/microbit-docs/ble/uart-service/)
|
||||
|
||||
### See also
|
||||
|
||||
[About Bluetooth](/reference/bluetooth/about-bluetooth), [micro:bit Bluetooth profile overview ](http://lancaster-university.github.io/microbit-docs/ble/profile/), [micro:bit Bluetooth profile reference](http://lancaster-university.github.io/microbit-docs/resources/bluetooth/microbit-profile-V1.9-Level-2.pdf), [Bluetooth on micro:bit resources](http://bluetooth-mdw.blogspot.co.uk/p/bbc-microbit.html), [Bluetooth SIG](https://www.bluetooth.com)
|
||||
|
||||
```package
|
||||
microbit-bluetooth
|
||||
```
|
@ -8,3 +8,7 @@ control.inBackground(() => {
|
||||
});
|
||||
control.reset();
|
||||
```
|
||||
|
||||
### See Also
|
||||
|
||||
[inBackground](/reference/control/in-background), [reset](/reference/control/reset)
|
||||
|
11
docs/reference/control/device-name.md
Normal file
11
docs/reference/control/device-name.md
Normal file
@ -0,0 +1,11 @@
|
||||
# Device Name
|
||||
|
||||
Gets a friendly name for the device derived from the its serial number.
|
||||
|
||||
```sig
|
||||
control.deviceName();
|
||||
```
|
||||
|
||||
**This is an advanced API.** For more information, see the
|
||||
[micro:bit runtime messageBus documentation](https://lancaster-university.github.io/microbit-docs/ubit/messageBus/).
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user